Skip to content

Commit e4dcf5c

Browse files
committed
image/color: have NYCbCrA.RGBA work in 16-bit color.
This makes NYCbCrA consistent with YCbCr. Fixes #13706. Change-Id: Ifced84372e4865925fa6efef9ca2f1de43da70e0 Reviewed-on: https://go-review.googlesource.com/18115 Reviewed-by: Rob Pike <[email protected]>
1 parent 5b5e19e commit e4dcf5c

File tree

2 files changed

+53
-9
lines changed

2 files changed

+53
-9
lines changed

src/image/color/ycbcr.go

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ func (c YCbCr) RGBA() (uint32, uint32, uint32, uint32) {
9898
// fmt.Printf("0x%04x 0x%04x 0x%04x\n", r0, g0, b0)
9999
// fmt.Printf("0x%04x 0x%04x 0x%04x\n", r1, g1, b1)
100100
// prints:
101-
// 0x7e18 0x808e 0x7db9
101+
// 0x7e18 0x808d 0x7db9
102102
// 0x7e7e 0x8080 0x7d7d
103103

104104
yy1 := int32(c.Y) * 0x10100 // Convert 0x12 to 0x121200.
@@ -144,13 +144,33 @@ type NYCbCrA struct {
144144
A uint8
145145
}
146146

147-
func (c NYCbCrA) RGBA() (r, g, b, a uint32) {
148-
r8, g8, b8 := YCbCrToRGB(c.Y, c.Cb, c.Cr)
149-
a = uint32(c.A) * 0x101
150-
r = uint32(r8) * 0x101 * a / 0xffff
151-
g = uint32(g8) * 0x101 * a / 0xffff
152-
b = uint32(b8) * 0x101 * a / 0xffff
153-
return
147+
func (c NYCbCrA) RGBA() (uint32, uint32, uint32, uint32) {
148+
// The first part of this method is the same as YCbCr.RGBA.
149+
yy1 := int32(c.Y) * 0x10100 // Convert 0x12 to 0x121200.
150+
cb1 := int32(c.Cb) - 128
151+
cr1 := int32(c.Cr) - 128
152+
r := (yy1 + 91881*cr1) >> 8
153+
g := (yy1 - 22554*cb1 - 46802*cr1) >> 8
154+
b := (yy1 + 116130*cb1) >> 8
155+
if r < 0 {
156+
r = 0
157+
} else if r > 0xffff {
158+
r = 0xffff
159+
}
160+
if g < 0 {
161+
g = 0
162+
} else if g > 0xffff {
163+
g = 0xffff
164+
}
165+
if b < 0 {
166+
b = 0
167+
} else if b > 0xffff {
168+
b = 0xffff
169+
}
170+
171+
// The second part of this method applies the alpha.
172+
a := uint32(c.A) * 0x101
173+
return uint32(r) * a / 0xffff, uint32(g) * a / 0xffff, uint32(b) * a / 0xffff, a
154174
}
155175

156176
// NYCbCrAModel is the Model for non-alpha-premultiplied Y'CbCr-with-alpha

src/image/color/ycbcr_test.go

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,31 @@ func TestYCbCrToRGBConsistency(t *testing.T) {
6767
// TestYCbCrGray tests that YCbCr colors are a superset of Gray colors.
6868
func TestYCbCrGray(t *testing.T) {
6969
for i := 0; i < 256; i++ {
70-
if err := eq(YCbCr{uint8(i), 0x80, 0x80}, Gray{uint8(i)}); err != nil {
70+
c0 := YCbCr{uint8(i), 0x80, 0x80}
71+
c1 := Gray{uint8(i)}
72+
if err := eq(c0, c1); err != nil {
73+
t.Errorf("i=0x%02x:\n%v", i, err)
74+
}
75+
}
76+
}
77+
78+
// TestNYCbCrAAlpha tests that NYCbCrA colors are a superset of Alpha colors.
79+
func TestNYCbCrAAlpha(t *testing.T) {
80+
for i := 0; i < 256; i++ {
81+
c0 := NYCbCrA{YCbCr{0xff, 0x80, 0x80}, uint8(i)}
82+
c1 := Alpha{uint8(i)}
83+
if err := eq(c0, c1); err != nil {
84+
t.Errorf("i=0x%02x:\n%v", i, err)
85+
}
86+
}
87+
}
88+
89+
// TestNYCbCrAYCbCr tests that NYCbCrA colors are a superset of YCbCr colors.
90+
func TestNYCbCrAYCbCr(t *testing.T) {
91+
for i := 0; i < 256; i++ {
92+
c0 := NYCbCrA{YCbCr{uint8(i), 0x40, 0xc0}, 0xff}
93+
c1 := YCbCr{uint8(i), 0x40, 0xc0}
94+
if err := eq(c0, c1); err != nil {
7195
t.Errorf("i=0x%02x:\n%v", i, err)
7296
}
7397
}

0 commit comments

Comments
 (0)