github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/rgba128f.go (about)

     1  // Copyright 2013 <chaishushan{AT}gmail.com>. 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
     6  
     7  import (
     8  	"image"
     9  	"image/color"
    10  
    11  	"github.com/chai2010/gopkg/builtin"
    12  	color_ext "github.com/chai2010/gopkg/image/color"
    13  )
    14  
    15  // RGBA128f is an in-memory image whose At method returns color.RGBA128f values.
    16  type RGBA128f struct {
    17  	// Pix holds the image's pixels. The pixel at (x, y) starts at
    18  	// Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*16].
    19  	Pix []byte
    20  	// Stride is the Pix stride between vertically adjacent pixels.
    21  	Stride int
    22  	// Rect is the image's bounds.
    23  	Rect image.Rectangle
    24  }
    25  
    26  func (p *RGBA128f) ColorModel() color.Model { return color_ext.RGBA128fModel }
    27  
    28  func (p *RGBA128f) Bounds() image.Rectangle { return p.Rect }
    29  
    30  func (p *RGBA128f) At(x, y int) color.Color {
    31  	return p.RGBA128fAt(x, y)
    32  }
    33  
    34  func (p *RGBA128f) RGBA128fAt(x, y int) color_ext.RGBA128f {
    35  	if !(image.Point{x, y}.In(p.Rect)) {
    36  		return color_ext.RGBA128f{}
    37  	}
    38  	i := p.PixOffset(x, y)
    39  	return color_ext.RGBA128f{
    40  		R: builtin.Float32(p.Pix[i+0:]),
    41  		G: builtin.Float32(p.Pix[i+4:]),
    42  		B: builtin.Float32(p.Pix[i+8:]),
    43  		A: builtin.Float32(p.Pix[i+12:]),
    44  	}
    45  }
    46  
    47  // PixOffset returns the index of the first element of Pix that corresponds to
    48  // the pixel at (x, y).
    49  func (p *RGBA128f) PixOffset(x, y int) int {
    50  	return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*16
    51  }
    52  
    53  func (p *RGBA128f) Set(x, y int, c color.Color) {
    54  	if !(image.Point{x, y}.In(p.Rect)) {
    55  		return
    56  	}
    57  	i := p.PixOffset(x, y)
    58  	c1 := color_ext.RGBA128fModel.Convert(c).(color_ext.RGBA128f)
    59  	builtin.PutFloat32(p.Pix[i+0:], c1.R)
    60  	builtin.PutFloat32(p.Pix[i+4:], c1.G)
    61  	builtin.PutFloat32(p.Pix[i+8:], c1.B)
    62  	builtin.PutFloat32(p.Pix[i+12:], c1.A)
    63  }
    64  
    65  func (p *RGBA128f) SetRGBA128f(x, y int, c color_ext.RGBA128f) {
    66  	if !(image.Point{x, y}.In(p.Rect)) {
    67  		return
    68  	}
    69  	i := p.PixOffset(x, y)
    70  	builtin.PutFloat32(p.Pix[i+0:], c.R)
    71  	builtin.PutFloat32(p.Pix[i+4:], c.G)
    72  	builtin.PutFloat32(p.Pix[i+8:], c.B)
    73  	builtin.PutFloat32(p.Pix[i+12:], c.A)
    74  }
    75  
    76  // SubImage returns an image representing the portion of the image p visible
    77  // through r. The returned value shares pixels with the original image.
    78  func (p *RGBA128f) SubImage(r image.Rectangle) image.Image {
    79  	r = r.Intersect(p.Rect)
    80  	// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
    81  	// either r1 or r2 if the intersection is empty. Without explicitly checking for
    82  	// this, the Pix[i:] expression below can panic.
    83  	if r.Empty() {
    84  		return &RGBA128f{}
    85  	}
    86  	i := p.PixOffset(r.Min.X, r.Min.Y)
    87  	return &RGBA128f{
    88  		Pix:    p.Pix[i:],
    89  		Stride: p.Stride,
    90  		Rect:   r,
    91  	}
    92  }
    93  
    94  // Opaque scans the entire image and reports whether it is fully opaque.
    95  func (p *RGBA128f) Opaque() bool {
    96  	return true
    97  }
    98  
    99  // NewRGBA128f returns a new RGBA128f with the given bounds.
   100  func NewRGBA128f(r image.Rectangle) *RGBA128f {
   101  	w, h := r.Dx(), r.Dy()
   102  	pix := make([]byte, w*h*16)
   103  	return &RGBA128f{pix, w * 16, r}
   104  }