...
Tawesoft Logo

Source file src/tawesoft.co.uk/go/ximage/rg.go

Documentation: src/tawesoft.co.uk/go/ximage/rg.go

     1  // Based on https://golang.org/src/image/image.go
     2  // Copyright 2009 The Go Authors. All rights reserved.
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSE file.
     5  
     6  package ximage
     7  
     8  import (
     9      "image"
    10      "image/color"
    11  
    12      "tawesoft.co.uk/go/ximage/xcolor"
    13  )
    14  
    15  // RG is an in-memory image whose At method returns color.RG values.
    16  type RG struct {
    17  	// Pix holds the image's pixels, as Red values. The pixel at
    18  	// (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*2].
    19  	Pix []uint8
    20  	// Stride is the Pix stride (in bytes) between vertically adjacent pixels.
    21  	Stride int
    22  	// Rect is the image's bounds.
    23  	Rect image.Rectangle
    24  }
    25  
    26  func (p *RG) ColorModel() color.Model { return xcolor.RGModel }
    27  
    28  func (p *RG) Bounds() image.Rectangle { return p.Rect }
    29  
    30  func (p *RG) At(x, y int) color.Color {
    31  	return p.RGAt(x, y)
    32  }
    33  
    34  func (p *RG) RGAt(x, y int) xcolor.RG {
    35  	if !(image.Point{x, y}.In(p.Rect)) {
    36  		return xcolor.RG{}
    37  	}
    38  	i := p.PixOffset(x, y)
    39  	return xcolor.RG{R: p.Pix[i], G: p.Pix[i+1]}
    40  }
    41  
    42  // PixOffset returns the index of the first element of Pix that corresponds to
    43  // the pixel at (x, y).
    44  func (p *RG) PixOffset(x, y int) int {
    45  	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1
    46  }
    47  
    48  func (p *RG) Set(x, y int, c color.Color) {
    49  	if !(image.Point{x, y}.In(p.Rect)) {
    50  		return
    51  	}
    52      i := p.PixOffset(x, y)
    53      rgba := xcolor.RGModel.Convert(c).(color.RGBA)
    54      p.Pix[i] = rgba.R
    55      p.Pix[i+1] = rgba.G
    56  }
    57  
    58  func (p *RG) SetRG(x, y int, c xcolor.RG) {
    59  	if !(image.Point{x, y}.In(p.Rect)) {
    60  		return
    61  	}
    62  	i := p.PixOffset(x, y)
    63      p.Pix[i] = c.R
    64      p.Pix[i+1] = c.G
    65  }
    66  
    67  // SubImage returns an image representing the portion of the image p visible
    68  // through r. The returned value shares pixels with the original image.
    69  func (p *RG) SubImage(r image.Rectangle) image.Image {
    70  	r = r.Intersect(p.Rect)
    71  	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
    72  	// either r1 or r2 if the intersection is empty. Without explicitly checking for
    73  	// this, the Pix[i:] expression below can panic.
    74  	if r.Empty() {
    75  		return &RG{}
    76  	}
    77  	i := p.PixOffset(r.Min.X, r.Min.Y)
    78  	return &RG{
    79  		Pix:    p.Pix[i:],
    80  		Stride: p.Stride,
    81  		Rect:   r,
    82  	}
    83  }
    84  
    85  // Opaque scans the entire image and reports whether it is fully opaque.
    86  func (p *RG) Opaque() bool {
    87  	return true
    88  }
    89  
    90  // NewRG returns a new RG image with the given bounds.
    91  func NewRG(r image.Rectangle) *RG {
    92  	w, h := r.Dx(), r.Dy()
    93  	pix := make([]uint8, 2*w*h)
    94  	return &RG{pix, 2 * w, r}
    95  }
    96  

View as plain text