diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..975d61a --- /dev/null +++ b/.gitignore @@ -0,0 +1,47 @@ +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio + +*.iml + +## Directory-based project format: +.idea/ +# if you remove the above rule, at least ignore the following: + +# User-specific stuff: +# .idea/workspace.xml +# .idea/tasks.xml +# .idea/dictionaries + +# Sensitive or high-churn files: +# .idea/dataSources.ids +# .idea/dataSources.xml +# .idea/sqlDataSources.xml +# .idea/dynamic.xml +# .idea/uiDesigner.xml + +# Gradle: +# .idea/gradle.xml +# .idea/libraries + +# Mongo Explorer plugin: +# .idea/mongoSettings.xml + +## File-based project format: +*.ipr +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +.DS_Store diff --git a/ase.go b/ase.go index 7fb78ee..6440e3e 100755 --- a/ase.go +++ b/ase.go @@ -42,6 +42,8 @@ func Decode(r io.Reader) (ase ASE, err error) { // decode the block container b.Read(r) + ase.Blocks = append(ase.Blocks, b) + // switch on block type switch b.Type { case color: @@ -95,26 +97,13 @@ func DecodeFile(file string) (ase ASE, err error) { return Decode(f) } -// TODO: complete encode method -func Encode(ase ASE, w io.Writer) (err error) { - - // write signature - - // write version - - // write number of blocks - - // write details of each block - - return -} - type ASE struct { signature [4]uint8 version [2]int16 numBlocks int32 Colors []Color Groups []Group + Blocks []block } // ASE Files start are signed with ASEF at the beginning of the file @@ -133,6 +122,81 @@ func (ase *ASE) readSignature(r io.Reader) (err error) { return } +func Encode(ase ASE, w io.Writer) (err error) { + + if err = ase.writeSignature(w); err != nil { + return + } + + if err = ase.writeVersion(w); err != nil { + return + } + + if err = ase.writeNumBlock(w); err != nil { + return + } + + var g Group + + //Group color index + j := 0 + + //Group index + k := 0 + + //Color index + l := 0 + + + // itereate based on our block count + for i := 0; i < int(ase.numBlocks); i++ { + + b := ase.Blocks[i] + + if err = b.Write(w); err != nil { + return + } + + switch b.Type { + case color: + c := Color{} + + if g.Name == "" { + c = ase.Colors[l] + l++ + } else { + c = g.Colors[j] + j++ + } + + + if err = c.write(w); err != nil { + return + } + + break + case groupStart: + g = ase.Groups[k] + if err = g.write(w); err != nil { + return + } + + k++ + break + case groupEnd: + g = Group{} + j = 0 + break + default: + err = ErrInvalidBlockType + return + } + + } + + return +} + // ASE version. Should be 1.0 func (ase *ASE) readVersion(r io.Reader) error { return binary.Read(r, binary.BigEndian, &ase.version) @@ -147,3 +211,15 @@ func (ase *ASE) readNumBlock(r io.Reader) error { func (ase *ASE) Signature() string { return string(ase.signature[0:]) } + +func (ase *ASE) writeSignature(w io.Writer) error { + return binary.Write(w, binary.BigEndian, ase.signature) +} + +func (ase *ASE) writeVersion(w io.Writer) error { + return binary.Write(w, binary.BigEndian, ase.version) +} + +func (ase *ASE) writeNumBlock(w io.Writer) error { + return binary.Write(w, binary.BigEndian, ase.numBlocks) +} diff --git a/ase_test.go b/ase_test.go index 364bbe3..2a71c58 100644 --- a/ase_test.go +++ b/ase_test.go @@ -4,10 +4,11 @@ import ( "log" "os" "testing" + "reflect" ) func TestDecode(t *testing.T) { - testFile := "testfiles/test.ase" + testFile := "samples/test.ase" // open our test file f, err := os.Open(testFile) @@ -26,7 +27,7 @@ func TestDecode(t *testing.T) { } func TestDecodeFile(t *testing.T) { - testFile := "testfiles/test.ase" + testFile := "samples/test.ase" ase, err := DecodeFile(testFile) if err != nil { @@ -38,7 +39,7 @@ func TestDecodeFile(t *testing.T) { } func TestSignature(t *testing.T) { - testFile := "testfiles/test.ase" + testFile := "samples/test.ase" ase, err := DecodeFile(testFile) if err != nil { @@ -49,3 +50,50 @@ func TestSignature(t *testing.T) { t.Error("file signature is invalid") } } + + +func TestEncode(t *testing.T) { + // open the file + f, err := os.Open("samples/test.ase") + if err != nil { + t.Error(err) + } + + output, err := Decode(f) + if err != nil { + t.Error(err) + } + + f.Close() + + fo, err := os.Create("samples/test-4.ase") + + err = Encode(output, fo) + + if err != nil { + t.Error(err) + } + + fo.Close() + + + //Decode previously created *.ase file + fTest4, err := os.Open("samples/test-4.ase") + + if err != nil { + t.Error(err) + } + + outputTest4, err := Decode(fTest4) + if err != nil { + t.Error(err) + } + + //Ensure they are equal + if isEqual := reflect.DeepEqual(output, outputTest4); isEqual == false { + t.Error("Did not produce identical structs") + } + + fTest4.Close() + +} diff --git a/block.go b/block.go index 55bb2eb..b5e9016 100755 --- a/block.go +++ b/block.go @@ -46,3 +46,23 @@ func (block *block) readType(r io.Reader) error { func (block *block) readLength(r io.Reader) error { return binary.Read(r, binary.BigEndian, &block.Length) } + +func (b *block) Write(w io.Writer) (err error) { + if err = b.writeType(w); err != nil { + return + } + + if err= b.writeLength(w); err != nil { + return + } + + return +} + +func (block *block) writeType(w io.Writer) error { + return binary.Write(w, binary.BigEndian, block.Type) +} + +func (block *block) writeLength(w io.Writer) error { + return binary.Write(w, binary.BigEndian, block.Length) +} \ No newline at end of file diff --git a/color.go b/color.go index 1615a60..38b9e42 100755 --- a/color.go +++ b/color.go @@ -140,3 +140,81 @@ func (color *Color) readColorType(r io.Reader) (err error) { return } + +func (color *Color) write(w io.Writer) (err error) { + if err = color.writeColorNameLength(w); err != nil { + return + } + + if err = color.writeColorName(w); err != nil { + return + } + + if err = color.writeColorModel(w); err != nil { + return + } + + if err = color.writeColorValues(w); err != nil { + return + } + + if err = color.writeColorType(w); err != nil { + return + } + + return +} + +func (color *Color) writeColorName(w io.Writer) error { + colorNameSlice := []rune(color.Name) + colorNameSlice = append(colorNameSlice, 0) + colorName := utf16.Encode(colorNameSlice) + return binary.Write(w, binary.BigEndian, colorName) +} + +func (color *Color) writeColorModel(w io.Writer) error { + colorSlice := []byte(color.Model) + + //If color model is either RGB or LAB append space (0x20) + if color.Model == "RGB" || color.Model == "LAB" { + colorSlice = append(colorSlice, 0x20) + } + + return binary.Write(w,binary.BigEndian, colorSlice) +} + +func (color *Color) writeColorValues(w io.Writer) error { + var err error + for _, cv := range color.Values { + + err = binary.Write(w,binary.BigEndian, cv) + + if(err != nil){ + return err + } + } + return err +} + +func (color *Color) writeColorType(w io.Writer) error { + var cType int16 + switch color.Type { + case "Global": + cType = 0 + break + case "Spot": + cType = 1 + break + case "Normal": + cType = 2 + break + default: + return ErrInvalidColorType + + } + return binary.Write(w, binary.BigEndian, cType) +} + +func (color *Color) writeColorNameLength(w io.Writer) error { + return binary.Write(w, binary.BigEndian, color.nameLen) +} \ No newline at end of file diff --git a/group.go b/group.go index 295a796..80ded38 100755 --- a/group.go +++ b/group.go @@ -13,6 +13,7 @@ type Group struct { } func (group *Group) read(r io.Reader) (err error) { + if err = group.readNameLen(r); err != nil { return } @@ -36,3 +37,26 @@ func (group *Group) readName(r io.Reader) (err error) { return } + +func (group *Group) write(w io.Writer) (err error){ + if err = group.writeNameLen(w); err != nil { + return + } + + if err = group.writeName(w); err != nil { + return + } + + return +} + +func (group *Group) writeNameLen(w io.Writer) error { + return binary.Write(w, binary.BigEndian, group.nameLen) +} + +func (group *Group) writeName(w io.Writer) error { + groupNameSlice := []rune(group.Name) + groupNameSlice = append(groupNameSlice, 0) + groupName := utf16.Encode(groupNameSlice) + return binary.Write(w, binary.BigEndian, groupName) +} diff --git a/testfiles/out.ase b/samples/out.ase similarity index 100% rename from testfiles/out.ase rename to samples/out.ase diff --git a/testfiles/test-2.ase b/samples/test-2.ase similarity index 100% rename from testfiles/test-2.ase rename to samples/test-2.ase diff --git a/testfiles/test.ase b/samples/test-4.ase similarity index 100% rename from testfiles/test.ase rename to samples/test-4.ase diff --git a/samples/test.ase b/samples/test.ase new file mode 100644 index 0000000..dc5cc5c Binary files /dev/null and b/samples/test.ase differ