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 }