OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [image/] [color/] [color.go] - Blame information for rev 747

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2011 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
// Package color implements a basic color library.
6
package color
7
 
8
// Color can convert itself to alpha-premultiplied 16-bits per channel RGBA.
9
// The conversion may be lossy.
10
type Color interface {
11
        // RGBA returns the alpha-premultiplied red, green, blue and alpha values
12
        // for the color. Each value ranges within [0, 0xFFFF], but is represented
13
        // by a uint32 so that multiplying by a blend factor up to 0xFFFF will not
14
        // overflow.
15
        RGBA() (r, g, b, a uint32)
16
}
17
 
18
// RGBA represents a traditional 32-bit alpha-premultiplied color,
19
// having 8 bits for each of red, green, blue and alpha.
20
type RGBA struct {
21
        R, G, B, A uint8
22
}
23
 
24
func (c RGBA) RGBA() (r, g, b, a uint32) {
25
        r = uint32(c.R)
26
        r |= r << 8
27
        g = uint32(c.G)
28
        g |= g << 8
29
        b = uint32(c.B)
30
        b |= b << 8
31
        a = uint32(c.A)
32
        a |= a << 8
33
        return
34
}
35
 
36
// RGBA64 represents a 64-bit alpha-premultiplied color,
37
// having 16 bits for each of red, green, blue and alpha.
38
type RGBA64 struct {
39
        R, G, B, A uint16
40
}
41
 
42
func (c RGBA64) RGBA() (r, g, b, a uint32) {
43
        return uint32(c.R), uint32(c.G), uint32(c.B), uint32(c.A)
44
}
45
 
46
// NRGBA represents a non-alpha-premultiplied 32-bit color.
47
type NRGBA struct {
48
        R, G, B, A uint8
49
}
50
 
51
func (c NRGBA) RGBA() (r, g, b, a uint32) {
52
        r = uint32(c.R)
53
        r |= r << 8
54
        r *= uint32(c.A)
55
        r /= 0xff
56
        g = uint32(c.G)
57
        g |= g << 8
58
        g *= uint32(c.A)
59
        g /= 0xff
60
        b = uint32(c.B)
61
        b |= b << 8
62
        b *= uint32(c.A)
63
        b /= 0xff
64
        a = uint32(c.A)
65
        a |= a << 8
66
        return
67
}
68
 
69
// NRGBA64 represents a non-alpha-premultiplied 64-bit color,
70
// having 16 bits for each of red, green, blue and alpha.
71
type NRGBA64 struct {
72
        R, G, B, A uint16
73
}
74
 
75
func (c NRGBA64) RGBA() (r, g, b, a uint32) {
76
        r = uint32(c.R)
77
        r *= uint32(c.A)
78
        r /= 0xffff
79
        g = uint32(c.G)
80
        g *= uint32(c.A)
81
        g /= 0xffff
82
        b = uint32(c.B)
83
        b *= uint32(c.A)
84
        b /= 0xffff
85
        a = uint32(c.A)
86
        return
87
}
88
 
89
// Alpha represents an 8-bit alpha color.
90
type Alpha struct {
91
        A uint8
92
}
93
 
94
func (c Alpha) RGBA() (r, g, b, a uint32) {
95
        a = uint32(c.A)
96
        a |= a << 8
97
        return a, a, a, a
98
}
99
 
100
// Alpha16 represents a 16-bit alpha color.
101
type Alpha16 struct {
102
        A uint16
103
}
104
 
105
func (c Alpha16) RGBA() (r, g, b, a uint32) {
106
        a = uint32(c.A)
107
        return a, a, a, a
108
}
109
 
110
// Gray represents an 8-bit grayscale color.
111
type Gray struct {
112
        Y uint8
113
}
114
 
115
func (c Gray) RGBA() (r, g, b, a uint32) {
116
        y := uint32(c.Y)
117
        y |= y << 8
118
        return y, y, y, 0xffff
119
}
120
 
121
// Gray16 represents a 16-bit grayscale color.
122
type Gray16 struct {
123
        Y uint16
124
}
125
 
126
func (c Gray16) RGBA() (r, g, b, a uint32) {
127
        y := uint32(c.Y)
128
        return y, y, y, 0xffff
129
}
130
 
131
// Model can convert any Color to one from its own color model. The conversion
132
// may be lossy.
133
type Model interface {
134
        Convert(c Color) Color
135
}
136
 
137
// ModelFunc returns a Model that invokes f to implement the conversion.
138
func ModelFunc(f func(Color) Color) Model {
139
        // Note: using *modelFunc as the implementation
140
        // means that callers can still use comparisons
141
        // like m == RGBAModel.  This is not possible if
142
        // we use the func value directly, because funcs
143
        // are no longer comparable.
144
        return &modelFunc{f}
145
}
146
 
147
type modelFunc struct {
148
        f func(Color) Color
149
}
150
 
151
func (m *modelFunc) Convert(c Color) Color {
152
        return m.f(c)
153
}
154
 
155
// Models for the standard color types.
156
var (
157
        RGBAModel    Model = ModelFunc(rgbaModel)
158
        RGBA64Model  Model = ModelFunc(rgba64Model)
159
        NRGBAModel   Model = ModelFunc(nrgbaModel)
160
        NRGBA64Model Model = ModelFunc(nrgba64Model)
161
        AlphaModel   Model = ModelFunc(alphaModel)
162
        Alpha16Model Model = ModelFunc(alpha16Model)
163
        GrayModel    Model = ModelFunc(grayModel)
164
        Gray16Model  Model = ModelFunc(gray16Model)
165
)
166
 
167
func rgbaModel(c Color) Color {
168
        if _, ok := c.(RGBA); ok {
169
                return c
170
        }
171
        r, g, b, a := c.RGBA()
172
        return RGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)}
173
}
174
 
175
func rgba64Model(c Color) Color {
176
        if _, ok := c.(RGBA64); ok {
177
                return c
178
        }
179
        r, g, b, a := c.RGBA()
180
        return RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
181
}
182
 
183
func nrgbaModel(c Color) Color {
184
        if _, ok := c.(NRGBA); ok {
185
                return c
186
        }
187
        r, g, b, a := c.RGBA()
188
        if a == 0xffff {
189
                return NRGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), 0xff}
190
        }
191
        if a == 0 {
192
                return NRGBA{0, 0, 0, 0}
193
        }
194
        // Since Color.RGBA returns a alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
195
        r = (r * 0xffff) / a
196
        g = (g * 0xffff) / a
197
        b = (b * 0xffff) / a
198
        return NRGBA{uint8(r >> 8), uint8(g >> 8), uint8(b >> 8), uint8(a >> 8)}
199
}
200
 
201
func nrgba64Model(c Color) Color {
202
        if _, ok := c.(NRGBA64); ok {
203
                return c
204
        }
205
        r, g, b, a := c.RGBA()
206
        if a == 0xffff {
207
                return NRGBA64{uint16(r), uint16(g), uint16(b), 0xffff}
208
        }
209
        if a == 0 {
210
                return NRGBA64{0, 0, 0, 0}
211
        }
212
        // Since Color.RGBA returns a alpha-premultiplied color, we should have r <= a && g <= a && b <= a.
213
        r = (r * 0xffff) / a
214
        g = (g * 0xffff) / a
215
        b = (b * 0xffff) / a
216
        return NRGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
217
}
218
 
219
func alphaModel(c Color) Color {
220
        if _, ok := c.(Alpha); ok {
221
                return c
222
        }
223
        _, _, _, a := c.RGBA()
224
        return Alpha{uint8(a >> 8)}
225
}
226
 
227
func alpha16Model(c Color) Color {
228
        if _, ok := c.(Alpha16); ok {
229
                return c
230
        }
231
        _, _, _, a := c.RGBA()
232
        return Alpha16{uint16(a)}
233
}
234
 
235
func grayModel(c Color) Color {
236
        if _, ok := c.(Gray); ok {
237
                return c
238
        }
239
        r, g, b, _ := c.RGBA()
240
        y := (299*r + 587*g + 114*b + 500) / 1000
241
        return Gray{uint8(y >> 8)}
242
}
243
 
244
func gray16Model(c Color) Color {
245
        if _, ok := c.(Gray16); ok {
246
                return c
247
        }
248
        r, g, b, _ := c.RGBA()
249
        y := (299*r + 587*g + 114*b + 500) / 1000
250
        return Gray16{uint16(y)}
251
}
252
 
253
// Palette is a palette of colors.
254
type Palette []Color
255
 
256
func diff(a, b uint32) uint32 {
257
        if a > b {
258
                return a - b
259
        }
260
        return b - a
261
}
262
 
263
// Convert returns the palette color closest to c in Euclidean R,G,B space.
264
func (p Palette) Convert(c Color) Color {
265
        if len(p) == 0 {
266
                return nil
267
        }
268
        return p[p.Index(c)]
269
}
270
 
271
// Index returns the index of the palette color closest to c in Euclidean
272
// R,G,B space.
273
func (p Palette) Index(c Color) int {
274
        cr, cg, cb, _ := c.RGBA()
275
        // Shift by 1 bit to avoid potential uint32 overflow in sum-squared-difference.
276
        cr >>= 1
277
        cg >>= 1
278
        cb >>= 1
279
        ret, bestSSD := 0, uint32(1<<32-1)
280
        for i, v := range p {
281
                vr, vg, vb, _ := v.RGBA()
282
                vr >>= 1
283
                vg >>= 1
284
                vb >>= 1
285
                dr, dg, db := diff(cr, vr), diff(cg, vg), diff(cb, vb)
286
                ssd := (dr * dr) + (dg * dg) + (db * db)
287
                if ssd < bestSSD {
288
                        if ssd == 0 {
289
                                return i
290
                        }
291
                        ret, bestSSD = i, ssd
292
                }
293
        }
294
        return ret
295
}
296
 
297
// Standard colors.
298
var (
299
        Black       = Gray16{0}
300
        White       = Gray16{0xffff}
301
        Transparent = Alpha16{0}
302
        Opaque      = Alpha16{0xffff}
303
)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.