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

     1  // Copyright 2014 <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 raw
     6  
     7  import (
     8  	"fmt"
     9  	"image"
    10  	"image/color"
    11  	"image/draw"
    12  	"reflect"
    13  
    14  	"github.com/chai2010/gopkg/builtin"
    15  	image_ext "github.com/chai2010/gopkg/image"
    16  	color_ext "github.com/chai2010/gopkg/image/color"
    17  )
    18  
    19  type Decoder struct {
    20  	Channels int          // 1/3/4
    21  	DataType reflect.Kind // Uint8/Uint16/Float32
    22  	Width    int          // need for Decode
    23  	Height   int          // need for Decode
    24  }
    25  
    26  func (p *Decoder) Decode(data []byte, buf image_ext.ImageBuffer) (m draw.Image, err error) {
    27  	// Gray/Gray16/Gray32f
    28  	if p.Channels == 1 && p.DataType == reflect.Uint8 {
    29  		return p.decodeGray(data, buf)
    30  	}
    31  	if p.Channels == 1 && p.DataType == reflect.Uint16 {
    32  		return p.decodeGray16(data, buf)
    33  	}
    34  	if p.Channels == 1 && p.DataType == reflect.Float32 {
    35  		return p.decodeGray32f(data, buf)
    36  	}
    37  
    38  	// RGB/RGB48/RGB96f
    39  	if p.Channels == 3 && p.DataType == reflect.Uint8 {
    40  		return p.decodeRGB(data, buf)
    41  	}
    42  	if p.Channels == 3 && p.DataType == reflect.Uint16 {
    43  		return p.decodeRGB48(data, buf)
    44  	}
    45  	if p.Channels == 3 && p.DataType == reflect.Float32 {
    46  		return p.decodeRGB96f(data, buf)
    47  	}
    48  
    49  	// RGBA/RGBA64/RGBA128f
    50  	if p.Channels == 4 && p.DataType == reflect.Uint8 {
    51  		return p.decodeRGBA(data, buf)
    52  	}
    53  	if p.Channels == 4 && p.DataType == reflect.Uint16 {
    54  		return p.decodeRGBA64(data, buf)
    55  	}
    56  	if p.Channels == 4 && p.DataType == reflect.Float32 {
    57  		return p.decodeRGBA128f(data, buf)
    58  	}
    59  
    60  	// Unknown
    61  	err = fmt.Errorf(
    62  		"image/raw: Decode, unknown image format, channels = %v, dataType = %v",
    63  		p.Channels, p.DataType,
    64  	)
    65  	return
    66  }
    67  
    68  func (p *Decoder) getPixelSize() int {
    69  	switch p.DataType {
    70  	case reflect.Uint8:
    71  		return p.Channels * 1
    72  	case reflect.Uint16:
    73  		return p.Channels * 2
    74  	case reflect.Float32:
    75  		return p.Channels * 4
    76  	}
    77  	panic("image/raw: getPixelSize, unreachable")
    78  }
    79  
    80  func (p *Decoder) getImageDataSize() int {
    81  	return p.getPixelSize() * p.Width * p.Height
    82  }
    83  
    84  func (p *Decoder) decodeGray(data []byte, buf image_ext.ImageBuffer) (m draw.Image, err error) {
    85  	if size := p.getImageDataSize(); len(data) != size {
    86  		err = fmt.Errorf("image/raw: decodeGray, bad data size, expect = %d, got = %d", size, len(data))
    87  		return
    88  	}
    89  	gray := newGray(image.Rect(0, 0, p.Width, p.Height), buf)
    90  	var off = 0
    91  	for y := 0; y < p.Height; y++ {
    92  		copy(gray.Pix[y*gray.Stride:][:p.Width], data[off:])
    93  		off += p.Width
    94  	}
    95  	m = gray
    96  	return
    97  }
    98  
    99  func (p *Decoder) decodeGray16(data []byte, buf image_ext.ImageBuffer) (m draw.Image, err error) {
   100  	if size := p.getImageDataSize(); len(data) != size {
   101  		err = fmt.Errorf("image/raw: decodeGray16, bad data size, expect = %d, got = %d", size, len(data))
   102  		return
   103  	}
   104  	gray16 := newGray16(image.Rect(0, 0, p.Width, p.Height), buf)
   105  	var off = 0
   106  	for y := 0; y < p.Height; y++ {
   107  		u16Pix := builtin.Slice(data[off:], reflect.TypeOf([]uint16(nil))).([]uint16)
   108  		for x := 0; x < p.Width; x++ {
   109  			gray16.SetGray16(x, y, color.Gray16{u16Pix[x]})
   110  		}
   111  		off += p.Width * 2
   112  	}
   113  	m = gray16
   114  	return
   115  }
   116  
   117  func (p *Decoder) decodeGray32f(data []byte, buf image_ext.ImageBuffer) (m draw.Image, err error) {
   118  	if size := p.getImageDataSize(); len(data) != size {
   119  		err = fmt.Errorf("image/raw: decodeGray32f, bad data size, expect = %d, got = %d", size, len(data))
   120  		return
   121  	}
   122  	gray32f := newGray32f(image.Rect(0, 0, p.Width, p.Height), buf)
   123  	var off = 0
   124  	for y := 0; y < p.Height; y++ {
   125  		copy(gray32f.Pix[y*gray32f.Stride:][:p.Width*4], data[off:])
   126  		off += p.Width * 4
   127  	}
   128  	m = gray32f
   129  	return
   130  }
   131  
   132  func (p *Decoder) decodeRGB(data []byte, buf image_ext.ImageBuffer) (m draw.Image, err error) {
   133  	if size := p.getImageDataSize(); len(data) != size {
   134  		err = fmt.Errorf("image/raw: decodeRGB, bad data size, expect = %d, got = %d", size, len(data))
   135  		return
   136  	}
   137  	rgb := newRGB(image.Rect(0, 0, p.Width, p.Height), buf)
   138  	var off = 0
   139  	for y := 0; y < p.Height; y++ {
   140  		for x := 0; x < p.Width; x++ {
   141  			rgb.SetRGB(x, y, color_ext.RGB{
   142  				R: data[off+0],
   143  				G: data[off+1],
   144  				B: data[off+2],
   145  			})
   146  			off += 3
   147  		}
   148  	}
   149  	m = rgb
   150  	return
   151  }
   152  
   153  func (p *Decoder) decodeRGB48(data []byte, buf image_ext.ImageBuffer) (m draw.Image, err error) {
   154  	if size := p.getImageDataSize(); len(data) != size {
   155  		err = fmt.Errorf("image/raw: decodeRGB48, bad data size, expect = %d, got = %d", size, len(data))
   156  		return
   157  	}
   158  	rgb48 := newRGB48(image.Rect(0, 0, p.Width, p.Height), buf)
   159  	var off = 0
   160  	for y := 0; y < p.Height; y++ {
   161  		u16Pix := builtin.Slice(data[off:], reflect.TypeOf([]uint16(nil))).([]uint16)
   162  		for x := 0; x < p.Width; x++ {
   163  			rgb48.SetRGB48(x, y, color_ext.RGB48{
   164  				R: u16Pix[x*3+0],
   165  				G: u16Pix[x*3+1],
   166  				B: u16Pix[x*3+2],
   167  			})
   168  		}
   169  		off += p.Width * 6
   170  	}
   171  	m = rgb48
   172  	return
   173  }
   174  
   175  func (p *Decoder) decodeRGB96f(data []byte, buf image_ext.ImageBuffer) (m draw.Image, err error) {
   176  	if size := p.getImageDataSize(); len(data) != size {
   177  		err = fmt.Errorf("image/raw: decodeRGB96f, bad data size, expect = %d, got = %d", size, len(data))
   178  		return
   179  	}
   180  	rgb96f := newRGB96f(image.Rect(0, 0, p.Width, p.Height), buf)
   181  	var off = 0
   182  	for y := 0; y < p.Height; y++ {
   183  		for x := 0; x < p.Width; x++ {
   184  			rgb96f.SetRGB96f(x, y, color_ext.RGB96f{
   185  				R: builtin.Float32(data[off+0:]),
   186  				G: builtin.Float32(data[off+4:]),
   187  				B: builtin.Float32(data[off+8:]),
   188  			})
   189  			off += 12
   190  		}
   191  	}
   192  	m = rgb96f
   193  	return
   194  }
   195  
   196  func (p *Decoder) decodeRGBA(data []byte, buf image_ext.ImageBuffer) (m draw.Image, err error) {
   197  	if size := p.getImageDataSize(); len(data) != size {
   198  		err = fmt.Errorf("image/raw: decodeRGBA, bad data size, expect = %d, got = %d", size, len(data))
   199  		return
   200  	}
   201  	rgba := newRGBA(image.Rect(0, 0, p.Width, p.Height), buf)
   202  	var off = 0
   203  	for y := 0; y < p.Height; y++ {
   204  		copy(rgba.Pix[y*rgba.Stride:][:p.Width*4], data[off:])
   205  		off += p.Width * 4
   206  	}
   207  	m = rgba
   208  	return
   209  }
   210  
   211  func (p *Decoder) decodeRGBA64(data []byte, buf image_ext.ImageBuffer) (m draw.Image, err error) {
   212  	if size := p.getImageDataSize(); len(data) != size {
   213  		err = fmt.Errorf("image/raw: decodeRGBA64, bad data size, expect = %d, got = %d", size, len(data))
   214  		return
   215  	}
   216  	rgba64 := newRGBA64(image.Rect(0, 0, p.Width, p.Height), buf)
   217  	var off = 0
   218  	for y := 0; y < p.Height; y++ {
   219  		u16Pix := builtin.Slice(data[off:], reflect.TypeOf([]uint16(nil))).([]uint16)
   220  		for x := 0; x < p.Width; x++ {
   221  			rgba64.SetRGBA64(x, y, color.RGBA64{
   222  				R: u16Pix[x*4+0],
   223  				G: u16Pix[x*4+1],
   224  				B: u16Pix[x*4+2],
   225  				A: u16Pix[x*4+3],
   226  			})
   227  		}
   228  		off += p.Width * 8
   229  	}
   230  	m = rgba64
   231  	return
   232  }
   233  
   234  func (p *Decoder) decodeRGBA128f(data []byte, buf image_ext.ImageBuffer) (m draw.Image, err error) {
   235  	if size := p.getImageDataSize(); len(data) != size {
   236  		err = fmt.Errorf("image/raw: decodeRGBA128f, bad data size, expect = %d, got = %d", size, len(data))
   237  		return
   238  	}
   239  	rgba128f := newRGBA128f(image.Rect(0, 0, p.Width, p.Height), buf)
   240  	var off = 0
   241  	for y := 0; y < p.Height; y++ {
   242  		copy(rgba128f.Pix[y*rgba128f.Stride:][:p.Width*16], data[off:])
   243  		off += p.Width * 16
   244  	}
   245  	m = rgba128f
   246  	return
   247  }