1
0
mirror of https://github.com/imgproxy/imgproxy.git synced 2026-05-16 09:18:09 +02:00
Files
imgproxy/imagemeta/photoshop/photoshop.go
T
2023-05-29 21:27:47 +03:00

86 lines
1.4 KiB
Go

package photoshop
import (
"bytes"
"encoding/binary"
"errors"
)
var (
ps3Header = []byte("Photoshop 3.0\x00")
ps3BlockHeader = []byte("8BIM")
errInvalidPS3Header = errors.New("invalid Photoshop 3.0 header")
)
const (
IptcKey = "\x04\x04"
ResolutionKey = "\x03\xed"
)
type PhotoshopMap map[string][]byte
func Parse(data []byte, m PhotoshopMap) error {
buf := bytes.NewBuffer(data)
if !bytes.Equal(buf.Next(14), ps3Header) {
return errInvalidPS3Header
}
// Read blocks
// Minimal block size is 12 (4 blockHeader + 2 resoureceID + 2 name + 4 blockSize)
for buf.Len() >= 12 {
if !bytes.Equal(buf.Bytes()[:4], ps3BlockHeader) {
buf.Next(1)
continue
}
// Skip block header
buf.Next(4)
resoureceID := buf.Next(2)
// Skip name
// Name is zero terminated string padded to even
for buf.Len() > 0 && buf.Next(2)[1] != 0 {
}
if buf.Len() < 4 {
break
}
blockSize := int(binary.BigEndian.Uint32(buf.Next(4)))
if buf.Len() < blockSize {
break
}
blockData := buf.Next(blockSize)
m[string(resoureceID)] = blockData
}
return nil
}
func (m PhotoshopMap) Dump() []byte {
buf := new(bytes.Buffer)
buf.Grow(26)
buf.Write(ps3Header)
for id, data := range m {
if len(data) == 0 {
continue
}
buf.Write(ps3BlockHeader)
buf.WriteString(id)
// Write empty name
buf.Write([]byte{0, 0})
binary.Write(buf, binary.BigEndian, uint32(len(data)))
buf.Write(data)
}
return buf.Bytes()
}