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