From 30ff0636b77f0e64084cc976e927355edb6d6f36 Mon Sep 17 00:00:00 2001 From: Nigel Tao Date: Mon, 7 Jan 2013 16:16:11 +1100 Subject: [PATCH] image/jpeg: handle those (unusual) grayscale images whose sampling 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 | 19 +++++++++++++++--- src/pkg/image/jpeg/reader_test.go | 1 + .../testdata/video-005.gray.q50.2x2.jpeg | Bin 0 -> 2782 bytes .../video-005.gray.q50.2x2.progressive.jpeg | Bin 0 -> 2699 bytes 4 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 src/pkg/image/testdata/video-005.gray.q50.2x2.jpeg create mode 100644 src/pkg/image/testdata/video-005.gray.q50.2x2.progressive.jpeg diff --git a/src/pkg/image/jpeg/reader.go b/src/pkg/image/jpeg/reader.go index 24dd65defc..1ee6bbcd1a 100644 --- a/src/pkg/image/jpeg/reader.go +++ b/src/pkg/image/jpeg/reader.go @@ -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) diff --git a/src/pkg/image/jpeg/reader_test.go b/src/pkg/image/jpeg/reader_test.go index f7fbd9a8a5..b520a8ab18 100644 --- a/src/pkg/image/jpeg/reader_test.go +++ b/src/pkg/image/jpeg/reader_test.go @@ -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 index 0000000000000000000000000000000000000000..630b615f73ad3ef5590f572340cbc9070efc2088 GIT binary patch literal 2782 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 gw