github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/raw/encode.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  	"reflect"
    12  
    13  	"github.com/chai2010/gopkg/builtin"
    14  	image_ext "github.com/chai2010/gopkg/image"
    15  )
    16  
    17  type Encoder struct {
    18  	Channels int          // 1/3/4
    19  	DataType reflect.Kind // Uint8/Uint16/Float32
    20  }
    21  
    22  func (p *Encoder) Encode(m image.Image, buf []byte) (data []byte, err error) {
    23  	// Gray/Gray16/Gray32f
    24  	if p.Channels == 1 && p.DataType == reflect.Uint8 {
    25  		return p.encodeGray(m, buf)
    26  	}
    27  	if p.Channels == 1 && p.DataType == reflect.Uint16 {
    28  		return p.encodeGray16(m, buf)
    29  	}
    30  	if p.Channels == 1 && p.DataType == reflect.Float32 {
    31  		return p.encodeGray32f(m, buf)
    32  	}
    33  
    34  	// RGB/RGB48/RGB96f
    35  	if p.Channels == 3 && p.DataType == reflect.Uint8 {
    36  		return p.encodeRGB(m, buf)
    37  	}
    38  	if p.Channels == 3 && p.DataType == reflect.Uint16 {
    39  		return p.encodeRGB48(m, buf)
    40  	}
    41  	if p.Channels == 3 && p.DataType == reflect.Float32 {
    42  		return p.encodeRGB96f(m, buf)
    43  	}
    44  
    45  	// RGBA/RGBA64/RGBA128f
    46  	if p.Channels == 4 && p.DataType == reflect.Uint8 {
    47  		return p.encodeRGBA(m, buf)
    48  	}
    49  	if p.Channels == 4 && p.DataType == reflect.Uint16 {
    50  		return p.encodeRGBA64(m, buf)
    51  	}
    52  	if p.Channels == 4 && p.DataType == reflect.Float32 {
    53  		return p.encodeRGBA128f(m, buf)
    54  	}
    55  
    56  	// Unknown
    57  	err = fmt.Errorf("image/raw: Encode, unknown image format, channels = %v, dataType = %v", p.Channels, p.DataType)
    58  	return
    59  }
    60  
    61  func (p *Encoder) encodeGray(m image.Image, buf []byte) (data []byte, err error) {
    62  	b := m.Bounds()
    63  	d := newBytes(b.Dx()*b.Dy(), buf)
    64  	switch m := m.(type) {
    65  	case *image.Gray:
    66  		var off = 0
    67  		for y := b.Min.Y; y < b.Max.Y; y++ {
    68  			copy(d[off:][:b.Dx()], m.Pix[y*m.Stride:])
    69  			off += b.Dx()
    70  		}
    71  	case *image.Gray16:
    72  		var off = 0
    73  		for y := b.Min.Y; y < b.Max.Y; y++ {
    74  			for x := b.Min.X; x < b.Max.X; x++ {
    75  				d[off] = uint8(m.Gray16At(x, y).Y >> 8)
    76  				off++
    77  			}
    78  		}
    79  	case *image.YCbCr:
    80  		var off = 0
    81  		for y := b.Min.Y; y < b.Max.Y; y++ {
    82  			copy(d[off:][:b.Dx()], m.Y[y*m.YStride:])
    83  			off += b.Dx()
    84  		}
    85  	default:
    86  		var off = 0
    87  		for y := b.Min.Y; y < b.Max.Y; y++ {
    88  			for x := b.Min.X; x < b.Max.X; x++ {
    89  				d[off] = color.GrayModel.Convert(m.At(x, y)).(color.Gray).Y
    90  				off++
    91  			}
    92  		}
    93  	}
    94  	data = d
    95  	return
    96  }
    97  
    98  func (p *Encoder) encodeGray16(m image.Image, buf []byte) (data []byte, err error) {
    99  	b := m.Bounds()
   100  	d := newBytes(b.Dx()*b.Dy()*2, buf)
   101  	switch m := m.(type) {
   102  	case *image.Gray:
   103  		var off = 0
   104  		for y := b.Min.Y; y < b.Max.Y; y++ {
   105  			for x := b.Min.X; x < b.Max.X; x++ {
   106  				builtin.PutUint16(d[off:], uint16(m.GrayAt(x, y).Y)<<8)
   107  				off += 2
   108  			}
   109  		}
   110  	case *image.Gray16:
   111  		var off = 0
   112  		for y := b.Min.Y; y < b.Max.Y; y++ {
   113  			for x := b.Min.X; x < b.Max.X; x++ {
   114  				v := m.Gray16At(x, y)
   115  				builtin.PutUint16(d[off:], v.Y)
   116  				off += 2
   117  			}
   118  		}
   119  	case *image.YCbCr:
   120  		var off = 0
   121  		for y := b.Min.Y; y < b.Max.Y; y++ {
   122  			for x := b.Min.X; x < b.Max.X; x++ {
   123  				v := m.YCbCrAt(x, y)
   124  				builtin.PutUint16(d[off:], uint16(v.Y)<<8)
   125  				off += 2
   126  			}
   127  		}
   128  	default:
   129  		var off = 0
   130  		for y := b.Min.Y; y < b.Max.Y; y++ {
   131  			for x := b.Min.X; x < b.Max.X; x++ {
   132  				v := color.Gray16Model.Convert(m.At(x, y)).(color.Gray16)
   133  				builtin.PutUint16(d[off:], v.Y)
   134  				off += 2
   135  			}
   136  		}
   137  	}
   138  	data = d
   139  	return
   140  }
   141  
   142  func (p *Encoder) encodeGray32f(m image.Image, buf []byte) (data []byte, err error) {
   143  	b := m.Bounds()
   144  	d := newBytes(b.Dx()*b.Dy()*4, buf)
   145  	switch m := m.(type) {
   146  	case *image.Gray:
   147  		var off = 0
   148  		for y := b.Min.Y; y < b.Max.Y; y++ {
   149  			for x := b.Min.X; x < b.Max.X; x++ {
   150  				builtin.PutFloat32(d[off:], float32(uint16(m.GrayAt(x, y).Y)<<8))
   151  				off += 4
   152  			}
   153  		}
   154  	case *image.Gray16:
   155  		var off = 0
   156  		for y := b.Min.Y; y < b.Max.Y; y++ {
   157  			for x := b.Min.X; x < b.Max.X; x++ {
   158  				v := m.Gray16At(x, y)
   159  				builtin.PutFloat32(d[off:], float32(v.Y))
   160  				off += 4
   161  			}
   162  		}
   163  	case *image_ext.Gray32f:
   164  		var off = 0
   165  		for y := b.Min.Y; y < b.Max.Y; y++ {
   166  			for x := b.Min.X; x < b.Max.X; x++ {
   167  				v := m.Gray32fAt(x, y)
   168  				builtin.PutFloat32(d[off:], v.Y)
   169  				off += 4
   170  			}
   171  		}
   172  	case *image_ext.RGB96f:
   173  		var off = 0
   174  		for y := b.Min.Y; y < b.Max.Y; y++ {
   175  			for x := b.Min.X; x < b.Max.X; x++ {
   176  				v := m.RGB96fAt(x, y)
   177  				builtin.PutFloat32(d[off:], 0.2990*v.R+0.5870*v.G+0.1140*v.B)
   178  				off += 4
   179  			}
   180  		}
   181  	case *image_ext.RGBA128f:
   182  		var off = 0
   183  		for y := b.Min.Y; y < b.Max.Y; y++ {
   184  			for x := b.Min.X; x < b.Max.X; x++ {
   185  				v := m.RGBA128fAt(x, y)
   186  				builtin.PutFloat32(d[off:], 0.2990*v.R+0.5870*v.G+0.1140*v.B)
   187  				off += 4
   188  			}
   189  		}
   190  	case *image.YCbCr:
   191  		var off = 0
   192  		for y := b.Min.Y; y < b.Max.Y; y++ {
   193  			for x := b.Min.X; x < b.Max.X; x++ {
   194  				v := m.YCbCrAt(x, y)
   195  				builtin.PutFloat32(d[off:], float32(uint16(v.Y)<<8))
   196  				off += 4
   197  			}
   198  		}
   199  	default:
   200  		var off = 0
   201  		for y := b.Min.Y; y < b.Max.Y; y++ {
   202  			for x := b.Min.X; x < b.Max.X; x++ {
   203  				v := color.Gray16Model.Convert(m.At(x, y)).(color.Gray16)
   204  				builtin.PutFloat32(d[off:], float32(v.Y))
   205  				off += 4
   206  			}
   207  		}
   208  	}
   209  	data = d
   210  	return
   211  }
   212  
   213  func (p *Encoder) encodeRGB(m image.Image, buf []byte) (data []byte, err error) {
   214  	b := m.Bounds()
   215  	d := newBytes(b.Dx()*b.Dy()*3, buf)
   216  	switch m := m.(type) {
   217  	case *image.Gray:
   218  		var off = 0
   219  		for y := b.Min.Y; y < b.Max.Y; y++ {
   220  			for x := b.Min.X; x < b.Max.X; x++ {
   221  				v := m.GrayAt(x, y)
   222  				d[off+0] = v.Y
   223  				d[off+1] = v.Y
   224  				d[off+2] = v.Y
   225  				off += 3
   226  			}
   227  		}
   228  	case *image.Gray16:
   229  		var off = 0
   230  		for y := b.Min.Y; y < b.Max.Y; y++ {
   231  			for x := b.Min.X; x < b.Max.X; x++ {
   232  				v := m.Gray16At(x, y)
   233  				d[off+0] = uint8(v.Y >> 8)
   234  				d[off+1] = uint8(v.Y >> 8)
   235  				d[off+2] = uint8(v.Y >> 8)
   236  				off += 3
   237  			}
   238  		}
   239  	case *image_ext.RGB:
   240  		var off = 0
   241  		for y := b.Min.Y; y < b.Max.Y; y++ {
   242  			copy(d[off:][:b.Dx()*3], m.Pix[y*m.Stride:])
   243  			off += b.Dx() * 3
   244  		}
   245  	case *image.RGBA:
   246  		var off = 0
   247  		for y := b.Min.Y; y < b.Max.Y; y++ {
   248  			for x := b.Min.X; x < b.Max.X; x++ {
   249  				v := m.RGBAAt(x, y)
   250  				d[off+0] = v.R
   251  				d[off+1] = v.G
   252  				d[off+2] = v.B
   253  				off += 3
   254  			}
   255  		}
   256  	case *image.YCbCr:
   257  		var off = 0
   258  		for y := b.Min.Y; y < b.Max.Y; y++ {
   259  			for x := b.Min.X; x < b.Max.X; x++ {
   260  				v := m.YCbCrAt(x, y)
   261  				R, G, B := color.YCbCrToRGB(v.Y, v.Cb, v.Cr)
   262  				d[off+0] = R
   263  				d[off+1] = G
   264  				d[off+2] = B
   265  				off += 3
   266  			}
   267  		}
   268  	default:
   269  		var off = 0
   270  		for y := b.Min.Y; y < b.Max.Y; y++ {
   271  			for x := b.Min.X; x < b.Max.X; x++ {
   272  				v := color.RGBAModel.Convert(m.At(x, y)).(color.RGBA)
   273  				d[off+0] = v.R
   274  				d[off+1] = v.G
   275  				d[off+2] = v.B
   276  				off += 3
   277  			}
   278  		}
   279  	}
   280  	data = d
   281  	return
   282  }
   283  
   284  func (p *Encoder) encodeRGB48(m image.Image, buf []byte) (data []byte, err error) {
   285  	b := m.Bounds()
   286  	d := newBytes(b.Dx()*b.Dy()*6, buf)
   287  	switch m := m.(type) {
   288  	case *image.Gray:
   289  		var off = 0
   290  		for y := b.Min.Y; y < b.Max.Y; y++ {
   291  			for x := b.Min.X; x < b.Max.X; x++ {
   292  				v := m.GrayAt(x, y)
   293  				builtin.PutUint16(d[off+0:], uint16(v.Y)<<8)
   294  				builtin.PutUint16(d[off+2:], uint16(v.Y)<<8)
   295  				builtin.PutUint16(d[off+4:], uint16(v.Y)<<8)
   296  				off += 6
   297  			}
   298  		}
   299  	case *image.Gray16:
   300  		var off = 0
   301  		for y := b.Min.Y; y < b.Max.Y; y++ {
   302  			for x := b.Min.X; x < b.Max.X; x++ {
   303  				v := m.Gray16At(x, y)
   304  				builtin.PutUint16(d[off+0:], v.Y)
   305  				builtin.PutUint16(d[off+2:], v.Y)
   306  				builtin.PutUint16(d[off+4:], v.Y)
   307  				off += 6
   308  			}
   309  		}
   310  	case *image_ext.RGB:
   311  		var off = 0
   312  		for y := b.Min.Y; y < b.Max.Y; y++ {
   313  			for x := b.Min.X; x < b.Max.X; x++ {
   314  				v := m.RGBAt(x, y)
   315  				builtin.PutUint16(d[off+0:], uint16(v.R)<<8)
   316  				builtin.PutUint16(d[off+2:], uint16(v.G)<<8)
   317  				builtin.PutUint16(d[off+4:], uint16(v.B)<<8)
   318  				off += 6
   319  			}
   320  		}
   321  	case *image.RGBA:
   322  		var off = 0
   323  		for y := b.Min.Y; y < b.Max.Y; y++ {
   324  			for x := b.Min.X; x < b.Max.X; x++ {
   325  				v := m.RGBAAt(x, y)
   326  				builtin.PutUint16(d[off+0:], uint16(v.R)<<8)
   327  				builtin.PutUint16(d[off+2:], uint16(v.G)<<8)
   328  				builtin.PutUint16(d[off+4:], uint16(v.B)<<8)
   329  				off += 6
   330  			}
   331  		}
   332  	case *image_ext.RGB48:
   333  		var off = 0
   334  		for y := b.Min.Y; y < b.Max.Y; y++ {
   335  			for x := b.Min.X; x < b.Max.X; x++ {
   336  				v := m.RGB48At(x, y)
   337  				builtin.PutUint16(d[off+0:], v.R)
   338  				builtin.PutUint16(d[off+2:], v.G)
   339  				builtin.PutUint16(d[off+4:], v.B)
   340  				off += 6
   341  			}
   342  		}
   343  	case *image.RGBA64:
   344  		var off = 0
   345  		for y := b.Min.Y; y < b.Max.Y; y++ {
   346  			for x := b.Min.X; x < b.Max.X; x++ {
   347  				v := m.RGBA64At(x, y)
   348  				builtin.PutUint16(d[off+0:], v.R)
   349  				builtin.PutUint16(d[off+2:], v.G)
   350  				builtin.PutUint16(d[off+4:], v.B)
   351  				off += 6
   352  			}
   353  		}
   354  	case *image.YCbCr:
   355  		var off = 0
   356  		for y := b.Min.Y; y < b.Max.Y; y++ {
   357  			for x := b.Min.X; x < b.Max.X; x++ {
   358  				v := m.YCbCrAt(x, y)
   359  				R, G, B := color.YCbCrToRGB(v.Y, v.Cb, v.Cr)
   360  				builtin.PutUint16(d[off+0:], uint16(R)<<8)
   361  				builtin.PutUint16(d[off+2:], uint16(G)<<8)
   362  				builtin.PutUint16(d[off+4:], uint16(B)<<8)
   363  				off += 6
   364  			}
   365  		}
   366  	default:
   367  		var off = 0
   368  		for y := b.Min.Y; y < b.Max.Y; y++ {
   369  			for x := b.Min.X; x < b.Max.X; x++ {
   370  				v := color.RGBA64Model.Convert(m.At(x, y)).(color.RGBA64)
   371  				builtin.PutUint16(d[off+0:], v.R)
   372  				builtin.PutUint16(d[off+2:], v.G)
   373  				builtin.PutUint16(d[off+4:], v.B)
   374  				off += 6
   375  			}
   376  		}
   377  	}
   378  	data = d
   379  	return
   380  }
   381  
   382  func (p *Encoder) encodeRGB96f(m image.Image, buf []byte) (data []byte, err error) {
   383  	b := m.Bounds()
   384  	d := newBytes(b.Dx()*b.Dy()*12, buf)
   385  	switch m := m.(type) {
   386  	case *image.Gray:
   387  		var off = 0
   388  		for y := b.Min.Y; y < b.Max.Y; y++ {
   389  			for x := b.Min.X; x < b.Max.X; x++ {
   390  				v := m.GrayAt(x, y)
   391  				builtin.PutFloat32(d[off+0:], float32(uint16(v.Y)<<8))
   392  				builtin.PutFloat32(d[off+4:], float32(uint16(v.Y)<<8))
   393  				builtin.PutFloat32(d[off+8:], float32(uint16(v.Y)<<8))
   394  				off += 12
   395  			}
   396  		}
   397  	case *image.Gray16:
   398  		var off = 0
   399  		for y := b.Min.Y; y < b.Max.Y; y++ {
   400  			for x := b.Min.X; x < b.Max.X; x++ {
   401  				v := m.Gray16At(x, y)
   402  				builtin.PutFloat32(d[off+0:], float32(v.Y))
   403  				builtin.PutFloat32(d[off+4:], float32(v.Y))
   404  				builtin.PutFloat32(d[off+8:], float32(v.Y))
   405  				off += 12
   406  			}
   407  		}
   408  	case *image_ext.Gray32f:
   409  		var off = 0
   410  		for y := b.Min.Y; y < b.Max.Y; y++ {
   411  			for x := b.Min.X; x < b.Max.X; x++ {
   412  				v := m.Gray32fAt(x, y)
   413  				builtin.PutFloat32(d[off+0:], v.Y)
   414  				builtin.PutFloat32(d[off+4:], v.Y)
   415  				builtin.PutFloat32(d[off+8:], v.Y)
   416  				off += 12
   417  			}
   418  		}
   419  	case *image_ext.RGB:
   420  		var off = 0
   421  		for y := b.Min.Y; y < b.Max.Y; y++ {
   422  			for x := b.Min.X; x < b.Max.X; x++ {
   423  				v := m.RGBAt(x, y)
   424  				builtin.PutFloat32(d[off+0:], float32(uint16(v.R)<<8))
   425  				builtin.PutFloat32(d[off+4:], float32(uint16(v.G)<<8))
   426  				builtin.PutFloat32(d[off+8:], float32(uint16(v.B)<<8))
   427  				off += 12
   428  			}
   429  		}
   430  	case *image.RGBA:
   431  		var off = 0
   432  		for y := b.Min.Y; y < b.Max.Y; y++ {
   433  			for x := b.Min.X; x < b.Max.X; x++ {
   434  				v := m.RGBAAt(x, y)
   435  				builtin.PutFloat32(d[off+0:], float32(uint16(v.R)<<8))
   436  				builtin.PutFloat32(d[off+4:], float32(uint16(v.G)<<8))
   437  				builtin.PutFloat32(d[off+8:], float32(uint16(v.B)<<8))
   438  				off += 12
   439  			}
   440  		}
   441  	case *image.RGBA64:
   442  		var off = 0
   443  		for y := b.Min.Y; y < b.Max.Y; y++ {
   444  			for x := b.Min.X; x < b.Max.X; x++ {
   445  				v := m.RGBA64At(x, y)
   446  				builtin.PutFloat32(d[off+0:], float32(v.R))
   447  				builtin.PutFloat32(d[off+4:], float32(v.G))
   448  				builtin.PutFloat32(d[off+8:], float32(v.B))
   449  				off += 12
   450  			}
   451  		}
   452  	case *image_ext.RGB96f:
   453  		var off = 0
   454  		for y := b.Min.Y; y < b.Max.Y; y++ {
   455  			for x := b.Min.X; x < b.Max.X; x++ {
   456  				v := m.RGB96fAt(x, y)
   457  				builtin.PutFloat32(d[off+0:], v.R)
   458  				builtin.PutFloat32(d[off+4:], v.G)
   459  				builtin.PutFloat32(d[off+8:], v.B)
   460  				off += 12
   461  			}
   462  		}
   463  	case *image_ext.RGBA128f:
   464  		var off = 0
   465  		for y := b.Min.Y; y < b.Max.Y; y++ {
   466  			for x := b.Min.X; x < b.Max.X; x++ {
   467  				v := m.RGBA128fAt(x, y)
   468  				builtin.PutFloat32(d[off+0:], v.R)
   469  				builtin.PutFloat32(d[off+4:], v.G)
   470  				builtin.PutFloat32(d[off+8:], v.B)
   471  				off += 12
   472  			}
   473  		}
   474  	case *image.YCbCr:
   475  		var off = 0
   476  		for y := b.Min.Y; y < b.Max.Y; y++ {
   477  			for x := b.Min.X; x < b.Max.X; x++ {
   478  				v := m.YCbCrAt(x, y)
   479  				R, G, B := color.YCbCrToRGB(v.Y, v.Cb, v.Cr)
   480  				builtin.PutFloat32(d[off+0:], float32(uint16(R)<<8))
   481  				builtin.PutFloat32(d[off+4:], float32(uint16(G)<<8))
   482  				builtin.PutFloat32(d[off+8:], float32(uint16(B)<<8))
   483  				off += 12
   484  			}
   485  		}
   486  	default:
   487  		var off = 0
   488  		for y := b.Min.Y; y < b.Max.Y; y++ {
   489  			for x := b.Min.X; x < b.Max.X; x++ {
   490  				v := color.RGBA64Model.Convert(m.At(x, y)).(color.RGBA64)
   491  				builtin.PutFloat32(d[off+0:], float32(v.R))
   492  				builtin.PutFloat32(d[off+4:], float32(v.G))
   493  				builtin.PutFloat32(d[off+8:], float32(v.B))
   494  				off += 12
   495  			}
   496  		}
   497  	}
   498  	data = d
   499  	return
   500  }
   501  
   502  func (p *Encoder) encodeRGBA(m image.Image, buf []byte) (data []byte, err error) {
   503  	b := m.Bounds()
   504  	d := newBytes(b.Dx()*b.Dy()*4, buf)
   505  	switch m := m.(type) {
   506  	case *image.Gray:
   507  		var off = 0
   508  		for y := b.Min.Y; y < b.Max.Y; y++ {
   509  			for x := b.Min.X; x < b.Max.X; x++ {
   510  				v := m.GrayAt(x, y)
   511  				d[off+0] = v.Y
   512  				d[off+1] = v.Y
   513  				d[off+2] = v.Y
   514  				d[off+3] = 0xFF
   515  				off += 4
   516  			}
   517  		}
   518  	case *image.Gray16:
   519  		var off = 0
   520  		for y := b.Min.Y; y < b.Max.Y; y++ {
   521  			for x := b.Min.X; x < b.Max.X; x++ {
   522  				v := m.Gray16At(x, y)
   523  				d[off+0] = uint8(v.Y >> 8)
   524  				d[off+1] = uint8(v.Y >> 8)
   525  				d[off+2] = uint8(v.Y >> 8)
   526  				d[off+3] = 0xFF
   527  				off += 4
   528  			}
   529  		}
   530  	case *image_ext.RGB:
   531  		var off = 0
   532  		for y := b.Min.Y; y < b.Max.Y; y++ {
   533  			for x := b.Min.X; x < b.Max.X; x++ {
   534  				v := m.RGBAt(x, y)
   535  				d[off+0] = uint8(v.R >> 8)
   536  				d[off+1] = uint8(v.G >> 8)
   537  				d[off+2] = uint8(v.B >> 8)
   538  				d[off+3] = 0xFF
   539  				off += 4
   540  			}
   541  		}
   542  	case *image.RGBA:
   543  		var off = 0
   544  		for y := 0; y < b.Max.Y-b.Min.Y; y++ {
   545  			copy(d[off:][:b.Dx()*4], m.Pix[y*m.Stride:])
   546  			off += b.Dx() * 4
   547  		}
   548  	case *image_ext.RGB48:
   549  		var off = 0
   550  		for y := b.Min.Y; y < b.Max.Y; y++ {
   551  			for x := b.Min.X; x < b.Max.X; x++ {
   552  				v := m.RGB48At(x, y)
   553  				d[off+0] = uint8(v.R >> 8)
   554  				d[off+1] = uint8(v.G >> 8)
   555  				d[off+2] = uint8(v.B >> 8)
   556  				d[off+3] = 0xFF
   557  				off += 4
   558  			}
   559  		}
   560  	case *image.RGBA64:
   561  		var off = 0
   562  		for y := b.Min.Y; y < b.Max.Y; y++ {
   563  			for x := b.Min.X; x < b.Max.X; x++ {
   564  				v := m.RGBA64At(x, y)
   565  				d[off+0] = uint8(v.R >> 8)
   566  				d[off+1] = uint8(v.G >> 8)
   567  				d[off+2] = uint8(v.B >> 8)
   568  				d[off+3] = uint8(v.A >> 8)
   569  				off += 4
   570  			}
   571  		}
   572  	case *image.YCbCr:
   573  		var off = 0
   574  		for y := b.Min.Y; y < b.Max.Y; y++ {
   575  			for x := b.Min.X; x < b.Max.X; x++ {
   576  				v := m.YCbCrAt(x, y)
   577  				R, G, B := color.YCbCrToRGB(v.Y, v.Cb, v.Cr)
   578  				d[off+0] = R
   579  				d[off+1] = G
   580  				d[off+2] = B
   581  				d[off+3] = 0xFF
   582  				off += 4
   583  			}
   584  		}
   585  	default:
   586  		var off = 0
   587  		for y := b.Min.Y; y < b.Max.Y; y++ {
   588  			for x := b.Min.X; x < b.Max.X; x++ {
   589  				v := color.RGBAModel.Convert(m.At(x, y)).(color.RGBA)
   590  				d[off+0] = v.R
   591  				d[off+1] = v.G
   592  				d[off+2] = v.B
   593  				d[off+3] = v.A
   594  				off += 4
   595  			}
   596  		}
   597  	}
   598  	data = d
   599  	return
   600  }
   601  
   602  func (p *Encoder) encodeRGBA64(m image.Image, buf []byte) (data []byte, err error) {
   603  	b := m.Bounds()
   604  	d := newBytes(b.Dx()*b.Dy()*8, buf)
   605  	switch m := m.(type) {
   606  	case *image.Gray:
   607  		var off = 0
   608  		for y := b.Min.Y; y < b.Max.Y; y++ {
   609  			for x := b.Min.X; x < b.Max.X; x++ {
   610  				v := m.GrayAt(x, y)
   611  				builtin.PutUint16(d[off+0:], uint16(v.Y)<<8)
   612  				builtin.PutUint16(d[off+2:], uint16(v.Y)<<8)
   613  				builtin.PutUint16(d[off+4:], uint16(v.Y)<<8)
   614  				builtin.PutUint16(d[off+6:], 0xFFFF)
   615  				off += 8
   616  			}
   617  		}
   618  	case *image.Gray16:
   619  		var off = 0
   620  		for y := b.Min.Y; y < b.Max.Y; y++ {
   621  			for x := b.Min.X; x < b.Max.X; x++ {
   622  				v := m.Gray16At(x, y)
   623  				builtin.PutUint16(d[off+0:], v.Y)
   624  				builtin.PutUint16(d[off+2:], v.Y)
   625  				builtin.PutUint16(d[off+4:], v.Y)
   626  				builtin.PutUint16(d[off+6:], 0xFFFF)
   627  				off += 8
   628  			}
   629  		}
   630  	case *image_ext.RGB:
   631  		var off = 0
   632  		for y := b.Min.Y; y < b.Max.Y; y++ {
   633  			for x := b.Min.X; x < b.Max.X; x++ {
   634  				v := m.RGBAt(x, y)
   635  				builtin.PutUint16(d[off+0:], uint16(v.R)<<8)
   636  				builtin.PutUint16(d[off+2:], uint16(v.G)<<8)
   637  				builtin.PutUint16(d[off+4:], uint16(v.B)<<8)
   638  				builtin.PutUint16(d[off+6:], 0xFFFF)
   639  				off += 8
   640  			}
   641  		}
   642  	case *image_ext.RGB48:
   643  		var off = 0
   644  		for y := b.Min.Y; y < b.Max.Y; y++ {
   645  			for x := b.Min.X; x < b.Max.X; x++ {
   646  				v := m.RGB48At(x, y)
   647  				builtin.PutUint16(d[off+0:], v.R)
   648  				builtin.PutUint16(d[off+2:], v.G)
   649  				builtin.PutUint16(d[off+4:], v.B)
   650  				builtin.PutUint16(d[off+6:], 0xFFFF)
   651  				off += 8
   652  			}
   653  		}
   654  	case *image.RGBA:
   655  		var off = 0
   656  		for y := b.Min.Y; y < b.Max.Y; y++ {
   657  			for x := b.Min.X; x < b.Max.X; x++ {
   658  				v := m.RGBAAt(x, y)
   659  				builtin.PutUint16(d[off+0:], uint16(v.R)<<8)
   660  				builtin.PutUint16(d[off+2:], uint16(v.G)<<8)
   661  				builtin.PutUint16(d[off+4:], uint16(v.B)<<8)
   662  				builtin.PutUint16(d[off+6:], uint16(v.A)<<8)
   663  				off += 8
   664  			}
   665  		}
   666  	case *image.RGBA64:
   667  		var off = 0
   668  		for y := b.Min.Y; y < b.Max.Y; y++ {
   669  			for x := b.Min.X; x < b.Max.X; x++ {
   670  				v := m.RGBA64At(x, y)
   671  				builtin.PutUint16(d[off+0:], v.R)
   672  				builtin.PutUint16(d[off+2:], v.G)
   673  				builtin.PutUint16(d[off+4:], v.B)
   674  				builtin.PutUint16(d[off+6:], v.A)
   675  				off += 8
   676  			}
   677  		}
   678  	case *image.YCbCr:
   679  		var off = 0
   680  		for y := b.Min.Y; y < b.Max.Y; y++ {
   681  			for x := b.Min.X; x < b.Max.X; x++ {
   682  				v := m.YCbCrAt(x, y)
   683  				R, G, B := color.YCbCrToRGB(v.Y, v.Cb, v.Cr)
   684  				builtin.PutUint16(d[off+0:], uint16(R)<<8)
   685  				builtin.PutUint16(d[off+2:], uint16(G)<<8)
   686  				builtin.PutUint16(d[off+4:], uint16(B)<<8)
   687  				builtin.PutUint16(d[off+6:], 0xFFFF)
   688  				off += 8
   689  			}
   690  		}
   691  	default:
   692  		var off = 0
   693  		for y := b.Min.Y; y < b.Max.Y; y++ {
   694  			for x := b.Min.X; x < b.Max.X; x++ {
   695  				v := color.RGBA64Model.Convert(m.At(x, y)).(color.RGBA64)
   696  				builtin.PutUint16(d[off+0:], v.R)
   697  				builtin.PutUint16(d[off+2:], v.G)
   698  				builtin.PutUint16(d[off+4:], v.B)
   699  				builtin.PutUint16(d[off+6:], v.A)
   700  				off += 8
   701  			}
   702  		}
   703  	}
   704  	data = d
   705  	return
   706  }
   707  
   708  func (p *Encoder) encodeRGBA128f(m image.Image, buf []byte) (data []byte, err error) {
   709  	b := m.Bounds()
   710  	d := newBytes(b.Dx()*b.Dy()*16, buf)
   711  	switch m := m.(type) {
   712  	case *image.Gray:
   713  		var off = 0
   714  		for y := b.Min.Y; y < b.Max.Y; y++ {
   715  			for x := b.Min.X; x < b.Max.X; x++ {
   716  				v := m.GrayAt(x, y)
   717  				builtin.PutFloat32(d[off+0:], float32(uint16(v.Y)<<8))
   718  				builtin.PutFloat32(d[off+4:], float32(uint16(v.Y)<<8))
   719  				builtin.PutFloat32(d[off+8:], float32(uint16(v.Y)<<8))
   720  				builtin.PutFloat32(d[off+12:], 0xFFFF)
   721  				off += 16
   722  			}
   723  		}
   724  	case *image.Gray16:
   725  		var off = 0
   726  		for y := b.Min.Y; y < b.Max.Y; y++ {
   727  			for x := b.Min.X; x < b.Max.X; x++ {
   728  				v := m.Gray16At(x, y)
   729  				builtin.PutFloat32(d[off+0:], float32(v.Y))
   730  				builtin.PutFloat32(d[off+4:], float32(v.Y))
   731  				builtin.PutFloat32(d[off+8:], float32(v.Y))
   732  				builtin.PutFloat32(d[off+12:], 0xFFFF)
   733  				off += 16
   734  			}
   735  		}
   736  	case *image_ext.Gray32f:
   737  		var off = 0
   738  		for y := b.Min.Y; y < b.Max.Y; y++ {
   739  			for x := b.Min.X; x < b.Max.X; x++ {
   740  				v := m.Gray32fAt(x, y)
   741  				builtin.PutFloat32(d[off+0:], v.Y)
   742  				builtin.PutFloat32(d[off+4:], v.Y)
   743  				builtin.PutFloat32(d[off+8:], v.Y)
   744  				builtin.PutFloat32(d[off+12:], 0xFFFF)
   745  				off += 16
   746  			}
   747  		}
   748  	case *image_ext.RGB:
   749  		var off = 0
   750  		for y := b.Min.Y; y < b.Max.Y; y++ {
   751  			for x := b.Min.X; x < b.Max.X; x++ {
   752  				v := m.RGBAt(x, y)
   753  				builtin.PutFloat32(d[off+0:], float32(uint16(v.R)<<8))
   754  				builtin.PutFloat32(d[off+4:], float32(uint16(v.G)<<8))
   755  				builtin.PutFloat32(d[off+8:], float32(uint16(v.B)<<8))
   756  				builtin.PutFloat32(d[off+12:], 0xFFFF)
   757  				off += 16
   758  			}
   759  		}
   760  	case *image_ext.RGB48:
   761  		var off = 0
   762  		for y := b.Min.Y; y < b.Max.Y; y++ {
   763  			for x := b.Min.X; x < b.Max.X; x++ {
   764  				v := m.RGB48At(x, y)
   765  				builtin.PutFloat32(d[off+0:], float32(v.R))
   766  				builtin.PutFloat32(d[off+4:], float32(v.G))
   767  				builtin.PutFloat32(d[off+8:], float32(v.B))
   768  				builtin.PutFloat32(d[off+12:], 0xFFFF)
   769  				off += 16
   770  			}
   771  		}
   772  	case *image_ext.RGB96f:
   773  		var off = 0
   774  		for y := b.Min.Y; y < b.Max.Y; y++ {
   775  			for x := b.Min.X; x < b.Max.X; x++ {
   776  				v := m.RGB96fAt(x, y)
   777  				builtin.PutFloat32(d[off+0:], v.R)
   778  				builtin.PutFloat32(d[off+4:], v.G)
   779  				builtin.PutFloat32(d[off+8:], v.B)
   780  				builtin.PutFloat32(d[off+12:], 0xFFFF)
   781  				off += 16
   782  			}
   783  		}
   784  	case *image.RGBA:
   785  		var off = 0
   786  		for y := b.Min.Y; y < b.Max.Y; y++ {
   787  			for x := b.Min.X; x < b.Max.X; x++ {
   788  				v := m.RGBAAt(x, y)
   789  				builtin.PutFloat32(d[off+0:], float32(uint16(v.R)<<8))
   790  				builtin.PutFloat32(d[off+4:], float32(uint16(v.G)<<8))
   791  				builtin.PutFloat32(d[off+8:], float32(uint16(v.B)<<8))
   792  				builtin.PutFloat32(d[off+12:], float32(uint16(v.A)<<8))
   793  				off += 16
   794  			}
   795  		}
   796  	case *image.RGBA64:
   797  		var off = 0
   798  		for y := b.Min.Y; y < b.Max.Y; y++ {
   799  			for x := b.Min.X; x < b.Max.X; x++ {
   800  				v := m.RGBA64At(x, y)
   801  				builtin.PutFloat32(d[off+0:], float32(v.R))
   802  				builtin.PutFloat32(d[off+4:], float32(v.G))
   803  				builtin.PutFloat32(d[off+8:], float32(v.B))
   804  				builtin.PutFloat32(d[off+12:], float32(v.A))
   805  				off += 16
   806  			}
   807  		}
   808  	case *image_ext.RGBA128f:
   809  		var off = 0
   810  		for y := b.Min.Y; y < b.Max.Y; y++ {
   811  			for x := b.Min.X; x < b.Max.X; x++ {
   812  				v := m.RGBA128fAt(x, y)
   813  				builtin.PutFloat32(d[off+0:], v.R)
   814  				builtin.PutFloat32(d[off+4:], v.G)
   815  				builtin.PutFloat32(d[off+8:], v.B)
   816  				builtin.PutFloat32(d[off+12:], v.A)
   817  				off += 16
   818  			}
   819  		}
   820  	case *image.YCbCr:
   821  		var off = 0
   822  		for y := b.Min.Y; y < b.Max.Y; y++ {
   823  			for x := b.Min.X; x < b.Max.X; x++ {
   824  				v := m.YCbCrAt(x, y)
   825  				R, G, B := color.YCbCrToRGB(v.Y, v.Cb, v.Cr)
   826  				builtin.PutFloat32(d[off+0:], float32(uint16(R)<<8))
   827  				builtin.PutFloat32(d[off+4:], float32(uint16(G)<<8))
   828  				builtin.PutFloat32(d[off+8:], float32(uint16(B)<<8))
   829  				builtin.PutFloat32(d[off+12:], 0xFFFF)
   830  				off += 16
   831  			}
   832  		}
   833  	default:
   834  		var off = 0
   835  		for y := b.Min.Y; y < b.Max.Y; y++ {
   836  			for x := b.Min.X; x < b.Max.X; x++ {
   837  				v := color.RGBA64Model.Convert(m.At(x, y)).(color.RGBA64)
   838  				builtin.PutFloat32(d[off+0:], float32(v.R))
   839  				builtin.PutFloat32(d[off+4:], float32(v.G))
   840  				builtin.PutFloat32(d[off+8:], float32(v.B))
   841  				builtin.PutFloat32(d[off+12:], float32(v.A))
   842  				off += 16
   843  			}
   844  		}
   845  	}
   846  	data = d
   847  	return
   848  }