Commits

mpl committed d489d53

image/jpeg: support for reading 4:4:0 subsampling.
Updates issue 2362.

R=nigeltao
CC=golang-dev
http://codereview.appspot.com/6326057

Committer: Nigel Tao <nigeltao@golang.org>

  • Participants
  • Parent commits c81ffe9

Comments (0)

Files changed (3)

File src/pkg/image/jpeg/reader.go

 	// A color JPEG image has Y, Cb and Cr components.
 	nColorComponent = 3
 
-	// We only support 4:4:4, 4:2:2 and 4:2:0 downsampling, and therefore the
+	// We only support 4:4:4, 4:4:0, 4:2:2 and 4:2:0 downsampling, and therefore the
 	// number of luma samples per chroma sample is at most 2 in the horizontal
 	// and 2 in the vertical direction.
 	maxH = 2
 		if d.nComp == nGrayComponent {
 			continue
 		}
-		// For color images, we only support 4:4:4, 4:2:2 or 4:2:0 chroma
+		// 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), (2, 1) or (2, 2), and the (h, v)
+		// component are either (1, 1), (1, 2), (2, 1) or (2, 2), and the (h, v)
 		// values for the Cr and Cb components must be (1, 1).
 		if i == 0 {
-			if hv != 0x11 && hv != 0x21 && hv != 0x22 {
+			if hv != 0x11 && hv != 0x21 && hv != 0x22 && hv != 0x12 {
 				return UnsupportedError("luma downsample ratio")
 			}
 		} else if hv != 0x11 {
 		return
 	}
 	var subsampleRatio image.YCbCrSubsampleRatio
-	switch h0 * v0 {
-	case 1:
+	switch {
+	case h0 == 1 && v0 == 1:
 		subsampleRatio = image.YCbCrSubsampleRatio444
-	case 2:
+	case h0 == 1 && v0 == 2:
+		subsampleRatio = image.YCbCrSubsampleRatio440
+	case h0 == 2 && v0 == 1:
 		subsampleRatio = image.YCbCrSubsampleRatio422
-	case 4:
+	case h0 == 2 && v0 == 2:
 		subsampleRatio = image.YCbCrSubsampleRatio420
 	default:
 		panic("unreachable")
 					} else {
 						switch i {
 						case 0:
-							mx0 := h0*mx + (j % 2)
-							my0 := v0*my + (j / 2)
+							mx0, my0 := h0*mx, v0*my
+							if h0 == 1 {
+								my0 += j
+							} else {
+								mx0 += j % 2
+								my0 += j / 2
+							}
 							idct(d.img3.Y[8*(my0*d.img3.YStride+mx0):], d.img3.YStride, &b)
 						case 1:
 							idct(d.img3.Cb[8*(my*d.img3.CStride+mx):], d.img3.CStride, &b)

File src/pkg/image/ycbcr.go

 	YCbCrSubsampleRatio444 YCbCrSubsampleRatio = iota
 	YCbCrSubsampleRatio422
 	YCbCrSubsampleRatio420
+	YCbCrSubsampleRatio440
 )
 
 func (s YCbCrSubsampleRatio) String() string {
 		return "YCbCrSubsampleRatio422"
 	case YCbCrSubsampleRatio420:
 		return "YCbCrSubsampleRatio420"
+	case YCbCrSubsampleRatio440:
+		return "YCbCrSubsampleRatio440"
 	}
 	return "YCbCrSubsampleRatioUnknown"
 }
 //	For 4:4:4, CStride == YStride/1 && len(Cb) == len(Cr) == len(Y)/1.
 //	For 4:2:2, CStride == YStride/2 && len(Cb) == len(Cr) == len(Y)/2.
 //	For 4:2:0, CStride == YStride/2 && len(Cb) == len(Cr) == len(Y)/4.
+//	For 4:4:0, CStride == YStride/1 && len(Cb) == len(Cr) == len(Y)/2.
 type YCbCr struct {
 	Y, Cb, Cr      []uint8
 	YStride        int
 		return (y-p.Rect.Min.Y)*p.CStride + (x/2 - p.Rect.Min.X/2)
 	case YCbCrSubsampleRatio420:
 		return (y/2-p.Rect.Min.Y/2)*p.CStride + (x/2 - p.Rect.Min.X/2)
+	case YCbCrSubsampleRatio440:
+		return (y/2-p.Rect.Min.Y/2)*p.CStride + (x - p.Rect.Min.X)
 	}
 	// Default to 4:4:4 subsampling.
 	return (y-p.Rect.Min.Y)*p.CStride + (x - p.Rect.Min.X)
 	case YCbCrSubsampleRatio420:
 		cw = (r.Max.X+1)/2 - r.Min.X/2
 		ch = (r.Max.Y+1)/2 - r.Min.Y/2
+	case YCbCrSubsampleRatio440:
+		cw = w
+		ch = (r.Max.Y+1)/2 - r.Min.Y/2
 	default:
 		// Default to 4:4:4 subsampling.
 		cw = w

File src/pkg/image/ycbcr_test.go

 		YCbCrSubsampleRatio444,
 		YCbCrSubsampleRatio422,
 		YCbCrSubsampleRatio420,
+		YCbCrSubsampleRatio440,
 	}
 	deltas := []Point{
 		Pt(0, 0),