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