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 }