...

Source file src/pkg/image/color/color.go

     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