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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2009 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 image implements a basic 2-D image library.
6
//
7
// The fundamental interface is called Image. An Image contains colors, which
8
// are described in the image/color package.
9
//
10
// Values of the Image interface are created either by calling functions such
11
// as NewRGBA and NewPaletted, or by calling Decode on an io.Reader containing
12
// image data in a format such as GIF, JPEG or PNG. Decoding any particular
13
// image format requires the prior registration of a decoder function.
14
// Registration is typically automatic as a side effect of initializing that
15
// format's package so that, to decode a PNG image, it suffices to have
16
//      import _ "image/png"
17
// in a program's main package. The _ means to import a package purely for its
18
// initialization side effects.
19
//
20
// See "The Go image package" for more details:
21
// http://blog.golang.org/2011/09/go-image-package.html
22
package image
23
 
24
import (
25
        "image/color"
26
)
27
 
28
// Config holds an image's color model and dimensions.
29
type Config struct {
30
        ColorModel    color.Model
31
        Width, Height int
32
}
33
 
34
// Image is a finite rectangular grid of color.Color values taken from a color
35
// model.
36
type Image interface {
37
        // ColorModel returns the Image's color model.
38
        ColorModel() color.Model
39
        // Bounds returns the domain for which At can return non-zero color.
40
        // The bounds do not necessarily contain the point (0, 0).
41
        Bounds() Rectangle
42
        // At returns the color of the pixel at (x, y).
43
        // At(Bounds().Min.X, Bounds().Min.Y) returns the upper-left pixel of the grid.
44
        // At(Bounds().Max.X-1, Bounds().Max.Y-1) returns the lower-right one.
45
        At(x, y int) color.Color
46
}
47
 
48
// PalettedImage is an image whose colors may come from a limited palette.
49
// If m is a PalettedImage and m.ColorModel() returns a PalettedColorModel p,
50
// then m.At(x, y) should be equivalent to p[m.ColorIndexAt(x, y)]. If m's
51
// color model is not a PalettedColorModel, then ColorIndexAt's behavior is
52
// undefined.
53
type PalettedImage interface {
54
        // ColorIndexAt returns the palette index of the pixel at (x, y).
55
        ColorIndexAt(x, y int) uint8
56
        Image
57
}
58
 
59
// RGBA is an in-memory image whose At method returns color.RGBA values.
60
type RGBA struct {
61
        // Pix holds the image's pixels, in R, G, B, A order. The pixel at
62
        // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4].
63
        Pix []uint8
64
        // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
65
        Stride int
66
        // Rect is the image's bounds.
67
        Rect Rectangle
68
}
69
 
70
func (p *RGBA) ColorModel() color.Model { return color.RGBAModel }
71
 
72
func (p *RGBA) Bounds() Rectangle { return p.Rect }
73
 
74
func (p *RGBA) At(x, y int) color.Color {
75
        if !(Point{x, y}.In(p.Rect)) {
76
                return color.RGBA{}
77
        }
78
        i := p.PixOffset(x, y)
79
        return color.RGBA{p.Pix[i+0], p.Pix[i+1], p.Pix[i+2], p.Pix[i+3]}
80
}
81
 
82
// PixOffset returns the index of the first element of Pix that corresponds to
83
// the pixel at (x, y).
84
func (p *RGBA) PixOffset(x, y int) int {
85
        return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4
86
}
87
 
88
func (p *RGBA) Set(x, y int, c color.Color) {
89
        if !(Point{x, y}.In(p.Rect)) {
90
                return
91
        }
92
        i := p.PixOffset(x, y)
93
        c1 := color.RGBAModel.Convert(c).(color.RGBA)
94
        p.Pix[i+0] = c1.R
95
        p.Pix[i+1] = c1.G
96
        p.Pix[i+2] = c1.B
97
        p.Pix[i+3] = c1.A
98
}
99
 
100
func (p *RGBA) SetRGBA(x, y int, c color.RGBA) {
101
        if !(Point{x, y}.In(p.Rect)) {
102
                return
103
        }
104
        i := p.PixOffset(x, y)
105
        p.Pix[i+0] = c.R
106
        p.Pix[i+1] = c.G
107
        p.Pix[i+2] = c.B
108
        p.Pix[i+3] = c.A
109
}
110
 
111
// SubImage returns an image representing the portion of the image p visible
112
// through r. The returned value shares pixels with the original image.
113
func (p *RGBA) SubImage(r Rectangle) Image {
114
        r = r.Intersect(p.Rect)
115
        // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
116
        // either r1 or r2 if the intersection is empty. Without explicitly checking for
117
        // this, the Pix[i:] expression below can panic.
118
        if r.Empty() {
119
                return &RGBA{}
120
        }
121
        i := p.PixOffset(r.Min.X, r.Min.Y)
122
        return &RGBA{
123
                Pix:    p.Pix[i:],
124
                Stride: p.Stride,
125
                Rect:   r,
126
        }
127
}
128
 
129
// Opaque scans the entire image and returns whether or not it is fully opaque.
130
func (p *RGBA) Opaque() bool {
131
        if p.Rect.Empty() {
132
                return true
133
        }
134
        i0, i1 := 3, p.Rect.Dx()*4
135
        for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
136
                for i := i0; i < i1; i += 4 {
137
                        if p.Pix[i] != 0xff {
138
                                return false
139
                        }
140
                }
141
                i0 += p.Stride
142
                i1 += p.Stride
143
        }
144
        return true
145
}
146
 
147
// NewRGBA returns a new RGBA with the given bounds.
148
func NewRGBA(r Rectangle) *RGBA {
149
        w, h := r.Dx(), r.Dy()
150
        buf := make([]uint8, 4*w*h)
151
        return &RGBA{buf, 4 * w, r}
152
}
153
 
154
// RGBA64 is an in-memory image whose At method returns color.RGBA64 values.
155
type RGBA64 struct {
156
        // Pix holds the image's pixels, in R, G, B, A order and big-endian format. The pixel at
157
        // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*8].
158
        Pix []uint8
159
        // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
160
        Stride int
161
        // Rect is the image's bounds.
162
        Rect Rectangle
163
}
164
 
165
func (p *RGBA64) ColorModel() color.Model { return color.RGBA64Model }
166
 
167
func (p *RGBA64) Bounds() Rectangle { return p.Rect }
168
 
169
func (p *RGBA64) At(x, y int) color.Color {
170
        if !(Point{x, y}.In(p.Rect)) {
171
                return color.RGBA64{}
172
        }
173
        i := p.PixOffset(x, y)
174
        return color.RGBA64{
175
                uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1]),
176
                uint16(p.Pix[i+2])<<8 | uint16(p.Pix[i+3]),
177
                uint16(p.Pix[i+4])<<8 | uint16(p.Pix[i+5]),
178
                uint16(p.Pix[i+6])<<8 | uint16(p.Pix[i+7]),
179
        }
180
}
181
 
182
// PixOffset returns the index of the first element of Pix that corresponds to
183
// the pixel at (x, y).
184
func (p *RGBA64) PixOffset(x, y int) int {
185
        return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*8
186
}
187
 
188
func (p *RGBA64) Set(x, y int, c color.Color) {
189
        if !(Point{x, y}.In(p.Rect)) {
190
                return
191
        }
192
        i := p.PixOffset(x, y)
193
        c1 := color.RGBA64Model.Convert(c).(color.RGBA64)
194
        p.Pix[i+0] = uint8(c1.R >> 8)
195
        p.Pix[i+1] = uint8(c1.R)
196
        p.Pix[i+2] = uint8(c1.G >> 8)
197
        p.Pix[i+3] = uint8(c1.G)
198
        p.Pix[i+4] = uint8(c1.B >> 8)
199
        p.Pix[i+5] = uint8(c1.B)
200
        p.Pix[i+6] = uint8(c1.A >> 8)
201
        p.Pix[i+7] = uint8(c1.A)
202
}
203
 
204
func (p *RGBA64) SetRGBA64(x, y int, c color.RGBA64) {
205
        if !(Point{x, y}.In(p.Rect)) {
206
                return
207
        }
208
        i := p.PixOffset(x, y)
209
        p.Pix[i+0] = uint8(c.R >> 8)
210
        p.Pix[i+1] = uint8(c.R)
211
        p.Pix[i+2] = uint8(c.G >> 8)
212
        p.Pix[i+3] = uint8(c.G)
213
        p.Pix[i+4] = uint8(c.B >> 8)
214
        p.Pix[i+5] = uint8(c.B)
215
        p.Pix[i+6] = uint8(c.A >> 8)
216
        p.Pix[i+7] = uint8(c.A)
217
}
218
 
219
// SubImage returns an image representing the portion of the image p visible
220
// through r. The returned value shares pixels with the original image.
221
func (p *RGBA64) SubImage(r Rectangle) Image {
222
        r = r.Intersect(p.Rect)
223
        // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
224
        // either r1 or r2 if the intersection is empty. Without explicitly checking for
225
        // this, the Pix[i:] expression below can panic.
226
        if r.Empty() {
227
                return &RGBA64{}
228
        }
229
        i := p.PixOffset(r.Min.X, r.Min.Y)
230
        return &RGBA64{
231
                Pix:    p.Pix[i:],
232
                Stride: p.Stride,
233
                Rect:   r,
234
        }
235
}
236
 
237
// Opaque scans the entire image and returns whether or not it is fully opaque.
238
func (p *RGBA64) Opaque() bool {
239
        if p.Rect.Empty() {
240
                return true
241
        }
242
        i0, i1 := 6, p.Rect.Dx()*8
243
        for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
244
                for i := i0; i < i1; i += 8 {
245
                        if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff {
246
                                return false
247
                        }
248
                }
249
                i0 += p.Stride
250
                i1 += p.Stride
251
        }
252
        return true
253
}
254
 
255
// NewRGBA64 returns a new RGBA64 with the given bounds.
256
func NewRGBA64(r Rectangle) *RGBA64 {
257
        w, h := r.Dx(), r.Dy()
258
        pix := make([]uint8, 8*w*h)
259
        return &RGBA64{pix, 8 * w, r}
260
}
261
 
262
// NRGBA is an in-memory image whose At method returns color.NRGBA values.
263
type NRGBA struct {
264
        // Pix holds the image's pixels, in R, G, B, A order. The pixel at
265
        // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4].
266
        Pix []uint8
267
        // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
268
        Stride int
269
        // Rect is the image's bounds.
270
        Rect Rectangle
271
}
272
 
273
func (p *NRGBA) ColorModel() color.Model { return color.NRGBAModel }
274
 
275
func (p *NRGBA) Bounds() Rectangle { return p.Rect }
276
 
277
func (p *NRGBA) At(x, y int) color.Color {
278
        if !(Point{x, y}.In(p.Rect)) {
279
                return color.NRGBA{}
280
        }
281
        i := p.PixOffset(x, y)
282
        return color.NRGBA{p.Pix[i+0], p.Pix[i+1], p.Pix[i+2], p.Pix[i+3]}
283
}
284
 
285
// PixOffset returns the index of the first element of Pix that corresponds to
286
// the pixel at (x, y).
287
func (p *NRGBA) PixOffset(x, y int) int {
288
        return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4
289
}
290
 
291
func (p *NRGBA) Set(x, y int, c color.Color) {
292
        if !(Point{x, y}.In(p.Rect)) {
293
                return
294
        }
295
        i := p.PixOffset(x, y)
296
        c1 := color.NRGBAModel.Convert(c).(color.NRGBA)
297
        p.Pix[i+0] = c1.R
298
        p.Pix[i+1] = c1.G
299
        p.Pix[i+2] = c1.B
300
        p.Pix[i+3] = c1.A
301
}
302
 
303
func (p *NRGBA) SetNRGBA(x, y int, c color.NRGBA) {
304
        if !(Point{x, y}.In(p.Rect)) {
305
                return
306
        }
307
        i := p.PixOffset(x, y)
308
        p.Pix[i+0] = c.R
309
        p.Pix[i+1] = c.G
310
        p.Pix[i+2] = c.B
311
        p.Pix[i+3] = c.A
312
}
313
 
314
// SubImage returns an image representing the portion of the image p visible
315
// through r. The returned value shares pixels with the original image.
316
func (p *NRGBA) SubImage(r Rectangle) Image {
317
        r = r.Intersect(p.Rect)
318
        // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
319
        // either r1 or r2 if the intersection is empty. Without explicitly checking for
320
        // this, the Pix[i:] expression below can panic.
321
        if r.Empty() {
322
                return &NRGBA{}
323
        }
324
        i := p.PixOffset(r.Min.X, r.Min.Y)
325
        return &NRGBA{
326
                Pix:    p.Pix[i:],
327
                Stride: p.Stride,
328
                Rect:   r,
329
        }
330
}
331
 
332
// Opaque scans the entire image and returns whether or not it is fully opaque.
333
func (p *NRGBA) Opaque() bool {
334
        if p.Rect.Empty() {
335
                return true
336
        }
337
        i0, i1 := 3, p.Rect.Dx()*4
338
        for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
339
                for i := i0; i < i1; i += 4 {
340
                        if p.Pix[i] != 0xff {
341
                                return false
342
                        }
343
                }
344
                i0 += p.Stride
345
                i1 += p.Stride
346
        }
347
        return true
348
}
349
 
350
// NewNRGBA returns a new NRGBA with the given bounds.
351
func NewNRGBA(r Rectangle) *NRGBA {
352
        w, h := r.Dx(), r.Dy()
353
        pix := make([]uint8, 4*w*h)
354
        return &NRGBA{pix, 4 * w, r}
355
}
356
 
357
// NRGBA64 is an in-memory image whose At method returns color.NRGBA64 values.
358
type NRGBA64 struct {
359
        // Pix holds the image's pixels, in R, G, B, A order and big-endian format. The pixel at
360
        // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*8].
361
        Pix []uint8
362
        // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
363
        Stride int
364
        // Rect is the image's bounds.
365
        Rect Rectangle
366
}
367
 
368
func (p *NRGBA64) ColorModel() color.Model { return color.NRGBA64Model }
369
 
370
func (p *NRGBA64) Bounds() Rectangle { return p.Rect }
371
 
372
func (p *NRGBA64) At(x, y int) color.Color {
373
        if !(Point{x, y}.In(p.Rect)) {
374
                return color.NRGBA64{}
375
        }
376
        i := p.PixOffset(x, y)
377
        return color.NRGBA64{
378
                uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1]),
379
                uint16(p.Pix[i+2])<<8 | uint16(p.Pix[i+3]),
380
                uint16(p.Pix[i+4])<<8 | uint16(p.Pix[i+5]),
381
                uint16(p.Pix[i+6])<<8 | uint16(p.Pix[i+7]),
382
        }
383
}
384
 
385
// PixOffset returns the index of the first element of Pix that corresponds to
386
// the pixel at (x, y).
387
func (p *NRGBA64) PixOffset(x, y int) int {
388
        return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*8
389
}
390
 
391
func (p *NRGBA64) Set(x, y int, c color.Color) {
392
        if !(Point{x, y}.In(p.Rect)) {
393
                return
394
        }
395
        i := p.PixOffset(x, y)
396
        c1 := color.NRGBA64Model.Convert(c).(color.NRGBA64)
397
        p.Pix[i+0] = uint8(c1.R >> 8)
398
        p.Pix[i+1] = uint8(c1.R)
399
        p.Pix[i+2] = uint8(c1.G >> 8)
400
        p.Pix[i+3] = uint8(c1.G)
401
        p.Pix[i+4] = uint8(c1.B >> 8)
402
        p.Pix[i+5] = uint8(c1.B)
403
        p.Pix[i+6] = uint8(c1.A >> 8)
404
        p.Pix[i+7] = uint8(c1.A)
405
}
406
 
407
func (p *NRGBA64) SetNRGBA64(x, y int, c color.NRGBA64) {
408
        if !(Point{x, y}.In(p.Rect)) {
409
                return
410
        }
411
        i := p.PixOffset(x, y)
412
        p.Pix[i+0] = uint8(c.R >> 8)
413
        p.Pix[i+1] = uint8(c.R)
414
        p.Pix[i+2] = uint8(c.G >> 8)
415
        p.Pix[i+3] = uint8(c.G)
416
        p.Pix[i+4] = uint8(c.B >> 8)
417
        p.Pix[i+5] = uint8(c.B)
418
        p.Pix[i+6] = uint8(c.A >> 8)
419
        p.Pix[i+7] = uint8(c.A)
420
}
421
 
422
// SubImage returns an image representing the portion of the image p visible
423
// through r. The returned value shares pixels with the original image.
424
func (p *NRGBA64) SubImage(r Rectangle) Image {
425
        r = r.Intersect(p.Rect)
426
        // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
427
        // either r1 or r2 if the intersection is empty. Without explicitly checking for
428
        // this, the Pix[i:] expression below can panic.
429
        if r.Empty() {
430
                return &NRGBA64{}
431
        }
432
        i := p.PixOffset(r.Min.X, r.Min.Y)
433
        return &NRGBA64{
434
                Pix:    p.Pix[i:],
435
                Stride: p.Stride,
436
                Rect:   r,
437
        }
438
}
439
 
440
// Opaque scans the entire image and returns whether or not it is fully opaque.
441
func (p *NRGBA64) Opaque() bool {
442
        if p.Rect.Empty() {
443
                return true
444
        }
445
        i0, i1 := 6, p.Rect.Dx()*8
446
        for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
447
                for i := i0; i < i1; i += 8 {
448
                        if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff {
449
                                return false
450
                        }
451
                }
452
                i0 += p.Stride
453
                i1 += p.Stride
454
        }
455
        return true
456
}
457
 
458
// NewNRGBA64 returns a new NRGBA64 with the given bounds.
459
func NewNRGBA64(r Rectangle) *NRGBA64 {
460
        w, h := r.Dx(), r.Dy()
461
        pix := make([]uint8, 8*w*h)
462
        return &NRGBA64{pix, 8 * w, r}
463
}
464
 
465
// Alpha is an in-memory image whose At method returns color.Alpha values.
466
type Alpha struct {
467
        // Pix holds the image's pixels, as alpha values. The pixel at
468
        // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
469
        Pix []uint8
470
        // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
471
        Stride int
472
        // Rect is the image's bounds.
473
        Rect Rectangle
474
}
475
 
476
func (p *Alpha) ColorModel() color.Model { return color.AlphaModel }
477
 
478
func (p *Alpha) Bounds() Rectangle { return p.Rect }
479
 
480
func (p *Alpha) At(x, y int) color.Color {
481
        if !(Point{x, y}.In(p.Rect)) {
482
                return color.Alpha{}
483
        }
484
        i := p.PixOffset(x, y)
485
        return color.Alpha{p.Pix[i]}
486
}
487
 
488
// PixOffset returns the index of the first element of Pix that corresponds to
489
// the pixel at (x, y).
490
func (p *Alpha) PixOffset(x, y int) int {
491
        return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
492
}
493
 
494
func (p *Alpha) Set(x, y int, c color.Color) {
495
        if !(Point{x, y}.In(p.Rect)) {
496
                return
497
        }
498
        i := p.PixOffset(x, y)
499
        p.Pix[i] = color.AlphaModel.Convert(c).(color.Alpha).A
500
}
501
 
502
func (p *Alpha) SetAlpha(x, y int, c color.Alpha) {
503
        if !(Point{x, y}.In(p.Rect)) {
504
                return
505
        }
506
        i := p.PixOffset(x, y)
507
        p.Pix[i] = c.A
508
}
509
 
510
// SubImage returns an image representing the portion of the image p visible
511
// through r. The returned value shares pixels with the original image.
512
func (p *Alpha) SubImage(r Rectangle) Image {
513
        r = r.Intersect(p.Rect)
514
        // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
515
        // either r1 or r2 if the intersection is empty. Without explicitly checking for
516
        // this, the Pix[i:] expression below can panic.
517
        if r.Empty() {
518
                return &Alpha{}
519
        }
520
        i := p.PixOffset(r.Min.X, r.Min.Y)
521
        return &Alpha{
522
                Pix:    p.Pix[i:],
523
                Stride: p.Stride,
524
                Rect:   r,
525
        }
526
}
527
 
528
// Opaque scans the entire image and returns whether or not it is fully opaque.
529
func (p *Alpha) Opaque() bool {
530
        if p.Rect.Empty() {
531
                return true
532
        }
533
        i0, i1 := 0, p.Rect.Dx()
534
        for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
535
                for i := i0; i < i1; i++ {
536
                        if p.Pix[i] != 0xff {
537
                                return false
538
                        }
539
                }
540
                i0 += p.Stride
541
                i1 += p.Stride
542
        }
543
        return true
544
}
545
 
546
// NewAlpha returns a new Alpha with the given bounds.
547
func NewAlpha(r Rectangle) *Alpha {
548
        w, h := r.Dx(), r.Dy()
549
        pix := make([]uint8, 1*w*h)
550
        return &Alpha{pix, 1 * w, r}
551
}
552
 
553
// Alpha16 is an in-memory image whose At method returns color.Alpha64 values.
554
type Alpha16 struct {
555
        // Pix holds the image's pixels, as alpha values in big-endian format. The pixel at
556
        // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*2].
557
        Pix []uint8
558
        // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
559
        Stride int
560
        // Rect is the image's bounds.
561
        Rect Rectangle
562
}
563
 
564
func (p *Alpha16) ColorModel() color.Model { return color.Alpha16Model }
565
 
566
func (p *Alpha16) Bounds() Rectangle { return p.Rect }
567
 
568
func (p *Alpha16) At(x, y int) color.Color {
569
        if !(Point{x, y}.In(p.Rect)) {
570
                return color.Alpha16{}
571
        }
572
        i := p.PixOffset(x, y)
573
        return color.Alpha16{uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1])}
574
}
575
 
576
// PixOffset returns the index of the first element of Pix that corresponds to
577
// the pixel at (x, y).
578
func (p *Alpha16) PixOffset(x, y int) int {
579
        return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*2
580
}
581
 
582
func (p *Alpha16) Set(x, y int, c color.Color) {
583
        if !(Point{x, y}.In(p.Rect)) {
584
                return
585
        }
586
        i := p.PixOffset(x, y)
587
        c1 := color.Alpha16Model.Convert(c).(color.Alpha16)
588
        p.Pix[i+0] = uint8(c1.A >> 8)
589
        p.Pix[i+1] = uint8(c1.A)
590
}
591
 
592
func (p *Alpha16) SetAlpha16(x, y int, c color.Alpha16) {
593
        if !(Point{x, y}.In(p.Rect)) {
594
                return
595
        }
596
        i := p.PixOffset(x, y)
597
        p.Pix[i+0] = uint8(c.A >> 8)
598
        p.Pix[i+1] = uint8(c.A)
599
}
600
 
601
// SubImage returns an image representing the portion of the image p visible
602
// through r. The returned value shares pixels with the original image.
603
func (p *Alpha16) SubImage(r Rectangle) Image {
604
        r = r.Intersect(p.Rect)
605
        // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
606
        // either r1 or r2 if the intersection is empty. Without explicitly checking for
607
        // this, the Pix[i:] expression below can panic.
608
        if r.Empty() {
609
                return &Alpha16{}
610
        }
611
        i := p.PixOffset(r.Min.X, r.Min.Y)
612
        return &Alpha16{
613
                Pix:    p.Pix[i:],
614
                Stride: p.Stride,
615
                Rect:   r,
616
        }
617
}
618
 
619
// Opaque scans the entire image and returns whether or not it is fully opaque.
620
func (p *Alpha16) Opaque() bool {
621
        if p.Rect.Empty() {
622
                return true
623
        }
624
        i0, i1 := 0, p.Rect.Dx()*2
625
        for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
626
                for i := i0; i < i1; i += 2 {
627
                        if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff {
628
                                return false
629
                        }
630
                }
631
                i0 += p.Stride
632
                i1 += p.Stride
633
        }
634
        return true
635
}
636
 
637
// NewAlpha16 returns a new Alpha16 with the given bounds.
638
func NewAlpha16(r Rectangle) *Alpha16 {
639
        w, h := r.Dx(), r.Dy()
640
        pix := make([]uint8, 2*w*h)
641
        return &Alpha16{pix, 2 * w, r}
642
}
643
 
644
// Gray is an in-memory image whose At method returns color.Gray values.
645
type Gray struct {
646
        // Pix holds the image's pixels, as gray values. The pixel at
647
        // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
648
        Pix []uint8
649
        // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
650
        Stride int
651
        // Rect is the image's bounds.
652
        Rect Rectangle
653
}
654
 
655
func (p *Gray) ColorModel() color.Model { return color.GrayModel }
656
 
657
func (p *Gray) Bounds() Rectangle { return p.Rect }
658
 
659
func (p *Gray) At(x, y int) color.Color {
660
        if !(Point{x, y}.In(p.Rect)) {
661
                return color.Gray{}
662
        }
663
        i := p.PixOffset(x, y)
664
        return color.Gray{p.Pix[i]}
665
}
666
 
667
// PixOffset returns the index of the first element of Pix that corresponds to
668
// the pixel at (x, y).
669
func (p *Gray) PixOffset(x, y int) int {
670
        return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
671
}
672
 
673
func (p *Gray) Set(x, y int, c color.Color) {
674
        if !(Point{x, y}.In(p.Rect)) {
675
                return
676
        }
677
        i := p.PixOffset(x, y)
678
        p.Pix[i] = color.GrayModel.Convert(c).(color.Gray).Y
679
}
680
 
681
func (p *Gray) SetGray(x, y int, c color.Gray) {
682
        if !(Point{x, y}.In(p.Rect)) {
683
                return
684
        }
685
        i := p.PixOffset(x, y)
686
        p.Pix[i] = c.Y
687
}
688
 
689
// SubImage returns an image representing the portion of the image p visible
690
// through r. The returned value shares pixels with the original image.
691
func (p *Gray) SubImage(r Rectangle) Image {
692
        r = r.Intersect(p.Rect)
693
        // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
694
        // either r1 or r2 if the intersection is empty. Without explicitly checking for
695
        // this, the Pix[i:] expression below can panic.
696
        if r.Empty() {
697
                return &Gray{}
698
        }
699
        i := p.PixOffset(r.Min.X, r.Min.Y)
700
        return &Gray{
701
                Pix:    p.Pix[i:],
702
                Stride: p.Stride,
703
                Rect:   r,
704
        }
705
}
706
 
707
// Opaque scans the entire image and returns whether or not it is fully opaque.
708
func (p *Gray) Opaque() bool {
709
        return true
710
}
711
 
712
// NewGray returns a new Gray with the given bounds.
713
func NewGray(r Rectangle) *Gray {
714
        w, h := r.Dx(), r.Dy()
715
        pix := make([]uint8, 1*w*h)
716
        return &Gray{pix, 1 * w, r}
717
}
718
 
719
// Gray16 is an in-memory image whose At method returns color.Gray16 values.
720
type Gray16 struct {
721
        // Pix holds the image's pixels, as gray values in big-endian format. The pixel at
722
        // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*2].
723
        Pix []uint8
724
        // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
725
        Stride int
726
        // Rect is the image's bounds.
727
        Rect Rectangle
728
}
729
 
730
func (p *Gray16) ColorModel() color.Model { return color.Gray16Model }
731
 
732
func (p *Gray16) Bounds() Rectangle { return p.Rect }
733
 
734
func (p *Gray16) At(x, y int) color.Color {
735
        if !(Point{x, y}.In(p.Rect)) {
736
                return color.Gray16{}
737
        }
738
        i := p.PixOffset(x, y)
739
        return color.Gray16{uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1])}
740
}
741
 
742
// PixOffset returns the index of the first element of Pix that corresponds to
743
// the pixel at (x, y).
744
func (p *Gray16) PixOffset(x, y int) int {
745
        return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*2
746
}
747
 
748
func (p *Gray16) Set(x, y int, c color.Color) {
749
        if !(Point{x, y}.In(p.Rect)) {
750
                return
751
        }
752
        i := p.PixOffset(x, y)
753
        c1 := color.Gray16Model.Convert(c).(color.Gray16)
754
        p.Pix[i+0] = uint8(c1.Y >> 8)
755
        p.Pix[i+1] = uint8(c1.Y)
756
}
757
 
758
func (p *Gray16) SetGray16(x, y int, c color.Gray16) {
759
        if !(Point{x, y}.In(p.Rect)) {
760
                return
761
        }
762
        i := p.PixOffset(x, y)
763
        p.Pix[i+0] = uint8(c.Y >> 8)
764
        p.Pix[i+1] = uint8(c.Y)
765
}
766
 
767
// SubImage returns an image representing the portion of the image p visible
768
// through r. The returned value shares pixels with the original image.
769
func (p *Gray16) SubImage(r Rectangle) Image {
770
        r = r.Intersect(p.Rect)
771
        // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
772
        // either r1 or r2 if the intersection is empty. Without explicitly checking for
773
        // this, the Pix[i:] expression below can panic.
774
        if r.Empty() {
775
                return &Gray16{}
776
        }
777
        i := p.PixOffset(r.Min.X, r.Min.Y)
778
        return &Gray16{
779
                Pix:    p.Pix[i:],
780
                Stride: p.Stride,
781
                Rect:   r,
782
        }
783
}
784
 
785
// Opaque scans the entire image and returns whether or not it is fully opaque.
786
func (p *Gray16) Opaque() bool {
787
        return true
788
}
789
 
790
// NewGray16 returns a new Gray16 with the given bounds.
791
func NewGray16(r Rectangle) *Gray16 {
792
        w, h := r.Dx(), r.Dy()
793
        pix := make([]uint8, 2*w*h)
794
        return &Gray16{pix, 2 * w, r}
795
}
796
 
797
// Paletted is an in-memory image of uint8 indices into a given palette.
798
type Paletted struct {
799
        // Pix holds the image's pixels, as palette indices. The pixel at
800
        // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
801
        Pix []uint8
802
        // Stride is the Pix stride (in bytes) between vertically adjacent pixels.
803
        Stride int
804
        // Rect is the image's bounds.
805
        Rect Rectangle
806
        // Palette is the image's palette.
807
        Palette color.Palette
808
}
809
 
810
func (p *Paletted) ColorModel() color.Model { return p.Palette }
811
 
812
func (p *Paletted) Bounds() Rectangle { return p.Rect }
813
 
814
func (p *Paletted) At(x, y int) color.Color {
815
        if len(p.Palette) == 0 {
816
                return nil
817
        }
818
        if !(Point{x, y}.In(p.Rect)) {
819
                return p.Palette[0]
820
        }
821
        i := p.PixOffset(x, y)
822
        return p.Palette[p.Pix[i]]
823
}
824
 
825
// PixOffset returns the index of the first element of Pix that corresponds to
826
// the pixel at (x, y).
827
func (p *Paletted) PixOffset(x, y int) int {
828
        return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
829
}
830
 
831
func (p *Paletted) Set(x, y int, c color.Color) {
832
        if !(Point{x, y}.In(p.Rect)) {
833
                return
834
        }
835
        i := p.PixOffset(x, y)
836
        p.Pix[i] = uint8(p.Palette.Index(c))
837
}
838
 
839
func (p *Paletted) ColorIndexAt(x, y int) uint8 {
840
        if !(Point{x, y}.In(p.Rect)) {
841
                return 0
842
        }
843
        i := p.PixOffset(x, y)
844
        return p.Pix[i]
845
}
846
 
847
func (p *Paletted) SetColorIndex(x, y int, index uint8) {
848
        if !(Point{x, y}.In(p.Rect)) {
849
                return
850
        }
851
        i := p.PixOffset(x, y)
852
        p.Pix[i] = index
853
}
854
 
855
// SubImage returns an image representing the portion of the image p visible
856
// through r. The returned value shares pixels with the original image.
857
func (p *Paletted) SubImage(r Rectangle) Image {
858
        r = r.Intersect(p.Rect)
859
        // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
860
        // either r1 or r2 if the intersection is empty. Without explicitly checking for
861
        // this, the Pix[i:] expression below can panic.
862
        if r.Empty() {
863
                return &Paletted{
864
                        Palette: p.Palette,
865
                }
866
        }
867
        i := p.PixOffset(r.Min.X, r.Min.Y)
868
        return &Paletted{
869
                Pix:     p.Pix[i:],
870
                Stride:  p.Stride,
871
                Rect:    p.Rect.Intersect(r),
872
                Palette: p.Palette,
873
        }
874
}
875
 
876
// Opaque scans the entire image and returns whether or not it is fully opaque.
877
func (p *Paletted) Opaque() bool {
878
        var present [256]bool
879
        i0, i1 := 0, p.Rect.Dx()
880
        for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
881
                for _, c := range p.Pix[i0:i1] {
882
                        present[c] = true
883
                }
884
                i0 += p.Stride
885
                i1 += p.Stride
886
        }
887
        for i, c := range p.Palette {
888
                if !present[i] {
889
                        continue
890
                }
891
                _, _, _, a := c.RGBA()
892
                if a != 0xffff {
893
                        return false
894
                }
895
        }
896
        return true
897
}
898
 
899
// NewPaletted returns a new Paletted with the given width, height and palette.
900
func NewPaletted(r Rectangle, p color.Palette) *Paletted {
901
        w, h := r.Dx(), r.Dy()
902
        pix := make([]uint8, 1*w*h)
903
        return &Paletted{pix, 1 * w, r, p}
904
}

powered by: WebSVN 2.1.0

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