diff options
Diffstat (limited to 'vendor/codeberg.org/superseriousbusiness/exif-terminator/webp.go')
-rw-r--r-- | vendor/codeberg.org/superseriousbusiness/exif-terminator/webp.go | 88 |
1 files changed, 48 insertions, 40 deletions
diff --git a/vendor/codeberg.org/superseriousbusiness/exif-terminator/webp.go b/vendor/codeberg.org/superseriousbusiness/exif-terminator/webp.go index 392c4871d..b050f38fc 100644 --- a/vendor/codeberg.org/superseriousbusiness/exif-terminator/webp.go +++ b/vendor/codeberg.org/superseriousbusiness/exif-terminator/webp.go @@ -25,17 +25,16 @@ import ( ) const ( - riffHeaderSize = 4 * 3 + riffHeader = "RIFF" + webpHeader = "WEBP" + exifFourcc = "EXIF" + xmpFourcc = "XMP " ) var ( - riffHeader = [4]byte{'R', 'I', 'F', 'F'} - webpHeader = [4]byte{'W', 'E', 'B', 'P'} - exifFourcc = [4]byte{'E', 'X', 'I', 'F'} - xmpFourcc = [4]byte{'X', 'M', 'P', ' '} - errNoRiffHeader = errors.New("no RIFF header") errNoWebpHeader = errors.New("not a WEBP file") + errInvalidChunk = errors.New("invalid chunk") ) type webpVisitor struct { @@ -43,59 +42,68 @@ type webpVisitor struct { doneHeader bool } -func fourCC(b []byte) [4]byte { - return [4]byte{b[0], b[1], b[2], b[3]} -} - func (v *webpVisitor) split(data []byte, atEOF bool) (advance int, token []byte, err error) { // parse/write the header first if !v.doneHeader { - if len(data) < riffHeaderSize { - // need the full header + + // const rifHeaderSize = 12 + if len(data) < 12 { + if atEOF { + err = errNoRiffHeader + } return } - if fourCC(data) != riffHeader { + + if string(data[:4]) != riffHeader { err = errNoRiffHeader return } - if fourCC(data[8:]) != webpHeader { + + if string(data[8:12]) != webpHeader { err = errNoWebpHeader return } - if _, err = v.writer.Write(data[:riffHeaderSize]); err != nil { + + if _, err = v.writer.Write(data[:12]); err != nil { return } - advance += riffHeaderSize - data = data[riffHeaderSize:] + + advance += 12 + data = data[12:] v.doneHeader = true } - // need enough for fourcc and size - if len(data) < 8 { - return - } - size := int64(binary.LittleEndian.Uint32(data[4:])) - if (size & 1) != 0 { - // odd chunk size - extra padding byte - size++ - } - // wait until there is enough - if int64(len(data)-8) < size { - return - } + for { + // need enough for + // fourcc and size + if len(data) < 8 { + return + } + + size := int64(binary.LittleEndian.Uint32(data[4:])) + + if (size & 1) != 0 { + // odd chunk size: + // extra padding byte + size++ + } + + // wait until there is enough + if int64(len(data)) < 8+size { + return + } - fourcc := fourCC(data) - rawChunkData := data[8 : 8+size] - if fourcc == exifFourcc || fourcc == xmpFourcc { // replace exif/xmp with blank - rawChunkData = make([]byte, size) - } + switch string(data[:4]) { + case exifFourcc, xmpFourcc: + clear(data[8 : 8+size]) + } - if _, err = v.writer.Write(data[:8]); err == nil { - if _, err = v.writer.Write(rawChunkData); err == nil { - advance += 8 + int(size) + if _, err = v.writer.Write(data[:8+size]); err != nil { + return } - } - return + advance += 8 + int(size) + data = data[8+size:] + } } |