mirror of
https://github.com/golang/go
synced 2024-11-25 08:07:57 -07:00
Make image.Color.RGBA return 16 bit color instead of 32 bit color.
R=rsc CC=golang-dev https://golang.org/cl/1388041
This commit is contained in:
parent
d5a8647d80
commit
2bb59fd71a
@ -51,13 +51,9 @@ func (c Color) RGBA() (r, g, b, a uint32) {
|
|||||||
x := uint32(c)
|
x := uint32(c)
|
||||||
r, g, b, a = x>>24, (x>>16)&0xFF, (x>>8)&0xFF, x&0xFF
|
r, g, b, a = x>>24, (x>>16)&0xFF, (x>>8)&0xFF, x&0xFF
|
||||||
r |= r << 8
|
r |= r << 8
|
||||||
r |= r << 16
|
|
||||||
g |= g << 8
|
g |= g << 8
|
||||||
g |= g << 16
|
|
||||||
b |= b << 8
|
b |= b << 8
|
||||||
b |= b << 16
|
|
||||||
a |= a << 8
|
a |= a << 8
|
||||||
a |= a << 16
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +99,7 @@ func toColor(color image.Color) image.Color {
|
|||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
r, g, b, a := color.RGBA()
|
r, g, b, a := color.RGBA()
|
||||||
return Color(r>>24<<24 | g>>24<<16 | b>>24<<8 | a>>24)
|
return Color(r>>8<<24 | g>>8<<16 | b>>8<<8 | a>>8)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Color) ColorModel() image.ColorModel { return image.ColorModelFunc(toColor) }
|
func (c Color) ColorModel() image.ColorModel { return image.ColorModelFunc(toColor) }
|
||||||
|
@ -105,13 +105,10 @@ func DrawMask(dst Image, r Rectangle, src image.Image, sp Point, mask image.Imag
|
|||||||
sx := sp.X + x0 - r.Min.X
|
sx := sp.X + x0 - r.Min.X
|
||||||
mx := mp.X + x0 - r.Min.X
|
mx := mp.X + x0 - r.Min.X
|
||||||
for x := x0; x != x1; x, sx, mx = x+dx, sx+dx, mx+dx {
|
for x := x0; x != x1; x, sx, mx = x+dx, sx+dx, mx+dx {
|
||||||
// A nil mask is equivalent to a fully opaque, infinitely large mask.
|
|
||||||
// We work in 16-bit color, so that multiplying two values does not overflow a uint32.
|
|
||||||
const M = 1<<16 - 1
|
const M = 1<<16 - 1
|
||||||
ma := uint32(M)
|
ma := uint32(M)
|
||||||
if mask != nil {
|
if mask != nil {
|
||||||
_, _, _, ma = mask.At(mx, my).RGBA()
|
_, _, _, ma = mask.At(mx, my).RGBA()
|
||||||
ma >>= 16
|
|
||||||
}
|
}
|
||||||
switch {
|
switch {
|
||||||
case ma == 0:
|
case ma == 0:
|
||||||
@ -124,19 +121,11 @@ func DrawMask(dst Image, r Rectangle, src image.Image, sp Point, mask image.Imag
|
|||||||
dst.Set(x, y, src.At(sx, sy))
|
dst.Set(x, y, src.At(sx, sy))
|
||||||
default:
|
default:
|
||||||
sr, sg, sb, sa := src.At(sx, sy).RGBA()
|
sr, sg, sb, sa := src.At(sx, sy).RGBA()
|
||||||
sr >>= 16
|
|
||||||
sg >>= 16
|
|
||||||
sb >>= 16
|
|
||||||
sa >>= 16
|
|
||||||
if out == nil {
|
if out == nil {
|
||||||
out = new(image.RGBA64Color)
|
out = new(image.RGBA64Color)
|
||||||
}
|
}
|
||||||
if op == Over {
|
if op == Over {
|
||||||
dr, dg, db, da := dst.At(x, y).RGBA()
|
dr, dg, db, da := dst.At(x, y).RGBA()
|
||||||
dr >>= 16
|
|
||||||
dg >>= 16
|
|
||||||
db >>= 16
|
|
||||||
da >>= 16
|
|
||||||
a := M - (sa * ma / M)
|
a := M - (sa * ma / M)
|
||||||
out.R = uint16((dr*a + sr*ma) / M)
|
out.R = uint16((dr*a + sr*ma) / M)
|
||||||
out.G = uint16((dg*a + sg*ma) / M)
|
out.G = uint16((dg*a + sg*ma) / M)
|
||||||
@ -158,10 +147,6 @@ func drawGlyphOver(dst *image.RGBA, r Rectangle, src image.ColorImage, mask *ima
|
|||||||
x0, x1 := r.Min.X, r.Max.X
|
x0, x1 := r.Min.X, r.Max.X
|
||||||
y0, y1 := r.Min.Y, r.Max.Y
|
y0, y1 := r.Min.Y, r.Max.Y
|
||||||
cr, cg, cb, ca := src.RGBA()
|
cr, cg, cb, ca := src.RGBA()
|
||||||
cr >>= 16
|
|
||||||
cg >>= 16
|
|
||||||
cb >>= 16
|
|
||||||
ca >>= 16
|
|
||||||
for y, my := y0, mp.Y; y != y1; y, my = y+1, my+1 {
|
for y, my := y0, mp.Y; y != y1; y, my = y+1, my+1 {
|
||||||
p := dst.Pixel[y]
|
p := dst.Pixel[y]
|
||||||
for x, mx := x0, mp.X; x != x1; x, mx = x+1, mx+1 {
|
for x, mx := x0, mp.X; x != x1; x, mx = x+1, mx+1 {
|
||||||
@ -192,7 +177,7 @@ func drawFill(dst *image.RGBA, r Rectangle, src image.ColorImage) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
cr, cg, cb, ca := src.RGBA()
|
cr, cg, cb, ca := src.RGBA()
|
||||||
color := image.RGBAColor{uint8(cr >> 24), uint8(cg >> 24), uint8(cb >> 24), uint8(ca >> 24)}
|
color := image.RGBAColor{uint8(cr >> 8), uint8(cg >> 8), uint8(cb >> 8), uint8(ca >> 8)}
|
||||||
// The built-in copy function is faster than a straightforward for loop to fill the destination with
|
// The built-in copy function is faster than a straightforward for loop to fill the destination with
|
||||||
// the color, but copy requires a slice source. We therefore use a for loop to fill the first row, and
|
// the color, but copy requires a slice source. We therefore use a for loop to fill the first row, and
|
||||||
// then use the first row as the slice source for the remaining rows.
|
// then use the first row as the slice source for the remaining rows.
|
||||||
@ -238,13 +223,8 @@ func drawRGBA(dst *image.RGBA, r Rectangle, src image.Image, sp Point, mask imag
|
|||||||
ma := uint32(M)
|
ma := uint32(M)
|
||||||
if mask != nil {
|
if mask != nil {
|
||||||
_, _, _, ma = mask.At(mx, my).RGBA()
|
_, _, _, ma = mask.At(mx, my).RGBA()
|
||||||
ma >>= 16
|
|
||||||
}
|
}
|
||||||
sr, sg, sb, sa := src.At(sx, sy).RGBA()
|
sr, sg, sb, sa := src.At(sx, sy).RGBA()
|
||||||
sr >>= 16
|
|
||||||
sg >>= 16
|
|
||||||
sb >>= 16
|
|
||||||
sa >>= 16
|
|
||||||
var dr, dg, db, da uint32
|
var dr, dg, db, da uint32
|
||||||
if op == Over {
|
if op == Over {
|
||||||
rgba := p[x]
|
rgba := p[x]
|
||||||
|
@ -106,20 +106,11 @@ func makeGolden(dst image.Image, t drawTest) image.Image {
|
|||||||
var dr, dg, db, da uint32
|
var dr, dg, db, da uint32
|
||||||
if t.op == Over {
|
if t.op == Over {
|
||||||
dr, dg, db, da = dst.At(x, y).RGBA()
|
dr, dg, db, da = dst.At(x, y).RGBA()
|
||||||
dr >>= 16
|
|
||||||
dg >>= 16
|
|
||||||
db >>= 16
|
|
||||||
da >>= 16
|
|
||||||
}
|
}
|
||||||
sr, sg, sb, sa := t.src.At(sx, sy).RGBA()
|
sr, sg, sb, sa := t.src.At(sx, sy).RGBA()
|
||||||
sr >>= 16
|
|
||||||
sg >>= 16
|
|
||||||
sb >>= 16
|
|
||||||
sa >>= 16
|
|
||||||
ma := uint32(M)
|
ma := uint32(M)
|
||||||
if t.mask != nil {
|
if t.mask != nil {
|
||||||
_, _, _, ma = t.mask.At(mx, my).RGBA()
|
_, _, _, ma = t.mask.At(mx, my).RGBA()
|
||||||
ma >>= 16
|
|
||||||
}
|
}
|
||||||
a := M - (sa * ma / M)
|
a := M - (sa * ma / M)
|
||||||
golden.Set(x, y, image.RGBA64Color{
|
golden.Set(x, y, image.RGBA64Color{
|
||||||
|
@ -61,16 +61,12 @@ func (p Color) RGBA() (r, g, b, a uint32) {
|
|||||||
x := uint32(p)
|
x := uint32(p)
|
||||||
a = x >> 24
|
a = x >> 24
|
||||||
a |= a << 8
|
a |= a << 8
|
||||||
a |= a << 16
|
|
||||||
r = (x >> 16) & 0xFF
|
r = (x >> 16) & 0xFF
|
||||||
r |= r << 8
|
r |= r << 8
|
||||||
r |= r << 16
|
|
||||||
g = (x >> 8) & 0xFF
|
g = (x >> 8) & 0xFF
|
||||||
g |= g << 8
|
g |= g << 8
|
||||||
g |= g << 16
|
|
||||||
b = x & 0xFF
|
b = x & 0xFF
|
||||||
b |= b << 8
|
b |= b << 8
|
||||||
b |= b << 16
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,14 +4,15 @@
|
|||||||
|
|
||||||
package image
|
package image
|
||||||
|
|
||||||
// TODO(nigeltao): Think about how floating-point color models work.
|
// All Colors can convert themselves, with a possible loss of precision,
|
||||||
|
// to 64-bit alpha-premultiplied RGBA. Each channel value ranges within
|
||||||
// All Colors can convert themselves, with a possible loss of precision, to 128-bit alpha-premultiplied RGBA.
|
// [0, 0xFFFF].
|
||||||
type Color interface {
|
type Color interface {
|
||||||
RGBA() (r, g, b, a uint32)
|
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.
|
// An RGBAColor represents a traditional 32-bit alpha-premultiplied color,
|
||||||
|
// having 8 bits for each of red, green, blue and alpha.
|
||||||
type RGBAColor struct {
|
type RGBAColor struct {
|
||||||
R, G, B, A uint8
|
R, G, B, A uint8
|
||||||
}
|
}
|
||||||
@ -19,34 +20,23 @@ type RGBAColor struct {
|
|||||||
func (c RGBAColor) RGBA() (r, g, b, a uint32) {
|
func (c RGBAColor) RGBA() (r, g, b, a uint32) {
|
||||||
r = uint32(c.R)
|
r = uint32(c.R)
|
||||||
r |= r << 8
|
r |= r << 8
|
||||||
r |= r << 16
|
|
||||||
g = uint32(c.G)
|
g = uint32(c.G)
|
||||||
g |= g << 8
|
g |= g << 8
|
||||||
g |= g << 16
|
|
||||||
b = uint32(c.B)
|
b = uint32(c.B)
|
||||||
b |= b << 8
|
b |= b << 8
|
||||||
b |= b << 16
|
|
||||||
a = uint32(c.A)
|
a = uint32(c.A)
|
||||||
a |= a << 8
|
a |= a << 8
|
||||||
a |= a << 16
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// An RGBA64Color represents a 64-bit alpha-premultiplied color, having 16 bits for each of red, green, blue and alpha.
|
// An RGBA64Color represents a 64-bit alpha-premultiplied color,
|
||||||
|
// having 16 bits for each of red, green, blue and alpha.
|
||||||
type RGBA64Color struct {
|
type RGBA64Color struct {
|
||||||
R, G, B, A uint16
|
R, G, B, A uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c RGBA64Color) RGBA() (r, g, b, a uint32) {
|
func (c RGBA64Color) RGBA() (r, g, b, a uint32) {
|
||||||
r = uint32(c.R)
|
return uint32(c.R), uint32(c.G), uint32(c.B), uint32(c.A)
|
||||||
r |= r << 16
|
|
||||||
g = uint32(c.G)
|
|
||||||
g |= g << 16
|
|
||||||
b = uint32(c.B)
|
|
||||||
b |= b << 16
|
|
||||||
a = uint32(c.A)
|
|
||||||
a |= a << 16
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// An NRGBAColor represents a non-alpha-premultiplied 32-bit color.
|
// An NRGBAColor represents a non-alpha-premultiplied 32-bit color.
|
||||||
@ -59,24 +49,21 @@ func (c NRGBAColor) RGBA() (r, g, b, a uint32) {
|
|||||||
r |= r << 8
|
r |= r << 8
|
||||||
r *= uint32(c.A)
|
r *= uint32(c.A)
|
||||||
r /= 0xff
|
r /= 0xff
|
||||||
r |= r << 16
|
|
||||||
g = uint32(c.G)
|
g = uint32(c.G)
|
||||||
g |= g << 8
|
g |= g << 8
|
||||||
g *= uint32(c.A)
|
g *= uint32(c.A)
|
||||||
g /= 0xff
|
g /= 0xff
|
||||||
g |= g << 16
|
|
||||||
b = uint32(c.B)
|
b = uint32(c.B)
|
||||||
b |= b << 8
|
b |= b << 8
|
||||||
b *= uint32(c.A)
|
b *= uint32(c.A)
|
||||||
b /= 0xff
|
b /= 0xff
|
||||||
b |= b << 16
|
|
||||||
a = uint32(c.A)
|
a = uint32(c.A)
|
||||||
a |= a << 8
|
a |= a << 8
|
||||||
a |= a << 16
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// An NRGBA64Color represents a non-alpha-premultiplied 64-bit color, having 16 bits for each of red, green, blue and alpha.
|
// An NRGBA64Color represents a non-alpha-premultiplied 64-bit color,
|
||||||
|
// having 16 bits for each of red, green, blue and alpha.
|
||||||
type NRGBA64Color struct {
|
type NRGBA64Color struct {
|
||||||
R, G, B, A uint16
|
R, G, B, A uint16
|
||||||
}
|
}
|
||||||
@ -85,18 +72,13 @@ func (c NRGBA64Color) RGBA() (r, g, b, a uint32) {
|
|||||||
r = uint32(c.R)
|
r = uint32(c.R)
|
||||||
r *= uint32(c.A)
|
r *= uint32(c.A)
|
||||||
r /= 0xffff
|
r /= 0xffff
|
||||||
r |= r << 16
|
|
||||||
g = uint32(c.G)
|
g = uint32(c.G)
|
||||||
g *= uint32(c.A)
|
g *= uint32(c.A)
|
||||||
g /= 0xffff
|
g /= 0xffff
|
||||||
g |= g << 16
|
|
||||||
b = uint32(c.B)
|
b = uint32(c.B)
|
||||||
b *= uint32(c.A)
|
b *= uint32(c.A)
|
||||||
b /= 0xffff
|
b /= 0xffff
|
||||||
b |= b << 16
|
|
||||||
a = uint32(c.A)
|
a = uint32(c.A)
|
||||||
a |= a << 8
|
|
||||||
a |= a << 16
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,12 +90,11 @@ type AlphaColor struct {
|
|||||||
func (c AlphaColor) RGBA() (r, g, b, a uint32) {
|
func (c AlphaColor) RGBA() (r, g, b, a uint32) {
|
||||||
a = uint32(c.A)
|
a = uint32(c.A)
|
||||||
a |= a << 8
|
a |= a << 8
|
||||||
a |= a << 16
|
|
||||||
return a, a, a, a
|
return a, a, a, a
|
||||||
}
|
}
|
||||||
|
|
||||||
// A ColorModel can convert foreign Colors, with a possible loss of precision, to a Color
|
// A ColorModel can convert foreign Colors, with a possible loss of precision,
|
||||||
// from its own color model.
|
// to a Color from its own color model.
|
||||||
type ColorModel interface {
|
type ColorModel interface {
|
||||||
Convert(c Color) Color
|
Convert(c Color) Color
|
||||||
}
|
}
|
||||||
@ -129,36 +110,32 @@ func (f ColorModelFunc) Convert(c Color) Color {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func toRGBAColor(c Color) Color {
|
func toRGBAColor(c Color) Color {
|
||||||
if _, ok := c.(RGBAColor); ok { // no-op conversion
|
if _, ok := c.(RGBAColor); ok {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
r, g, b, a := c.RGBA()
|
r, g, b, a := c.RGBA()
|
||||||
return RGBAColor{uint8(r >> 24), uint8(g >> 24), uint8(b >> 24), uint8(a >> 24)}
|
return RGBAColor{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toRGBA64Color(c Color) Color {
|
func toRGBA64Color(c Color) Color {
|
||||||
if _, ok := c.(RGBA64Color); ok { // no-op conversion
|
if _, ok := c.(RGBA64Color); ok {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
r, g, b, a := c.RGBA()
|
r, g, b, a := c.RGBA()
|
||||||
return RGBA64Color{uint16(r >> 16), uint16(g >> 16), uint16(b >> 16), uint16(a >> 16)}
|
return RGBA64Color{uint16(r), uint16(g), uint16(b), uint16(a)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toNRGBAColor(c Color) Color {
|
func toNRGBAColor(c Color) Color {
|
||||||
if _, ok := c.(NRGBAColor); ok { // no-op conversion
|
if _, ok := c.(NRGBAColor); ok {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
r, g, b, a := c.RGBA()
|
r, g, b, a := c.RGBA()
|
||||||
a >>= 16
|
|
||||||
if a == 0xffff {
|
if a == 0xffff {
|
||||||
return NRGBAColor{uint8(r >> 24), uint8(g >> 24), uint8(b >> 24), 0xff}
|
return NRGBAColor{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), 0xff}
|
||||||
}
|
}
|
||||||
if a == 0 {
|
if a == 0 {
|
||||||
return NRGBAColor{0, 0, 0, 0}
|
return NRGBAColor{0, 0, 0, 0}
|
||||||
}
|
}
|
||||||
r >>= 16
|
|
||||||
g >>= 16
|
|
||||||
b >>= 16
|
|
||||||
// Since Color.RGBA returns a alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
|
// Since Color.RGBA returns a alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
|
||||||
r = (r * 0xffff) / a
|
r = (r * 0xffff) / a
|
||||||
g = (g * 0xffff) / a
|
g = (g * 0xffff) / a
|
||||||
@ -167,14 +144,10 @@ func toNRGBAColor(c Color) Color {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func toNRGBA64Color(c Color) Color {
|
func toNRGBA64Color(c Color) Color {
|
||||||
if _, ok := c.(NRGBA64Color); ok { // no-op conversion
|
if _, ok := c.(NRGBA64Color); ok {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
r, g, b, a := c.RGBA()
|
r, g, b, a := c.RGBA()
|
||||||
a >>= 16
|
|
||||||
r >>= 16
|
|
||||||
g >>= 16
|
|
||||||
b >>= 16
|
|
||||||
if a == 0xffff {
|
if a == 0xffff {
|
||||||
return NRGBA64Color{uint16(r), uint16(g), uint16(b), 0xffff}
|
return NRGBA64Color{uint16(r), uint16(g), uint16(b), 0xffff}
|
||||||
}
|
}
|
||||||
@ -189,11 +162,11 @@ func toNRGBA64Color(c Color) Color {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func toAlphaColor(c Color) Color {
|
func toAlphaColor(c Color) Color {
|
||||||
if _, ok := c.(AlphaColor); ok { // no-op conversion
|
if _, ok := c.(AlphaColor); ok {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
_, _, _, a := c.RGBA()
|
_, _, _, a := c.RGBA()
|
||||||
return AlphaColor{uint8(a >> 24)}
|
return AlphaColor{uint8(a >> 8)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The ColorModel associated with RGBAColor.
|
// The ColorModel associated with RGBAColor.
|
||||||
|
@ -185,21 +185,18 @@ func (p PalettedColorModel) Convert(c Color) Color {
|
|||||||
if len(p) == 0 {
|
if len(p) == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
// TODO(nigeltao): Revisit the "pick the palette color which minimizes sum-squared-difference"
|
|
||||||
// algorithm when the premultiplied vs unpremultiplied issue is resolved.
|
|
||||||
// Currently, we only compare the R, G and B values, and ignore A.
|
|
||||||
cr, cg, cb, _ := c.RGBA()
|
cr, cg, cb, _ := c.RGBA()
|
||||||
// Shift by 17 bits to avoid potential uint32 overflow in sum-squared-difference.
|
// Shift by 1 bit to avoid potential uint32 overflow in sum-squared-difference.
|
||||||
cr >>= 17
|
cr >>= 1
|
||||||
cg >>= 17
|
cg >>= 1
|
||||||
cb >>= 17
|
cb >>= 1
|
||||||
result := Color(nil)
|
result := Color(nil)
|
||||||
bestSSD := uint32(1<<32 - 1)
|
bestSSD := uint32(1<<32 - 1)
|
||||||
for _, v := range p {
|
for _, v := range p {
|
||||||
vr, vg, vb, _ := v.RGBA()
|
vr, vg, vb, _ := v.RGBA()
|
||||||
vr >>= 17
|
vr >>= 1
|
||||||
vg >>= 17
|
vg >>= 1
|
||||||
vb >>= 17
|
vb >>= 1
|
||||||
dr, dg, db := diff(cr, vr), diff(cg, vg), diff(cb, vb)
|
dr, dg, db := diff(cr, vr), diff(cg, vg), diff(cb, vb)
|
||||||
ssd := (dr * dr) + (dg * dg) + (db * db)
|
ssd := (dr * dr) + (dg * dg) + (db * db)
|
||||||
if ssd < bestSSD {
|
if ssd < bestSSD {
|
||||||
|
@ -76,9 +76,9 @@ func sng(w io.WriteCloser, filename string, png image.Image) {
|
|||||||
io.WriteString(w, "PLTE {\n")
|
io.WriteString(w, "PLTE {\n")
|
||||||
for i := 0; i < len(cpm); i++ {
|
for i := 0; i < len(cpm); i++ {
|
||||||
r, g, b, _ := cpm[i].RGBA()
|
r, g, b, _ := cpm[i].RGBA()
|
||||||
r >>= 24
|
r >>= 8
|
||||||
g >>= 24
|
g >>= 8
|
||||||
b >>= 24
|
b >>= 8
|
||||||
fmt.Fprintf(w, " (%3d,%3d,%3d) # rgb = (0x%02x,0x%02x,0x%02x)\n", r, g, b, r, g, b)
|
fmt.Fprintf(w, " (%3d,%3d,%3d) # rgb = (0x%02x,0x%02x,0x%02x)\n", r, g, b, r, g, b)
|
||||||
}
|
}
|
||||||
io.WriteString(w, "}\n")
|
io.WriteString(w, "}\n")
|
||||||
|
@ -37,7 +37,7 @@ func opaque(m image.Image) bool {
|
|||||||
for y := 0; y < m.Height(); y++ {
|
for y := 0; y < m.Height(); y++ {
|
||||||
for x := 0; x < m.Width(); x++ {
|
for x := 0; x < m.Width(); x++ {
|
||||||
_, _, _, a := m.At(x, y).RGBA()
|
_, _, _, a := m.At(x, y).RGBA()
|
||||||
if a != 0xffffffff {
|
if a != 0xffff {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -101,13 +101,13 @@ func (e *encoder) writePLTE(p image.PalettedColorModel) {
|
|||||||
}
|
}
|
||||||
for i := 0; i < len(p); i++ {
|
for i := 0; i < len(p); i++ {
|
||||||
r, g, b, a := p[i].RGBA()
|
r, g, b, a := p[i].RGBA()
|
||||||
if a != 0xffffffff {
|
if a != 0xffff {
|
||||||
e.err = UnsupportedError("non-opaque palette color")
|
e.err = UnsupportedError("non-opaque palette color")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
e.tmp[3*i+0] = uint8(r >> 24)
|
e.tmp[3*i+0] = uint8(r >> 8)
|
||||||
e.tmp[3*i+1] = uint8(g >> 24)
|
e.tmp[3*i+1] = uint8(g >> 8)
|
||||||
e.tmp[3*i+2] = uint8(b >> 24)
|
e.tmp[3*i+2] = uint8(b >> 8)
|
||||||
}
|
}
|
||||||
e.writeChunk(e.tmp[0:3*len(p)], "PLTE")
|
e.writeChunk(e.tmp[0:3*len(p)], "PLTE")
|
||||||
}
|
}
|
||||||
@ -261,9 +261,9 @@ func writeImage(w io.Writer, m image.Image, ct uint8) os.Error {
|
|||||||
for x := 0; x < m.Width(); x++ {
|
for x := 0; x < m.Width(); x++ {
|
||||||
// We have previously verified that the alpha value is fully opaque.
|
// We have previously verified that the alpha value is fully opaque.
|
||||||
r, g, b, _ := m.At(x, y).RGBA()
|
r, g, b, _ := m.At(x, y).RGBA()
|
||||||
cr[0][3*x+1] = uint8(r >> 24)
|
cr[0][3*x+1] = uint8(r >> 8)
|
||||||
cr[0][3*x+2] = uint8(g >> 24)
|
cr[0][3*x+2] = uint8(g >> 8)
|
||||||
cr[0][3*x+3] = uint8(b >> 24)
|
cr[0][3*x+3] = uint8(b >> 8)
|
||||||
}
|
}
|
||||||
case ctPaletted:
|
case ctPaletted:
|
||||||
for x := 0; x < m.Width(); x++ {
|
for x := 0; x < m.Width(); x++ {
|
||||||
|
Loading…
Reference in New Issue
Block a user