tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/image/jpeg/writer.go (about) 1 // Copyright 2011 The Go Authors. 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 jpeg 6 7 import ( 8 "bufio" 9 "errors" 10 "image" 11 "image/color" 12 "io" 13 ) 14 15 // min returns the minimum of two integers. 16 func min(x, y int) int { 17 if x < y { 18 return x 19 } 20 return y 21 } 22 23 // div returns a/b rounded to the nearest integer, instead of rounded to zero. 24 func div(a, b int32) int32 { 25 if a >= 0 { 26 return (a + (b >> 1)) / b 27 } 28 return -((-a + (b >> 1)) / b) 29 } 30 31 // bitCount counts the number of bits needed to hold an integer. 32 var bitCount = [256]byte{ 33 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 34 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 35 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 36 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 37 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 38 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 39 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 41 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 42 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 43 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 44 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 45 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 46 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 47 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 48 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 49 } 50 51 type quantIndex int 52 53 const ( 54 quantIndexLuminance quantIndex = iota 55 quantIndexChrominance 56 nQuantIndex 57 ) 58 59 // unscaledQuant are the unscaled quantization tables in zig-zag order. Each 60 // encoder copies and scales the tables according to its quality parameter. 61 // The values are derived from section K.1 after converting from natural to 62 // zig-zag order. 63 var unscaledQuant = [nQuantIndex][blockSize]byte{ 64 // Luminance. 65 { 66 16, 11, 12, 14, 12, 10, 16, 14, 67 13, 14, 18, 17, 16, 19, 24, 40, 68 26, 24, 22, 22, 24, 49, 35, 37, 69 29, 40, 58, 51, 61, 60, 57, 51, 70 56, 55, 64, 72, 92, 78, 64, 68, 71 87, 69, 55, 56, 80, 109, 81, 87, 72 95, 98, 103, 104, 103, 62, 77, 113, 73 121, 112, 100, 120, 92, 101, 103, 99, 74 }, 75 // Chrominance. 76 { 77 17, 18, 18, 24, 21, 24, 47, 26, 78 26, 47, 99, 66, 56, 66, 99, 99, 79 99, 99, 99, 99, 99, 99, 99, 99, 80 99, 99, 99, 99, 99, 99, 99, 99, 81 99, 99, 99, 99, 99, 99, 99, 99, 82 99, 99, 99, 99, 99, 99, 99, 99, 83 99, 99, 99, 99, 99, 99, 99, 99, 84 99, 99, 99, 99, 99, 99, 99, 99, 85 }, 86 } 87 88 type huffIndex int 89 90 const ( 91 huffIndexLuminanceDC huffIndex = iota 92 huffIndexLuminanceAC 93 huffIndexChrominanceDC 94 huffIndexChrominanceAC 95 nHuffIndex 96 ) 97 98 // huffmanSpec specifies a Huffman encoding. 99 type huffmanSpec struct { 100 // count[i] is the number of codes of length i bits. 101 count [16]byte 102 // value[i] is the decoded value of the i'th codeword. 103 value []byte 104 } 105 106 // theHuffmanSpec is the Huffman encoding specifications. 107 // This encoder uses the same Huffman encoding for all images. 108 var theHuffmanSpec = [nHuffIndex]huffmanSpec{ 109 // Luminance DC. 110 { 111 [16]byte{0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, 112 []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 113 }, 114 // Luminance AC. 115 { 116 [16]byte{0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125}, 117 []byte{ 118 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 119 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 120 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 121 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 122 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 123 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 124 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 125 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 126 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 127 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 128 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 129 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 130 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 131 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 132 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 133 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 134 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 135 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 136 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 137 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 138 0xf9, 0xfa, 139 }, 140 }, 141 // Chrominance DC. 142 { 143 [16]byte{0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0}, 144 []byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 145 }, 146 // Chrominance AC. 147 { 148 [16]byte{0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119}, 149 []byte{ 150 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 151 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 152 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 153 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 154 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 155 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 156 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 157 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 158 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 159 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 160 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 161 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 162 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 163 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 164 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 165 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 166 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 167 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 168 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 169 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 170 0xf9, 0xfa, 171 }, 172 }, 173 } 174 175 // huffmanLUT is a compiled look-up table representation of a huffmanSpec. 176 // Each value maps to a uint32 of which the 8 most significant bits hold the 177 // codeword size in bits and the 24 least significant bits hold the codeword. 178 // The maximum codeword size is 16 bits. 179 type huffmanLUT []uint32 180 181 func (h *huffmanLUT) init(s huffmanSpec) { 182 maxValue := 0 183 for _, v := range s.value { 184 if int(v) > maxValue { 185 maxValue = int(v) 186 } 187 } 188 *h = make([]uint32, maxValue+1) 189 code, k := uint32(0), 0 190 for i := 0; i < len(s.count); i++ { 191 nBits := uint32(i+1) << 24 192 for j := uint8(0); j < s.count[i]; j++ { 193 (*h)[s.value[k]] = nBits | code 194 code++ 195 k++ 196 } 197 code <<= 1 198 } 199 } 200 201 // theHuffmanLUT are compiled representations of theHuffmanSpec. 202 var theHuffmanLUT [4]huffmanLUT 203 204 func init() { 205 for i, s := range theHuffmanSpec { 206 theHuffmanLUT[i].init(s) 207 } 208 } 209 210 // writer is a buffered writer. 211 type writer interface { 212 Flush() error 213 io.Writer 214 io.ByteWriter 215 } 216 217 // encoder encodes an image to the JPEG format. 218 type encoder struct { 219 // w is the writer to write to. err is the first error encountered during 220 // writing. All attempted writes after the first error become no-ops. 221 w writer 222 err error 223 // buf is a scratch buffer. 224 buf [16]byte 225 // bits and nBits are accumulated bits to write to w. 226 bits, nBits uint32 227 // quant is the scaled quantization tables, in zig-zag order. 228 quant [nQuantIndex][blockSize]byte 229 } 230 231 func (e *encoder) flush() { 232 if e.err != nil { 233 return 234 } 235 e.err = e.w.Flush() 236 } 237 238 func (e *encoder) write(p []byte) { 239 if e.err != nil { 240 return 241 } 242 _, e.err = e.w.Write(p) 243 } 244 245 func (e *encoder) writeByte(b byte) { 246 if e.err != nil { 247 return 248 } 249 e.err = e.w.WriteByte(b) 250 } 251 252 // emit emits the least significant nBits bits of bits to the bit-stream. 253 // The precondition is bits < 1<<nBits && nBits <= 16. 254 func (e *encoder) emit(bits, nBits uint32) { 255 nBits += e.nBits 256 bits <<= 32 - nBits 257 bits |= e.bits 258 for nBits >= 8 { 259 b := uint8(bits >> 24) 260 e.writeByte(b) 261 if b == 0xff { 262 e.writeByte(0x00) 263 } 264 bits <<= 8 265 nBits -= 8 266 } 267 e.bits, e.nBits = bits, nBits 268 } 269 270 // emitHuff emits the given value with the given Huffman encoder. 271 func (e *encoder) emitHuff(h huffIndex, value int32) { 272 x := theHuffmanLUT[h][value] 273 e.emit(x&(1<<24-1), x>>24) 274 } 275 276 // emitHuffRLE emits a run of runLength copies of value encoded with the given 277 // Huffman encoder. 278 func (e *encoder) emitHuffRLE(h huffIndex, runLength, value int32) { 279 a, b := value, value 280 if a < 0 { 281 a, b = -value, value-1 282 } 283 var nBits uint32 284 if a < 0x100 { 285 nBits = uint32(bitCount[a]) 286 } else { 287 nBits = 8 + uint32(bitCount[a>>8]) 288 } 289 e.emitHuff(h, runLength<<4|int32(nBits)) 290 if nBits > 0 { 291 e.emit(uint32(b)&(1<<nBits-1), nBits) 292 } 293 } 294 295 // writeMarkerHeader writes the header for a marker with the given length. 296 func (e *encoder) writeMarkerHeader(marker uint8, markerlen int) { 297 e.buf[0] = 0xff 298 e.buf[1] = marker 299 e.buf[2] = uint8(markerlen >> 8) 300 e.buf[3] = uint8(markerlen & 0xff) 301 e.write(e.buf[:4]) 302 } 303 304 // writeDQT writes the Define Quantization Table marker. 305 func (e *encoder) writeDQT() { 306 const markerlen = 2 + int(nQuantIndex)*(1+blockSize) 307 e.writeMarkerHeader(dqtMarker, markerlen) 308 for i := range e.quant { 309 e.writeByte(uint8(i)) 310 e.write(e.quant[i][:]) 311 } 312 } 313 314 // writeSOF0 writes the Start Of Frame (Baseline Sequential) marker. 315 func (e *encoder) writeSOF0(size image.Point, nComponent int) { 316 markerlen := 8 + 3*nComponent 317 e.writeMarkerHeader(sof0Marker, markerlen) 318 e.buf[0] = 8 // 8-bit color. 319 e.buf[1] = uint8(size.Y >> 8) 320 e.buf[2] = uint8(size.Y & 0xff) 321 e.buf[3] = uint8(size.X >> 8) 322 e.buf[4] = uint8(size.X & 0xff) 323 e.buf[5] = uint8(nComponent) 324 if nComponent == 1 { 325 e.buf[6] = 1 326 // No subsampling for grayscale image. 327 e.buf[7] = 0x11 328 e.buf[8] = 0x00 329 } else { 330 for i := 0; i < nComponent; i++ { 331 e.buf[3*i+6] = uint8(i + 1) 332 // We use 4:2:0 chroma subsampling. 333 e.buf[3*i+7] = "\x22\x11\x11"[i] 334 e.buf[3*i+8] = "\x00\x01\x01"[i] 335 } 336 } 337 e.write(e.buf[:3*(nComponent-1)+9]) 338 } 339 340 // writeDHT writes the Define Huffman Table marker. 341 func (e *encoder) writeDHT(nComponent int) { 342 markerlen := 2 343 specs := theHuffmanSpec[:] 344 if nComponent == 1 { 345 // Drop the Chrominance tables. 346 specs = specs[:2] 347 } 348 for _, s := range specs { 349 markerlen += 1 + 16 + len(s.value) 350 } 351 e.writeMarkerHeader(dhtMarker, markerlen) 352 for i, s := range specs { 353 e.writeByte("\x00\x10\x01\x11"[i]) 354 e.write(s.count[:]) 355 e.write(s.value) 356 } 357 } 358 359 // writeBlock writes a block of pixel data using the given quantization table, 360 // returning the post-quantized DC value of the DCT-transformed block. b is in 361 // natural (not zig-zag) order. 362 func (e *encoder) writeBlock(b *block, q quantIndex, prevDC int32) int32 { 363 fdct(b) 364 // Emit the DC delta. 365 dc := div(b[0], 8*int32(e.quant[q][0])) 366 e.emitHuffRLE(huffIndex(2*q+0), 0, dc-prevDC) 367 // Emit the AC components. 368 h, runLength := huffIndex(2*q+1), int32(0) 369 for zig := 1; zig < blockSize; zig++ { 370 ac := div(b[unzig[zig]], 8*int32(e.quant[q][zig])) 371 if ac == 0 { 372 runLength++ 373 } else { 374 for runLength > 15 { 375 e.emitHuff(h, 0xf0) 376 runLength -= 16 377 } 378 e.emitHuffRLE(h, runLength, ac) 379 runLength = 0 380 } 381 } 382 if runLength > 0 { 383 e.emitHuff(h, 0x00) 384 } 385 return dc 386 } 387 388 // toYCbCr converts the 8x8 region of m whose top-left corner is p to its 389 // YCbCr values. 390 func toYCbCr(m image.Image, p image.Point, yBlock, cbBlock, crBlock *block) { 391 b := m.Bounds() 392 xmax := b.Max.X - 1 393 ymax := b.Max.Y - 1 394 for j := 0; j < 8; j++ { 395 for i := 0; i < 8; i++ { 396 r, g, b, _ := m.At(min(p.X+i, xmax), min(p.Y+j, ymax)).RGBA() 397 yy, cb, cr := color.RGBToYCbCr(uint8(r>>8), uint8(g>>8), uint8(b>>8)) 398 yBlock[8*j+i] = int32(yy) 399 cbBlock[8*j+i] = int32(cb) 400 crBlock[8*j+i] = int32(cr) 401 } 402 } 403 } 404 405 // grayToY stores the 8x8 region of m whose top-left corner is p in yBlock. 406 func grayToY(m *image.Gray, p image.Point, yBlock *block) { 407 b := m.Bounds() 408 xmax := b.Max.X - 1 409 ymax := b.Max.Y - 1 410 pix := m.Pix 411 for j := 0; j < 8; j++ { 412 for i := 0; i < 8; i++ { 413 idx := m.PixOffset(min(p.X+i, xmax), min(p.Y+j, ymax)) 414 yBlock[8*j+i] = int32(pix[idx]) 415 } 416 } 417 } 418 419 // rgbaToYCbCr is a specialized version of toYCbCr for image.RGBA images. 420 func rgbaToYCbCr(m *image.RGBA, p image.Point, yBlock, cbBlock, crBlock *block) { 421 b := m.Bounds() 422 xmax := b.Max.X - 1 423 ymax := b.Max.Y - 1 424 for j := 0; j < 8; j++ { 425 sj := p.Y + j 426 if sj > ymax { 427 sj = ymax 428 } 429 offset := (sj-b.Min.Y)*m.Stride - b.Min.X*4 430 for i := 0; i < 8; i++ { 431 sx := p.X + i 432 if sx > xmax { 433 sx = xmax 434 } 435 pix := m.Pix[offset+sx*4:] 436 yy, cb, cr := color.RGBToYCbCr(pix[0], pix[1], pix[2]) 437 yBlock[8*j+i] = int32(yy) 438 cbBlock[8*j+i] = int32(cb) 439 crBlock[8*j+i] = int32(cr) 440 } 441 } 442 } 443 444 // yCbCrToYCbCr is a specialized version of toYCbCr for image.YCbCr images. 445 func yCbCrToYCbCr(m *image.YCbCr, p image.Point, yBlock, cbBlock, crBlock *block) { 446 b := m.Bounds() 447 xmax := b.Max.X - 1 448 ymax := b.Max.Y - 1 449 for j := 0; j < 8; j++ { 450 sy := p.Y + j 451 if sy > ymax { 452 sy = ymax 453 } 454 for i := 0; i < 8; i++ { 455 sx := p.X + i 456 if sx > xmax { 457 sx = xmax 458 } 459 yi := m.YOffset(sx, sy) 460 ci := m.COffset(sx, sy) 461 yBlock[8*j+i] = int32(m.Y[yi]) 462 cbBlock[8*j+i] = int32(m.Cb[ci]) 463 crBlock[8*j+i] = int32(m.Cr[ci]) 464 } 465 } 466 } 467 468 // scale scales the 16x16 region represented by the 4 src blocks to the 8x8 469 // dst block. 470 func scale(dst *block, src *[4]block) { 471 for i := 0; i < 4; i++ { 472 dstOff := (i&2)<<4 | (i&1)<<2 473 for y := 0; y < 4; y++ { 474 for x := 0; x < 4; x++ { 475 j := 16*y + 2*x 476 sum := src[i][j] + src[i][j+1] + src[i][j+8] + src[i][j+9] 477 dst[8*y+x+dstOff] = (sum + 2) >> 2 478 } 479 } 480 } 481 } 482 483 // sosHeaderY is the SOS marker "\xff\xda" followed by 8 bytes: 484 // - the marker length "\x00\x08", 485 // - the number of components "\x01", 486 // - component 1 uses DC table 0 and AC table 0 "\x01\x00", 487 // - the bytes "\x00\x3f\x00". Section B.2.3 of the spec says that for 488 // sequential DCTs, those bytes (8-bit Ss, 8-bit Se, 4-bit Ah, 4-bit Al) 489 // should be 0x00, 0x3f, 0x00<<4 | 0x00. 490 var sosHeaderY = []byte{ 491 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x00, 0x3f, 0x00, 492 } 493 494 // sosHeaderYCbCr is the SOS marker "\xff\xda" followed by 12 bytes: 495 // - the marker length "\x00\x0c", 496 // - the number of components "\x03", 497 // - component 1 uses DC table 0 and AC table 0 "\x01\x00", 498 // - component 2 uses DC table 1 and AC table 1 "\x02\x11", 499 // - component 3 uses DC table 1 and AC table 1 "\x03\x11", 500 // - the bytes "\x00\x3f\x00". Section B.2.3 of the spec says that for 501 // sequential DCTs, those bytes (8-bit Ss, 8-bit Se, 4-bit Ah, 4-bit Al) 502 // should be 0x00, 0x3f, 0x00<<4 | 0x00. 503 var sosHeaderYCbCr = []byte{ 504 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02, 505 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 506 } 507 508 // writeSOS writes the StartOfScan marker. 509 func (e *encoder) writeSOS(m image.Image) { 510 switch m.(type) { 511 case *image.Gray: 512 e.write(sosHeaderY) 513 default: 514 e.write(sosHeaderYCbCr) 515 } 516 var ( 517 // Scratch buffers to hold the YCbCr values. 518 // The blocks are in natural (not zig-zag) order. 519 b block 520 cb, cr [4]block 521 // DC components are delta-encoded. 522 prevDCY, prevDCCb, prevDCCr int32 523 ) 524 bounds := m.Bounds() 525 switch m := m.(type) { 526 // TODO(wathiede): switch on m.ColorModel() instead of type. 527 case *image.Gray: 528 for y := bounds.Min.Y; y < bounds.Max.Y; y += 8 { 529 for x := bounds.Min.X; x < bounds.Max.X; x += 8 { 530 p := image.Pt(x, y) 531 grayToY(m, p, &b) 532 prevDCY = e.writeBlock(&b, 0, prevDCY) 533 } 534 } 535 default: 536 rgba, _ := m.(*image.RGBA) 537 ycbcr, _ := m.(*image.YCbCr) 538 for y := bounds.Min.Y; y < bounds.Max.Y; y += 16 { 539 for x := bounds.Min.X; x < bounds.Max.X; x += 16 { 540 for i := 0; i < 4; i++ { 541 xOff := (i & 1) * 8 542 yOff := (i & 2) * 4 543 p := image.Pt(x+xOff, y+yOff) 544 if rgba != nil { 545 rgbaToYCbCr(rgba, p, &b, &cb[i], &cr[i]) 546 } else if ycbcr != nil { 547 yCbCrToYCbCr(ycbcr, p, &b, &cb[i], &cr[i]) 548 } else { 549 toYCbCr(m, p, &b, &cb[i], &cr[i]) 550 } 551 prevDCY = e.writeBlock(&b, 0, prevDCY) 552 } 553 scale(&b, &cb) 554 prevDCCb = e.writeBlock(&b, 1, prevDCCb) 555 scale(&b, &cr) 556 prevDCCr = e.writeBlock(&b, 1, prevDCCr) 557 } 558 } 559 } 560 // Pad the last byte with 1's. 561 e.emit(0x7f, 7) 562 } 563 564 // DefaultQuality is the default quality encoding parameter. 565 const DefaultQuality = 75 566 567 // Options are the encoding parameters. 568 // Quality ranges from 1 to 100 inclusive, higher is better. 569 type Options struct { 570 Quality int 571 } 572 573 // Encode writes the Image m to w in JPEG 4:2:0 baseline format with the given 574 // options. Default parameters are used if a nil *Options is passed. 575 func Encode(w io.Writer, m image.Image, o *Options) error { 576 b := m.Bounds() 577 if b.Dx() >= 1<<16 || b.Dy() >= 1<<16 { 578 return errors.New("jpeg: image is too large to encode") 579 } 580 var e encoder 581 if ww, ok := w.(writer); ok { 582 e.w = ww 583 } else { 584 e.w = bufio.NewWriter(w) 585 } 586 // Clip quality to [1, 100]. 587 quality := DefaultQuality 588 if o != nil { 589 quality = o.Quality 590 if quality < 1 { 591 quality = 1 592 } else if quality > 100 { 593 quality = 100 594 } 595 } 596 // Convert from a quality rating to a scaling factor. 597 var scale int 598 if quality < 50 { 599 scale = 5000 / quality 600 } else { 601 scale = 200 - quality*2 602 } 603 // Initialize the quantization tables. 604 for i := range e.quant { 605 for j := range e.quant[i] { 606 x := int(unscaledQuant[i][j]) 607 x = (x*scale + 50) / 100 608 if x < 1 { 609 x = 1 610 } else if x > 255 { 611 x = 255 612 } 613 e.quant[i][j] = uint8(x) 614 } 615 } 616 // Compute number of components based on input image type. 617 nComponent := 3 618 switch m.(type) { 619 // TODO(wathiede): switch on m.ColorModel() instead of type. 620 case *image.Gray: 621 nComponent = 1 622 } 623 // Write the Start Of Image marker. 624 e.buf[0] = 0xff 625 e.buf[1] = 0xd8 626 e.write(e.buf[:2]) 627 // Write the quantization tables. 628 e.writeDQT() 629 // Write the image dimensions. 630 e.writeSOF0(b.Size(), nComponent) 631 // Write the Huffman tables. 632 e.writeDHT(nComponent) 633 // Write the image data. 634 e.writeSOS(m) 635 // Write the End Of Image marker. 636 e.buf[0] = 0xff 637 e.buf[1] = 0xd9 638 e.write(e.buf[:2]) 639 e.flush() 640 return e.err 641 }