...
Run Format

Source file src/image/image.go

     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	// http://golang.org/doc/articles/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		return p.RGBAAt(x, y)
    76	}
    77	
    78	func (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).
    88	func (p *RGBA) PixOffset(x, y int) int {
    89		return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4
    90	}
    91	
    92	func (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	
   104	func (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.
   117	func (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.
   134	func (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 with the given bounds.
   152	func 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.
   159	type 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	
   169	func (p *RGBA64) ColorModel() color.Model { return color.RGBA64Model }
   170	
   171	func (p *RGBA64) Bounds() Rectangle { return p.Rect }
   172	
   173	func (p *RGBA64) At(x, y int) color.Color {
   174		return p.RGBA64At(x, y)
   175	}
   176	
   177	func (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).
   192	func (p *RGBA64) PixOffset(x, y int) int {
   193		return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*8
   194	}
   195	
   196	func (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	
   212	func (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.
   229	func (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.
   246	func (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 with the given bounds.
   264	func 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.
   271	type 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	
   281	func (p *NRGBA) ColorModel() color.Model { return color.NRGBAModel }
   282	
   283	func (p *NRGBA) Bounds() Rectangle { return p.Rect }
   284	
   285	func (p *NRGBA) At(x, y int) color.Color {
   286		return p.NRGBAAt(x, y)
   287	}
   288	
   289	func (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).
   299	func (p *NRGBA) PixOffset(x, y int) int {
   300		return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4
   301	}
   302	
   303	func (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	
   315	func (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.
   328	func (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.
   345	func (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 with the given bounds.
   363	func 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.
   370	type 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	
   380	func (p *NRGBA64) ColorModel() color.Model { return color.NRGBA64Model }
   381	
   382	func (p *NRGBA64) Bounds() Rectangle { return p.Rect }
   383	
   384	func (p *NRGBA64) At(x, y int) color.Color {
   385		return p.NRGBA64At(x, y)
   386	}
   387	
   388	func (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).
   403	func (p *NRGBA64) PixOffset(x, y int) int {
   404		return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*8
   405	}
   406	
   407	func (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	
   423	func (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.
   440	func (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.
   457	func (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 with the given bounds.
   475	func 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.
   482	type 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	
   492	func (p *Alpha) ColorModel() color.Model { return color.AlphaModel }
   493	
   494	func (p *Alpha) Bounds() Rectangle { return p.Rect }
   495	
   496	func (p *Alpha) At(x, y int) color.Color {
   497		return p.AlphaAt(x, y)
   498	}
   499	
   500	func (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).
   510	func (p *Alpha) PixOffset(x, y int) int {
   511		return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
   512	}
   513	
   514	func (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	
   522	func (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.
   532	func (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.
   549	func (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 with the given bounds.
   567	func 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.Alpha64 values.
   574	type 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	
   584	func (p *Alpha16) ColorModel() color.Model { return color.Alpha16Model }
   585	
   586	func (p *Alpha16) Bounds() Rectangle { return p.Rect }
   587	
   588	func (p *Alpha16) At(x, y int) color.Color {
   589		return p.Alpha16At(x, y)
   590	}
   591	
   592	func (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).
   602	func (p *Alpha16) PixOffset(x, y int) int {
   603		return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*2
   604	}
   605	
   606	func (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	
   616	func (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.
   627	func (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.
   644	func (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 with the given bounds.
   662	func 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.
   669	type 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	
   679	func (p *Gray) ColorModel() color.Model { return color.GrayModel }
   680	
   681	func (p *Gray) Bounds() Rectangle { return p.Rect }
   682	
   683	func (p *Gray) At(x, y int) color.Color {
   684		return p.GrayAt(x, y)
   685	}
   686	
   687	func (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).
   697	func (p *Gray) PixOffset(x, y int) int {
   698		return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
   699	}
   700	
   701	func (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	
   709	func (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.
   719	func (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.
   736	func (p *Gray) Opaque() bool {
   737		return true
   738	}
   739	
   740	// NewGray returns a new Gray with the given bounds.
   741	func 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.
   748	type 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	
   758	func (p *Gray16) ColorModel() color.Model { return color.Gray16Model }
   759	
   760	func (p *Gray16) Bounds() Rectangle { return p.Rect }
   761	
   762	func (p *Gray16) At(x, y int) color.Color {
   763		return p.Gray16At(x, y)
   764	}
   765	
   766	func (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).
   776	func (p *Gray16) PixOffset(x, y int) int {
   777		return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*2
   778	}
   779	
   780	func (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	
   790	func (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.
   801	func (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.
   818	func (p *Gray16) Opaque() bool {
   819		return true
   820	}
   821	
   822	// NewGray16 returns a new Gray16 with the given bounds.
   823	func 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	// Paletted is an in-memory image of uint8 indices into a given palette.
   830	type Paletted struct {
   831		// Pix holds the image's pixels, as palette indices. The pixel at
   832		// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1].
   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		// Palette is the image's palette.
   839		Palette color.Palette
   840	}
   841	
   842	func (p *Paletted) ColorModel() color.Model { return p.Palette }
   843	
   844	func (p *Paletted) Bounds() Rectangle { return p.Rect }
   845	
   846	func (p *Paletted) At(x, y int) color.Color {
   847		if len(p.Palette) == 0 {
   848			return nil
   849		}
   850		if !(Point{x, y}.In(p.Rect)) {
   851			return p.Palette[0]
   852		}
   853		i := p.PixOffset(x, y)
   854		return p.Palette[p.Pix[i]]
   855	}
   856	
   857	// PixOffset returns the index of the first element of Pix that corresponds to
   858	// the pixel at (x, y).
   859	func (p *Paletted) PixOffset(x, y int) int {
   860		return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
   861	}
   862	
   863	func (p *Paletted) Set(x, y int, c color.Color) {
   864		if !(Point{x, y}.In(p.Rect)) {
   865			return
   866		}
   867		i := p.PixOffset(x, y)
   868		p.Pix[i] = uint8(p.Palette.Index(c))
   869	}
   870	
   871	func (p *Paletted) ColorIndexAt(x, y int) uint8 {
   872		if !(Point{x, y}.In(p.Rect)) {
   873			return 0
   874		}
   875		i := p.PixOffset(x, y)
   876		return p.Pix[i]
   877	}
   878	
   879	func (p *Paletted) SetColorIndex(x, y int, index uint8) {
   880		if !(Point{x, y}.In(p.Rect)) {
   881			return
   882		}
   883		i := p.PixOffset(x, y)
   884		p.Pix[i] = index
   885	}
   886	
   887	// SubImage returns an image representing the portion of the image p visible
   888	// through r. The returned value shares pixels with the original image.
   889	func (p *Paletted) SubImage(r Rectangle) Image {
   890		r = r.Intersect(p.Rect)
   891		// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
   892		// either r1 or r2 if the intersection is empty. Without explicitly checking for
   893		// this, the Pix[i:] expression below can panic.
   894		if r.Empty() {
   895			return &Paletted{
   896				Palette: p.Palette,
   897			}
   898		}
   899		i := p.PixOffset(r.Min.X, r.Min.Y)
   900		return &Paletted{
   901			Pix:     p.Pix[i:],
   902			Stride:  p.Stride,
   903			Rect:    p.Rect.Intersect(r),
   904			Palette: p.Palette,
   905		}
   906	}
   907	
   908	// Opaque scans the entire image and reports whether it is fully opaque.
   909	func (p *Paletted) Opaque() bool {
   910		var present [256]bool
   911		i0, i1 := 0, p.Rect.Dx()
   912		for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ {
   913			for _, c := range p.Pix[i0:i1] {
   914				present[c] = true
   915			}
   916			i0 += p.Stride
   917			i1 += p.Stride
   918		}
   919		for i, c := range p.Palette {
   920			if !present[i] {
   921				continue
   922			}
   923			_, _, _, a := c.RGBA()
   924			if a != 0xffff {
   925				return false
   926			}
   927		}
   928		return true
   929	}
   930	
   931	// NewPaletted returns a new Paletted with the given width, height and palette.
   932	func NewPaletted(r Rectangle, p color.Palette) *Paletted {
   933		w, h := r.Dx(), r.Dy()
   934		pix := make([]uint8, 1*w*h)
   935		return &Paletted{pix, 1 * w, r, p}
   936	}
   937	

View as plain text