| // Copyright 2015 The Go Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style | 
 | // license that can be found in the LICENSE file. | 
 |  | 
 | // +build ignore | 
 |  | 
 | package main | 
 |  | 
 | import ( | 
 | 	"bytes" | 
 | 	"flag" | 
 | 	"fmt" | 
 | 	"go/format" | 
 | 	"io/ioutil" | 
 | 	"log" | 
 | 	"os" | 
 | ) | 
 |  | 
 | var debug = flag.Bool("debug", false, "") | 
 |  | 
 | func main() { | 
 | 	flag.Parse() | 
 |  | 
 | 	w := new(bytes.Buffer) | 
 | 	w.WriteString(pre) | 
 | 	for _, sratio := range subsampleRatios { | 
 | 		fmt.Fprintf(w, sratioCase, sratio, sratioLines[sratio]) | 
 | 	} | 
 | 	w.WriteString(post) | 
 |  | 
 | 	if *debug { | 
 | 		os.Stdout.Write(w.Bytes()) | 
 | 		return | 
 | 	} | 
 | 	out, err := format.Source(w.Bytes()) | 
 | 	if err != nil { | 
 | 		log.Fatal(err) | 
 | 	} | 
 | 	if err := ioutil.WriteFile("impl.go", out, 0660); err != nil { | 
 | 		log.Fatal(err) | 
 | 	} | 
 | } | 
 |  | 
 | const pre = `// Code generated by go run gen.go; DO NOT EDIT. | 
 |  | 
 | package imageutil | 
 |  | 
 | import ( | 
 | 	"image" | 
 | ) | 
 |  | 
 | // DrawYCbCr draws the YCbCr source image on the RGBA destination image with | 
 | // r.Min in dst aligned with sp in src. It reports whether the draw was | 
 | // successful. If it returns false, no dst pixels were changed. | 
 | // | 
 | // This function assumes that r is entirely within dst's bounds and the | 
 | // translation of r from dst coordinate space to src coordinate space is | 
 | // entirely within src's bounds. | 
 | func DrawYCbCr(dst *image.RGBA, r image.Rectangle, src *image.YCbCr, sp image.Point) (ok bool) { | 
 | 	// This function exists in the image/internal/imageutil package because it | 
 | 	// is needed by both the image/draw and image/jpeg packages, but it doesn't | 
 | 	// seem right for one of those two to depend on the other. | 
 | 	// | 
 | 	// Another option is to have this code be exported in the image package, | 
 | 	// but we'd need to make sure we're totally happy with the API (for the | 
 | 	// rest of Go 1 compatibility), and decide if we want to have a more | 
 | 	// general purpose DrawToRGBA method for other image types. One possibility | 
 | 	// is: | 
 | 	// | 
 | 	// func (src *YCbCr) CopyToRGBA(dst *RGBA, dr, sr Rectangle) (effectiveDr, effectiveSr Rectangle) | 
 | 	// | 
 | 	// in the spirit of the built-in copy function for 1-dimensional slices, | 
 | 	// that also allowed a CopyFromRGBA method if needed. | 
 |  | 
 | 	x0 := (r.Min.X - dst.Rect.Min.X) * 4 | 
 | 	x1 := (r.Max.X - dst.Rect.Min.X) * 4 | 
 | 	y0 := r.Min.Y - dst.Rect.Min.Y | 
 | 	y1 := r.Max.Y - dst.Rect.Min.Y | 
 | 	switch src.SubsampleRatio { | 
 | ` | 
 |  | 
 | const post = ` | 
 | 	default: | 
 | 		return false | 
 | 	} | 
 | 	return true | 
 | } | 
 | ` | 
 |  | 
 | const sratioCase = ` | 
 | 	case image.YCbCrSubsampleRatio%s: | 
 | 		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 { | 
 | 			dpix := dst.Pix[y*dst.Stride:] | 
 | 			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X) | 
 | 			%s | 
 |  | 
 | 				// This is an inline version of image/color/ycbcr.go's func YCbCrToRGB. | 
 | 				yy1 := int32(src.Y[yi]) * 0x10101 | 
 | 				cb1 := int32(src.Cb[ci]) - 128 | 
 | 				cr1 := int32(src.Cr[ci]) - 128 | 
 |  | 
 | 				// The bit twiddling below is equivalent to | 
 | 				// | 
 | 				// r := (yy1 + 91881*cr1) >> 16 | 
 | 				// if r < 0 { | 
 | 				//     r = 0 | 
 | 				// } else if r > 0xff { | 
 | 				//     r = ^int32(0) | 
 | 				// } | 
 | 				// | 
 | 				// but uses fewer branches and is faster. | 
 | 				// Note that the uint8 type conversion in the return | 
 | 				// statement will convert ^int32(0) to 0xff. | 
 | 				// The code below to compute g and b uses a similar pattern. | 
 | 				r := yy1 + 91881*cr1 | 
 | 				if uint32(r)&0xff000000 == 0 { | 
 | 					r >>= 16 | 
 | 				} else { | 
 | 					r = ^(r >> 31) | 
 | 				} | 
 |  | 
 | 				g := yy1 - 22554*cb1 - 46802*cr1 | 
 | 				if uint32(g)&0xff000000 == 0 { | 
 | 					g >>= 16 | 
 | 				} else { | 
 | 					g = ^(g >> 31) | 
 | 				} | 
 |  | 
 | 				b := yy1 + 116130*cb1 | 
 | 				if uint32(b)&0xff000000 == 0 { | 
 | 					b >>= 16 | 
 | 				} else { | 
 | 					b = ^(b >> 31) | 
 | 				} | 
 |  | 
 |  | 
 | 				// use a temp slice to hint to the compiler that a single bounds check suffices | 
 | 				rgba := dpix[x : x+4 : len(dpix)] | 
 | 				rgba[0] = uint8(r) | 
 | 				rgba[1] = uint8(g) | 
 | 				rgba[2] = uint8(b) | 
 | 				rgba[3] = 255 | 
 | 			} | 
 | 		} | 
 | ` | 
 |  | 
 | var subsampleRatios = []string{ | 
 | 	"444", | 
 | 	"422", | 
 | 	"420", | 
 | 	"440", | 
 | } | 
 |  | 
 | var sratioLines = map[string]string{ | 
 | 	"444": ` | 
 | 		ci := (sy-src.Rect.Min.Y)*src.CStride + (sp.X - src.Rect.Min.X) | 
 | 		for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 { | 
 | 	`, | 
 | 	"422": ` | 
 | 		ciBase := (sy-src.Rect.Min.Y)*src.CStride - src.Rect.Min.X/2 | 
 | 		for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 { | 
 | 			ci := ciBase + sx/2 | 
 | 	`, | 
 | 	"420": ` | 
 | 		ciBase := (sy/2-src.Rect.Min.Y/2)*src.CStride - src.Rect.Min.X/2 | 
 | 		for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 { | 
 | 			ci := ciBase + sx/2 | 
 | 	`, | 
 | 	"440": ` | 
 | 		ci := (sy/2-src.Rect.Min.Y/2)*src.CStride + (sp.X - src.Rect.Min.X) | 
 | 		for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 { | 
 | 	`, | 
 | } |