1
2
3
4
5
6
7
8 package jpeg
9
10 import (
11 "image"
12 "image/color"
13 "image/internal/imageutil"
14 "io"
15 )
16
17
18 type FormatError string
19
20 func (e FormatError) Error() string { return "invalid JPEG format: " + string(e) }
21
22
23 type UnsupportedError string
24
25 func (e UnsupportedError) Error() string { return "unsupported JPEG feature: " + string(e) }
26
27 var errUnsupportedSubsamplingRatio = UnsupportedError("luma/chroma subsampling ratio")
28
29
30 type component struct {
31 h int
32 v int
33 c uint8
34 tq uint8
35 }
36
37 const (
38 dcTable = 0
39 acTable = 1
40 maxTc = 1
41 maxTh = 3
42 maxTq = 3
43
44 maxComponents = 4
45 )
46
47 const (
48 sof0Marker = 0xc0
49 sof1Marker = 0xc1
50 sof2Marker = 0xc2
51 dhtMarker = 0xc4
52 rst0Marker = 0xd0
53 rst7Marker = 0xd7
54 soiMarker = 0xd8
55 eoiMarker = 0xd9
56 sosMarker = 0xda
57 dqtMarker = 0xdb
58 driMarker = 0xdd
59 comMarker = 0xfe
60
61
62
63 app0Marker = 0xe0
64 app14Marker = 0xee
65 app15Marker = 0xef
66 )
67
68
69 const (
70 adobeTransformUnknown = 0
71 adobeTransformYCbCr = 1
72 adobeTransformYCbCrK = 2
73 )
74
75
76
77
78 var unzig = [blockSize]int{
79 0, 1, 8, 16, 9, 2, 3, 10,
80 17, 24, 32, 25, 18, 11, 4, 5,
81 12, 19, 26, 33, 40, 48, 41, 34,
82 27, 20, 13, 6, 7, 14, 21, 28,
83 35, 42, 49, 56, 57, 50, 43, 36,
84 29, 22, 15, 23, 30, 37, 44, 51,
85 58, 59, 52, 45, 38, 31, 39, 46,
86 53, 60, 61, 54, 47, 55, 62, 63,
87 }
88
89
90
91 type Reader interface {
92 io.ByteReader
93 io.Reader
94 }
95
96
97
98
99 type bits struct {
100 a uint32
101 m uint32
102 n int32
103 }
104
105 type decoder struct {
106 r io.Reader
107 bits bits
108
109
110
111 bytes struct {
112
113
114 buf [4096]byte
115 i, j int
116
117
118 nUnreadable int
119 }
120 width, height int
121
122 img1 *image.Gray
123 img3 *image.YCbCr
124 blackPix []byte
125 blackStride int
126
127 ri int
128 nComp int
129
130
131
132
133
134
135 baseline bool
136 progressive bool
137
138 jfif bool
139 adobeTransformValid bool
140 adobeTransform uint8
141 eobRun uint16
142
143 comp [maxComponents]component
144 progCoeffs [maxComponents][]block
145 huff [maxTc + 1][maxTh + 1]huffman
146 quant [maxTq + 1]block
147 tmp [2 * blockSize]byte
148 }
149
150
151
152 func (d *decoder) fill() error {
153 if d.bytes.i != d.bytes.j {
154 panic("jpeg: fill called when unread bytes exist")
155 }
156
157
158 if d.bytes.j > 2 {
159 d.bytes.buf[0] = d.bytes.buf[d.bytes.j-2]
160 d.bytes.buf[1] = d.bytes.buf[d.bytes.j-1]
161 d.bytes.i, d.bytes.j = 2, 2
162 }
163
164 n, err := d.r.Read(d.bytes.buf[d.bytes.j:])
165 d.bytes.j += n
166 if n > 0 {
167 err = nil
168 }
169 return err
170 }
171
172
173
174
175
176
177 func (d *decoder) unreadByteStuffedByte() {
178 d.bytes.i -= d.bytes.nUnreadable
179 d.bytes.nUnreadable = 0
180 if d.bits.n >= 8 {
181 d.bits.a >>= 8
182 d.bits.n -= 8
183 d.bits.m >>= 8
184 }
185 }
186
187
188
189 func (d *decoder) readByte() (x byte, err error) {
190 for d.bytes.i == d.bytes.j {
191 if err = d.fill(); err != nil {
192 return 0, err
193 }
194 }
195 x = d.bytes.buf[d.bytes.i]
196 d.bytes.i++
197 d.bytes.nUnreadable = 0
198 return x, nil
199 }
200
201
202
203 var errMissingFF00 = FormatError("missing 0xff00 sequence")
204
205
206 func (d *decoder) readByteStuffedByte() (x byte, err error) {
207
208 if d.bytes.i+2 <= d.bytes.j {
209 x = d.bytes.buf[d.bytes.i]
210 d.bytes.i++
211 d.bytes.nUnreadable = 1
212 if x != 0xff {
213 return x, err
214 }
215 if d.bytes.buf[d.bytes.i] != 0x00 {
216 return 0, errMissingFF00
217 }
218 d.bytes.i++
219 d.bytes.nUnreadable = 2
220 return 0xff, nil
221 }
222
223 d.bytes.nUnreadable = 0
224
225 x, err = d.readByte()
226 if err != nil {
227 return 0, err
228 }
229 d.bytes.nUnreadable = 1
230 if x != 0xff {
231 return x, nil
232 }
233
234 x, err = d.readByte()
235 if err != nil {
236 return 0, err
237 }
238 d.bytes.nUnreadable = 2
239 if x != 0x00 {
240 return 0, errMissingFF00
241 }
242 return 0xff, nil
243 }
244
245
246
247 func (d *decoder) readFull(p []byte) error {
248
249 if d.bytes.nUnreadable != 0 {
250 if d.bits.n >= 8 {
251 d.unreadByteStuffedByte()
252 }
253 d.bytes.nUnreadable = 0
254 }
255
256 for {
257 n := copy(p, d.bytes.buf[d.bytes.i:d.bytes.j])
258 p = p[n:]
259 d.bytes.i += n
260 if len(p) == 0 {
261 break
262 }
263 if err := d.fill(); err != nil {
264 if err == io.EOF {
265 err = io.ErrUnexpectedEOF
266 }
267 return err
268 }
269 }
270 return nil
271 }
272
273
274 func (d *decoder) ignore(n int) error {
275
276 if d.bytes.nUnreadable != 0 {
277 if d.bits.n >= 8 {
278 d.unreadByteStuffedByte()
279 }
280 d.bytes.nUnreadable = 0
281 }
282
283 for {
284 m := d.bytes.j - d.bytes.i
285 if m > n {
286 m = n
287 }
288 d.bytes.i += m
289 n -= m
290 if n == 0 {
291 break
292 }
293 if err := d.fill(); err != nil {
294 if err == io.EOF {
295 err = io.ErrUnexpectedEOF
296 }
297 return err
298 }
299 }
300 return nil
301 }
302
303
304 func (d *decoder) processSOF(n int) error {
305 if d.nComp != 0 {
306 return FormatError("multiple SOF markers")
307 }
308 switch n {
309 case 6 + 3*1:
310 d.nComp = 1
311 case 6 + 3*3:
312 d.nComp = 3
313 case 6 + 3*4:
314 d.nComp = 4
315 default:
316 return UnsupportedError("number of components")
317 }
318 if err := d.readFull(d.tmp[:n]); err != nil {
319 return err
320 }
321
322 if d.tmp[0] != 8 {
323 return UnsupportedError("precision")
324 }
325 d.height = int(d.tmp[1])<<8 + int(d.tmp[2])
326 d.width = int(d.tmp[3])<<8 + int(d.tmp[4])
327 if int(d.tmp[5]) != d.nComp {
328 return FormatError("SOF has wrong length")
329 }
330
331 for i := 0; i < d.nComp; i++ {
332 d.comp[i].c = d.tmp[6+3*i]
333
334
335 for j := 0; j < i; j++ {
336 if d.comp[i].c == d.comp[j].c {
337 return FormatError("repeated component identifier")
338 }
339 }
340
341 d.comp[i].tq = d.tmp[8+3*i]
342 if d.comp[i].tq > maxTq {
343 return FormatError("bad Tq value")
344 }
345
346 hv := d.tmp[7+3*i]
347 h, v := int(hv>>4), int(hv&0x0f)
348 if h < 1 || 4 < h || v < 1 || 4 < v {
349 return FormatError("luma/chroma subsampling ratio")
350 }
351 if h == 3 || v == 3 {
352 return errUnsupportedSubsamplingRatio
353 }
354 switch d.nComp {
355 case 1:
356
357
358
359
360
361
362
363
364
365
366
367 h, v = 1, 1
368
369 case 3:
370
371
372
373
374
375
376
377 switch i {
378 case 0:
379
380
381
382 if v == 4 {
383 return errUnsupportedSubsamplingRatio
384 }
385 case 1:
386 if d.comp[0].h%h != 0 || d.comp[0].v%v != 0 {
387 return errUnsupportedSubsamplingRatio
388 }
389 case 2:
390 if d.comp[1].h != h || d.comp[1].v != v {
391 return errUnsupportedSubsamplingRatio
392 }
393 }
394
395 case 4:
396
397
398
399
400
401
402
403
404
405 switch i {
406 case 0:
407 if hv != 0x11 && hv != 0x22 {
408 return errUnsupportedSubsamplingRatio
409 }
410 case 1, 2:
411 if hv != 0x11 {
412 return errUnsupportedSubsamplingRatio
413 }
414 case 3:
415 if d.comp[0].h != h || d.comp[0].v != v {
416 return errUnsupportedSubsamplingRatio
417 }
418 }
419 }
420
421 d.comp[i].h = h
422 d.comp[i].v = v
423 }
424 return nil
425 }
426
427
428 func (d *decoder) processDQT(n int) error {
429 loop:
430 for n > 0 {
431 n--
432 x, err := d.readByte()
433 if err != nil {
434 return err
435 }
436 tq := x & 0x0f
437 if tq > maxTq {
438 return FormatError("bad Tq value")
439 }
440 switch x >> 4 {
441 default:
442 return FormatError("bad Pq value")
443 case 0:
444 if n < blockSize {
445 break loop
446 }
447 n -= blockSize
448 if err := d.readFull(d.tmp[:blockSize]); err != nil {
449 return err
450 }
451 for i := range d.quant[tq] {
452 d.quant[tq][i] = int32(d.tmp[i])
453 }
454 case 1:
455 if n < 2*blockSize {
456 break loop
457 }
458 n -= 2 * blockSize
459 if err := d.readFull(d.tmp[:2*blockSize]); err != nil {
460 return err
461 }
462 for i := range d.quant[tq] {
463 d.quant[tq][i] = int32(d.tmp[2*i])<<8 | int32(d.tmp[2*i+1])
464 }
465 }
466 }
467 if n != 0 {
468 return FormatError("DQT has wrong length")
469 }
470 return nil
471 }
472
473
474 func (d *decoder) processDRI(n int) error {
475 if n != 2 {
476 return FormatError("DRI has wrong length")
477 }
478 if err := d.readFull(d.tmp[:2]); err != nil {
479 return err
480 }
481 d.ri = int(d.tmp[0])<<8 + int(d.tmp[1])
482 return nil
483 }
484
485 func (d *decoder) processApp0Marker(n int) error {
486 if n < 5 {
487 return d.ignore(n)
488 }
489 if err := d.readFull(d.tmp[:5]); err != nil {
490 return err
491 }
492 n -= 5
493
494 d.jfif = d.tmp[0] == 'J' && d.tmp[1] == 'F' && d.tmp[2] == 'I' && d.tmp[3] == 'F' && d.tmp[4] == '\x00'
495
496 if n > 0 {
497 return d.ignore(n)
498 }
499 return nil
500 }
501
502 func (d *decoder) processApp14Marker(n int) error {
503 if n < 12 {
504 return d.ignore(n)
505 }
506 if err := d.readFull(d.tmp[:12]); err != nil {
507 return err
508 }
509 n -= 12
510
511 if d.tmp[0] == 'A' && d.tmp[1] == 'd' && d.tmp[2] == 'o' && d.tmp[3] == 'b' && d.tmp[4] == 'e' {
512 d.adobeTransformValid = true
513 d.adobeTransform = d.tmp[11]
514 }
515
516 if n > 0 {
517 return d.ignore(n)
518 }
519 return nil
520 }
521
522
523 func (d *decoder) decode(r io.Reader, configOnly bool) (image.Image, error) {
524 d.r = r
525
526
527 if err := d.readFull(d.tmp[:2]); err != nil {
528 return nil, err
529 }
530 if d.tmp[0] != 0xff || d.tmp[1] != soiMarker {
531 return nil, FormatError("missing SOI marker")
532 }
533
534
535 for {
536 err := d.readFull(d.tmp[:2])
537 if err != nil {
538 return nil, err
539 }
540 for d.tmp[0] != 0xff {
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561 d.tmp[0] = d.tmp[1]
562 d.tmp[1], err = d.readByte()
563 if err != nil {
564 return nil, err
565 }
566 }
567 marker := d.tmp[1]
568 if marker == 0 {
569
570 continue
571 }
572 for marker == 0xff {
573
574
575 marker, err = d.readByte()
576 if err != nil {
577 return nil, err
578 }
579 }
580 if marker == eoiMarker {
581 break
582 }
583 if rst0Marker <= marker && marker <= rst7Marker {
584
585
586
587
588
589
590 continue
591 }
592
593
594
595 if err = d.readFull(d.tmp[:2]); err != nil {
596 return nil, err
597 }
598 n := int(d.tmp[0])<<8 + int(d.tmp[1]) - 2
599 if n < 0 {
600 return nil, FormatError("short segment length")
601 }
602
603 switch marker {
604 case sof0Marker, sof1Marker, sof2Marker:
605 d.baseline = marker == sof0Marker
606 d.progressive = marker == sof2Marker
607 err = d.processSOF(n)
608 if configOnly && d.jfif {
609 return nil, err
610 }
611 case dhtMarker:
612 if configOnly {
613 err = d.ignore(n)
614 } else {
615 err = d.processDHT(n)
616 }
617 case dqtMarker:
618 if configOnly {
619 err = d.ignore(n)
620 } else {
621 err = d.processDQT(n)
622 }
623 case sosMarker:
624 if configOnly {
625 return nil, nil
626 }
627 err = d.processSOS(n)
628 case driMarker:
629 if configOnly {
630 err = d.ignore(n)
631 } else {
632 err = d.processDRI(n)
633 }
634 case app0Marker:
635 err = d.processApp0Marker(n)
636 case app14Marker:
637 err = d.processApp14Marker(n)
638 default:
639 if app0Marker <= marker && marker <= app15Marker || marker == comMarker {
640 err = d.ignore(n)
641 } else if marker < 0xc0 {
642 err = FormatError("unknown marker")
643 } else {
644 err = UnsupportedError("unknown marker")
645 }
646 }
647 if err != nil {
648 return nil, err
649 }
650 }
651
652 if d.progressive {
653 if err := d.reconstructProgressiveImage(); err != nil {
654 return nil, err
655 }
656 }
657 if d.img1 != nil {
658 return d.img1, nil
659 }
660 if d.img3 != nil {
661 if d.blackPix != nil {
662 return d.applyBlack()
663 } else if d.isRGB() {
664 return d.convertToRGB()
665 }
666 return d.img3, nil
667 }
668 return nil, FormatError("missing SOS marker")
669 }
670
671
672
673
674
675
676
677
678 func (d *decoder) applyBlack() (image.Image, error) {
679 if !d.adobeTransformValid {
680 return nil, UnsupportedError("unknown color model: 4-component JPEG doesn't have Adobe APP14 metadata")
681 }
682
683
684
685
686
687 if d.adobeTransform != adobeTransformUnknown {
688
689
690
691
692 bounds := d.img3.Bounds()
693 img := image.NewRGBA(bounds)
694 imageutil.DrawYCbCr(img, bounds, d.img3, bounds.Min)
695 for iBase, y := 0, bounds.Min.Y; y < bounds.Max.Y; iBase, y = iBase+img.Stride, y+1 {
696 for i, x := iBase+3, bounds.Min.X; x < bounds.Max.X; i, x = i+4, x+1 {
697 img.Pix[i] = 255 - d.blackPix[(y-bounds.Min.Y)*d.blackStride+(x-bounds.Min.X)]
698 }
699 }
700 return &image.CMYK{
701 Pix: img.Pix,
702 Stride: img.Stride,
703 Rect: img.Rect,
704 }, nil
705 }
706
707
708
709
710
711
712 bounds := d.img3.Bounds()
713 img := image.NewCMYK(bounds)
714
715 translations := [4]struct {
716 src []byte
717 stride int
718 }{
719 {d.img3.Y, d.img3.YStride},
720 {d.img3.Cb, d.img3.CStride},
721 {d.img3.Cr, d.img3.CStride},
722 {d.blackPix, d.blackStride},
723 }
724 for t, translation := range translations {
725 subsample := d.comp[t].h != d.comp[0].h || d.comp[t].v != d.comp[0].v
726 for iBase, y := 0, bounds.Min.Y; y < bounds.Max.Y; iBase, y = iBase+img.Stride, y+1 {
727 sy := y - bounds.Min.Y
728 if subsample {
729 sy /= 2
730 }
731 for i, x := iBase+t, bounds.Min.X; x < bounds.Max.X; i, x = i+4, x+1 {
732 sx := x - bounds.Min.X
733 if subsample {
734 sx /= 2
735 }
736 img.Pix[i] = 255 - translation.src[sy*translation.stride+sx]
737 }
738 }
739 }
740 return img, nil
741 }
742
743 func (d *decoder) isRGB() bool {
744 if d.jfif {
745 return false
746 }
747 if d.adobeTransformValid && d.adobeTransform == adobeTransformUnknown {
748
749
750 return true
751 }
752 return d.comp[0].c == 'R' && d.comp[1].c == 'G' && d.comp[2].c == 'B'
753 }
754
755 func (d *decoder) convertToRGB() (image.Image, error) {
756 cScale := d.comp[0].h / d.comp[1].h
757 bounds := d.img3.Bounds()
758 img := image.NewRGBA(bounds)
759 for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
760 po := img.PixOffset(bounds.Min.X, y)
761 yo := d.img3.YOffset(bounds.Min.X, y)
762 co := d.img3.COffset(bounds.Min.X, y)
763 for i, iMax := 0, bounds.Max.X-bounds.Min.X; i < iMax; i++ {
764 img.Pix[po+4*i+0] = d.img3.Y[yo+i]
765 img.Pix[po+4*i+1] = d.img3.Cb[co+i/cScale]
766 img.Pix[po+4*i+2] = d.img3.Cr[co+i/cScale]
767 img.Pix[po+4*i+3] = 255
768 }
769 }
770 return img, nil
771 }
772
773
774 func Decode(r io.Reader) (image.Image, error) {
775 var d decoder
776 return d.decode(r, false)
777 }
778
779
780
781 func DecodeConfig(r io.Reader) (image.Config, error) {
782 var d decoder
783 if _, err := d.decode(r, true); err != nil {
784 return image.Config{}, err
785 }
786 switch d.nComp {
787 case 1:
788 return image.Config{
789 ColorModel: color.GrayModel,
790 Width: d.width,
791 Height: d.height,
792 }, nil
793 case 3:
794 cm := color.YCbCrModel
795 if d.isRGB() {
796 cm = color.RGBAModel
797 }
798 return image.Config{
799 ColorModel: cm,
800 Width: d.width,
801 Height: d.height,
802 }, nil
803 case 4:
804 return image.Config{
805 ColorModel: color.CMYKModel,
806 Width: d.width,
807 Height: d.height,
808 }, nil
809 }
810 return image.Config{}, FormatError("missing SOF marker")
811 }
812
813 func init() {
814 image.RegisterFormat("jpeg", "\xff\xd8", Decode, DecodeConfig)
815 }
816
View as plain text