]> Cypherpunks repositories - gostls13.git/commitdiff
image/jpeg: handle those (unusual) grayscale images whose sampling
authorNigel Tao <nigeltao@golang.org>
Mon, 7 Jan 2013 05:16:11 +0000 (16:16 +1100)
committerNigel Tao <nigeltao@golang.org>
Mon, 7 Jan 2013 05:16:11 +0000 (16:16 +1100)
ratio isn't 1x1.

Fixes #4259.

The test data was generated by
cjpeg -quality 50 -sample 2x2 video-005.gray.pgm > video-005.gray.q50.2x2.jpeg
cjpeg -quality 50 -sample 2x2 -progressive video-005.gray.pgm > video-005.gray.q50.2x2.progressive.jpeg

similarly to video-005.gray.q50.* from
http://code.google.com/p/go/source/detail?r=51f26e36ba98
the key difference being the "-sample 2x2".

R=rsc
CC=golang-dev
https://golang.org/cl/7069045

src/pkg/image/jpeg/reader.go
src/pkg/image/jpeg/reader_test.go
src/pkg/image/testdata/video-005.gray.q50.2x2.jpeg [new file with mode: 0644]
src/pkg/image/testdata/video-005.gray.q50.2x2.progressive.jpeg [new file with mode: 0644]

index 24dd65defcc75b96de8a1906e86a75c60d404587..1ee6bbcd1acc04055c9bb5161ad56687f90f7584 100644 (file)
@@ -147,14 +147,27 @@ func (d *decoder) processSOF(n int) error {
                return UnsupportedError("SOF has wrong number of image components")
        }
        for i := 0; i < d.nComp; i++ {
-               hv := d.tmp[7+3*i]
-               d.comp[i].h = int(hv >> 4)
-               d.comp[i].v = int(hv & 0x0f)
                d.comp[i].c = d.tmp[6+3*i]
                d.comp[i].tq = d.tmp[8+3*i]
                if d.nComp == nGrayComponent {
+                       // If a JPEG image has only one component, section A.2 says "this data
+                       // is non-interleaved by definition" and section A.2.2 says "[in this
+                       // case...] the order of data units within a scan shall be left-to-right
+                       // and top-to-bottom... regardless of the values of H_1 and V_1". Section
+                       // 4.8.2 also says "[for non-interleaved data], the MCU is defined to be
+                       // one data unit". Similarly, section A.1.1 explains that it is the ratio
+                       // of H_i to max_j(H_j) that matters, and similarly for V. For grayscale
+                       // images, H_1 is the maximum H_j for all components j, so that ratio is
+                       // always 1. The component's (h, v) is effectively always (1, 1): even if
+                       // the nominal (h, v) is (2, 1), a 20x5 image is encoded in three 8x8
+                       // MCUs, not two 16x8 MCUs.
+                       d.comp[i].h = 1
+                       d.comp[i].v = 1
                        continue
                }
+               hv := d.tmp[7+3*i]
+               d.comp[i].h = int(hv >> 4)
+               d.comp[i].v = int(hv & 0x0f)
                // For color images, we only support 4:4:4, 4:4:0, 4:2:2 or 4:2:0 chroma
                // downsampling ratios. This implies that the (h, v) values for the Y
                // component are either (1, 1), (1, 2), (2, 1) or (2, 2), and the (h, v)
index f7fbd9a8a5ea48f169853654e151cc4b9bf7708a..b520a8ab18c684044bd9f66ca80c3396b61159a8 100644 (file)
@@ -24,6 +24,7 @@ func TestDecodeProgressive(t *testing.T) {
                "../testdata/video-001.q50.440",
                "../testdata/video-001.q50.444",
                "../testdata/video-005.gray.q50",
+               "../testdata/video-005.gray.q50.2x2",
        }
        for _, tc := range testCases {
                m0, err := decodeFile(tc + ".jpeg")
diff --git a/src/pkg/image/testdata/video-005.gray.q50.2x2.jpeg b/src/pkg/image/testdata/video-005.gray.q50.2x2.jpeg
new file mode 100644 (file)
index 0000000..630b615
Binary files /dev/null and b/src/pkg/image/testdata/video-005.gray.q50.2x2.jpeg differ
diff --git a/src/pkg/image/testdata/video-005.gray.q50.2x2.progressive.jpeg b/src/pkg/image/testdata/video-005.gray.q50.2x2.progressive.jpeg
new file mode 100644 (file)
index 0000000..c6b9360
Binary files /dev/null and b/src/pkg/image/testdata/video-005.gray.q50.2x2.progressive.jpeg differ