...

Source file src/image/color/color.go

Documentation: image/color

		 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.
		 6  package color
		 7  
		 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.
		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.
		26  type RGBA struct {
		27  	R, G, B, A uint8
		28  }
		29  
		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
		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.
		47  type RGBA64 struct {
		48  	R, G, B, A uint16
		49  }
		50  
		51  func (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.
		56  type NRGBA struct {
		57  	R, G, B, A uint8
		58  }
		59  
		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
		76  }
		77  
		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
		82  }
		83  
		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
		96  }
		97  
		98  // Alpha represents an 8-bit alpha color.
		99  type Alpha struct {
	 100  	A uint8
	 101  }
	 102  
	 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
	 107  }
	 108  
	 109  // Alpha16 represents a 16-bit alpha color.
	 110  type Alpha16 struct {
	 111  	A uint16
	 112  }
	 113  
	 114  func (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.
	 120  type Gray struct {
	 121  	Y uint8
	 122  }
	 123  
	 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
	 128  }
	 129  
	 130  // Gray16 represents a 16-bit grayscale color.
	 131  type Gray16 struct {
	 132  	Y uint16
	 133  }
	 134  
	 135  func (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.
	 142  type Model interface {
	 143  	Convert(c Color) Color
	 144  }
	 145  
	 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}
	 154  }
	 155  
	 156  type modelFunc struct {
	 157  	f func(Color) Color
	 158  }
	 159  
	 160  func (m *modelFunc) Convert(c Color) Color {
	 161  	return m.f(c)
	 162  }
	 163  
	 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)
	 174  )
	 175  
	 176  func 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  
	 184  func 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  
	 192  func 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  
	 210  func 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  
	 228  func 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  
	 236  func 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  
	 244  func 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  
	 263  func 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.
	 280  type Palette []Color
	 281  
	 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
	 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.
	 292  func (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].
	 314  func 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.
	 342  var (
	 343  	Black			 = Gray16{0}
	 344  	White			 = Gray16{0xffff}
	 345  	Transparent = Alpha16{0}
	 346  	Opaque			= Alpha16{0xffff}
	 347  )
	 348  

View as plain text