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
e5902fc7
Commit
e5902fc7
authored
Dec 12, 2013
by
ChaiShushan
Committed by
Rob Pike
Dec 12, 2013
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
image: add RGB and RGB48
R=golang-dev, r, nigeltao CC=golang-dev
https://golang.org/cl/13239051
parent
0d624e18
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
218 additions
and
0 deletions
+218
-0
color.go
src/pkg/image/color/color.go
+45
-0
image.go
src/pkg/image/image.go
+170
-0
image_test.go
src/pkg/image/image_test.go
+3
-0
No files found.
src/pkg/image/color/color.go
View file @
e5902fc7
...
...
@@ -15,6 +15,33 @@ type Color interface {
RGBA
()
(
r
,
g
,
b
,
a
uint32
)
}
// RGB represents a traditional 24-bit fully opaque color,
// having 8 bits for each of red, green and blue.
type
RGB
struct
{
R
,
G
,
B
uint8
}
func
(
c
RGB
)
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
=
0xFFFF
return
}
// RGB48 represents a 48-bit fully opaque color,
// having 16 bits for each of red, green and blue.
type
RGB48
struct
{
R
,
G
,
B
uint16
}
func
(
c
RGB48
)
RGBA
()
(
r
,
g
,
b
,
a
uint32
)
{
return
uint32
(
c
.
R
),
uint32
(
c
.
G
),
uint32
(
c
.
B
),
0xFFFF
}
// RGBA represents a traditional 32-bit alpha-premultiplied color,
// having 8 bits for each of red, green, blue and alpha.
type
RGBA
struct
{
...
...
@@ -154,6 +181,8 @@ func (m *modelFunc) Convert(c Color) Color {
// Models for the standard color types.
var
(
RGBModel
Model
=
ModelFunc
(
rgbModel
)
RGB48Model
Model
=
ModelFunc
(
rgb48Model
)
RGBAModel
Model
=
ModelFunc
(
rgbaModel
)
RGBA64Model
Model
=
ModelFunc
(
rgba64Model
)
NRGBAModel
Model
=
ModelFunc
(
nrgbaModel
)
...
...
@@ -164,6 +193,22 @@ var (
Gray16Model
Model
=
ModelFunc
(
gray16Model
)
)
func
rgbModel
(
c
Color
)
Color
{
if
_
,
ok
:=
c
.
(
RGB
);
ok
{
return
c
}
r
,
g
,
b
,
_
:=
c
.
RGBA
()
return
RGB
{
uint8
(
r
>>
8
),
uint8
(
g
>>
8
),
uint8
(
b
>>
8
)}
}
func
rgb48Model
(
c
Color
)
Color
{
if
_
,
ok
:=
c
.
(
RGB48
);
ok
{
return
c
}
r
,
g
,
b
,
_
:=
c
.
RGBA
()
return
RGB48
{
uint16
(
r
),
uint16
(
g
),
uint16
(
b
)}
}
func
rgbaModel
(
c
Color
)
Color
{
if
_
,
ok
:=
c
.
(
RGBA
);
ok
{
return
c
...
...
src/pkg/image/image.go
View file @
e5902fc7
...
...
@@ -56,6 +56,176 @@ type PalettedImage interface {
Image
}
// RGB is an in-memory image whose At method returns color.RGB values.
type
RGB
struct
{
// Pix holds the image's pixels, in R, G, B order. The pixel at
// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*3].
Pix
[]
uint8
// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
Stride
int
// Rect is the image's bounds.
Rect
Rectangle
}
func
(
p
*
RGB
)
ColorModel
()
color
.
Model
{
return
color
.
RGBModel
}
func
(
p
*
RGB
)
Bounds
()
Rectangle
{
return
p
.
Rect
}
func
(
p
*
RGB
)
At
(
x
,
y
int
)
color
.
Color
{
if
!
(
Point
{
x
,
y
}
.
In
(
p
.
Rect
))
{
return
color
.
RGB
{}
}
i
:=
p
.
PixOffset
(
x
,
y
)
return
color
.
RGB
{
p
.
Pix
[
i
+
0
],
p
.
Pix
[
i
+
1
],
p
.
Pix
[
i
+
2
]}
}
// PixOffset returns the index of the first element of Pix that corresponds to
// the pixel at (x, y).
func
(
p
*
RGB
)
PixOffset
(
x
,
y
int
)
int
{
return
(
y
-
p
.
Rect
.
Min
.
Y
)
*
p
.
Stride
+
(
x
-
p
.
Rect
.
Min
.
X
)
*
3
}
func
(
p
*
RGB
)
Set
(
x
,
y
int
,
c
color
.
Color
)
{
if
!
(
Point
{
x
,
y
}
.
In
(
p
.
Rect
))
{
return
}
i
:=
p
.
PixOffset
(
x
,
y
)
c1
:=
color
.
RGBModel
.
Convert
(
c
)
.
(
color
.
RGB
)
p
.
Pix
[
i
+
0
]
=
c1
.
R
p
.
Pix
[
i
+
1
]
=
c1
.
G
p
.
Pix
[
i
+
2
]
=
c1
.
B
}
func
(
p
*
RGB
)
SetRGB
(
x
,
y
int
,
c
color
.
RGB
)
{
if
!
(
Point
{
x
,
y
}
.
In
(
p
.
Rect
))
{
return
}
i
:=
p
.
PixOffset
(
x
,
y
)
p
.
Pix
[
i
+
0
]
=
c
.
R
p
.
Pix
[
i
+
1
]
=
c
.
G
p
.
Pix
[
i
+
2
]
=
c
.
B
}
// SubImage returns an image representing the portion of the image p visible
// through r. The returned value shares pixels with the original image.
func
(
p
*
RGB
)
SubImage
(
r
Rectangle
)
Image
{
r
=
r
.
Intersect
(
p
.
Rect
)
// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
// either r1 or r2 if the intersection is empty. Without explicitly checking for
// this, the Pix[i:] expression below can panic.
if
r
.
Empty
()
{
return
&
RGB
{}
}
i
:=
p
.
PixOffset
(
r
.
Min
.
X
,
r
.
Min
.
Y
)
return
&
RGB
{
Pix
:
p
.
Pix
[
i
:
],
Stride
:
p
.
Stride
,
Rect
:
r
,
}
}
// Opaque scans the entire image and reports whether it is fully opaque.
func
(
p
*
RGB
)
Opaque
()
bool
{
return
true
}
// NewRGB returns a new RGB with the given bounds.
func
NewRGB
(
r
Rectangle
)
*
RGB
{
w
,
h
:=
r
.
Dx
(),
r
.
Dy
()
buf
:=
make
([]
uint8
,
3
*
w
*
h
)
return
&
RGB
{
buf
,
3
*
w
,
r
}
}
// RGB48 is an in-memory image whose At method returns color.RGB48 values.
type
RGB48
struct
{
// Pix holds the image's pixels, in R, G, B order and big-endian format. The pixel at
// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*6].
Pix
[]
uint8
// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
Stride
int
// Rect is the image's bounds.
Rect
Rectangle
}
func
(
p
*
RGB48
)
ColorModel
()
color
.
Model
{
return
color
.
RGB48Model
}
func
(
p
*
RGB48
)
Bounds
()
Rectangle
{
return
p
.
Rect
}
func
(
p
*
RGB48
)
At
(
x
,
y
int
)
color
.
Color
{
if
!
(
Point
{
x
,
y
}
.
In
(
p
.
Rect
))
{
return
color
.
RGB48
{}
}
i
:=
p
.
PixOffset
(
x
,
y
)
return
color
.
RGB48
{
uint16
(
p
.
Pix
[
i
+
0
])
<<
8
|
uint16
(
p
.
Pix
[
i
+
1
]),
uint16
(
p
.
Pix
[
i
+
2
])
<<
8
|
uint16
(
p
.
Pix
[
i
+
3
]),
uint16
(
p
.
Pix
[
i
+
4
])
<<
8
|
uint16
(
p
.
Pix
[
i
+
5
]),
}
}
// PixOffset returns the index of the first element of Pix that corresponds to
// the pixel at (x, y).
func
(
p
*
RGB48
)
PixOffset
(
x
,
y
int
)
int
{
return
(
y
-
p
.
Rect
.
Min
.
Y
)
*
p
.
Stride
+
(
x
-
p
.
Rect
.
Min
.
X
)
*
6
}
func
(
p
*
RGB48
)
Set
(
x
,
y
int
,
c
color
.
Color
)
{
if
!
(
Point
{
x
,
y
}
.
In
(
p
.
Rect
))
{
return
}
i
:=
p
.
PixOffset
(
x
,
y
)
c1
:=
color
.
RGB48Model
.
Convert
(
c
)
.
(
color
.
RGB48
)
p
.
Pix
[
i
+
0
]
=
uint8
(
c1
.
R
>>
8
)
p
.
Pix
[
i
+
1
]
=
uint8
(
c1
.
R
)
p
.
Pix
[
i
+
2
]
=
uint8
(
c1
.
G
>>
8
)
p
.
Pix
[
i
+
3
]
=
uint8
(
c1
.
G
)
p
.
Pix
[
i
+
4
]
=
uint8
(
c1
.
B
>>
8
)
p
.
Pix
[
i
+
5
]
=
uint8
(
c1
.
B
)
}
func
(
p
*
RGB48
)
SetRGB48
(
x
,
y
int
,
c
color
.
RGB48
)
{
if
!
(
Point
{
x
,
y
}
.
In
(
p
.
Rect
))
{
return
}
i
:=
p
.
PixOffset
(
x
,
y
)
p
.
Pix
[
i
+
0
]
=
uint8
(
c
.
R
>>
8
)
p
.
Pix
[
i
+
1
]
=
uint8
(
c
.
R
)
p
.
Pix
[
i
+
2
]
=
uint8
(
c
.
G
>>
8
)
p
.
Pix
[
i
+
3
]
=
uint8
(
c
.
G
)
p
.
Pix
[
i
+
4
]
=
uint8
(
c
.
B
>>
8
)
p
.
Pix
[
i
+
5
]
=
uint8
(
c
.
B
)
}
// SubImage returns an image representing the portion of the image p visible
// through r. The returned value shares pixels with the original image.
func
(
p
*
RGB48
)
SubImage
(
r
Rectangle
)
Image
{
r
=
r
.
Intersect
(
p
.
Rect
)
// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
// either r1 or r2 if the intersection is empty. Without explicitly checking for
// this, the Pix[i:] expression below can panic.
if
r
.
Empty
()
{
return
&
RGB48
{}
}
i
:=
p
.
PixOffset
(
r
.
Min
.
X
,
r
.
Min
.
Y
)
return
&
RGB48
{
Pix
:
p
.
Pix
[
i
:
],
Stride
:
p
.
Stride
,
Rect
:
r
,
}
}
// Opaque scans the entire image and reports whether it is fully opaque.
func
(
p
*
RGB48
)
Opaque
()
bool
{
return
true
}
// NewRGB48 returns a new RGB48 with the given bounds.
func
NewRGB48
(
r
Rectangle
)
*
RGB48
{
w
,
h
:=
r
.
Dx
(),
r
.
Dy
()
pix
:=
make
([]
uint8
,
6
*
w
*
h
)
return
&
RGB48
{
pix
,
6
*
w
,
r
}
}
// RGBA is an in-memory image whose At method returns color.RGBA values.
type
RGBA
struct
{
// Pix holds the image's pixels, in R, G, B, A order. The pixel at
...
...
src/pkg/image/image_test.go
View file @
e5902fc7
...
...
@@ -24,6 +24,8 @@ func cmp(t *testing.T, cm color.Model, c0, c1 color.Color) bool {
func
TestImage
(
t
*
testing
.
T
)
{
testImage
:=
[]
image
{
NewRGB
(
Rect
(
0
,
0
,
10
,
10
)),
NewRGB48
(
Rect
(
0
,
0
,
10
,
10
)),
NewRGBA
(
Rect
(
0
,
0
,
10
,
10
)),
NewRGBA64
(
Rect
(
0
,
0
,
10
,
10
)),
NewNRGBA
(
Rect
(
0
,
0
,
10
,
10
)),
...
...
@@ -97,6 +99,7 @@ func Test16BitsPerColorChannel(t *testing.T) {
}
}
testImage
:=
[]
image
{
NewRGB48
(
Rect
(
0
,
0
,
10
,
10
)),
NewRGBA64
(
Rect
(
0
,
0
,
10
,
10
)),
NewNRGBA64
(
Rect
(
0
,
0
,
10
,
10
)),
NewAlpha16
(
Rect
(
0
,
0
,
10
,
10
)),
...
...
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