github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/image/color/color.go (about) 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 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)} 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 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)} 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 var d uint32 316 if x > y { 317 d = x - y 318 } else { 319 d = y - x 320 } 321 return (d * d) >> 2 322 } 323 324 // Standard colors. 325 var ( 326 Black = Gray16{0} 327 White = Gray16{0xffff} 328 Transparent = Alpha16{0} 329 Opaque = Alpha16{0xffff} 330 )