diff --git a/go.mod b/go.mod index 2c32d3e80..c4d9865bf 100644 --- a/go.mod +++ b/go.mod @@ -32,7 +32,7 @@ require ( github.com/vektah/gqlparser/v2 v2.0.1 github.com/vektra/mockery/v2 v2.2.1 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 - golang.org/x/image v0.0.0-20190802002840-cff245a6509b + golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb golang.org/x/net v0.0.0-20200822124328-c89045814202 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd golang.org/x/tools v0.0.0-20200915031644-64986481280e // indirect diff --git a/go.sum b/go.sum index 9c3bf7c37..d08261d70 100644 --- a/go.sum +++ b/go.sum @@ -539,8 +539,6 @@ github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/ github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.10.0 h1:jbhqpg7tQe4SupckyijYiy0mJJ/pRyHvXf7JdWK860o= github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-sqlite3 v1.13.0 h1:LnJI81JidiW9r7pS/hXe6cFeO5EXNq7KbfvoJLRI69c= -github.com/mattn/go-sqlite3 v1.13.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -805,6 +803,8 @@ golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86h golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb h1:fqpd0EBDzlHRCjiphRR5Zo/RSWWQlWv34418dnEixWk= +golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= diff --git a/ui/v2.5/src/components/Changelog/versions/v070.md b/ui/v2.5/src/components/Changelog/versions/v070.md index 0e204e29a..82964822c 100644 --- a/ui/v2.5/src/components/Changelog/versions/v070.md +++ b/ui/v2.5/src/components/Changelog/versions/v070.md @@ -8,4 +8,5 @@ * Change performer text query to search by name and alias only. ### 🐛 Bug fixes +* Fix processing some webp files. * Fix incorrect performer age calculation in UI. diff --git a/vendor/golang.org/x/image/bmp/reader.go b/vendor/golang.org/x/image/bmp/reader.go index c10a022f6..52e25205c 100644 --- a/vendor/golang.org/x/image/bmp/reader.go +++ b/vendor/golang.org/x/image/bmp/reader.go @@ -144,6 +144,9 @@ func decodeConfig(r io.Reader) (config image.Config, bitsPerPixel int, topDown b ) var b [1024]byte if _, err := io.ReadFull(r, b[:fileHeaderLen+4]); err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } return image.Config{}, 0, false, err } if string(b[:2]) != "BM" { @@ -155,6 +158,9 @@ func decodeConfig(r io.Reader) (config image.Config, bitsPerPixel int, topDown b return image.Config{}, 0, false, ErrUnsupported } if _, err := io.ReadFull(r, b[fileHeaderLen+4:fileHeaderLen+infoLen]); err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } return image.Config{}, 0, false, err } width := int(int32(readUint32(b[18:22]))) diff --git a/vendor/golang.org/x/image/ccitt/reader.go b/vendor/golang.org/x/image/ccitt/reader.go index 62986f977..340de0536 100644 --- a/vendor/golang.org/x/image/ccitt/reader.go +++ b/vendor/golang.org/x/image/ccitt/reader.go @@ -16,6 +16,7 @@ import ( ) var ( + errIncompleteCode = errors.New("ccitt: incomplete code") errInvalidBounds = errors.New("ccitt: invalid bounds") errInvalidCode = errors.New("ccitt: invalid code") errInvalidMode = errors.New("ccitt: invalid mode") @@ -48,6 +49,10 @@ const ( Group4 ) +// AutoDetectHeight is passed as the height argument to NewReader to indicate +// that the image height (the number of rows) is not known in advance. +const AutoDetectHeight = -1 + // Options are optional parameters. type Options struct { // Align means that some variable-bit-width codes are byte-aligned. @@ -73,6 +78,56 @@ func reverseBitsWithinBytes(b []byte) { } } +// highBits writes to dst (1 bit per pixel, most significant bit first) the +// high (0x80) bits from src (1 byte per pixel). It returns the number of bytes +// written and read such that dst[:d] is the packed form of src[:s]. +// +// For example, if src starts with the 8 bytes [0x7D, 0x7E, 0x7F, 0x80, 0x81, +// 0x82, 0x00, 0xFF] then 0x1D will be written to dst[0]. +// +// If src has (8 * len(dst)) or more bytes then only len(dst) bytes are +// written, (8 * len(dst)) bytes are read, and invert is ignored. +// +// Otherwise, if len(src) is not a multiple of 8 then the final byte written to +// dst is padded with 1 bits (if invert is true) or 0 bits. If inverted, the 1s +// are typically temporary, e.g. they will be flipped back to 0s by an +// invertBytes call in the highBits caller, reader.Read. +func highBits(dst []byte, src []byte, invert bool) (d int, s int) { + // Pack as many complete groups of 8 src bytes as we can. + n := len(src) / 8 + if n > len(dst) { + n = len(dst) + } + dstN := dst[:n] + for i := range dstN { + src8 := src[i*8 : i*8+8] + dstN[i] = ((src8[0] & 0x80) >> 0) | + ((src8[1] & 0x80) >> 1) | + ((src8[2] & 0x80) >> 2) | + ((src8[3] & 0x80) >> 3) | + ((src8[4] & 0x80) >> 4) | + ((src8[5] & 0x80) >> 5) | + ((src8[6] & 0x80) >> 6) | + ((src8[7] & 0x80) >> 7) + } + d, s = n, 8*n + dst, src = dst[d:], src[s:] + + // Pack up to 7 remaining src bytes, if there's room in dst. + if (len(dst) > 0) && (len(src) > 0) { + dstByte := byte(0) + if invert { + dstByte = 0xFF >> uint(len(src)) + } + for n, srcByte := range src { + dstByte |= (srcByte & 0x80) >> uint(n) + } + dst[0] = dstByte + d, s = d+1, s+len(src) + } + return d, s +} + type bitReader struct { r io.Reader @@ -84,7 +139,7 @@ type bitReader struct { // order is whether to process r's bytes LSB first or MSB first. order Order - // The low nBits bits of the bits field hold upcoming bits in LSB order. + // The high nBits bits of the bits field hold upcoming bits in MSB order. bits uint64 nBits uint32 @@ -96,7 +151,7 @@ type bitReader struct { func (b *bitReader) alignToByteBoundary() { n := b.nBits & 7 - b.bits >>= n + b.bits <<= n b.nBits -= n } @@ -108,11 +163,11 @@ func (b *bitReader) alignToByteBoundary() { // bitReader.nBits value above nextBitMaxNBits. const nextBitMaxNBits = 31 -func (b *bitReader) nextBit() (uint32, error) { +func (b *bitReader) nextBit() (uint64, error) { for { if b.nBits > 0 { - bit := uint32(b.bits) & 1 - b.bits >>= 1 + bit := b.bits >> 63 + b.bits <<= 1 b.nBits-- return bit, nil } @@ -124,12 +179,12 @@ func (b *bitReader) nextBit() (uint32, error) { // checks that the generated maxCodeLength constant fits. // // If changing the Uint32 call, also change nextBitMaxNBits. - b.bits = uint64(binary.LittleEndian.Uint32(b.bytes[b.br:])) + b.bits = uint64(binary.BigEndian.Uint32(b.bytes[b.br:])) << 32 b.br += 4 b.nBits = 32 continue } else if available > 0 { - b.bits = uint64(b.bytes[b.br]) + b.bits = uint64(b.bytes[b.br]) << (7 * 8) b.br++ b.nBits = 8 continue @@ -144,34 +199,67 @@ func (b *bitReader) nextBit() (uint32, error) { b.bw = uint32(n) b.readErr = err - if b.order != LSB { + if b.order != MSB { reverseBitsWithinBytes(b.bytes[:b.bw]) } } } func decode(b *bitReader, decodeTable [][2]int16) (uint32, error) { - nBitsRead, bitsRead, state := uint32(0), uint32(0), int32(1) + nBitsRead, bitsRead, state := uint32(0), uint64(0), int32(1) for { bit, err := b.nextBit() if err != nil { + if err == io.EOF { + err = errIncompleteCode + } return 0, err } - bitsRead |= bit << nBitsRead + bitsRead |= bit << (63 - nBitsRead) nBitsRead++ + // The "&1" is redundant, but can eliminate a bounds check. state = int32(decodeTable[state][bit&1]) if state < 0 { return uint32(^state), nil } else if state == 0 { // Unread the bits we've read, then return errInvalidCode. - b.bits = (b.bits << nBitsRead) | uint64(bitsRead) + b.bits = (b.bits >> nBitsRead) | bitsRead b.nBits += nBitsRead return 0, errInvalidCode } } } +// decodeEOL decodes the 12-bit EOL code 0000_0000_0001. +func decodeEOL(b *bitReader) error { + nBitsRead, bitsRead := uint32(0), uint64(0) + for { + bit, err := b.nextBit() + if err != nil { + if err == io.EOF { + err = errMissingEOL + } + return err + } + bitsRead |= bit << (63 - nBitsRead) + nBitsRead++ + + if nBitsRead < 12 { + if bit&1 == 0 { + continue + } + } else if bit&1 != 0 { + return nil + } + + // Unread the bits we've read, then return errMissingEOL. + b.bits = (b.bits >> nBitsRead) | bitsRead + b.nBits += nBitsRead + return errMissingEOL + } +} + type reader struct { br bitReader subFormat SubFormat @@ -181,7 +269,10 @@ type reader struct { // rowsRemaining starts at the image height in pixels, when the reader is // driven through the io.Reader interface, and decrements to zero as rows - // are decoded. When driven through DecodeIntoGray, this field is unused. + // are decoded. Alternatively, it may be negative if the image height is + // not known in advance at the time of the NewReader call. + // + // When driven through DecodeIntoGray, this field is unused. rowsRemaining int // curr and prev hold the current and previous rows. Each element is either @@ -219,6 +310,19 @@ type reader struct { // seenStartOfImage is whether we've called the startDecode method. seenStartOfImage bool + // truncated is whether the input is missing the final 6 consecutive EOL's + // (for Group3) or 2 consecutive EOL's (for Group4). Omitting that trailer + // (but otherwise padding to a byte boundary, with either all 0 bits or all + // 1 bits) is invalid according to the spec, but happens in practice when + // exporting from Adobe Acrobat to TIFF + CCITT. This package silently + // ignores the format error for CCITT input that has been truncated in that + // fashion, returning the full decoded image. + // + // Detecting trailer truncation (just after the final row of pixels) + // requires knowing which row is the final row, and therefore does not + // trigger if the image height is not known in advance. + truncated bool + // readErr is a sticky error for the Read method. readErr error } @@ -244,38 +348,56 @@ func (z *reader) Read(p []byte) (int, error) { // Decode the next row, if necessary. if z.atStartOfRow { - if z.rowsRemaining <= 0 { - if z.readErr = z.finishDecode(); z.readErr != nil { + if z.rowsRemaining < 0 { + // We do not know the image height in advance. See if the next + // code is an EOL. If it is, it is consumed. If it isn't, the + // bitReader shouldn't advance along the bit stream, and we + // simply decode another row of pixel data. + // + // For the Group4 subFormat, we may need to align to a byte + // boundary. For the Group3 subFormat, the previous z.decodeRow + // call (or z.startDecode call) has already consumed one of the + // 6 consecutive EOL's. The next EOL is actually the second of + // 6, in the middle, and we shouldn't align at that point. + if z.align && (z.subFormat == Group4) { + z.br.alignToByteBoundary() + } + + if err := z.decodeEOL(); err == errMissingEOL { + // No-op. It's another row of pixel data. + } else if err != nil { + z.readErr = err + break + } else { + if z.readErr = z.finishDecode(true); z.readErr != nil { + break + } + z.readErr = io.EOF + break + } + + } else if z.rowsRemaining == 0 { + // We do know the image height in advance, and we have already + // decoded exactly that many rows. + if z.readErr = z.finishDecode(false); z.readErr != nil { break } z.readErr = io.EOF break - } - if z.readErr = z.decodeRow(); z.readErr != nil { - break - } - z.rowsRemaining-- - } - // Pack from z.curr (1 byte per pixel) to p (1 bit per pixel), up to 8 - // elements per iteration. - i := 0 - for ; i < len(p); i++ { - numToPack := len(z.curr) - z.ri - if numToPack <= 0 { - break - } else if numToPack > 8 { - numToPack = 8 + } else { + z.rowsRemaining-- } - byteValue := byte(0) - for j := 0; j < numToPack; j++ { - byteValue |= (z.curr[z.ri] & 0x80) >> uint(j) - z.ri++ + if z.readErr = z.decodeRow(z.rowsRemaining == 0); z.readErr != nil { + break } - p[i] = byteValue } - p = p[i:] + + // Pack from z.curr (1 byte per pixel) to p (1 bit per pixel). + packD, packS := highBits(p, z.curr[z.ri:], z.invert) + p = p[packD:] + z.ri += packS // Prepare to decode the next row, if necessary. if z.ri == len(z.curr) { @@ -285,7 +407,6 @@ func (z *reader) Read(p []byte) (int, error) { } n := len(originalP) - len(p) - // TODO: when invert is true, should the end-of-row padding bits be 0 or 1? if z.invert { invertBytes(originalP[:n]) } @@ -317,32 +438,44 @@ func (z *reader) startDecode() error { return nil } -func (z *reader) finishDecode() error { +func (z *reader) finishDecode(alreadySeenEOL bool) error { numberOfEOLs := 0 switch z.subFormat { case Group3: + if z.truncated { + return nil + } // The stream ends with a RTC (Return To Control) of 6 consecutive // EOL's, but we should have already just seen an EOL, either in // z.startDecode (for a zero-height image) or in z.decodeRow. numberOfEOLs = 5 case Group4: - // The stream ends with two EOL's, the first of which is possibly - // byte-aligned. - numberOfEOLs = 2 - if err := z.decodeEOL(); err == nil { - numberOfEOLs-- - } else if err == errInvalidCode { - // Try again, this time starting from a byte boundary. + autoDetectHeight := z.rowsRemaining < 0 + if autoDetectHeight { + // Aligning to a byte boundary was already handled by reader.Read. + } else if z.align { z.br.alignToByteBoundary() - } else { + } + // The stream ends with two EOL's. If the first one is missing, and we + // had an explicit image height, we just assume that the trailing two + // EOL's were truncated and return a nil error. + if err := z.decodeEOL(); err != nil { + if (err == errMissingEOL) && !autoDetectHeight { + z.truncated = true + return nil + } return err } + numberOfEOLs = 1 default: return errUnsupportedSubFormat } + if alreadySeenEOL { + numberOfEOLs-- + } for ; numberOfEOLs > 0; numberOfEOLs-- { if err := z.decodeEOL(); err != nil { return err @@ -352,23 +485,18 @@ func (z *reader) finishDecode() error { } func (z *reader) decodeEOL() error { - // TODO: EOL doesn't have to be in the modeDecodeTable. It could be in its - // own table, or we could just hard-code it, especially if we might need to - // cater for optional byte-alignment, or an arbitrary number (potentially - // more than 8) of 0-valued padding bits. - if mode, err := decode(&z.br, modeDecodeTable[:]); err != nil { - return err - } else if mode != modeEOL { - return errMissingEOL - } - return nil + return decodeEOL(&z.br) } -func (z *reader) decodeRow() error { +func (z *reader) decodeRow(finalRow bool) error { z.wi = 0 z.atStartOfRow = true z.penColorIsWhite = true + if z.align { + z.br.alignToByteBoundary() + } + switch z.subFormat { case Group3: for ; z.wi < len(z.curr); z.atStartOfRow = false { @@ -376,13 +504,14 @@ func (z *reader) decodeRow() error { return err } } - return z.decodeEOL() + err := z.decodeEOL() + if finalRow && (err == errMissingEOL) { + z.truncated = true + return nil + } + return err case Group4: - if z.align { - z.br.alignToByteBoundary() - } - for ; z.wi < len(z.curr); z.atStartOfRow = false { mode, err := decode(&z.br, modeDecodeTable[:]) if err != nil { @@ -620,13 +749,13 @@ func DecodeIntoGray(dst *image.Gray, r io.Reader, order Order, sf SubFormat, opt for y := bounds.Min.Y; y < bounds.Max.Y; y++ { p := (y - bounds.Min.Y) * dst.Stride z.curr = dst.Pix[p : p+width] - if err := z.decodeRow(); err != nil { + if err := z.decodeRow(y+1 == bounds.Max.Y); err != nil { return err } z.curr, z.prev = nil, z.curr } - if err := z.finishDecode(); err != nil { + if err := z.finishDecode(false); err != nil { return err } @@ -643,9 +772,12 @@ func DecodeIntoGray(dst *image.Gray, r io.Reader, order Order, sf SubFormat, opt // NewReader returns an io.Reader that decodes the CCITT-formatted data in r. // The resultant byte stream is one bit per pixel (MSB first), with 1 meaning // white and 0 meaning black. Each row in the result is byte-aligned. +// +// A negative height, such as passing AutoDetectHeight, means that the image +// height is not known in advance. A negative width is invalid. func NewReader(r io.Reader, order Order, sf SubFormat, width int, height int, opts *Options) io.Reader { readErr := error(nil) - if (width < 0) || (height < 0) { + if width < 0 { readErr = errInvalidBounds } else if width > maxWidth { readErr = errUnsupportedWidth diff --git a/vendor/golang.org/x/image/ccitt/table.go b/vendor/golang.org/x/image/ccitt/table.go index f01cc12b5..ef7ea9d40 100644 --- a/vendor/golang.org/x/image/ccitt/table.go +++ b/vendor/golang.org/x/image/ccitt/table.go @@ -31,17 +31,7 @@ package ccitt // modeDecodeTable represents Table 1 and the End-of-Line code. // -// +=XXXXX -// b015 +-+ -// | +=v0010 -// b014 +-+ -// | +=XXXXX -// b013 +-+ -// | +=XXXXX -// b012 +-+ -// | +=XXXXX -// b011 +-+ -// | +=XXXXX +// +=XXXXX // b009 +-+ // | +=v0009 // b007 +-+ @@ -72,13 +62,8 @@ var modeDecodeTable = [...][2]int16{ 6: {7, 8}, 7: {9, 10}, 8: {^7, ^4}, - 9: {11, ^9}, + 9: {0, ^9}, 10: {^8, ^5}, - 11: {12, 0}, - 12: {13, 0}, - 13: {14, 0}, - 14: {15, 0}, - 15: {0, ^10}, } // whiteDecodeTable represents Tables 2 and 3 for a white run. @@ -733,17 +718,16 @@ type bitString struct { // modeEncodeTable represents Table 1 and the End-of-Line code. var modeEncodeTable = [...]bitString{ - 0: {0x0001, 4}, // "0001" - 1: {0x0001, 3}, // "001" - 2: {0x0001, 1}, // "1" - 3: {0x0003, 3}, // "011" - 4: {0x0003, 6}, // "000011" - 5: {0x0003, 7}, // "0000011" - 6: {0x0002, 3}, // "010" - 7: {0x0002, 6}, // "000010" - 8: {0x0002, 7}, // "0000010" - 9: {0x0001, 7}, // "0000001" - 10: {0x0001, 12}, // "000000000001" + 0: {0x0001, 4}, // "0001" + 1: {0x0001, 3}, // "001" + 2: {0x0001, 1}, // "1" + 3: {0x0003, 3}, // "011" + 4: {0x0003, 6}, // "000011" + 5: {0x0003, 7}, // "0000011" + 6: {0x0002, 3}, // "010" + 7: {0x0002, 6}, // "000010" + 8: {0x0002, 7}, // "0000010" + 9: {0x0001, 7}, // "0000001" } // whiteEncodeTable2 represents Table 2 for a white run. @@ -983,7 +967,6 @@ const ( modeVL2 // Vertical-Left-2 modeVL3 // Vertical-Left-3 modeExt // Extension - modeEOL // End-of-Line ) // COPY PASTE table.go END diff --git a/vendor/golang.org/x/image/tiff/fuzz.go b/vendor/golang.org/x/image/tiff/fuzz.go index ec52c7882..b27c54004 100644 --- a/vendor/golang.org/x/image/tiff/fuzz.go +++ b/vendor/golang.org/x/image/tiff/fuzz.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build gofuzz // +build gofuzz package tiff diff --git a/vendor/golang.org/x/image/tiff/lzw/reader.go b/vendor/golang.org/x/image/tiff/lzw/reader.go index 51ae39f8a..78204ba92 100644 --- a/vendor/golang.org/x/image/tiff/lzw/reader.go +++ b/vendor/golang.org/x/image/tiff/lzw/reader.go @@ -178,7 +178,7 @@ loop: break loop case code <= d.hi: c, i := code, len(d.output)-1 - if code == d.hi { + if code == d.hi && d.last != decoderInvalidCode { // code == hi is a special case which expands to the last expansion // followed by the head of the last expansion. To find the head, we walk // the prefix chain until we find a literal code. diff --git a/vendor/golang.org/x/image/tiff/reader.go b/vendor/golang.org/x/image/tiff/reader.go index c26ec36bb..de73f4b99 100644 --- a/vendor/golang.org/x/image/tiff/reader.go +++ b/vendor/golang.org/x/image/tiff/reader.go @@ -404,6 +404,9 @@ func newDecoder(r io.Reader) (*decoder, error) { p := make([]byte, 8) if _, err := d.r.ReadAt(p, 0); err != nil { + if err == io.EOF { + err = io.ErrUnexpectedEOF + } return nil, err } switch string(p[0:4]) { diff --git a/vendor/golang.org/x/image/webp/decode.go b/vendor/golang.org/x/image/webp/decode.go index f77a4ebf8..d6eefd596 100644 --- a/vendor/golang.org/x/image/webp/decode.go +++ b/vendor/golang.org/x/image/webp/decode.go @@ -126,22 +126,23 @@ func decode(r io.Reader, configOnly bool) (image.Image, image.Config, error) { alphaBit = 1 << 4 iccProfileBit = 1 << 5 ) - if buf[0] != alphaBit { - return nil, image.Config{}, errors.New("webp: non-Alpha VP8X is not implemented") - } + wantAlpha = (buf[0] & alphaBit) != 0 widthMinusOne = uint32(buf[4]) | uint32(buf[5])<<8 | uint32(buf[6])<<16 heightMinusOne = uint32(buf[7]) | uint32(buf[8])<<8 | uint32(buf[9])<<16 if configOnly { + if wantAlpha { + return nil, image.Config{ + ColorModel: color.NYCbCrAModel, + Width: int(widthMinusOne) + 1, + Height: int(heightMinusOne) + 1, + }, nil + } return nil, image.Config{ - ColorModel: color.NYCbCrAModel, + ColorModel: color.YCbCrModel, Width: int(widthMinusOne) + 1, Height: int(heightMinusOne) + 1, }, nil } - wantAlpha = true - - default: - return nil, image.Config{}, errInvalidFormat } } } diff --git a/vendor/modules.txt b/vendor/modules.txt index 30d132c26..b9ea5e2e0 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -307,7 +307,7 @@ github.com/vektra/mockery/v2/pkg/logging golang.org/x/crypto/bcrypt golang.org/x/crypto/blowfish golang.org/x/crypto/ssh/terminal -# golang.org/x/image v0.0.0-20190802002840-cff245a6509b +# golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb golang.org/x/image/bmp golang.org/x/image/ccitt golang.org/x/image/riff