summaryrefslogtreecommitdiff
path: root/libgo/go/image/color.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/image/color.go')
-rw-r--r--libgo/go/image/color.go251
1 files changed, 251 insertions, 0 deletions
diff --git a/libgo/go/image/color.go b/libgo/go/image/color.go
new file mode 100644
index 000000000..c1345c025
--- /dev/null
+++ b/libgo/go/image/color.go
@@ -0,0 +1,251 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package image
+
+// All Colors can convert themselves, with a possible loss of precision,
+// to 64-bit alpha-premultiplied RGBA. Each channel value ranges within
+// [0, 0xFFFF].
+type Color interface {
+ RGBA() (r, g, b, a uint32)
+}
+
+// An RGBAColor represents a traditional 32-bit alpha-premultiplied color,
+// having 8 bits for each of red, green, blue and alpha.
+type RGBAColor struct {
+ R, G, B, A uint8
+}
+
+func (c RGBAColor) RGBA() (r, g, b, a uint32) {
+ r = uint32(c.R)
+ r |= r << 8
+ g = uint32(c.G)
+ g |= g << 8
+ b = uint32(c.B)
+ b |= b << 8
+ a = uint32(c.A)
+ a |= a << 8
+ return
+}
+
+// An RGBA64Color represents a 64-bit alpha-premultiplied color,
+// having 16 bits for each of red, green, blue and alpha.
+type RGBA64Color struct {
+ R, G, B, A uint16
+}
+
+func (c RGBA64Color) RGBA() (r, g, b, a uint32) {
+ return uint32(c.R), uint32(c.G), uint32(c.B), uint32(c.A)
+}
+
+// An NRGBAColor represents a non-alpha-premultiplied 32-bit color.
+type NRGBAColor struct {
+ R, G, B, A uint8
+}
+
+func (c NRGBAColor) RGBA() (r, g, b, a uint32) {
+ r = uint32(c.R)
+ r |= r << 8
+ r *= uint32(c.A)
+ r /= 0xff
+ g = uint32(c.G)
+ g |= g << 8
+ g *= uint32(c.A)
+ g /= 0xff
+ b = uint32(c.B)
+ b |= b << 8
+ b *= uint32(c.A)
+ b /= 0xff
+ a = uint32(c.A)
+ a |= a << 8
+ return
+}
+
+// An NRGBA64Color represents a non-alpha-premultiplied 64-bit color,
+// having 16 bits for each of red, green, blue and alpha.
+type NRGBA64Color struct {
+ R, G, B, A uint16
+}
+
+func (c NRGBA64Color) RGBA() (r, g, b, a uint32) {
+ r = uint32(c.R)
+ r *= uint32(c.A)
+ r /= 0xffff
+ g = uint32(c.G)
+ g *= uint32(c.A)
+ g /= 0xffff
+ b = uint32(c.B)
+ b *= uint32(c.A)
+ b /= 0xffff
+ a = uint32(c.A)
+ return
+}
+
+// An AlphaColor represents an 8-bit alpha.
+type AlphaColor struct {
+ A uint8
+}
+
+func (c AlphaColor) RGBA() (r, g, b, a uint32) {
+ a = uint32(c.A)
+ a |= a << 8
+ return a, a, a, a
+}
+
+// An Alpha16Color represents a 16-bit alpha.
+type Alpha16Color struct {
+ A uint16
+}
+
+func (c Alpha16Color) RGBA() (r, g, b, a uint32) {
+ a = uint32(c.A)
+ return a, a, a, a
+}
+
+// A GrayColor represents an 8-bit grayscale color.
+type GrayColor struct {
+ Y uint8
+}
+
+func (c GrayColor) RGBA() (r, g, b, a uint32) {
+ y := uint32(c.Y)
+ y |= y << 8
+ return y, y, y, 0xffff
+}
+
+// A Gray16Color represents a 16-bit grayscale color.
+type Gray16Color struct {
+ Y uint16
+}
+
+func (c Gray16Color) RGBA() (r, g, b, a uint32) {
+ y := uint32(c.Y)
+ return y, y, y, 0xffff
+}
+
+// A ColorModel can convert foreign Colors, with a possible loss of precision,
+// to a Color from its own color model.
+type ColorModel interface {
+ Convert(c Color) Color
+}
+
+// The ColorModelFunc type is an adapter to allow the use of an ordinary
+// color conversion function as a ColorModel. If f is such a function,
+// ColorModelFunc(f) is a ColorModel object that invokes f to implement
+// the conversion.
+type ColorModelFunc func(Color) Color
+
+func (f ColorModelFunc) Convert(c Color) Color {
+ return f(c)
+}
+
+func toRGBAColor(c Color) Color {
+ if _, ok := c.(RGBAColor); ok {
+ return c
+ }
+ r, g, b, a := c.RGBA()
+ return RGBAColor{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)}
+}
+
+func toRGBA64Color(c Color) Color {
+ if _, ok := c.(RGBA64Color); ok {
+ return c
+ }
+ r, g, b, a := c.RGBA()
+ return RGBA64Color{uint16(r), uint16(g), uint16(b), uint16(a)}
+}
+
+func toNRGBAColor(c Color) Color {
+ if _, ok := c.(NRGBAColor); ok {
+ return c
+ }
+ r, g, b, a := c.RGBA()
+ if a == 0xffff {
+ return NRGBAColor{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), 0xff}
+ }
+ if a == 0 {
+ return NRGBAColor{0, 0, 0, 0}
+ }
+ // Since Color.RGBA returns a alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
+ r = (r * 0xffff) / a
+ g = (g * 0xffff) / a
+ b = (b * 0xffff) / a
+ return NRGBAColor{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)}
+}
+
+func toNRGBA64Color(c Color) Color {
+ if _, ok := c.(NRGBA64Color); ok {
+ return c
+ }
+ r, g, b, a := c.RGBA()
+ if a == 0xffff {
+ return NRGBA64Color{uint16(r), uint16(g), uint16(b), 0xffff}
+ }
+ if a == 0 {
+ return NRGBA64Color{0, 0, 0, 0}
+ }
+ // Since Color.RGBA returns a alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
+ r = (r * 0xffff) / a
+ g = (g * 0xffff) / a
+ b = (b * 0xffff) / a
+ return NRGBA64Color{uint16(r), uint16(g), uint16(b), uint16(a)}
+}
+
+func toAlphaColor(c Color) Color {
+ if _, ok := c.(AlphaColor); ok {
+ return c
+ }
+ _, _, _, a := c.RGBA()
+ return AlphaColor{uint8(a >> 8)}
+}
+
+func toAlpha16Color(c Color) Color {
+ if _, ok := c.(Alpha16Color); ok {
+ return c
+ }
+ _, _, _, a := c.RGBA()
+ return Alpha16Color{uint16(a)}
+}
+
+func toGrayColor(c Color) Color {
+ if _, ok := c.(GrayColor); ok {
+ return c
+ }
+ r, g, b, _ := c.RGBA()
+ y := (299*r + 587*g + 114*b + 500) / 1000
+ return GrayColor{uint8(y >> 8)}
+}
+
+func toGray16Color(c Color) Color {
+ if _, ok := c.(Gray16Color); ok {
+ return c
+ }
+ r, g, b, _ := c.RGBA()
+ y := (299*r + 587*g + 114*b + 500) / 1000
+ return Gray16Color{uint16(y)}
+}
+
+// The ColorModel associated with RGBAColor.
+var RGBAColorModel ColorModel = ColorModelFunc(toRGBAColor)
+
+// The ColorModel associated with RGBA64Color.
+var RGBA64ColorModel ColorModel = ColorModelFunc(toRGBA64Color)
+
+// The ColorModel associated with NRGBAColor.
+var NRGBAColorModel ColorModel = ColorModelFunc(toNRGBAColor)
+
+// The ColorModel associated with NRGBA64Color.
+var NRGBA64ColorModel ColorModel = ColorModelFunc(toNRGBA64Color)
+
+// The ColorModel associated with AlphaColor.
+var AlphaColorModel ColorModel = ColorModelFunc(toAlphaColor)
+
+// The ColorModel associated with Alpha16Color.
+var Alpha16ColorModel ColorModel = ColorModelFunc(toAlpha16Color)
+
+// The ColorModel associated with GrayColor.
+var GrayColorModel ColorModel = ColorModelFunc(toGrayColor)
+
+// The ColorModel associated with Gray16Color.
+var Gray16ColorModel ColorModel = ColorModelFunc(toGray16Color)