PR tree-optimization/82929
[official-gcc.git] / libgo / go / image / color / color.go
blob0832c597293751afe38b00f3b3811c60fdf31a2d
1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package color implements a basic color library.
6 package color
8 // Color can convert itself to alpha-premultiplied 16-bits per channel RGBA.
9 // The conversion may be lossy.
10 type Color interface {
11 // RGBA returns the alpha-premultiplied red, green, blue and alpha values
12 // for the color. Each value ranges within [0, 0xffff], but is represented
13 // by a uint32 so that multiplying by a blend factor up to 0xffff will not
14 // overflow.
16 // An alpha-premultiplied color component c has been scaled by alpha (a),
17 // so has valid values 0 <= c <= a.
18 RGBA() (r, g, b, a uint32)
21 // RGBA represents a traditional 32-bit alpha-premultiplied color, having 8
22 // bits for each of red, green, blue and alpha.
24 // An alpha-premultiplied color component C has been scaled by alpha (A), so
25 // has valid values 0 <= C <= A.
26 type RGBA struct {
27 R, G, B, A uint8
30 func (c RGBA) RGBA() (r, g, b, a uint32) {
31 r = uint32(c.R)
32 r |= r << 8
33 g = uint32(c.G)
34 g |= g << 8
35 b = uint32(c.B)
36 b |= b << 8
37 a = uint32(c.A)
38 a |= a << 8
39 return
42 // RGBA64 represents a 64-bit alpha-premultiplied color, having 16 bits for
43 // each of red, green, blue and alpha.
45 // An alpha-premultiplied color component C has been scaled by alpha (A), so
46 // has valid values 0 <= C <= A.
47 type RGBA64 struct {
48 R, G, B, A uint16
51 func (c RGBA64) RGBA() (r, g, b, a uint32) {
52 return uint32(c.R), uint32(c.G), uint32(c.B), uint32(c.A)
55 // NRGBA represents a non-alpha-premultiplied 32-bit color.
56 type NRGBA struct {
57 R, G, B, A uint8
60 func (c NRGBA) RGBA() (r, g, b, a uint32) {
61 r = uint32(c.R)
62 r |= r << 8
63 r *= uint32(c.A)
64 r /= 0xff
65 g = uint32(c.G)
66 g |= g << 8
67 g *= uint32(c.A)
68 g /= 0xff
69 b = uint32(c.B)
70 b |= b << 8
71 b *= uint32(c.A)
72 b /= 0xff
73 a = uint32(c.A)
74 a |= a << 8
75 return
78 // NRGBA64 represents a non-alpha-premultiplied 64-bit color,
79 // having 16 bits for each of red, green, blue and alpha.
80 type NRGBA64 struct {
81 R, G, B, A uint16
84 func (c NRGBA64) RGBA() (r, g, b, a uint32) {
85 r = uint32(c.R)
86 r *= uint32(c.A)
87 r /= 0xffff
88 g = uint32(c.G)
89 g *= uint32(c.A)
90 g /= 0xffff
91 b = uint32(c.B)
92 b *= uint32(c.A)
93 b /= 0xffff
94 a = uint32(c.A)
95 return
98 // Alpha represents an 8-bit alpha color.
99 type Alpha struct {
100 A uint8
103 func (c Alpha) RGBA() (r, g, b, a uint32) {
104 a = uint32(c.A)
105 a |= a << 8
106 return a, a, a, a
109 // Alpha16 represents a 16-bit alpha color.
110 type Alpha16 struct {
111 A uint16
114 func (c Alpha16) RGBA() (r, g, b, a uint32) {
115 a = uint32(c.A)
116 return a, a, a, a
119 // Gray represents an 8-bit grayscale color.
120 type Gray struct {
121 Y uint8
124 func (c Gray) RGBA() (r, g, b, a uint32) {
125 y := uint32(c.Y)
126 y |= y << 8
127 return y, y, y, 0xffff
130 // Gray16 represents a 16-bit grayscale color.
131 type Gray16 struct {
132 Y uint16
135 func (c Gray16) RGBA() (r, g, b, a uint32) {
136 y := uint32(c.Y)
137 return y, y, y, 0xffff
140 // Model can convert any Color to one from its own color model. The conversion
141 // may be lossy.
142 type Model interface {
143 Convert(c Color) Color
146 // ModelFunc returns a Model that invokes f to implement the conversion.
147 func ModelFunc(f func(Color) Color) Model {
148 // Note: using *modelFunc as the implementation
149 // means that callers can still use comparisons
150 // like m == RGBAModel. This is not possible if
151 // we use the func value directly, because funcs
152 // are no longer comparable.
153 return &modelFunc{f}
156 type modelFunc struct {
157 f func(Color) Color
160 func (m *modelFunc) Convert(c Color) Color {
161 return m.f(c)
164 // Models for the standard color types.
165 var (
166 RGBAModel Model = ModelFunc(rgbaModel)
167 RGBA64Model Model = ModelFunc(rgba64Model)
168 NRGBAModel Model = ModelFunc(nrgbaModel)
169 NRGBA64Model Model = ModelFunc(nrgba64Model)
170 AlphaModel Model = ModelFunc(alphaModel)
171 Alpha16Model Model = ModelFunc(alpha16Model)
172 GrayModel Model = ModelFunc(grayModel)
173 Gray16Model Model = ModelFunc(gray16Model)
176 func rgbaModel(c Color) Color {
177 if _, ok := c.(RGBA); ok {
178 return c
180 r, g, b, a := c.RGBA()
181 return RGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)}
184 func rgba64Model(c Color) Color {
185 if _, ok := c.(RGBA64); ok {
186 return c
188 r, g, b, a := c.RGBA()
189 return RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
192 func nrgbaModel(c Color) Color {
193 if _, ok := c.(NRGBA); ok {
194 return c
196 r, g, b, a := c.RGBA()
197 if a == 0xffff {
198 return NRGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), 0xff}
200 if a == 0 {
201 return NRGBA{0, 0, 0, 0}
203 // Since Color.RGBA returns a alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
204 r = (r * 0xffff) / a
205 g = (g * 0xffff) / a
206 b = (b * 0xffff) / a
207 return NRGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)}
210 func nrgba64Model(c Color) Color {
211 if _, ok := c.(NRGBA64); ok {
212 return c
214 r, g, b, a := c.RGBA()
215 if a == 0xffff {
216 return NRGBA64{uint16(r), uint16(g), uint16(b), 0xffff}
218 if a == 0 {
219 return NRGBA64{0, 0, 0, 0}
221 // Since Color.RGBA returns a alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
222 r = (r * 0xffff) / a
223 g = (g * 0xffff) / a
224 b = (b * 0xffff) / a
225 return NRGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
228 func alphaModel(c Color) Color {
229 if _, ok := c.(Alpha); ok {
230 return c
232 _, _, _, a := c.RGBA()
233 return Alpha{uint8(a >> 8)}
236 func alpha16Model(c Color) Color {
237 if _, ok := c.(Alpha16); ok {
238 return c
240 _, _, _, a := c.RGBA()
241 return Alpha16{uint16(a)}
244 func grayModel(c Color) Color {
245 if _, ok := c.(Gray); ok {
246 return c
248 r, g, b, _ := c.RGBA()
250 // These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
251 // as those given by the JFIF specification and used by func RGBToYCbCr in
252 // ycbcr.go.
254 // Note that 19595 + 38470 + 7471 equals 65536.
256 // The 24 is 16 + 8. The 16 is the same as used in RGBToYCbCr. The 8 is
257 // because the return value is 8 bit color, not 16 bit color.
258 y := (19595*r + 38470*g + 7471*b + 1<<15) >> 24
260 return Gray{uint8(y)}
263 func gray16Model(c Color) Color {
264 if _, ok := c.(Gray16); ok {
265 return c
267 r, g, b, _ := c.RGBA()
269 // These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
270 // as those given by the JFIF specification and used by func RGBToYCbCr in
271 // ycbcr.go.
273 // Note that 19595 + 38470 + 7471 equals 65536.
274 y := (19595*r + 38470*g + 7471*b + 1<<15) >> 16
276 return Gray16{uint16(y)}
279 // Palette is a palette of colors.
280 type Palette []Color
282 // Convert returns the palette color closest to c in Euclidean R,G,B space.
283 func (p Palette) Convert(c Color) Color {
284 if len(p) == 0 {
285 return nil
287 return p[p.Index(c)]
290 // Index returns the index of the palette color closest to c in Euclidean
291 // R,G,B,A space.
292 func (p Palette) Index(c Color) int {
293 // A batch version of this computation is in image/draw/draw.go.
295 cr, cg, cb, ca := c.RGBA()
296 ret, bestSum := 0, uint32(1<<32-1)
297 for i, v := range p {
298 vr, vg, vb, va := v.RGBA()
299 sum := sqDiff(cr, vr) + sqDiff(cg, vg) + sqDiff(cb, vb) + sqDiff(ca, va)
300 if sum < bestSum {
301 if sum == 0 {
302 return i
304 ret, bestSum = i, sum
307 return ret
310 // sqDiff returns the squared-difference of x and y, shifted by 2 so that
311 // adding four of those won't overflow a uint32.
313 // x and y are both assumed to be in the range [0, 0xffff].
314 func sqDiff(x, y uint32) uint32 {
315 var d uint32
316 if x > y {
317 d = x - y
318 } else {
319 d = y - x
321 return (d * d) >> 2
324 // Standard colors.
325 var (
326 Black = Gray16{0}
327 White = Gray16{0xffff}
328 Transparent = Alpha16{0}
329 Opaque = Alpha16{0xffff}