github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/pkg/image/image.go (about)

     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  	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 reports whether 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 reports whether 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 reports whether 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 reports whether 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 reports whether 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 reports whether 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 reports whether 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 reports whether 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 reports whether 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  }