1// Code generated by go run gen.go; DO NOT EDIT.
2
3package imageutil
4
5import (
6	"image"
7)
8
9// DrawYCbCr draws the YCbCr source image on the RGBA destination image with
10// r.Min in dst aligned with sp in src. It reports whether the draw was
11// successful. If it returns false, no dst pixels were changed.
12//
13// This function assumes that r is entirely within dst's bounds and the
14// translation of r from dst coordinate space to src coordinate space is
15// entirely within src's bounds.
16func DrawYCbCr(dst *image.RGBA, r image.Rectangle, src *image.YCbCr, sp image.Point) (ok bool) {
17	// This function exists in the image/internal/imageutil package because it
18	// is needed by both the image/draw and image/jpeg packages, but it doesn't
19	// seem right for one of those two to depend on the other.
20	//
21	// Another option is to have this code be exported in the image package,
22	// but we'd need to make sure we're totally happy with the API (for the
23	// rest of Go 1 compatibility), and decide if we want to have a more
24	// general purpose DrawToRGBA method for other image types. One possibility
25	// is:
26	//
27	// func (src *YCbCr) CopyToRGBA(dst *RGBA, dr, sr Rectangle) (effectiveDr, effectiveSr Rectangle)
28	//
29	// in the spirit of the built-in copy function for 1-dimensional slices,
30	// that also allowed a CopyFromRGBA method if needed.
31
32	x0 := (r.Min.X - dst.Rect.Min.X) * 4
33	x1 := (r.Max.X - dst.Rect.Min.X) * 4
34	y0 := r.Min.Y - dst.Rect.Min.Y
35	y1 := r.Max.Y - dst.Rect.Min.Y
36	switch src.SubsampleRatio {
37
38	case image.YCbCrSubsampleRatio444:
39		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
40			dpix := dst.Pix[y*dst.Stride:]
41			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
42
43			ci := (sy-src.Rect.Min.Y)*src.CStride + (sp.X - src.Rect.Min.X)
44			for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
45
46				// This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
47				yy1 := int32(src.Y[yi]) * 0x10101
48				cb1 := int32(src.Cb[ci]) - 128
49				cr1 := int32(src.Cr[ci]) - 128
50
51				// The bit twiddling below is equivalent to
52				//
53				// r := (yy1 + 91881*cr1) >> 16
54				// if r < 0 {
55				//     r = 0
56				// } else if r > 0xff {
57				//     r = ^int32(0)
58				// }
59				//
60				// but uses fewer branches and is faster.
61				// Note that the uint8 type conversion in the return
62				// statement will convert ^int32(0) to 0xff.
63				// The code below to compute g and b uses a similar pattern.
64				r := yy1 + 91881*cr1
65				if uint32(r)&0xff000000 == 0 {
66					r >>= 16
67				} else {
68					r = ^(r >> 31)
69				}
70
71				g := yy1 - 22554*cb1 - 46802*cr1
72				if uint32(g)&0xff000000 == 0 {
73					g >>= 16
74				} else {
75					g = ^(g >> 31)
76				}
77
78				b := yy1 + 116130*cb1
79				if uint32(b)&0xff000000 == 0 {
80					b >>= 16
81				} else {
82					b = ^(b >> 31)
83				}
84
85				// use a temp slice to hint to the compiler that a single bounds check suffices
86				rgba := dpix[x : x+4 : len(dpix)]
87				rgba[0] = uint8(r)
88				rgba[1] = uint8(g)
89				rgba[2] = uint8(b)
90				rgba[3] = 255
91			}
92		}
93
94	case image.YCbCrSubsampleRatio422:
95		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
96			dpix := dst.Pix[y*dst.Stride:]
97			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
98
99			ciBase := (sy-src.Rect.Min.Y)*src.CStride - src.Rect.Min.X/2
100			for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
101				ci := ciBase + sx/2
102
103				// This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
104				yy1 := int32(src.Y[yi]) * 0x10101
105				cb1 := int32(src.Cb[ci]) - 128
106				cr1 := int32(src.Cr[ci]) - 128
107
108				// The bit twiddling below is equivalent to
109				//
110				// r := (yy1 + 91881*cr1) >> 16
111				// if r < 0 {
112				//     r = 0
113				// } else if r > 0xff {
114				//     r = ^int32(0)
115				// }
116				//
117				// but uses fewer branches and is faster.
118				// Note that the uint8 type conversion in the return
119				// statement will convert ^int32(0) to 0xff.
120				// The code below to compute g and b uses a similar pattern.
121				r := yy1 + 91881*cr1
122				if uint32(r)&0xff000000 == 0 {
123					r >>= 16
124				} else {
125					r = ^(r >> 31)
126				}
127
128				g := yy1 - 22554*cb1 - 46802*cr1
129				if uint32(g)&0xff000000 == 0 {
130					g >>= 16
131				} else {
132					g = ^(g >> 31)
133				}
134
135				b := yy1 + 116130*cb1
136				if uint32(b)&0xff000000 == 0 {
137					b >>= 16
138				} else {
139					b = ^(b >> 31)
140				}
141
142				// use a temp slice to hint to the compiler that a single bounds check suffices
143				rgba := dpix[x : x+4 : len(dpix)]
144				rgba[0] = uint8(r)
145				rgba[1] = uint8(g)
146				rgba[2] = uint8(b)
147				rgba[3] = 255
148			}
149		}
150
151	case image.YCbCrSubsampleRatio420:
152		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
153			dpix := dst.Pix[y*dst.Stride:]
154			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
155
156			ciBase := (sy/2-src.Rect.Min.Y/2)*src.CStride - src.Rect.Min.X/2
157			for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
158				ci := ciBase + sx/2
159
160				// This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
161				yy1 := int32(src.Y[yi]) * 0x10101
162				cb1 := int32(src.Cb[ci]) - 128
163				cr1 := int32(src.Cr[ci]) - 128
164
165				// The bit twiddling below is equivalent to
166				//
167				// r := (yy1 + 91881*cr1) >> 16
168				// if r < 0 {
169				//     r = 0
170				// } else if r > 0xff {
171				//     r = ^int32(0)
172				// }
173				//
174				// but uses fewer branches and is faster.
175				// Note that the uint8 type conversion in the return
176				// statement will convert ^int32(0) to 0xff.
177				// The code below to compute g and b uses a similar pattern.
178				r := yy1 + 91881*cr1
179				if uint32(r)&0xff000000 == 0 {
180					r >>= 16
181				} else {
182					r = ^(r >> 31)
183				}
184
185				g := yy1 - 22554*cb1 - 46802*cr1
186				if uint32(g)&0xff000000 == 0 {
187					g >>= 16
188				} else {
189					g = ^(g >> 31)
190				}
191
192				b := yy1 + 116130*cb1
193				if uint32(b)&0xff000000 == 0 {
194					b >>= 16
195				} else {
196					b = ^(b >> 31)
197				}
198
199				// use a temp slice to hint to the compiler that a single bounds check suffices
200				rgba := dpix[x : x+4 : len(dpix)]
201				rgba[0] = uint8(r)
202				rgba[1] = uint8(g)
203				rgba[2] = uint8(b)
204				rgba[3] = 255
205			}
206		}
207
208	case image.YCbCrSubsampleRatio440:
209		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
210			dpix := dst.Pix[y*dst.Stride:]
211			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
212
213			ci := (sy/2-src.Rect.Min.Y/2)*src.CStride + (sp.X - src.Rect.Min.X)
214			for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
215
216				// This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
217				yy1 := int32(src.Y[yi]) * 0x10101
218				cb1 := int32(src.Cb[ci]) - 128
219				cr1 := int32(src.Cr[ci]) - 128
220
221				// The bit twiddling below is equivalent to
222				//
223				// r := (yy1 + 91881*cr1) >> 16
224				// if r < 0 {
225				//     r = 0
226				// } else if r > 0xff {
227				//     r = ^int32(0)
228				// }
229				//
230				// but uses fewer branches and is faster.
231				// Note that the uint8 type conversion in the return
232				// statement will convert ^int32(0) to 0xff.
233				// The code below to compute g and b uses a similar pattern.
234				r := yy1 + 91881*cr1
235				if uint32(r)&0xff000000 == 0 {
236					r >>= 16
237				} else {
238					r = ^(r >> 31)
239				}
240
241				g := yy1 - 22554*cb1 - 46802*cr1
242				if uint32(g)&0xff000000 == 0 {
243					g >>= 16
244				} else {
245					g = ^(g >> 31)
246				}
247
248				b := yy1 + 116130*cb1
249				if uint32(b)&0xff000000 == 0 {
250					b >>= 16
251				} else {
252					b = ^(b >> 31)
253				}
254
255				// use a temp slice to hint to the compiler that a single bounds check suffices
256				rgba := dpix[x : x+4 : len(dpix)]
257				rgba[0] = uint8(r)
258				rgba[1] = uint8(g)
259				rgba[2] = uint8(b)
260				rgba[3] = 255
261			}
262		}
263
264	default:
265		return false
266	}
267	return true
268}
269