1 // Code generated by go run gen.go; DO NOT EDIT.
2 3 package imageutil
4 5 import (
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.
16 func 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