1// 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// https://golang.org/doc/articles/image_package.html
22package image
23
24import (
25	"image/color"
26)
27
28// Config holds an image's color model and dimensions.
29type 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.
36type 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 color.Palette 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 color.Palette, then ColorIndexAt's behavior is
52// undefined.
53type 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.
60type 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
70func (p *RGBA) ColorModel() color.Model { return color.RGBAModel }
71
72func (p *RGBA) Bounds() Rectangle { return p.Rect }
73
74func (p *RGBA) At(x, y int) color.Color {
75	return p.RGBAAt(x, y)
76}
77
78func (p *RGBA) RGBAAt(x, y int) color.RGBA {
79	if !(Point{x, y}.In(p.Rect)) {
80		return color.RGBA{}
81	}
82	i := p.PixOffset(x, y)
83	return color.RGBA{p.Pix[i+0], p.Pix[i+1], p.Pix[i+2], p.Pix[i+3]}
84}
85
86// PixOffset returns the index of the first element of Pix that corresponds to
87// the pixel at (x, y).
88func (p *RGBA) PixOffset(x, y int) int {
89	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4
90}
91
92func (p *RGBA) Set(x, y int, c color.Color) {
93	if !(Point{x, y}.In(p.Rect)) {
94		return
95	}
96	i := p.PixOffset(x, y)
97	c1 := color.RGBAModel.Convert(c).(color.RGBA)
98	p.Pix[i+0] = c1.R
99	p.Pix[i+1] = c1.G
100	p.Pix[i+2] = c1.B
101	p.Pix[i+3] = c1.A
102}
103
104func (p *RGBA) SetRGBA(x, y int, c color.RGBA) {
105	if !(Point{x, y}.In(p.Rect)) {
106		return
107	}
108	i := p.PixOffset(x, y)
109	p.Pix[i+0] = c.R
110	p.Pix[i+1] = c.G
111	p.Pix[i+2] = c.B
112	p.Pix[i+3] = c.A
113}
114
115// SubImage returns an image representing the portion of the image p visible
116// through r. The returned value shares pixels with the original image.
117func (p *RGBA) SubImage(r Rectangle) Image {
118	r = r.Intersect(p.Rect)
119	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
120	// either r1 or r2 if the intersection is empty. Without explicitly checking for
121	// this, the Pix[i:] expression below can panic.
122	if r.Empty() {
123		return &RGBA{}
124	}
125	i := p.PixOffset(r.Min.X, r.Min.Y)
126	return &RGBA{
127		Pix:    p.Pix[i:],
128		Stride: p.Stride,
129		Rect:   r,
130	}
131}
132
133// Opaque scans the entire image and reports whether it is fully opaque.
134func (p *RGBA) Opaque() bool {
135	if p.Rect.Empty() {
136		return true
137	}
138	i0, i1 := 3, p.Rect.Dx()*4
139	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
140		for i := i0; i < i1; i += 4 {
141			if p.Pix[i] != 0xff {
142				return false
143			}
144		}
145		i0 += p.Stride
146		i1 += p.Stride
147	}
148	return true
149}
150
151// NewRGBA returns a new RGBA image with the given bounds.
152func NewRGBA(r Rectangle) *RGBA {
153	w, h := r.Dx(), r.Dy()
154	buf := make([]uint8, 4*w*h)
155	return &RGBA{buf, 4 * w, r}
156}
157
158// RGBA64 is an in-memory image whose At method returns color.RGBA64 values.
159type RGBA64 struct {
160	// Pix holds the image's pixels, in R, G, B, A order and big-endian format. The pixel at
161	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*8].
162	Pix []uint8
163	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
164	Stride int
165	// Rect is the image's bounds.
166	Rect Rectangle
167}
168
169func (p *RGBA64) ColorModel() color.Model { return color.RGBA64Model }
170
171func (p *RGBA64) Bounds() Rectangle { return p.Rect }
172
173func (p *RGBA64) At(x, y int) color.Color {
174	return p.RGBA64At(x, y)
175}
176
177func (p *RGBA64) RGBA64At(x, y int) color.RGBA64 {
178	if !(Point{x, y}.In(p.Rect)) {
179		return color.RGBA64{}
180	}
181	i := p.PixOffset(x, y)
182	return color.RGBA64{
183		uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1]),
184		uint16(p.Pix[i+2])<<8 | uint16(p.Pix[i+3]),
185		uint16(p.Pix[i+4])<<8 | uint16(p.Pix[i+5]),
186		uint16(p.Pix[i+6])<<8 | uint16(p.Pix[i+7]),
187	}
188}
189
190// PixOffset returns the index of the first element of Pix that corresponds to
191// the pixel at (x, y).
192func (p *RGBA64) PixOffset(x, y int) int {
193	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*8
194}
195
196func (p *RGBA64) Set(x, y int, c color.Color) {
197	if !(Point{x, y}.In(p.Rect)) {
198		return
199	}
200	i := p.PixOffset(x, y)
201	c1 := color.RGBA64Model.Convert(c).(color.RGBA64)
202	p.Pix[i+0] = uint8(c1.R >> 8)
203	p.Pix[i+1] = uint8(c1.R)
204	p.Pix[i+2] = uint8(c1.G >> 8)
205	p.Pix[i+3] = uint8(c1.G)
206	p.Pix[i+4] = uint8(c1.B >> 8)
207	p.Pix[i+5] = uint8(c1.B)
208	p.Pix[i+6] = uint8(c1.A >> 8)
209	p.Pix[i+7] = uint8(c1.A)
210}
211
212func (p *RGBA64) SetRGBA64(x, y int, c color.RGBA64) {
213	if !(Point{x, y}.In(p.Rect)) {
214		return
215	}
216	i := p.PixOffset(x, y)
217	p.Pix[i+0] = uint8(c.R >> 8)
218	p.Pix[i+1] = uint8(c.R)
219	p.Pix[i+2] = uint8(c.G >> 8)
220	p.Pix[i+3] = uint8(c.G)
221	p.Pix[i+4] = uint8(c.B >> 8)
222	p.Pix[i+5] = uint8(c.B)
223	p.Pix[i+6] = uint8(c.A >> 8)
224	p.Pix[i+7] = uint8(c.A)
225}
226
227// SubImage returns an image representing the portion of the image p visible
228// through r. The returned value shares pixels with the original image.
229func (p *RGBA64) SubImage(r Rectangle) Image {
230	r = r.Intersect(p.Rect)
231	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
232	// either r1 or r2 if the intersection is empty. Without explicitly checking for
233	// this, the Pix[i:] expression below can panic.
234	if r.Empty() {
235		return &RGBA64{}
236	}
237	i := p.PixOffset(r.Min.X, r.Min.Y)
238	return &RGBA64{
239		Pix:    p.Pix[i:],
240		Stride: p.Stride,
241		Rect:   r,
242	}
243}
244
245// Opaque scans the entire image and reports whether it is fully opaque.
246func (p *RGBA64) Opaque() bool {
247	if p.Rect.Empty() {
248		return true
249	}
250	i0, i1 := 6, p.Rect.Dx()*8
251	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
252		for i := i0; i < i1; i += 8 {
253			if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff {
254				return false
255			}
256		}
257		i0 += p.Stride
258		i1 += p.Stride
259	}
260	return true
261}
262
263// NewRGBA64 returns a new RGBA64 image with the given bounds.
264func NewRGBA64(r Rectangle) *RGBA64 {
265	w, h := r.Dx(), r.Dy()
266	pix := make([]uint8, 8*w*h)
267	return &RGBA64{pix, 8 * w, r}
268}
269
270// NRGBA is an in-memory image whose At method returns color.NRGBA values.
271type NRGBA struct {
272	// Pix holds the image's pixels, in R, G, B, A order. The pixel at
273	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4].
274	Pix []uint8
275	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
276	Stride int
277	// Rect is the image's bounds.
278	Rect Rectangle
279}
280
281func (p *NRGBA) ColorModel() color.Model { return color.NRGBAModel }
282
283func (p *NRGBA) Bounds() Rectangle { return p.Rect }
284
285func (p *NRGBA) At(x, y int) color.Color {
286	return p.NRGBAAt(x, y)
287}
288
289func (p *NRGBA) NRGBAAt(x, y int) color.NRGBA {
290	if !(Point{x, y}.In(p.Rect)) {
291		return color.NRGBA{}
292	}
293	i := p.PixOffset(x, y)
294	return color.NRGBA{p.Pix[i+0], p.Pix[i+1], p.Pix[i+2], p.Pix[i+3]}
295}
296
297// PixOffset returns the index of the first element of Pix that corresponds to
298// the pixel at (x, y).
299func (p *NRGBA) PixOffset(x, y int) int {
300	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4
301}
302
303func (p *NRGBA) Set(x, y int, c color.Color) {
304	if !(Point{x, y}.In(p.Rect)) {
305		return
306	}
307	i := p.PixOffset(x, y)
308	c1 := color.NRGBAModel.Convert(c).(color.NRGBA)
309	p.Pix[i+0] = c1.R
310	p.Pix[i+1] = c1.G
311	p.Pix[i+2] = c1.B
312	p.Pix[i+3] = c1.A
313}
314
315func (p *NRGBA) SetNRGBA(x, y int, c color.NRGBA) {
316	if !(Point{x, y}.In(p.Rect)) {
317		return
318	}
319	i := p.PixOffset(x, y)
320	p.Pix[i+0] = c.R
321	p.Pix[i+1] = c.G
322	p.Pix[i+2] = c.B
323	p.Pix[i+3] = c.A
324}
325
326// SubImage returns an image representing the portion of the image p visible
327// through r. The returned value shares pixels with the original image.
328func (p *NRGBA) SubImage(r Rectangle) Image {
329	r = r.Intersect(p.Rect)
330	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
331	// either r1 or r2 if the intersection is empty. Without explicitly checking for
332	// this, the Pix[i:] expression below can panic.
333	if r.Empty() {
334		return &NRGBA{}
335	}
336	i := p.PixOffset(r.Min.X, r.Min.Y)
337	return &NRGBA{
338		Pix:    p.Pix[i:],
339		Stride: p.Stride,
340		Rect:   r,
341	}
342}
343
344// Opaque scans the entire image and reports whether it is fully opaque.
345func (p *NRGBA) Opaque() bool {
346	if p.Rect.Empty() {
347		return true
348	}
349	i0, i1 := 3, p.Rect.Dx()*4
350	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
351		for i := i0; i < i1; i += 4 {
352			if p.Pix[i] != 0xff {
353				return false
354			}
355		}
356		i0 += p.Stride
357		i1 += p.Stride
358	}
359	return true
360}
361
362// NewNRGBA returns a new NRGBA image with the given bounds.
363func NewNRGBA(r Rectangle) *NRGBA {
364	w, h := r.Dx(), r.Dy()
365	pix := make([]uint8, 4*w*h)
366	return &NRGBA{pix, 4 * w, r}
367}
368
369// NRGBA64 is an in-memory image whose At method returns color.NRGBA64 values.
370type NRGBA64 struct {
371	// Pix holds the image's pixels, in R, G, B, A order and big-endian format. The pixel at
372	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*8].
373	Pix []uint8
374	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
375	Stride int
376	// Rect is the image's bounds.
377	Rect Rectangle
378}
379
380func (p *NRGBA64) ColorModel() color.Model { return color.NRGBA64Model }
381
382func (p *NRGBA64) Bounds() Rectangle { return p.Rect }
383
384func (p *NRGBA64) At(x, y int) color.Color {
385	return p.NRGBA64At(x, y)
386}
387
388func (p *NRGBA64) NRGBA64At(x, y int) color.NRGBA64 {
389	if !(Point{x, y}.In(p.Rect)) {
390		return color.NRGBA64{}
391	}
392	i := p.PixOffset(x, y)
393	return color.NRGBA64{
394		uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1]),
395		uint16(p.Pix[i+2])<<8 | uint16(p.Pix[i+3]),
396		uint16(p.Pix[i+4])<<8 | uint16(p.Pix[i+5]),
397		uint16(p.Pix[i+6])<<8 | uint16(p.Pix[i+7]),
398	}
399}
400
401// PixOffset returns the index of the first element of Pix that corresponds to
402// the pixel at (x, y).
403func (p *NRGBA64) PixOffset(x, y int) int {
404	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*8
405}
406
407func (p *NRGBA64) Set(x, y int, c color.Color) {
408	if !(Point{x, y}.In(p.Rect)) {
409		return
410	}
411	i := p.PixOffset(x, y)
412	c1 := color.NRGBA64Model.Convert(c).(color.NRGBA64)
413	p.Pix[i+0] = uint8(c1.R >> 8)
414	p.Pix[i+1] = uint8(c1.R)
415	p.Pix[i+2] = uint8(c1.G >> 8)
416	p.Pix[i+3] = uint8(c1.G)
417	p.Pix[i+4] = uint8(c1.B >> 8)
418	p.Pix[i+5] = uint8(c1.B)
419	p.Pix[i+6] = uint8(c1.A >> 8)
420	p.Pix[i+7] = uint8(c1.A)
421}
422
423func (p *NRGBA64) SetNRGBA64(x, y int, c color.NRGBA64) {
424	if !(Point{x, y}.In(p.Rect)) {
425		return
426	}
427	i := p.PixOffset(x, y)
428	p.Pix[i+0] = uint8(c.R >> 8)
429	p.Pix[i+1] = uint8(c.R)
430	p.Pix[i+2] = uint8(c.G >> 8)
431	p.Pix[i+3] = uint8(c.G)
432	p.Pix[i+4] = uint8(c.B >> 8)
433	p.Pix[i+5] = uint8(c.B)
434	p.Pix[i+6] = uint8(c.A >> 8)
435	p.Pix[i+7] = uint8(c.A)
436}
437
438// SubImage returns an image representing the portion of the image p visible
439// through r. The returned value shares pixels with the original image.
440func (p *NRGBA64) SubImage(r Rectangle) Image {
441	r = r.Intersect(p.Rect)
442	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
443	// either r1 or r2 if the intersection is empty. Without explicitly checking for
444	// this, the Pix[i:] expression below can panic.
445	if r.Empty() {
446		return &NRGBA64{}
447	}
448	i := p.PixOffset(r.Min.X, r.Min.Y)
449	return &NRGBA64{
450		Pix:    p.Pix[i:],
451		Stride: p.Stride,
452		Rect:   r,
453	}
454}
455
456// Opaque scans the entire image and reports whether it is fully opaque.
457func (p *NRGBA64) Opaque() bool {
458	if p.Rect.Empty() {
459		return true
460	}
461	i0, i1 := 6, p.Rect.Dx()*8
462	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
463		for i := i0; i < i1; i += 8 {
464			if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff {
465				return false
466			}
467		}
468		i0 += p.Stride
469		i1 += p.Stride
470	}
471	return true
472}
473
474// NewNRGBA64 returns a new NRGBA64 image with the given bounds.
475func NewNRGBA64(r Rectangle) *NRGBA64 {
476	w, h := r.Dx(), r.Dy()
477	pix := make([]uint8, 8*w*h)
478	return &NRGBA64{pix, 8 * w, r}
479}
480
481// Alpha is an in-memory image whose At method returns color.Alpha values.
482type Alpha struct {
483	// Pix holds the image's pixels, as alpha values. The pixel at
484	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
485	Pix []uint8
486	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
487	Stride int
488	// Rect is the image's bounds.
489	Rect Rectangle
490}
491
492func (p *Alpha) ColorModel() color.Model { return color.AlphaModel }
493
494func (p *Alpha) Bounds() Rectangle { return p.Rect }
495
496func (p *Alpha) At(x, y int) color.Color {
497	return p.AlphaAt(x, y)
498}
499
500func (p *Alpha) AlphaAt(x, y int) color.Alpha {
501	if !(Point{x, y}.In(p.Rect)) {
502		return color.Alpha{}
503	}
504	i := p.PixOffset(x, y)
505	return color.Alpha{p.Pix[i]}
506}
507
508// PixOffset returns the index of the first element of Pix that corresponds to
509// the pixel at (x, y).
510func (p *Alpha) PixOffset(x, y int) int {
511	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
512}
513
514func (p *Alpha) Set(x, y int, c color.Color) {
515	if !(Point{x, y}.In(p.Rect)) {
516		return
517	}
518	i := p.PixOffset(x, y)
519	p.Pix[i] = color.AlphaModel.Convert(c).(color.Alpha).A
520}
521
522func (p *Alpha) SetAlpha(x, y int, c color.Alpha) {
523	if !(Point{x, y}.In(p.Rect)) {
524		return
525	}
526	i := p.PixOffset(x, y)
527	p.Pix[i] = c.A
528}
529
530// SubImage returns an image representing the portion of the image p visible
531// through r. The returned value shares pixels with the original image.
532func (p *Alpha) SubImage(r Rectangle) Image {
533	r = r.Intersect(p.Rect)
534	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
535	// either r1 or r2 if the intersection is empty. Without explicitly checking for
536	// this, the Pix[i:] expression below can panic.
537	if r.Empty() {
538		return &Alpha{}
539	}
540	i := p.PixOffset(r.Min.X, r.Min.Y)
541	return &Alpha{
542		Pix:    p.Pix[i:],
543		Stride: p.Stride,
544		Rect:   r,
545	}
546}
547
548// Opaque scans the entire image and reports whether it is fully opaque.
549func (p *Alpha) Opaque() bool {
550	if p.Rect.Empty() {
551		return true
552	}
553	i0, i1 := 0, p.Rect.Dx()
554	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
555		for i := i0; i < i1; i++ {
556			if p.Pix[i] != 0xff {
557				return false
558			}
559		}
560		i0 += p.Stride
561		i1 += p.Stride
562	}
563	return true
564}
565
566// NewAlpha returns a new Alpha image with the given bounds.
567func NewAlpha(r Rectangle) *Alpha {
568	w, h := r.Dx(), r.Dy()
569	pix := make([]uint8, 1*w*h)
570	return &Alpha{pix, 1 * w, r}
571}
572
573// Alpha16 is an in-memory image whose At method returns color.Alpha16 values.
574type Alpha16 struct {
575	// Pix holds the image's pixels, as alpha values in big-endian format. The pixel at
576	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*2].
577	Pix []uint8
578	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
579	Stride int
580	// Rect is the image's bounds.
581	Rect Rectangle
582}
583
584func (p *Alpha16) ColorModel() color.Model { return color.Alpha16Model }
585
586func (p *Alpha16) Bounds() Rectangle { return p.Rect }
587
588func (p *Alpha16) At(x, y int) color.Color {
589	return p.Alpha16At(x, y)
590}
591
592func (p *Alpha16) Alpha16At(x, y int) color.Alpha16 {
593	if !(Point{x, y}.In(p.Rect)) {
594		return color.Alpha16{}
595	}
596	i := p.PixOffset(x, y)
597	return color.Alpha16{uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1])}
598}
599
600// PixOffset returns the index of the first element of Pix that corresponds to
601// the pixel at (x, y).
602func (p *Alpha16) PixOffset(x, y int) int {
603	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*2
604}
605
606func (p *Alpha16) Set(x, y int, c color.Color) {
607	if !(Point{x, y}.In(p.Rect)) {
608		return
609	}
610	i := p.PixOffset(x, y)
611	c1 := color.Alpha16Model.Convert(c).(color.Alpha16)
612	p.Pix[i+0] = uint8(c1.A >> 8)
613	p.Pix[i+1] = uint8(c1.A)
614}
615
616func (p *Alpha16) SetAlpha16(x, y int, c color.Alpha16) {
617	if !(Point{x, y}.In(p.Rect)) {
618		return
619	}
620	i := p.PixOffset(x, y)
621	p.Pix[i+0] = uint8(c.A >> 8)
622	p.Pix[i+1] = uint8(c.A)
623}
624
625// SubImage returns an image representing the portion of the image p visible
626// through r. The returned value shares pixels with the original image.
627func (p *Alpha16) SubImage(r Rectangle) Image {
628	r = r.Intersect(p.Rect)
629	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
630	// either r1 or r2 if the intersection is empty. Without explicitly checking for
631	// this, the Pix[i:] expression below can panic.
632	if r.Empty() {
633		return &Alpha16{}
634	}
635	i := p.PixOffset(r.Min.X, r.Min.Y)
636	return &Alpha16{
637		Pix:    p.Pix[i:],
638		Stride: p.Stride,
639		Rect:   r,
640	}
641}
642
643// Opaque scans the entire image and reports whether it is fully opaque.
644func (p *Alpha16) Opaque() bool {
645	if p.Rect.Empty() {
646		return true
647	}
648	i0, i1 := 0, p.Rect.Dx()*2
649	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
650		for i := i0; i < i1; i += 2 {
651			if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff {
652				return false
653			}
654		}
655		i0 += p.Stride
656		i1 += p.Stride
657	}
658	return true
659}
660
661// NewAlpha16 returns a new Alpha16 image with the given bounds.
662func NewAlpha16(r Rectangle) *Alpha16 {
663	w, h := r.Dx(), r.Dy()
664	pix := make([]uint8, 2*w*h)
665	return &Alpha16{pix, 2 * w, r}
666}
667
668// Gray is an in-memory image whose At method returns color.Gray values.
669type Gray struct {
670	// Pix holds the image's pixels, as gray values. The pixel at
671	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
672	Pix []uint8
673	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
674	Stride int
675	// Rect is the image's bounds.
676	Rect Rectangle
677}
678
679func (p *Gray) ColorModel() color.Model { return color.GrayModel }
680
681func (p *Gray) Bounds() Rectangle { return p.Rect }
682
683func (p *Gray) At(x, y int) color.Color {
684	return p.GrayAt(x, y)
685}
686
687func (p *Gray) GrayAt(x, y int) color.Gray {
688	if !(Point{x, y}.In(p.Rect)) {
689		return color.Gray{}
690	}
691	i := p.PixOffset(x, y)
692	return color.Gray{p.Pix[i]}
693}
694
695// PixOffset returns the index of the first element of Pix that corresponds to
696// the pixel at (x, y).
697func (p *Gray) PixOffset(x, y int) int {
698	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
699}
700
701func (p *Gray) Set(x, y int, c color.Color) {
702	if !(Point{x, y}.In(p.Rect)) {
703		return
704	}
705	i := p.PixOffset(x, y)
706	p.Pix[i] = color.GrayModel.Convert(c).(color.Gray).Y
707}
708
709func (p *Gray) SetGray(x, y int, c color.Gray) {
710	if !(Point{x, y}.In(p.Rect)) {
711		return
712	}
713	i := p.PixOffset(x, y)
714	p.Pix[i] = c.Y
715}
716
717// SubImage returns an image representing the portion of the image p visible
718// through r. The returned value shares pixels with the original image.
719func (p *Gray) SubImage(r Rectangle) Image {
720	r = r.Intersect(p.Rect)
721	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
722	// either r1 or r2 if the intersection is empty. Without explicitly checking for
723	// this, the Pix[i:] expression below can panic.
724	if r.Empty() {
725		return &Gray{}
726	}
727	i := p.PixOffset(r.Min.X, r.Min.Y)
728	return &Gray{
729		Pix:    p.Pix[i:],
730		Stride: p.Stride,
731		Rect:   r,
732	}
733}
734
735// Opaque scans the entire image and reports whether it is fully opaque.
736func (p *Gray) Opaque() bool {
737	return true
738}
739
740// NewGray returns a new Gray image with the given bounds.
741func NewGray(r Rectangle) *Gray {
742	w, h := r.Dx(), r.Dy()
743	pix := make([]uint8, 1*w*h)
744	return &Gray{pix, 1 * w, r}
745}
746
747// Gray16 is an in-memory image whose At method returns color.Gray16 values.
748type Gray16 struct {
749	// Pix holds the image's pixels, as gray values in big-endian format. The pixel at
750	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*2].
751	Pix []uint8
752	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
753	Stride int
754	// Rect is the image's bounds.
755	Rect Rectangle
756}
757
758func (p *Gray16) ColorModel() color.Model { return color.Gray16Model }
759
760func (p *Gray16) Bounds() Rectangle { return p.Rect }
761
762func (p *Gray16) At(x, y int) color.Color {
763	return p.Gray16At(x, y)
764}
765
766func (p *Gray16) Gray16At(x, y int) color.Gray16 {
767	if !(Point{x, y}.In(p.Rect)) {
768		return color.Gray16{}
769	}
770	i := p.PixOffset(x, y)
771	return color.Gray16{uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1])}
772}
773
774// PixOffset returns the index of the first element of Pix that corresponds to
775// the pixel at (x, y).
776func (p *Gray16) PixOffset(x, y int) int {
777	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*2
778}
779
780func (p *Gray16) Set(x, y int, c color.Color) {
781	if !(Point{x, y}.In(p.Rect)) {
782		return
783	}
784	i := p.PixOffset(x, y)
785	c1 := color.Gray16Model.Convert(c).(color.Gray16)
786	p.Pix[i+0] = uint8(c1.Y >> 8)
787	p.Pix[i+1] = uint8(c1.Y)
788}
789
790func (p *Gray16) SetGray16(x, y int, c color.Gray16) {
791	if !(Point{x, y}.In(p.Rect)) {
792		return
793	}
794	i := p.PixOffset(x, y)
795	p.Pix[i+0] = uint8(c.Y >> 8)
796	p.Pix[i+1] = uint8(c.Y)
797}
798
799// SubImage returns an image representing the portion of the image p visible
800// through r. The returned value shares pixels with the original image.
801func (p *Gray16) SubImage(r Rectangle) Image {
802	r = r.Intersect(p.Rect)
803	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
804	// either r1 or r2 if the intersection is empty. Without explicitly checking for
805	// this, the Pix[i:] expression below can panic.
806	if r.Empty() {
807		return &Gray16{}
808	}
809	i := p.PixOffset(r.Min.X, r.Min.Y)
810	return &Gray16{
811		Pix:    p.Pix[i:],
812		Stride: p.Stride,
813		Rect:   r,
814	}
815}
816
817// Opaque scans the entire image and reports whether it is fully opaque.
818func (p *Gray16) Opaque() bool {
819	return true
820}
821
822// NewGray16 returns a new Gray16 image with the given bounds.
823func NewGray16(r Rectangle) *Gray16 {
824	w, h := r.Dx(), r.Dy()
825	pix := make([]uint8, 2*w*h)
826	return &Gray16{pix, 2 * w, r}
827}
828
829// CMYK is an in-memory image whose At method returns color.CMYK values.
830type CMYK struct {
831	// Pix holds the image's pixels, in C, M, Y, K order. The pixel at
832	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4].
833	Pix []uint8
834	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
835	Stride int
836	// Rect is the image's bounds.
837	Rect Rectangle
838}
839
840func (p *CMYK) ColorModel() color.Model { return color.CMYKModel }
841
842func (p *CMYK) Bounds() Rectangle { return p.Rect }
843
844func (p *CMYK) At(x, y int) color.Color {
845	return p.CMYKAt(x, y)
846}
847
848func (p *CMYK) CMYKAt(x, y int) color.CMYK {
849	if !(Point{x, y}.In(p.Rect)) {
850		return color.CMYK{}
851	}
852	i := p.PixOffset(x, y)
853	return color.CMYK{p.Pix[i+0], p.Pix[i+1], p.Pix[i+2], p.Pix[i+3]}
854}
855
856// PixOffset returns the index of the first element of Pix that corresponds to
857// the pixel at (x, y).
858func (p *CMYK) PixOffset(x, y int) int {
859	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4
860}
861
862func (p *CMYK) Set(x, y int, c color.Color) {
863	if !(Point{x, y}.In(p.Rect)) {
864		return
865	}
866	i := p.PixOffset(x, y)
867	c1 := color.CMYKModel.Convert(c).(color.CMYK)
868	p.Pix[i+0] = c1.C
869	p.Pix[i+1] = c1.M
870	p.Pix[i+2] = c1.Y
871	p.Pix[i+3] = c1.K
872}
873
874func (p *CMYK) SetCMYK(x, y int, c color.CMYK) {
875	if !(Point{x, y}.In(p.Rect)) {
876		return
877	}
878	i := p.PixOffset(x, y)
879	p.Pix[i+0] = c.C
880	p.Pix[i+1] = c.M
881	p.Pix[i+2] = c.Y
882	p.Pix[i+3] = c.K
883}
884
885// SubImage returns an image representing the portion of the image p visible
886// through r. The returned value shares pixels with the original image.
887func (p *CMYK) SubImage(r Rectangle) Image {
888	r = r.Intersect(p.Rect)
889	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
890	// either r1 or r2 if the intersection is empty. Without explicitly checking for
891	// this, the Pix[i:] expression below can panic.
892	if r.Empty() {
893		return &CMYK{}
894	}
895	i := p.PixOffset(r.Min.X, r.Min.Y)
896	return &CMYK{
897		Pix:    p.Pix[i:],
898		Stride: p.Stride,
899		Rect:   r,
900	}
901}
902
903// Opaque scans the entire image and reports whether it is fully opaque.
904func (p *CMYK) Opaque() bool {
905	return true
906}
907
908// NewCMYK returns a new CMYK image with the given bounds.
909func NewCMYK(r Rectangle) *CMYK {
910	w, h := r.Dx(), r.Dy()
911	buf := make([]uint8, 4*w*h)
912	return &CMYK{buf, 4 * w, r}
913}
914
915// Paletted is an in-memory image of uint8 indices into a given palette.
916type Paletted struct {
917	// Pix holds the image's pixels, as palette indices. The pixel at
918	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
919	Pix []uint8
920	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
921	Stride int
922	// Rect is the image's bounds.
923	Rect Rectangle
924	// Palette is the image's palette.
925	Palette color.Palette
926}
927
928func (p *Paletted) ColorModel() color.Model { return p.Palette }
929
930func (p *Paletted) Bounds() Rectangle { return p.Rect }
931
932func (p *Paletted) At(x, y int) color.Color {
933	if len(p.Palette) == 0 {
934		return nil
935	}
936	if !(Point{x, y}.In(p.Rect)) {
937		return p.Palette[0]
938	}
939	i := p.PixOffset(x, y)
940	return p.Palette[p.Pix[i]]
941}
942
943// PixOffset returns the index of the first element of Pix that corresponds to
944// the pixel at (x, y).
945func (p *Paletted) PixOffset(x, y int) int {
946	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
947}
948
949func (p *Paletted) Set(x, y int, c color.Color) {
950	if !(Point{x, y}.In(p.Rect)) {
951		return
952	}
953	i := p.PixOffset(x, y)
954	p.Pix[i] = uint8(p.Palette.Index(c))
955}
956
957func (p *Paletted) ColorIndexAt(x, y int) uint8 {
958	if !(Point{x, y}.In(p.Rect)) {
959		return 0
960	}
961	i := p.PixOffset(x, y)
962	return p.Pix[i]
963}
964
965func (p *Paletted) SetColorIndex(x, y int, index uint8) {
966	if !(Point{x, y}.In(p.Rect)) {
967		return
968	}
969	i := p.PixOffset(x, y)
970	p.Pix[i] = index
971}
972
973// SubImage returns an image representing the portion of the image p visible
974// through r. The returned value shares pixels with the original image.
975func (p *Paletted) SubImage(r Rectangle) Image {
976	r = r.Intersect(p.Rect)
977	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
978	// either r1 or r2 if the intersection is empty. Without explicitly checking for
979	// this, the Pix[i:] expression below can panic.
980	if r.Empty() {
981		return &Paletted{
982			Palette: p.Palette,
983		}
984	}
985	i := p.PixOffset(r.Min.X, r.Min.Y)
986	return &Paletted{
987		Pix:     p.Pix[i:],
988		Stride:  p.Stride,
989		Rect:    p.Rect.Intersect(r),
990		Palette: p.Palette,
991	}
992}
993
994// Opaque scans the entire image and reports whether it is fully opaque.
995func (p *Paletted) Opaque() bool {
996	var present [256]bool
997	i0, i1 := 0, p.Rect.Dx()
998	for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
999		for _, c := range p.Pix[i0:i1] {
1000			present[c] = true
1001		}
1002		i0 += p.Stride
1003		i1 += p.Stride
1004	}
1005	for i, c := range p.Palette {
1006		if !present[i] {
1007			continue
1008		}
1009		_, _, _, a := c.RGBA()
1010		if a != 0xffff {
1011			return false
1012		}
1013	}
1014	return true
1015}
1016
1017// NewPaletted returns a new Paletted image with the given width, height and
1018// palette.
1019func NewPaletted(r Rectangle, p color.Palette) *Paletted {
1020	w, h := r.Dx(), r.Dy()
1021	pix := make([]uint8, 1*w*h)
1022	return &Paletted{pix, 1 * w, r, p}
1023}
1024