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.
4
5// Package color implements a basic color library.
6package color
7
8// Color can convert itself to alpha-premultiplied 16-bits per channel RGBA.
9// The conversion may be lossy.
10type 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.
15	//
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)
19}
20
21// RGBA represents a traditional 32-bit alpha-premultiplied color, having 8
22// bits for each of red, green, blue and alpha.
23//
24// An alpha-premultiplied color component C has been scaled by alpha (A), so
25// has valid values 0 <= C <= A.
26type RGBA struct {
27	R, G, B, A uint8
28}
29
30func (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
40}
41
42// RGBA64 represents a 64-bit alpha-premultiplied color, having 16 bits for
43// each of red, green, blue and alpha.
44//
45// An alpha-premultiplied color component C has been scaled by alpha (A), so
46// has valid values 0 <= C <= A.
47type RGBA64 struct {
48	R, G, B, A uint16
49}
50
51func (c RGBA64) RGBA() (r, g, b, a uint32) {
52	return uint32(c.R), uint32(c.G), uint32(c.B), uint32(c.A)
53}
54
55// NRGBA represents a non-alpha-premultiplied 32-bit color.
56type NRGBA struct {
57	R, G, B, A uint8
58}
59
60func (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
76}
77
78// NRGBA64 represents a non-alpha-premultiplied 64-bit color,
79// having 16 bits for each of red, green, blue and alpha.
80type NRGBA64 struct {
81	R, G, B, A uint16
82}
83
84func (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
96}
97
98// Alpha represents an 8-bit alpha color.
99type Alpha struct {
100	A uint8
101}
102
103func (c Alpha) RGBA() (r, g, b, a uint32) {
104	a = uint32(c.A)
105	a |= a << 8
106	return a, a, a, a
107}
108
109// Alpha16 represents a 16-bit alpha color.
110type Alpha16 struct {
111	A uint16
112}
113
114func (c Alpha16) RGBA() (r, g, b, a uint32) {
115	a = uint32(c.A)
116	return a, a, a, a
117}
118
119// Gray represents an 8-bit grayscale color.
120type Gray struct {
121	Y uint8
122}
123
124func (c Gray) RGBA() (r, g, b, a uint32) {
125	y := uint32(c.Y)
126	y |= y << 8
127	return y, y, y, 0xffff
128}
129
130// Gray16 represents a 16-bit grayscale color.
131type Gray16 struct {
132	Y uint16
133}
134
135func (c Gray16) RGBA() (r, g, b, a uint32) {
136	y := uint32(c.Y)
137	return y, y, y, 0xffff
138}
139
140// Model can convert any [Color] to one from its own color model. The conversion
141// may be lossy.
142type Model interface {
143	Convert(c Color) Color
144}
145
146// ModelFunc returns a [Model] that invokes f to implement the conversion.
147func 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}
154}
155
156type modelFunc struct {
157	f func(Color) Color
158}
159
160func (m *modelFunc) Convert(c Color) Color {
161	return m.f(c)
162}
163
164// Models for the standard color types.
165var (
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)
174)
175
176func rgbaModel(c Color) Color {
177	if _, ok := c.(RGBA); ok {
178		return c
179	}
180	r, g, b, a := c.RGBA()
181	return RGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)}
182}
183
184func rgba64Model(c Color) Color {
185	if _, ok := c.(RGBA64); ok {
186		return c
187	}
188	r, g, b, a := c.RGBA()
189	return RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
190}
191
192func nrgbaModel(c Color) Color {
193	if _, ok := c.(NRGBA); ok {
194		return c
195	}
196	r, g, b, a := c.RGBA()
197	if a == 0xffff {
198		return NRGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), 0xff}
199	}
200	if a == 0 {
201		return NRGBA{0, 0, 0, 0}
202	}
203	// Since Color.RGBA returns an 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)}
208}
209
210func nrgba64Model(c Color) Color {
211	if _, ok := c.(NRGBA64); ok {
212		return c
213	}
214	r, g, b, a := c.RGBA()
215	if a == 0xffff {
216		return NRGBA64{uint16(r), uint16(g), uint16(b), 0xffff}
217	}
218	if a == 0 {
219		return NRGBA64{0, 0, 0, 0}
220	}
221	// Since Color.RGBA returns an 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)}
226}
227
228func alphaModel(c Color) Color {
229	if _, ok := c.(Alpha); ok {
230		return c
231	}
232	_, _, _, a := c.RGBA()
233	return Alpha{uint8(a >> 8)}
234}
235
236func alpha16Model(c Color) Color {
237	if _, ok := c.(Alpha16); ok {
238		return c
239	}
240	_, _, _, a := c.RGBA()
241	return Alpha16{uint16(a)}
242}
243
244func grayModel(c Color) Color {
245	if _, ok := c.(Gray); ok {
246		return c
247	}
248	r, g, b, _ := c.RGBA()
249
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.
253	//
254	// Note that 19595 + 38470 + 7471 equals 65536.
255	//
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
259
260	return Gray{uint8(y)}
261}
262
263func gray16Model(c Color) Color {
264	if _, ok := c.(Gray16); ok {
265		return c
266	}
267	r, g, b, _ := c.RGBA()
268
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.
272	//
273	// Note that 19595 + 38470 + 7471 equals 65536.
274	y := (19595*r + 38470*g + 7471*b + 1<<15) >> 16
275
276	return Gray16{uint16(y)}
277}
278
279// Palette is a palette of colors.
280type Palette []Color
281
282// Convert returns the palette color closest to c in Euclidean R,G,B space.
283func (p Palette) Convert(c Color) Color {
284	if len(p) == 0 {
285		return nil
286	}
287	return p[p.Index(c)]
288}
289
290// Index returns the index of the palette color closest to c in Euclidean
291// R,G,B,A space.
292func (p Palette) Index(c Color) int {
293	// A batch version of this computation is in image/draw/draw.go.
294
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
303			}
304			ret, bestSum = i, sum
305		}
306	}
307	return ret
308}
309
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.
312//
313// x and y are both assumed to be in the range [0, 0xffff].
314func sqDiff(x, y uint32) uint32 {
315	// The canonical code of this function looks as follows:
316	//
317	//	var d uint32
318	//	if x > y {
319	//		d = x - y
320	//	} else {
321	//		d = y - x
322	//	}
323	//	return (d * d) >> 2
324	//
325	// Language spec guarantees the following properties of unsigned integer
326	// values operations with respect to overflow/wrap around:
327	//
328	// > For unsigned integer values, the operations +, -, *, and << are
329	// > computed modulo 2n, where n is the bit width of the unsigned
330	// > integer's type. Loosely speaking, these unsigned integer operations
331	// > discard high bits upon overflow, and programs may rely on ``wrap
332	// > around''.
333	//
334	// Considering these properties and the fact that this function is
335	// called in the hot paths (x,y loops), it is reduced to the below code
336	// which is slightly faster. See TestSqDiff for correctness check.
337	d := x - y
338	return (d * d) >> 2
339}
340
341// Standard colors.
342var (
343	Black       = Gray16{0}
344	White       = Gray16{0xffff}
345	Transparent = Alpha16{0}
346	Opaque      = Alpha16{0xffff}
347)
348