forked from mewbak/framebuffer
-
Notifications
You must be signed in to change notification settings - Fork 2
/
pixelformat.go
106 lines (94 loc) · 2.76 KB
/
pixelformat.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// This file is subject to a 1-clause BSD license.
// Its contents can be found in the enclosed LICENSE file.
package framebuffer
// List of known image/pixel formats.
const (
PF_UNKNOWN = iota
PF_RGBA // 32-bit color
PF_BGRA // 32-bit color
PF_RGB_555 // 16-bit color
PF_RGB_565 // 16-bit color
PF_BGR_555 // 16-bit color
PF_BGR_565 // 16-bit color
PF_INDEXED // 8-bit color (grayscale or paletted).
)
// PixelFormat describes the color layout of a single pixel
// in a given pixel buffer. Specifically, how many and which bits
// are occupied by a given color channel.
//
// For example, a standard RGBA pixel would look like this:
//
// | bit 31 bit 0 |
// | |
// pixel: rrrrrrrrggggggggbbbbbbbbaaaaaaaa
//
// The PixelFormat for this looks as follows:
//
// red bits: 8
// red shift: 24
//
// green bits: 8
// green shift: 16
//
// blue bits: 8
// blue shift: 8
//
// alpha bits: 8
// alpha shift: 0
//
//
// We can extract the channel information as follows:
//
// red_mask := (1 << red_bits) - 1
// green_mask := (1 << green_bits) - 1
// blue_mask := (1 << blue_bits) - 1
// alpha_mask := (1 << alpha_bits) - 1
//
// r := (pixel >> red_shift) & red_mask
// g := (pixel >> green_shift) & green_mask
// b := (pixel >> blue_shift) & blue_mask
// a := (pixel >> alpha_shift) & alpha_mask
//
type PixelFormat struct {
RedBits uint8 // Bit count for the red channel.
RedShift uint8 // Shift offset for the red channel.
GreenBits uint8 // Bit count for the green channel.
GreenShift uint8 // Shift offset for the green channel.
BlueBits uint8 // Bit count for the blue channel.
BlueShift uint8 // Shift offset for the blue channel.
AlphaBits uint8 // Bit count for the alpha channel.
AlphaShift uint8 // Shift offset for the alpha channel.
}
// Stride returns the width, in bytes, for a single pixel.
func (p PixelFormat) Stride() int {
return (int(p.RedBits) + int(p.GreenBits) + int(p.BlueBits) + int(p.AlphaBits) + 7) / 8
}
// Type returns an integer constant from the PF_XXX list, which
// identifies the type of pixelformat.
func (p PixelFormat) Type() int {
switch p.Stride() {
case 4: // 32-bit color
if p.RedShift > p.BlueShift {
return PF_BGRA
}
return PF_RGBA
case 2: // 16-bit color
if p.RedShift < p.BlueShift {
if p.RedBits == 5 && p.GreenBits == 6 && p.BlueBits == 5 {
return PF_BGR_565
}
if p.RedBits == 5 && p.GreenBits == 5 && p.BlueBits == 5 {
return PF_BGR_555
}
}
if p.RedBits == 5 && p.GreenBits == 6 && p.BlueBits == 5 {
return PF_RGB_565
}
if p.RedBits == 5 && p.GreenBits == 5 && p.BlueBits == 5 {
return PF_RGB_555
}
case 1: // 8-bit color
return PF_INDEXED
}
return PF_UNKNOWN
}