1
2
3
4
5 package jpeg
6
7 import (
8 "bufio"
9 "errors"
10 "image"
11 "image/color"
12 "io"
13 )
14
15
16 func min(x, y int) int {
17 if x < y {
18 return x
19 }
20 return y
21 }
22
23
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
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
60
61
62
63 var unscaledQuant = [nQuantIndex][blockSize]byte{
64
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
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
99 type huffmanSpec struct {
100
101 count [16]byte
102
103 value []byte
104 }
105
106
107
108 var theHuffmanSpec = [nHuffIndex]huffmanSpec{
109
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
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
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
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
176
177
178
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
202 var theHuffmanLUT [4]huffmanLUT
203
204 func init() {
205 for i, s := range theHuffmanSpec {
206 theHuffmanLUT[i].init(s)
207 }
208 }
209
210
211 type writer interface {
212 Flush() error
213 io.Writer
214 io.ByteWriter
215 }
216
217
218 type encoder struct {
219
220
221 w writer
222 err error
223
224 buf [16]byte
225
226 bits, nBits uint32
227
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
253
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
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
277
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
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
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
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
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
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
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
341 func (e *encoder) writeDHT(nComponent int) {
342 markerlen := 2
343 specs := theHuffmanSpec[:]
344 if nComponent == 1 {
345
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
360
361
362 func (e *encoder) writeBlock(b *block, q quantIndex, prevDC int32) int32 {
363 fdct(b)
364
365 dc := div(b[0], 8*int32(e.quant[q][0]))
366 e.emitHuffRLE(huffIndex(2*q+0), 0, dc-prevDC)
367
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
389
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
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
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
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
469
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
484
485
486
487
488
489
490 var sosHeaderY = []byte{
491 0xff, 0xda, 0x00, 0x08, 0x01, 0x01, 0x00, 0x00, 0x3f, 0x00,
492 }
493
494
495
496
497
498
499
500
501
502
503 var sosHeaderYCbCr = []byte{
504 0xff, 0xda, 0x00, 0x0c, 0x03, 0x01, 0x00, 0x02,
505 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00,
506 }
507
508
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
518
519 b block
520 cb, cr [4]block
521
522 prevDCY, prevDCCb, prevDCCr int32
523 )
524 bounds := m.Bounds()
525 switch m := m.(type) {
526
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
561 e.emit(0x7f, 7)
562 }
563
564
565 const DefaultQuality = 75
566
567
568
569 type Options struct {
570 Quality int
571 }
572
573
574
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
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
597 var scale int
598 if quality < 50 {
599 scale = 5000 / quality
600 } else {
601 scale = 200 - quality*2
602 }
603
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
617 nComponent := 3
618 switch m.(type) {
619
620 case *image.Gray:
621 nComponent = 1
622 }
623
624 e.buf[0] = 0xff
625 e.buf[1] = 0xd8
626 e.write(e.buf[:2])
627
628 e.writeDQT()
629
630 e.writeSOF0(b.Size(), nComponent)
631
632 e.writeDHT(nComponent)
633
634 e.writeSOS(m)
635
636 e.buf[0] = 0xff
637 e.buf[1] = 0xd9
638 e.write(e.buf[:2])
639 e.flush()
640 return e.err
641 }
642
View as plain text