]> Cypherpunks repositories - gostls13.git/commitdiff
image/color: have NYCbCrA.RGBA work in 16-bit color.
authorNigel Tao <nigeltao@golang.org>
Wed, 23 Dec 2015 06:35:46 +0000 (17:35 +1100)
committerNigel Tao <nigeltao@golang.org>
Thu, 24 Dec 2015 06:55:33 +0000 (06:55 +0000)
This makes NYCbCrA consistent with YCbCr.

Fixes #13706.

Change-Id: Ifced84372e4865925fa6efef9ca2f1de43da70e0
Reviewed-on: https://go-review.googlesource.com/18115
Reviewed-by: Rob Pike <r@golang.org>
src/image/color/ycbcr.go
src/image/color/ycbcr_test.go

index 0c2ba84c57293fe70cbda1ffd3dbe20bb7e0e376..904434f6a3d8a9830c15befc4623550c737fba3f 100644 (file)
@@ -98,7 +98,7 @@ func (c YCbCr) RGBA() (uint32, uint32, uint32, uint32) {
        //      fmt.Printf("0x%04x 0x%04x 0x%04x\n", r0, g0, b0)
        //      fmt.Printf("0x%04x 0x%04x 0x%04x\n", r1, g1, b1)
        // prints:
-       //      0x7e18 0x808e 0x7db9
+       //      0x7e18 0x808d 0x7db9
        //      0x7e7e 0x8080 0x7d7d
 
        yy1 := int32(c.Y) * 0x10100 // Convert 0x12 to 0x121200.
@@ -144,13 +144,33 @@ type NYCbCrA struct {
        A uint8
 }
 
-func (c NYCbCrA) RGBA() (r, g, b, a uint32) {
-       r8, g8, b8 := YCbCrToRGB(c.Y, c.Cb, c.Cr)
-       a = uint32(c.A) * 0x101
-       r = uint32(r8) * 0x101 * a / 0xffff
-       g = uint32(g8) * 0x101 * a / 0xffff
-       b = uint32(b8) * 0x101 * a / 0xffff
-       return
+func (c NYCbCrA) RGBA() (uint32, uint32, uint32, uint32) {
+       // The first part of this method is the same as YCbCr.RGBA.
+       yy1 := int32(c.Y) * 0x10100 // Convert 0x12 to 0x121200.
+       cb1 := int32(c.Cb) - 128
+       cr1 := int32(c.Cr) - 128
+       r := (yy1 + 91881*cr1) >> 8
+       g := (yy1 - 22554*cb1 - 46802*cr1) >> 8
+       b := (yy1 + 116130*cb1) >> 8
+       if r < 0 {
+               r = 0
+       } else if r > 0xffff {
+               r = 0xffff
+       }
+       if g < 0 {
+               g = 0
+       } else if g > 0xffff {
+               g = 0xffff
+       }
+       if b < 0 {
+               b = 0
+       } else if b > 0xffff {
+               b = 0xffff
+       }
+
+       // The second part of this method applies the alpha.
+       a := uint32(c.A) * 0x101
+       return uint32(r) * a / 0xffff, uint32(g) * a / 0xffff, uint32(b) * a / 0xffff, a
 }
 
 // NYCbCrAModel is the Model for non-alpha-premultiplied Y'CbCr-with-alpha
index 5da49d379aa799d04f0ed8a1ba480f0cbab536ec..f5e7cbf3358ce609e5986d814abdbbb9b116a608 100644 (file)
@@ -67,7 +67,31 @@ func TestYCbCrToRGBConsistency(t *testing.T) {
 // TestYCbCrGray tests that YCbCr colors are a superset of Gray colors.
 func TestYCbCrGray(t *testing.T) {
        for i := 0; i < 256; i++ {
-               if err := eq(YCbCr{uint8(i), 0x80, 0x80}, Gray{uint8(i)}); err != nil {
+               c0 := YCbCr{uint8(i), 0x80, 0x80}
+               c1 := Gray{uint8(i)}
+               if err := eq(c0, c1); err != nil {
+                       t.Errorf("i=0x%02x:\n%v", i, err)
+               }
+       }
+}
+
+// TestNYCbCrAAlpha tests that NYCbCrA colors are a superset of Alpha colors.
+func TestNYCbCrAAlpha(t *testing.T) {
+       for i := 0; i < 256; i++ {
+               c0 := NYCbCrA{YCbCr{0xff, 0x80, 0x80}, uint8(i)}
+               c1 := Alpha{uint8(i)}
+               if err := eq(c0, c1); err != nil {
+                       t.Errorf("i=0x%02x:\n%v", i, err)
+               }
+       }
+}
+
+// TestNYCbCrAYCbCr tests that NYCbCrA colors are a superset of YCbCr colors.
+func TestNYCbCrAYCbCr(t *testing.T) {
+       for i := 0; i < 256; i++ {
+               c0 := NYCbCrA{YCbCr{uint8(i), 0x40, 0xc0}, 0xff}
+               c1 := YCbCr{uint8(i), 0x40, 0xc0}
+               if err := eq(c0, c1); err != nil {
                        t.Errorf("i=0x%02x:\n%v", i, err)
                }
        }