github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/raw/decode_image.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  	image_ext "github.com/chai2010/gopkg/image"
    15  	color_ext "github.com/chai2010/gopkg/image/color"
    16  )
    17  
    18  func (p *Decoder) DecodeImage(data image.Image, buf image_ext.ImageBuffer) (m draw.Image, err error) {
    19  	// Gray/Gray16/Gray32f
    20  	if p.Channels == 1 && p.DataType == reflect.Uint8 {
    21  		return p.decodeImageGray(data, buf)
    22  	}
    23  	if p.Channels == 1 && p.DataType == reflect.Uint16 {
    24  		return p.decodeImageGray16(data, buf)
    25  	}
    26  	if p.Channels == 1 && p.DataType == reflect.Float32 {
    27  		return p.decodeImageGray32f(data, buf)
    28  	}
    29  
    30  	// RGB/RGB48/RGB96f
    31  	if p.Channels == 3 && p.DataType == reflect.Uint8 {
    32  		return p.decodeImageRGB(data, buf)
    33  	}
    34  	if p.Channels == 3 && p.DataType == reflect.Uint16 {
    35  		return p.decodeImageRGB48(data, buf)
    36  	}
    37  	if p.Channels == 3 && p.DataType == reflect.Float32 {
    38  		return p.decodeImageRGB96f(data, buf)
    39  	}
    40  
    41  	// RGBA/RGBA64/RGBA128f
    42  	if p.Channels == 4 && p.DataType == reflect.Uint8 {
    43  		return p.decodeImageRGBA(data, buf)
    44  	}
    45  	if p.Channels == 4 && p.DataType == reflect.Uint16 {
    46  		return p.decodeImageRGBA64(data, buf)
    47  	}
    48  	if p.Channels == 4 && p.DataType == reflect.Float32 {
    49  		return p.decodeImageRGBA128f(data, buf)
    50  	}
    51  
    52  	// Unknown
    53  	err = fmt.Errorf(
    54  		"image/raw: DecodeImage, unknown image format, channels = %v, dataType = %v",
    55  		p.Channels, p.DataType,
    56  	)
    57  	return
    58  }
    59  
    60  func (p *Decoder) decodeImageGray(data image.Image, buf image_ext.ImageBuffer) (m draw.Image, err error) {
    61  	if b := data.Bounds(); b.Dx() != p.Width || b.Dy() != p.Height {
    62  		err = fmt.Errorf("image/raw: bad bounds: %v", data.Bounds())
    63  		return
    64  	}
    65  	if m, ok := data.(*image.Gray); ok {
    66  		return m, nil
    67  	}
    68  	gray := newGray(image.Rect(0, 0, p.Width, p.Height), buf)
    69  	switch data := data.(type) {
    70  	case *image.Gray16:
    71  		for y := 0; y < p.Height; y++ {
    72  			for x := 0; x < p.Width; x++ {
    73  				v := data.Gray16At(x, y)
    74  				gray.SetGray(x, y, color.Gray{uint8(v.Y >> 8)})
    75  			}
    76  		}
    77  	case *image.RGBA:
    78  		for y := 0; y < p.Height; y++ {
    79  			for x := 0; x < p.Width; x++ {
    80  				gray.SetGray(x, y, color.GrayModel.Convert(data.RGBAAt(x, y)).(color.Gray))
    81  			}
    82  		}
    83  	case *image.RGBA64:
    84  		for y := 0; y < p.Height; y++ {
    85  			for x := 0; x < p.Width; x++ {
    86  				gray.SetGray(x, y, color.GrayModel.Convert(data.RGBA64At(x, y)).(color.Gray))
    87  			}
    88  		}
    89  	case *image.YCbCr:
    90  		for y := 0; y < p.Height; y++ {
    91  			copy(
    92  				gray.Pix[y*gray.Stride:][:gray.Stride],
    93  				data.Y[y*data.YStride:][:data.YStride],
    94  			)
    95  		}
    96  	default:
    97  		for y := 0; y < p.Height; y++ {
    98  			for x := 0; x < p.Width; x++ {
    99  				gray.Set(x, y, data.At(x, y))
   100  			}
   101  		}
   102  	}
   103  	m = gray
   104  	return
   105  }
   106  
   107  func (p *Decoder) decodeImageGray16(data image.Image, buf image_ext.ImageBuffer) (m draw.Image, err error) {
   108  	if b := data.Bounds(); b.Dx() != p.Width || b.Dy() != p.Height {
   109  		err = fmt.Errorf("image/raw: bad bounds: %v", data.Bounds())
   110  		return
   111  	}
   112  	if m, ok := data.(*image.Gray16); ok {
   113  		return m, nil
   114  	}
   115  	gray16 := newGray16(image.Rect(0, 0, p.Width, p.Height), buf)
   116  	switch data := data.(type) {
   117  	case *image.Gray:
   118  		for y := 0; y < p.Height; y++ {
   119  			for x := 0; x < p.Width; x++ {
   120  				v := data.GrayAt(x, y)
   121  				gray16.SetGray16(x, y, color.Gray16{uint16(v.Y) << 8})
   122  			}
   123  		}
   124  	case *image.RGBA:
   125  		for y := 0; y < p.Height; y++ {
   126  			for x := 0; x < p.Width; x++ {
   127  				gray16.SetGray16(x, y,
   128  					color.Gray16Model.Convert(data.RGBAAt(x, y)).(color.Gray16),
   129  				)
   130  			}
   131  		}
   132  	case *image.RGBA64:
   133  		for y := 0; y < p.Height; y++ {
   134  			for x := 0; x < p.Width; x++ {
   135  				gray16.SetGray16(x, y,
   136  					color.Gray16Model.Convert(data.RGBA64At(x, y)).(color.Gray16),
   137  				)
   138  			}
   139  		}
   140  	case *image.YCbCr:
   141  		for y := 0; y < p.Height; y++ {
   142  			for x := 0; x < p.Width; x++ {
   143  				v := data.Y[data.YOffset(x, y)]
   144  				gray16.SetGray16(x, y, color.Gray16{uint16(v) << 8})
   145  			}
   146  		}
   147  	default:
   148  		for y := 0; y < p.Height; y++ {
   149  			for x := 0; x < p.Width; x++ {
   150  				gray16.Set(x, y, data.At(x, y))
   151  			}
   152  		}
   153  	}
   154  	m = gray16
   155  	return
   156  }
   157  
   158  func (p *Decoder) decodeImageGray32f(data image.Image, buf image_ext.ImageBuffer) (m draw.Image, err error) {
   159  	if b := data.Bounds(); b.Dx() != p.Width || b.Dy() != p.Height {
   160  		err = fmt.Errorf("image/raw: bad bounds: %v", data.Bounds())
   161  		return
   162  	}
   163  	if m, ok := data.(*image_ext.Gray32f); ok {
   164  		return m, nil
   165  	}
   166  	gray32f := newGray32f(image.Rect(0, 0, p.Width, p.Height), buf)
   167  	for y := 0; y < p.Height; y++ {
   168  		for x := 0; x < p.Width; x++ {
   169  			gray32f.Set(x, y, data.At(x, y))
   170  		}
   171  	}
   172  	m = gray32f
   173  	return
   174  }
   175  
   176  func (p *Decoder) decodeImageRGB(data image.Image, buf image_ext.ImageBuffer) (m draw.Image, err error) {
   177  	if b := data.Bounds(); b.Dx() != p.Width || b.Dy() != p.Height {
   178  		err = fmt.Errorf("image/raw: bad bounds: %v", data.Bounds())
   179  		return
   180  	}
   181  	if m, ok := data.(*image_ext.RGB); ok {
   182  		return m, nil
   183  	}
   184  	rgb := newRGB(image.Rect(0, 0, p.Width, p.Height), buf)
   185  	switch data := data.(type) {
   186  	case *image.Gray:
   187  		for y := 0; y < p.Height; y++ {
   188  			for x := 0; x < p.Width; x++ {
   189  				v := data.GrayAt(x, y)
   190  				rgb.SetRGB(x, y, color_ext.RGB{
   191  					R: v.Y,
   192  					G: v.Y,
   193  					B: v.Y,
   194  				})
   195  			}
   196  		}
   197  	case *image.Gray16:
   198  		for y := 0; y < p.Height; y++ {
   199  			for x := 0; x < p.Width; x++ {
   200  				v := data.Gray16At(x, y)
   201  				rgb.SetRGB(x, y, color_ext.RGB{
   202  					R: uint8(v.Y >> 8),
   203  					G: uint8(v.Y >> 8),
   204  					B: uint8(v.Y >> 8),
   205  				})
   206  			}
   207  		}
   208  	default:
   209  		for y := 0; y < p.Height; y++ {
   210  			for x := 0; x < p.Width; x++ {
   211  				rgb.Set(x, y, data.At(x, y))
   212  			}
   213  		}
   214  	}
   215  	m = rgb
   216  	return
   217  }
   218  
   219  func (p *Decoder) decodeImageRGB48(data image.Image, buf image_ext.ImageBuffer) (m draw.Image, err error) {
   220  	if b := data.Bounds(); b.Dx() != p.Width || b.Dy() != p.Height {
   221  		err = fmt.Errorf("image/raw: bad bounds: %v", data.Bounds())
   222  		return
   223  	}
   224  	if m, ok := data.(*image_ext.RGB48); ok {
   225  		return m, nil
   226  	}
   227  	rgb48 := newRGB48(image.Rect(0, 0, p.Width, p.Height), buf)
   228  	switch data := data.(type) {
   229  	case *image.Gray:
   230  		for y := 0; y < p.Height; y++ {
   231  			for x := 0; x < p.Width; x++ {
   232  				v := data.GrayAt(x, y)
   233  				rgb48.SetRGB48(x, y, color_ext.RGB48{
   234  					R: uint16(v.Y) >> 8,
   235  					G: uint16(v.Y) >> 8,
   236  					B: uint16(v.Y) >> 8,
   237  				})
   238  			}
   239  		}
   240  	case *image.Gray16:
   241  		for y := 0; y < p.Height; y++ {
   242  			for x := 0; x < p.Width; x++ {
   243  				v := data.Gray16At(x, y)
   244  				rgb48.SetRGB48(x, y, color_ext.RGB48{
   245  					R: v.Y,
   246  					G: v.Y,
   247  					B: v.Y,
   248  				})
   249  			}
   250  		}
   251  	default:
   252  		for y := 0; y < p.Height; y++ {
   253  			for x := 0; x < p.Width; x++ {
   254  				rgb48.Set(x, y, data.At(x, y))
   255  			}
   256  		}
   257  	}
   258  	m = rgb48
   259  	return
   260  }
   261  
   262  func (p *Decoder) decodeImageRGB96f(data image.Image, buf image_ext.ImageBuffer) (m draw.Image, err error) {
   263  	if b := data.Bounds(); b.Dx() != p.Width || b.Dy() != p.Height {
   264  		err = fmt.Errorf("image/raw: bad bounds: %v", data.Bounds())
   265  		return
   266  	}
   267  	if m, ok := data.(*image_ext.RGB96f); ok {
   268  		return m, nil
   269  	}
   270  	rgb96f := newRGB96f(image.Rect(0, 0, p.Width, p.Height), buf)
   271  	switch data := data.(type) {
   272  	case *image.Gray:
   273  		for y := 0; y < p.Height; y++ {
   274  			for x := 0; x < p.Width; x++ {
   275  				v := data.GrayAt(x, y)
   276  				rgb96f.SetRGB96f(x, y, color_ext.RGB96f{
   277  					R: float32(uint16(v.Y) >> 8),
   278  					G: float32(uint16(v.Y) >> 8),
   279  					B: float32(uint16(v.Y) >> 8),
   280  				})
   281  			}
   282  		}
   283  	case *image.Gray16:
   284  		for y := 0; y < p.Height; y++ {
   285  			for x := 0; x < p.Width; x++ {
   286  				v := data.Gray16At(x, y)
   287  				rgb96f.SetRGB96f(x, y, color_ext.RGB96f{
   288  					R: float32(v.Y),
   289  					G: float32(v.Y),
   290  					B: float32(v.Y),
   291  				})
   292  			}
   293  		}
   294  	default:
   295  		for y := 0; y < p.Height; y++ {
   296  			for x := 0; x < p.Width; x++ {
   297  				rgb96f.Set(x, y, data.At(x, y))
   298  			}
   299  		}
   300  	}
   301  	m = rgb96f
   302  	return
   303  }
   304  
   305  func (p *Decoder) decodeImageRGBA(data image.Image, buf image_ext.ImageBuffer) (m draw.Image, err error) {
   306  	if b := data.Bounds(); b.Dx() != p.Width || b.Dy() != p.Height {
   307  		err = fmt.Errorf("image/raw: bad bounds: %v", data.Bounds())
   308  		return
   309  	}
   310  	if m, ok := data.(*image.RGBA); ok {
   311  		return m, nil
   312  	}
   313  	rgba := newRGBA(image.Rect(0, 0, p.Width, p.Height), buf)
   314  	switch data := data.(type) {
   315  	case *image.Gray:
   316  		for y := 0; y < p.Height; y++ {
   317  			for x := 0; x < p.Width; x++ {
   318  				v := data.GrayAt(x, y)
   319  				rgba.SetRGBA(x, y, color.RGBA{
   320  					R: v.Y,
   321  					G: v.Y,
   322  					B: v.Y,
   323  					A: 0xFF,
   324  				})
   325  			}
   326  		}
   327  	case *image.Gray16:
   328  		for y := 0; y < p.Height; y++ {
   329  			for x := 0; x < p.Width; x++ {
   330  				v := data.Gray16At(x, y)
   331  				rgba.SetRGBA(x, y, color.RGBA{
   332  					R: uint8(v.Y >> 8),
   333  					G: uint8(v.Y >> 8),
   334  					B: uint8(v.Y >> 8),
   335  					A: 0xFF,
   336  				})
   337  			}
   338  		}
   339  	default:
   340  		for y := 0; y < p.Height; y++ {
   341  			for x := 0; x < p.Width; x++ {
   342  				rgba.Set(x, y, data.At(x, y))
   343  			}
   344  		}
   345  	}
   346  	m = rgba
   347  	return
   348  }
   349  
   350  func (p *Decoder) decodeImageRGBA64(data image.Image, buf image_ext.ImageBuffer) (m draw.Image, err error) {
   351  	if b := data.Bounds(); b.Dx() != p.Width || b.Dy() != p.Height {
   352  		err = fmt.Errorf("image/raw: bad bounds: %v", data.Bounds())
   353  		return
   354  	}
   355  	if m, ok := data.(*image.RGBA64); ok {
   356  		return m, nil
   357  	}
   358  	rgba64 := newRGBA64(image.Rect(0, 0, p.Width, p.Height), buf)
   359  	switch data := data.(type) {
   360  	case *image.Gray:
   361  		for y := 0; y < p.Height; y++ {
   362  			for x := 0; x < p.Width; x++ {
   363  				v := data.GrayAt(x, y)
   364  				rgba64.SetRGBA64(x, y, color.RGBA64{
   365  					R: uint16(v.Y) >> 8,
   366  					G: uint16(v.Y) >> 8,
   367  					B: uint16(v.Y) >> 8,
   368  					A: 0xFFFF,
   369  				})
   370  			}
   371  		}
   372  	case *image.Gray16:
   373  		for y := 0; y < p.Height; y++ {
   374  			for x := 0; x < p.Width; x++ {
   375  				v := data.Gray16At(x, y)
   376  				rgba64.SetRGBA64(x, y, color.RGBA64{
   377  					R: v.Y,
   378  					G: v.Y,
   379  					B: v.Y,
   380  					A: 0xFFFF,
   381  				})
   382  			}
   383  		}
   384  	case *image.RGBA:
   385  		for y := 0; y < p.Height; y++ {
   386  			for x := 0; x < p.Width; x++ {
   387  				v := data.RGBAAt(x, y)
   388  				rgba64.SetRGBA64(x, y, color.RGBA64{
   389  					R: uint16(v.R) >> 8,
   390  					G: uint16(v.G) >> 8,
   391  					B: uint16(v.B) >> 8,
   392  					A: uint16(v.A) >> 8,
   393  				})
   394  			}
   395  		}
   396  	default:
   397  		for y := 0; y < p.Height; y++ {
   398  			for x := 0; x < p.Width; x++ {
   399  				rgba64.Set(x, y, data.At(x, y))
   400  			}
   401  		}
   402  	}
   403  	m = rgba64
   404  	return
   405  }
   406  
   407  func (p *Decoder) decodeImageRGBA128f(data image.Image, buf image_ext.ImageBuffer) (m draw.Image, err error) {
   408  	if b := data.Bounds(); b.Dx() != p.Width || b.Dy() != p.Height {
   409  		err = fmt.Errorf("image/raw: bad bounds: %v", data.Bounds())
   410  		return
   411  	}
   412  	if m, ok := data.(*image_ext.RGBA128f); ok {
   413  		return m, nil
   414  	}
   415  	rgba128f := newRGBA128f(image.Rect(0, 0, p.Width, p.Height), buf)
   416  	switch data := data.(type) {
   417  	case *image.Gray:
   418  		for y := 0; y < p.Height; y++ {
   419  			for x := 0; x < p.Width; x++ {
   420  				v := data.GrayAt(x, y)
   421  				rgba128f.SetRGBA128f(x, y, color_ext.RGBA128f{
   422  					R: float32(uint16(v.Y) >> 8),
   423  					G: float32(uint16(v.Y) >> 8),
   424  					B: float32(uint16(v.Y) >> 8),
   425  					A: 0xFFFF,
   426  				})
   427  			}
   428  		}
   429  	case *image.Gray16:
   430  		for y := 0; y < p.Height; y++ {
   431  			for x := 0; x < p.Width; x++ {
   432  				v := data.Gray16At(x, y)
   433  				rgba128f.SetRGBA128f(x, y, color_ext.RGBA128f{
   434  					R: float32(v.Y),
   435  					G: float32(v.Y),
   436  					B: float32(v.Y),
   437  					A: 0xFFFF,
   438  				})
   439  			}
   440  		}
   441  	case *image.RGBA:
   442  		for y := 0; y < p.Height; y++ {
   443  			for x := 0; x < p.Width; x++ {
   444  				v := data.RGBAAt(x, y)
   445  				rgba128f.SetRGBA128f(x, y, color_ext.RGBA128f{
   446  					R: float32(uint16(v.R) >> 8),
   447  					G: float32(uint16(v.G) >> 8),
   448  					B: float32(uint16(v.B) >> 8),
   449  					A: float32(uint16(v.A) >> 8),
   450  				})
   451  			}
   452  		}
   453  	default:
   454  		for y := 0; y < p.Height; y++ {
   455  			for x := 0; x < p.Width; x++ {
   456  				rgba128f.Set(x, y, data.At(x, y))
   457  			}
   458  		}
   459  	}
   460  	m = rgba128f
   461  	return
   462  }