Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
2bb59fd7
Commit
2bb59fd7
authored
May 28, 2010
by
Nigel Tao
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make image.Color.RGBA return 16 bit color instead of 32 bit color.
R=rsc CC=golang-dev
https://golang.org/cl/1388041
parent
d5a8647d
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
41 additions
and
108 deletions
+41
-108
color.go
src/pkg/exp/draw/color.go
+1
-5
draw.go
src/pkg/exp/draw/draw.go
+1
-21
draw_test.go
src/pkg/exp/draw/draw_test.go
+0
-9
image.go
src/pkg/exp/nacl/av/image.go
+0
-4
color.go
src/pkg/image/color.go
+21
-48
image.go
src/pkg/image/image.go
+7
-10
reader_test.go
src/pkg/image/png/reader_test.go
+3
-3
writer.go
src/pkg/image/png/writer.go
+8
-8
No files found.
src/pkg/exp/draw/color.go
View file @
2bb59fd7
...
...
@@ -51,13 +51,9 @@ func (c Color) RGBA() (r, g, b, a uint32) {
x
:=
uint32
(
c
)
r
,
g
,
b
,
a
=
x
>>
24
,
(
x
>>
16
)
&
0xFF
,
(
x
>>
8
)
&
0xFF
,
x
&
0xFF
r
|=
r
<<
8
r
|=
r
<<
16
g
|=
g
<<
8
g
|=
g
<<
16
b
|=
b
<<
8
b
|=
b
<<
16
a
|=
a
<<
8
a
|=
a
<<
16
return
}
...
...
@@ -103,7 +99,7 @@ func toColor(color image.Color) image.Color {
return
c
}
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
)
}
src/pkg/exp/draw/draw.go
View file @
2bb59fd7
...
...
@@ -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
mx
:=
mp
.
X
+
x0
-
r
.
Min
.
X
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
ma
:=
uint32
(
M
)
if
mask
!=
nil
{
_
,
_
,
_
,
ma
=
mask
.
At
(
mx
,
my
)
.
RGBA
()
ma
>>=
16
}
switch
{
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
))
default
:
sr
,
sg
,
sb
,
sa
:=
src
.
At
(
sx
,
sy
)
.
RGBA
()
sr
>>=
16
sg
>>=
16
sb
>>=
16
sa
>>=
16
if
out
==
nil
{
out
=
new
(
image
.
RGBA64Color
)
}
if
op
==
Over
{
dr
,
dg
,
db
,
da
:=
dst
.
At
(
x
,
y
)
.
RGBA
()
dr
>>=
16
dg
>>=
16
db
>>=
16
da
>>=
16
a
:=
M
-
(
sa
*
ma
/
M
)
out
.
R
=
uint16
((
dr
*
a
+
sr
*
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
y0
,
y1
:=
r
.
Min
.
Y
,
r
.
Max
.
Y
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
{
p
:=
dst
.
Pixel
[
y
]
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
}
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 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.
...
...
@@ -238,13 +223,8 @@ func drawRGBA(dst *image.RGBA, r Rectangle, src image.Image, sp Point, mask imag
ma
:=
uint32
(
M
)
if
mask
!=
nil
{
_
,
_
,
_
,
ma
=
mask
.
At
(
mx
,
my
)
.
RGBA
()
ma
>>=
16
}
sr
,
sg
,
sb
,
sa
:=
src
.
At
(
sx
,
sy
)
.
RGBA
()
sr
>>=
16
sg
>>=
16
sb
>>=
16
sa
>>=
16
var
dr
,
dg
,
db
,
da
uint32
if
op
==
Over
{
rgba
:=
p
[
x
]
...
...
src/pkg/exp/draw/draw_test.go
View file @
2bb59fd7
...
...
@@ -106,20 +106,11 @@ func makeGolden(dst image.Image, t drawTest) image.Image {
var
dr
,
dg
,
db
,
da
uint32
if
t
.
op
==
Over
{
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
>>=
16
sg
>>=
16
sb
>>=
16
sa
>>=
16
ma
:=
uint32
(
M
)
if
t
.
mask
!=
nil
{
_
,
_
,
_
,
ma
=
t
.
mask
.
At
(
mx
,
my
)
.
RGBA
()
ma
>>=
16
}
a
:=
M
-
(
sa
*
ma
/
M
)
golden
.
Set
(
x
,
y
,
image
.
RGBA64Color
{
...
...
src/pkg/exp/nacl/av/image.go
View file @
2bb59fd7
...
...
@@ -61,16 +61,12 @@ func (p Color) RGBA() (r, g, b, a uint32) {
x
:=
uint32
(
p
)
a
=
x
>>
24
a
|=
a
<<
8
a
|=
a
<<
16
r
=
(
x
>>
16
)
&
0xFF
r
|=
r
<<
8
r
|=
r
<<
16
g
=
(
x
>>
8
)
&
0xFF
g
|=
g
<<
8
g
|=
g
<<
16
b
=
x
&
0xFF
b
|=
b
<<
8
b
|=
b
<<
16
return
}
...
...
src/pkg/image/color.go
View file @
2bb59fd7
...
...
@@ -4,14 +4,15 @@
package
image
//
TODO(nigeltao): Think about how floating-point color models work.
//
All Colors can convert themselves, with a possible loss of precision, to 128-bit alpha-premultiplied RGBA
.
//
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.
// 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
}
...
...
@@ -19,34 +20,23 @@ type RGBAColor struct {
func
(
c
RGBAColor
)
RGBA
()
(
r
,
g
,
b
,
a
uint32
)
{
r
=
uint32
(
c
.
R
)
r
|=
r
<<
8
r
|=
r
<<
16
g
=
uint32
(
c
.
G
)
g
|=
g
<<
8
g
|=
g
<<
16
b
=
uint32
(
c
.
B
)
b
|=
b
<<
8
b
|=
b
<<
16
a
=
uint32
(
c
.
A
)
a
|=
a
<<
8
a
|=
a
<<
16
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
{
R
,
G
,
B
,
A
uint16
}
func
(
c
RGBA64Color
)
RGBA
()
(
r
,
g
,
b
,
a
uint32
)
{
r
=
uint32
(
c
.
R
)
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
return
uint32
(
c
.
R
),
uint32
(
c
.
G
),
uint32
(
c
.
B
),
uint32
(
c
.
A
)
}
// 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
*=
uint32
(
c
.
A
)
r
/=
0xff
r
|=
r
<<
16
g
=
uint32
(
c
.
G
)
g
|=
g
<<
8
g
*=
uint32
(
c
.
A
)
g
/=
0xff
g
|=
g
<<
16
b
=
uint32
(
c
.
B
)
b
|=
b
<<
8
b
*=
uint32
(
c
.
A
)
b
/=
0xff
b
|=
b
<<
16
a
=
uint32
(
c
.
A
)
a
|=
a
<<
8
a
|=
a
<<
16
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
{
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
.
A
)
r
/=
0xffff
r
|=
r
<<
16
g
=
uint32
(
c
.
G
)
g
*=
uint32
(
c
.
A
)
g
/=
0xffff
g
|=
g
<<
16
b
=
uint32
(
c
.
B
)
b
*=
uint32
(
c
.
A
)
b
/=
0xffff
b
|=
b
<<
16
a
=
uint32
(
c
.
A
)
a
|=
a
<<
8
a
|=
a
<<
16
return
}
...
...
@@ -108,12 +90,11 @@ type AlphaColor struct {
func
(
c
AlphaColor
)
RGBA
()
(
r
,
g
,
b
,
a
uint32
)
{
a
=
uint32
(
c
.
A
)
a
|=
a
<<
8
a
|=
a
<<
16
return
a
,
a
,
a
,
a
}
// A ColorModel can convert foreign Colors, with a possible loss of precision,
to a Color
// from its own color model.
// 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
}
...
...
@@ -129,36 +110,32 @@ func (f ColorModelFunc) Convert(c Color) Color {
}
func
toRGBAColor
(
c
Color
)
Color
{
if
_
,
ok
:=
c
.
(
RGBAColor
);
ok
{
// no-op conversion
if
_
,
ok
:=
c
.
(
RGBAColor
);
ok
{
return
c
}
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
{
if
_
,
ok
:=
c
.
(
RGBA64Color
);
ok
{
// no-op conversion
if
_
,
ok
:=
c
.
(
RGBA64Color
);
ok
{
return
c
}
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
{
if
_
,
ok
:=
c
.
(
NRGBAColor
);
ok
{
// no-op conversion
if
_
,
ok
:=
c
.
(
NRGBAColor
);
ok
{
return
c
}
r
,
g
,
b
,
a
:=
c
.
RGBA
()
a
>>=
16
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
{
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.
r
=
(
r
*
0xffff
)
/
a
g
=
(
g
*
0xffff
)
/
a
...
...
@@ -167,14 +144,10 @@ func toNRGBAColor(c Color) Color {
}
func
toNRGBA64Color
(
c
Color
)
Color
{
if
_
,
ok
:=
c
.
(
NRGBA64Color
);
ok
{
// no-op conversion
if
_
,
ok
:=
c
.
(
NRGBA64Color
);
ok
{
return
c
}
r
,
g
,
b
,
a
:=
c
.
RGBA
()
a
>>=
16
r
>>=
16
g
>>=
16
b
>>=
16
if
a
==
0xffff
{
return
NRGBA64Color
{
uint16
(
r
),
uint16
(
g
),
uint16
(
b
),
0xffff
}
}
...
...
@@ -189,11 +162,11 @@ func toNRGBA64Color(c Color) Color {
}
func
toAlphaColor
(
c
Color
)
Color
{
if
_
,
ok
:=
c
.
(
AlphaColor
);
ok
{
// no-op conversion
if
_
,
ok
:=
c
.
(
AlphaColor
);
ok
{
return
c
}
_
,
_
,
_
,
a
:=
c
.
RGBA
()
return
AlphaColor
{
uint8
(
a
>>
24
)}
return
AlphaColor
{
uint8
(
a
>>
8
)}
}
// The ColorModel associated with RGBAColor.
...
...
src/pkg/image/image.go
View file @
2bb59fd7
...
...
@@ -185,21 +185,18 @@ func (p PalettedColorModel) Convert(c Color) Color {
if
len
(
p
)
==
0
{
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
()
// Shift by 1
7 bits
to avoid potential uint32 overflow in sum-squared-difference.
cr
>>=
1
7
cg
>>=
1
7
cb
>>=
1
7
// Shift by 1
bit
to avoid potential uint32 overflow in sum-squared-difference.
cr
>>=
1
cg
>>=
1
cb
>>=
1
result
:=
Color
(
nil
)
bestSSD
:=
uint32
(
1
<<
32
-
1
)
for
_
,
v
:=
range
p
{
vr
,
vg
,
vb
,
_
:=
v
.
RGBA
()
vr
>>=
1
7
vg
>>=
1
7
vb
>>=
1
7
vr
>>=
1
vg
>>=
1
vb
>>=
1
dr
,
dg
,
db
:=
diff
(
cr
,
vr
),
diff
(
cg
,
vg
),
diff
(
cb
,
vb
)
ssd
:=
(
dr
*
dr
)
+
(
dg
*
dg
)
+
(
db
*
db
)
if
ssd
<
bestSSD
{
...
...
src/pkg/image/png/reader_test.go
View file @
2bb59fd7
...
...
@@ -76,9 +76,9 @@ func sng(w io.WriteCloser, filename string, png image.Image) {
io
.
WriteString
(
w
,
"PLTE {
\n
"
)
for
i
:=
0
;
i
<
len
(
cpm
);
i
++
{
r
,
g
,
b
,
_
:=
cpm
[
i
]
.
RGBA
()
r
>>=
24
g
>>=
24
b
>>=
24
r
>>=
8
g
>>=
8
b
>>=
8
fmt
.
Fprintf
(
w
,
" (%3d,%3d,%3d) # rgb = (0x%02x,0x%02x,0x%02x)
\n
"
,
r
,
g
,
b
,
r
,
g
,
b
)
}
io
.
WriteString
(
w
,
"}
\n
"
)
...
...
src/pkg/image/png/writer.go
View file @
2bb59fd7
...
...
@@ -37,7 +37,7 @@ func opaque(m image.Image) bool {
for
y
:=
0
;
y
<
m
.
Height
();
y
++
{
for
x
:=
0
;
x
<
m
.
Width
();
x
++
{
_
,
_
,
_
,
a
:=
m
.
At
(
x
,
y
)
.
RGBA
()
if
a
!=
0xffff
ffff
{
if
a
!=
0xffff
{
return
false
}
}
...
...
@@ -101,13 +101,13 @@ func (e *encoder) writePLTE(p image.PalettedColorModel) {
}
for
i
:=
0
;
i
<
len
(
p
);
i
++
{
r
,
g
,
b
,
a
:=
p
[
i
]
.
RGBA
()
if
a
!=
0xffff
ffff
{
if
a
!=
0xffff
{
e
.
err
=
UnsupportedError
(
"non-opaque palette color"
)
return
}
e
.
tmp
[
3
*
i
+
0
]
=
uint8
(
r
>>
24
)
e
.
tmp
[
3
*
i
+
1
]
=
uint8
(
g
>>
24
)
e
.
tmp
[
3
*
i
+
2
]
=
uint8
(
b
>>
24
)
e
.
tmp
[
3
*
i
+
0
]
=
uint8
(
r
>>
8
)
e
.
tmp
[
3
*
i
+
1
]
=
uint8
(
g
>>
8
)
e
.
tmp
[
3
*
i
+
2
]
=
uint8
(
b
>>
8
)
}
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
++
{
// We have previously verified that the alpha value is fully opaque.
r
,
g
,
b
,
_
:=
m
.
At
(
x
,
y
)
.
RGBA
()
cr
[
0
][
3
*
x
+
1
]
=
uint8
(
r
>>
24
)
cr
[
0
][
3
*
x
+
2
]
=
uint8
(
g
>>
24
)
cr
[
0
][
3
*
x
+
3
]
=
uint8
(
b
>>
24
)
cr
[
0
][
3
*
x
+
1
]
=
uint8
(
r
>>
8
)
cr
[
0
][
3
*
x
+
2
]
=
uint8
(
g
>>
8
)
cr
[
0
][
3
*
x
+
3
]
=
uint8
(
b
>>
8
)
}
case
ctPaletted
:
for
x
:=
0
;
x
<
m
.
Width
();
x
++
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment