From ef5e0288ce5e28b9a3018034309582dd227fc31d Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Mon, 20 Oct 2014 10:46:12 +1100 Subject: [PATCH] go.image/webp: implement lossy-with-alpha. This fixes all three lossy_alpha*.webp conformance tests. The test data was generated by cwebp/dwebp version 0.4.1: cwebp yellow_rose.png -o yellow_rose.lossy-with-alpha.webp dwebp yellow_rose.lossy-with-alpha.webp -pgm -o tmp.pgm convert tmp.pgm yellow_rose.lossy-with-alpha.webp.nycbcra.png LGTM=pascal.massimino, r R=r, pascal.massimino CC=golang-codereviews https://golang.org/cl/154350043 --- cmd/webp-manual-test/main.go | 41 +++- testdata/yellow_rose.lossy-with-alpha.webp | Bin 0 -> 11572 bytes ...low_rose.lossy-with-alpha.webp.nycbcra.png | Bin 0 -> 67874 bytes webp/decode.go | 159 ++++++++++++-- webp/decode_test.go | 203 +++++++++++------- 5 files changed, 298 insertions(+), 105 deletions(-) create mode 100644 testdata/yellow_rose.lossy-with-alpha.webp create mode 100644 testdata/yellow_rose.lossy-with-alpha.webp.nycbcra.png diff --git a/cmd/webp-manual-test/main.go b/cmd/webp-manual-test/main.go index f08c183..3d17734 100644 --- a/cmd/webp-manual-test/main.go +++ b/cmd/webp-manual-test/main.go @@ -17,10 +17,11 @@ import ( "strings" "code.google.com/p/go.image/webp" + "code.google.com/p/go.image/webp/nycbcra" ) var ( - dwebp = flag.String("dwebp", "", "path to the dwebp program "+ + dwebp = flag.String("dwebp", "/usr/bin/dwebp", "path to the dwebp program "+ "installed from https://developers.google.com/speed/webp/download") testdata = flag.String("testdata", "", "path to the libwebp-test-data directory "+ "checked out from https://chromium.googlesource.com/webm/libwebp-test-data") @@ -32,6 +33,10 @@ func main() { flag.Usage() log.Fatal("dwebp flag was not specified") } + if _, err := os.Stat(*dwebp); err != nil { + flag.Usage() + log.Fatalf("could not find dwebp program at %q", *dwebp) + } if *testdata == "" { flag.Usage() log.Fatal("testdata flag was not specified") @@ -80,9 +85,9 @@ func test(name string) error { if err != nil { return fmt.Errorf("Decode: %v", err) } - format, encode := "-pam", encodePAM - if _, lossy := gotImage.(*image.YCbCr); lossy { - format, encode = "-pgm", encodePGM + format, encode := "-pgm", encodePGM + if _, lossless := gotImage.(*image.NRGBA); lossless { + format, encode = "-pam", encodePAM } got, err := encode(gotImage) if err != nil { @@ -130,8 +135,17 @@ func encodePAM(gotImage image.Image) ([]byte, error) { // encodePGM encodes gotImage in the PGM format in the IMC4 layout. func encodePGM(gotImage image.Image) ([]byte, error) { - m, ok := gotImage.(*image.YCbCr) - if !ok { + var ( + m *image.YCbCr + ma *nycbcra.Image + ) + switch g := gotImage.(type) { + case *image.YCbCr: + m = g + case *nycbcra.Image: + m = &g.YCbCr + ma = g + default: return nil, fmt.Errorf("lossy image did not decode to an *image.YCbCr") } if m.SubsampleRatio != image.YCbCrSubsampleRatio420 { @@ -140,8 +154,12 @@ func encodePGM(gotImage image.Image) ([]byte, error) { b := m.Bounds() w, h := b.Dx(), b.Dy() w2, h2 := (w+1)/2, (h+1)/2 + outW, outH := 2*w2, h+h2 + if ma != nil { + outH += h + } buf := new(bytes.Buffer) - fmt.Fprintf(buf, "P5\n%d %d\n255\n", 2*w2, h+h2) + fmt.Fprintf(buf, "P5\n%d %d\n255\n", outW, outH) for y := b.Min.Y; y < b.Max.Y; y++ { o := m.YOffset(b.Min.X, y) buf.Write(m.Y[o : o+w]) @@ -154,6 +172,15 @@ func encodePGM(gotImage image.Image) ([]byte, error) { buf.Write(m.Cb[o : o+w2]) buf.Write(m.Cr[o : o+w2]) } + if ma != nil { + for y := b.Min.Y; y < b.Max.Y; y++ { + o := ma.AOffset(b.Min.X, y) + buf.Write(ma.A[o : o+w]) + if w&1 != 0 { + buf.WriteByte(0x00) + } + } + } return buf.Bytes(), nil } diff --git a/testdata/yellow_rose.lossy-with-alpha.webp b/testdata/yellow_rose.lossy-with-alpha.webp new file mode 100644 index 0000000000000000000000000000000000000000..64d3b5d304f898df4865d5b6b87eb572c6fc3702 GIT binary patch literal 11572 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 1<<31 { + if dataLen == 0 || dataLen >= 1<<31 { return nil, image.Config{}, errors.New("webp: invalid format") } - if format == formatVP8 { - d := vp8.NewDecoder() - d.Init(r, int(dataLen)) - fh, err := d.DecodeFrameHeader() + if format == formatVP8L { + r = &io.LimitedReader{R: r, N: int64(dataLen)} + if configOnly { + c, err := vp8l.DecodeConfig(r) + return nil, c, err + } + m, err := vp8l.Decode(r) + return m, image.Config{}, err + } + + var ( + alpha []byte + alphaStride int + ) + if format == formatVP8X { + if dataLen != 10 { + return nil, image.Config{}, errors.New("webp: invalid format") + } + if _, err := io.ReadFull(r, b[:10]); err != nil { + return nil, image.Config{}, err + } + const ( + animationBit = 1 << 1 + xmpMetadataBit = 1 << 2 + exifMetadataBit = 1 << 3 + alphaBit = 1 << 4 + iccProfileBit = 1 << 5 + ) + if b[0] != alphaBit { + return nil, image.Config{}, errors.New("webp: non-Alpha VP8X is not implemented") + } + widthMinusOne := uint32(b[4]) | uint32(b[5])<<8 | uint32(b[6])<<16 + heightMinusOne := uint32(b[7]) | uint32(b[8])<<8 | uint32(b[9])<<16 + if configOnly { + return nil, image.Config{ + ColorModel: nycbcra.ColorModel, + Width: int(widthMinusOne) + 1, + Height: int(heightMinusOne) + 1, + }, nil + } + + // Read the 8-byte chunk header plus the mandatory PFC (Pre-processing, + // Filter, Compression) byte. + if _, err := io.ReadFull(r, b[:9]); err != nil { + return nil, image.Config{}, err + } + if b[0] != 'A' || b[1] != 'L' || b[2] != 'P' || b[3] != 'H' { + return nil, image.Config{}, errors.New("webp: invalid format") + } + chunkLen := roundUp2(uint32(b[4]) | uint32(b[5])<<8 | uint32(b[6])<<16 | uint32(b[7])<<24) + // Subtract one byte from chunkLen, since we've already read the PFC byte. + if chunkLen == 0 { + return nil, image.Config{}, errors.New("webp: invalid format") + } + chunkLen-- + filter := (b[8] >> 2) & 0x03 + if filter != 0 { + return nil, image.Config{}, errors.New("webp: VP8X Alpha filtering != 0 is not implemented") + } + compression := b[8] & 0x03 + if compression != 1 { + return nil, image.Config{}, errors.New("webp: VP8X Alpha compression != 1 is not implemented") + } + + // Read the VP8L-compressed alpha values. First, synthesize a 5-byte VP8L header: + // a 1-byte magic number, a 14-bit widthMinusOne, a 14-bit heightMinusOne, + // a 1-bit (ignored, zero) alphaIsUsed and a 3-bit (zero) version. + // TODO(nigeltao): be more efficient than decoding an *image.NRGBA just to + // extract the green values to a separately allocated []byte. Fixing this + // will require changes to the vp8l package's API. + if widthMinusOne > 0x3fff || heightMinusOne > 0x3fff { + return nil, image.Config{}, errors.New("webp: invalid format") + } + b[0] = 0x2f // VP8L magic number. + b[1] = uint8(widthMinusOne) + b[2] = uint8(widthMinusOne>>8) | uint8(heightMinusOne<<6) + b[3] = uint8(heightMinusOne >> 2) + b[4] = uint8(heightMinusOne >> 10) + alphaImage, err := vp8l.Decode(io.MultiReader( + bytes.NewReader(b[:5]), + &io.LimitedReader{R: r, N: int64(chunkLen)}, + )) if err != nil { return nil, image.Config{}, err } - if configOnly { - return nil, image.Config{ - ColorModel: color.YCbCrModel, - Width: fh.Width, - Height: fh.Height, - }, nil + // The green values of the inner NRGBA image are the alpha values of the outer NYCbCrA image. + pix := alphaImage.(*image.NRGBA).Pix + alpha = make([]byte, len(pix)/4) + for i := range alpha { + alpha[i] = pix[4*i+1] + } + alphaStride = int(widthMinusOne) + 1 + + // The rest of the image should be in the lossy format. Check the "VP8 " + // header and fall through. + if _, err := io.ReadFull(r, b[:8]); err != nil { + return nil, image.Config{}, err + } + if b[0] != 'V' || b[1] != 'P' || b[2] != '8' || b[3] != ' ' { + return nil, image.Config{}, errors.New("webp: invalid format") + } + dataLen = roundUp2(uint32(b[4]) | uint32(b[5])<<8 | uint32(b[6])<<16 | uint32(b[7])<<24) + if dataLen == 0 || dataLen >= 1<<31 { + return nil, image.Config{}, errors.New("webp: invalid format") } - m, err := d.DecodeFrame() - return m, image.Config{}, nil } - r = &io.LimitedReader{R: r, N: int64(dataLen)} - if configOnly { - c, err := vp8l.DecodeConfig(r) - return nil, c, err + d := vp8.NewDecoder() + d.Init(r, int(dataLen)) + fh, err := d.DecodeFrameHeader() + if err != nil { + return nil, image.Config{}, err } - m, err := vp8l.Decode(r) - return m, image.Config{}, err + if configOnly { + return nil, image.Config{ + ColorModel: color.YCbCrModel, + Width: fh.Width, + Height: fh.Height, + }, nil + } + m, err := d.DecodeFrame() + if err != nil { + return nil, image.Config{}, err + } + if alpha != nil { + return &nycbcra.Image{ + YCbCr: *m, + A: alpha, + AStride: alphaStride, + }, image.Config{}, nil + } + return m, image.Config{}, nil } // Decode reads a WEBP image from r and returns it as an image.Image. diff --git a/webp/decode_test.go b/webp/decode_test.go index a86e32c..b1af0e7 100644 --- a/webp/decode_test.go +++ b/webp/decode_test.go @@ -13,6 +13,8 @@ import ( "os" "strings" "testing" + + "code.google.com/p/go.image/webp/nycbcra" ) // hex is like fmt.Sprintf("% x", x) but also inserts dots every 16 bytes, to @@ -30,6 +32,120 @@ func hex(x []byte) string { return buf.String() } +func testDecodeLossy(t *testing.T, tc string, withAlpha bool) { + webpFilename := "../testdata/" + tc + ".lossy.webp" + pngFilename := webpFilename + ".ycbcr.png" + if withAlpha { + webpFilename = "../testdata/" + tc + ".lossy-with-alpha.webp" + pngFilename = webpFilename + ".nycbcra.png" + } + + f0, err := os.Open(webpFilename) + if err != nil { + t.Errorf("%s: Open WEBP: %v", tc, err) + return + } + defer f0.Close() + img0, err := Decode(f0) + if err != nil { + t.Errorf("%s: Decode WEBP: %v", tc, err) + return + } + + var ( + m0 *image.YCbCr + a0 *nycbcra.Image + ok bool + ) + if withAlpha { + a0, ok = img0.(*nycbcra.Image) + if ok { + m0 = &a0.YCbCr + } + } else { + m0, ok = img0.(*image.YCbCr) + } + if !ok || m0.SubsampleRatio != image.YCbCrSubsampleRatio420 { + t.Errorf("%s: decoded WEBP image is not a 4:2:0 YCbCr or 4:2:0 NYCbCrA", tc) + return + } + // w2 and h2 are the half-width and half-height, rounded up. + w, h := m0.Bounds().Dx(), m0.Bounds().Dy() + w2, h2 := int((w+1)/2), int((h+1)/2) + + f1, err := os.Open(pngFilename) + if err != nil { + t.Errorf("%s: Open PNG: %v", tc, err) + return + } + defer f1.Close() + img1, err := png.Decode(f1) + if err != nil { + t.Errorf("%s: Open PNG: %v", tc, err) + return + } + + // The split-into-YCbCr-planes golden image is a 2*w2 wide and h+h2 high + // (or 2*h+h2 high, if with Alpha) gray image arranged in IMC4 format: + // YYYY + // YYYY + // BBRR + // AAAA + // See http://www.fourcc.org/yuv.php#IMC4 + pngW, pngH := 2*w2, h+h2 + if withAlpha { + pngH += h + } + if got, want := img1.Bounds(), image.Rect(0, 0, pngW, pngH); got != want { + t.Errorf("%s: bounds0: got %v, want %v", tc, got, want) + return + } + m1, ok := img1.(*image.Gray) + if !ok { + t.Errorf("%s: decoded PNG image is not a Gray", tc) + return + } + + type plane struct { + name string + m0Pix []uint8 + m0Stride int + m1Rect image.Rectangle + } + planes := []plane{ + {"Y", m0.Y, m0.YStride, image.Rect(0, 0, w, h)}, + {"Cb", m0.Cb, m0.CStride, image.Rect(0*w2, h, 1*w2, h+h2)}, + {"Cr", m0.Cr, m0.CStride, image.Rect(1*w2, h, 2*w2, h+h2)}, + } + if withAlpha { + planes = append(planes, plane{ + "A", a0.A, a0.AStride, image.Rect(0, h+h2, w, 2*h+h2), + }) + } + + for _, plane := range planes { + dx := plane.m1Rect.Dx() + nDiff, diff := 0, make([]byte, dx) + for j, y := 0, plane.m1Rect.Min.Y; y < plane.m1Rect.Max.Y; j, y = j+1, y+1 { + got := plane.m0Pix[j*plane.m0Stride:][:dx] + want := m1.Pix[y*m1.Stride+plane.m1Rect.Min.X:][:dx] + if bytes.Equal(got, want) { + continue + } + nDiff++ + if nDiff > 10 { + t.Errorf("%s: %s plane: more rows differ", tc, plane.name) + break + } + for i := range got { + diff[i] = got[i] - want[i] + } + t.Errorf("%s: %s plane: m0 row %d, m1 row %d\ngot %s\nwant%s\ndiff%s", + tc, plane.name, j, y, hex(got), hex(want), hex(diff)) + } + } +} + func TestDecodeVP8(t *testing.T) { testCases := []string{ "blue-purple-pink", @@ -41,86 +157,17 @@ func TestDecodeVP8(t *testing.T) { } for _, tc := range testCases { - f0, err := os.Open("../testdata/" + tc + ".lossy.webp") - if err != nil { - t.Errorf("%s: Open WEBP: %v", tc, err) - continue - } - defer f0.Close() - img0, err := Decode(f0) - if err != nil { - t.Errorf("%s: Decode WEBP: %v", tc, err) - continue - } + testDecodeLossy(t, tc, false) + } +} - m0, ok := img0.(*image.YCbCr) - if !ok || m0.SubsampleRatio != image.YCbCrSubsampleRatio420 { - t.Errorf("%s: decoded WEBP image is not a 4:2:0 YCbCr", tc) - continue - } - // w2 and h2 are the half-width and half-height, rounded up. - w, h := m0.Bounds().Dx(), m0.Bounds().Dy() - w2, h2 := int((w+1)/2), int((h+1)/2) +func TestDecodeVP8XAlpha(t *testing.T) { + testCases := []string{ + "yellow_rose", + } - f1, err := os.Open("../testdata/" + tc + ".lossy.webp.ycbcr.png") - if err != nil { - t.Errorf("%s: Open PNG: %v", tc, err) - continue - } - defer f1.Close() - img1, err := png.Decode(f1) - if err != nil { - t.Errorf("%s: Open PNG: %v", tc, err) - continue - } - - // The split-into-YCbCr-planes golden image is a 2*w2 wide and h+h2 high - // gray image arranged in IMC4 format: - // YYYY - // YYYY - // BBRR - // See http://www.fourcc.org/yuv.php#IMC4 - if got, want := img1.Bounds(), image.Rect(0, 0, 2*w2, h+h2); got != want { - t.Errorf("%s: bounds0: got %v, want %v", tc, got, want) - continue - } - m1, ok := img1.(*image.Gray) - if !ok { - t.Errorf("%s: decoded PNG image is not a Gray", tc) - continue - } - - planes := []struct { - name string - m0Pix []uint8 - m0Stride int - m1Rect image.Rectangle - }{ - {"Y", m0.Y, m0.YStride, image.Rect(0, 0, w, h)}, - {"Cb", m0.Cb, m0.CStride, image.Rect(0*w2, h, 1*w2, h+h2)}, - {"Cr", m0.Cr, m0.CStride, image.Rect(1*w2, h, 2*w2, h+h2)}, - } - for _, plane := range planes { - dx := plane.m1Rect.Dx() - nDiff, diff := 0, make([]byte, dx) - for j, y := 0, plane.m1Rect.Min.Y; y < plane.m1Rect.Max.Y; j, y = j+1, y+1 { - got := plane.m0Pix[j*plane.m0Stride:][:dx] - want := m1.Pix[y*m1.Stride+plane.m1Rect.Min.X:][:dx] - if bytes.Equal(got, want) { - continue - } - nDiff++ - if nDiff > 10 { - t.Errorf("%s: %s plane: more rows differ", tc, plane.name) - break - } - for i := range got { - diff[i] = got[i] - want[i] - } - t.Errorf("%s: %s plane: m0 row %d, m1 row %d\ngot %s\nwant%s\ndiff%s", - tc, plane.name, j, y, hex(got), hex(want), hex(diff)) - } - } + for _, tc := range testCases { + testDecodeLossy(t, tc, true) } }