diff options
Diffstat (limited to 'vendor/github.com/dsoprea/go-photoshop-info-format/info.go')
-rw-r--r-- | vendor/github.com/dsoprea/go-photoshop-info-format/info.go | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/vendor/github.com/dsoprea/go-photoshop-info-format/info.go b/vendor/github.com/dsoprea/go-photoshop-info-format/info.go new file mode 100644 index 000000000..7f17fa6c0 --- /dev/null +++ b/vendor/github.com/dsoprea/go-photoshop-info-format/info.go @@ -0,0 +1,119 @@ +package photoshopinfo + +import ( + "fmt" + "io" + + "encoding/binary" + + "github.com/dsoprea/go-logging" +) + +var ( + defaultByteOrder = binary.BigEndian +) + +// Photoshop30InfoRecord is the data for one parsed Photoshop-info record. +type Photoshop30InfoRecord struct { + // RecordType is the record-type. + RecordType string + + // ImageResourceId is the image resource-ID. + ImageResourceId uint16 + + // Name is the name of the record. It is optional and will be an empty- + // string if not present. + Name string + + // Data is the raw record data. + Data []byte +} + +// String returns a descriptive string. +func (pir Photoshop30InfoRecord) String() string { + return fmt.Sprintf("RECORD-TYPE=[%s] IMAGE-RESOURCE-ID=[0x%04x] NAME=[%s] DATA-SIZE=(%d)", pir.RecordType, pir.ImageResourceId, pir.Name, len(pir.Data)) +} + +// ReadPhotoshop30InfoRecord parses a single photoshop-info record. +func ReadPhotoshop30InfoRecord(r io.Reader) (pir Photoshop30InfoRecord, err error) { + defer func() { + if state := recover(); state != nil { + err = log.Wrap(state.(error)) + } + }() + + recordType := make([]byte, 4) + _, err = io.ReadFull(r, recordType) + if err != nil { + if err == io.EOF { + return pir, err + } + + log.Panic(err) + } + + // TODO(dustin): Move BigEndian to constant/config. + + irId := uint16(0) + err = binary.Read(r, defaultByteOrder, &irId) + log.PanicIf(err) + + nameSize := uint8(0) + err = binary.Read(r, defaultByteOrder, &nameSize) + log.PanicIf(err) + + // Add an extra byte if the two length+data size is odd to make the total + // bytes read even. + doAddPadding := (1+nameSize)%2 == 1 + if doAddPadding == true { + nameSize++ + } + + name := make([]byte, nameSize) + _, err = io.ReadFull(r, name) + log.PanicIf(err) + + // If the last byte is padding, truncate it. + if doAddPadding == true { + name = name[:nameSize-1] + } + + dataSize := uint32(0) + err = binary.Read(r, defaultByteOrder, &dataSize) + log.PanicIf(err) + + data := make([]byte, dataSize+dataSize%2) + _, err = io.ReadFull(r, data) + log.PanicIf(err) + + data = data[:dataSize] + + pir = Photoshop30InfoRecord{ + RecordType: string(recordType), + ImageResourceId: irId, + Name: string(name), + Data: data, + } + + return pir, nil +} + +// ReadPhotoshop30Info parses a sequence of photoship-info records from the stream. +func ReadPhotoshop30Info(r io.Reader) (pirIndex map[uint16]Photoshop30InfoRecord, err error) { + pirIndex = make(map[uint16]Photoshop30InfoRecord) + + for { + pir, err := ReadPhotoshop30InfoRecord(r) + if err != nil { + if err == io.EOF { + break + } + + log.Panic(err) + } + + pirIndex[pir.ImageResourceId] = pir + } + + return pirIndex, nil +} |