github.com/goproxy0/go@v0.0.0-20171111080102-49cc0c489d2c/src/image/internal/imageutil/impl.go (about) 1 // 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 // This is an inline version of image/color/ycbcr.go's func YCbCrToRGB. 46 yy1 := int32(src.Y[yi]) * 0x10101 47 cb1 := int32(src.Cb[ci]) - 128 48 cr1 := int32(src.Cr[ci]) - 128 49 50 // The bit twiddling below is equivalent to 51 // 52 // r := (yy1 + 91881*cr1) >> 16 53 // if r < 0 { 54 // r = 0 55 // } else if r > 0xff { 56 // r = ^int32(0) 57 // } 58 // 59 // but uses fewer branches and is faster. 60 // Note that the uint8 type conversion in the return 61 // statement will convert ^int32(0) to 0xff. 62 // The code below to compute g and b uses a similar pattern. 63 r := yy1 + 91881*cr1 64 if uint32(r)&0xff000000 == 0 { 65 r >>= 16 66 } else { 67 r = ^(r >> 31) 68 } 69 70 g := yy1 - 22554*cb1 - 46802*cr1 71 if uint32(g)&0xff000000 == 0 { 72 g >>= 16 73 } else { 74 g = ^(g >> 31) 75 } 76 77 b := yy1 + 116130*cb1 78 if uint32(b)&0xff000000 == 0 { 79 b >>= 16 80 } else { 81 b = ^(b >> 31) 82 } 83 84 // use a temp slice to hint to the compiler that a single bounds check suffices 85 rgba := dpix[x : x+4 : len(dpix)] 86 rgba[0] = uint8(r) 87 rgba[1] = uint8(g) 88 rgba[2] = uint8(b) 89 rgba[3] = 255 90 } 91 } 92 93 case image.YCbCrSubsampleRatio422: 94 for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 { 95 dpix := dst.Pix[y*dst.Stride:] 96 yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X) 97 98 ciBase := (sy-src.Rect.Min.Y)*src.CStride - src.Rect.Min.X/2 99 for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 { 100 ci := ciBase + sx/2 101 102 // This is an inline version of image/color/ycbcr.go's func YCbCrToRGB. 103 yy1 := int32(src.Y[yi]) * 0x10101 104 cb1 := int32(src.Cb[ci]) - 128 105 cr1 := int32(src.Cr[ci]) - 128 106 107 // The bit twiddling below is equivalent to 108 // 109 // r := (yy1 + 91881*cr1) >> 16 110 // if r < 0 { 111 // r = 0 112 // } else if r > 0xff { 113 // r = ^int32(0) 114 // } 115 // 116 // but uses fewer branches and is faster. 117 // Note that the uint8 type conversion in the return 118 // statement will convert ^int32(0) to 0xff. 119 // The code below to compute g and b uses a similar pattern. 120 r := yy1 + 91881*cr1 121 if uint32(r)&0xff000000 == 0 { 122 r >>= 16 123 } else { 124 r = ^(r >> 31) 125 } 126 127 g := yy1 - 22554*cb1 - 46802*cr1 128 if uint32(g)&0xff000000 == 0 { 129 g >>= 16 130 } else { 131 g = ^(g >> 31) 132 } 133 134 b := yy1 + 116130*cb1 135 if uint32(b)&0xff000000 == 0 { 136 b >>= 16 137 } else { 138 b = ^(b >> 31) 139 } 140 141 // use a temp slice to hint to the compiler that a single bounds check suffices 142 rgba := dpix[x : x+4 : len(dpix)] 143 rgba[0] = uint8(r) 144 rgba[1] = uint8(g) 145 rgba[2] = uint8(b) 146 rgba[3] = 255 147 } 148 } 149 150 case image.YCbCrSubsampleRatio420: 151 for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 { 152 dpix := dst.Pix[y*dst.Stride:] 153 yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X) 154 155 ciBase := (sy/2-src.Rect.Min.Y/2)*src.CStride - src.Rect.Min.X/2 156 for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 { 157 ci := ciBase + sx/2 158 159 // This is an inline version of image/color/ycbcr.go's func YCbCrToRGB. 160 yy1 := int32(src.Y[yi]) * 0x10101 161 cb1 := int32(src.Cb[ci]) - 128 162 cr1 := int32(src.Cr[ci]) - 128 163 164 // The bit twiddling below is equivalent to 165 // 166 // r := (yy1 + 91881*cr1) >> 16 167 // if r < 0 { 168 // r = 0 169 // } else if r > 0xff { 170 // r = ^int32(0) 171 // } 172 // 173 // but uses fewer branches and is faster. 174 // Note that the uint8 type conversion in the return 175 // statement will convert ^int32(0) to 0xff. 176 // The code below to compute g and b uses a similar pattern. 177 r := yy1 + 91881*cr1 178 if uint32(r)&0xff000000 == 0 { 179 r >>= 16 180 } else { 181 r = ^(r >> 31) 182 } 183 184 g := yy1 - 22554*cb1 - 46802*cr1 185 if uint32(g)&0xff000000 == 0 { 186 g >>= 16 187 } else { 188 g = ^(g >> 31) 189 } 190 191 b := yy1 + 116130*cb1 192 if uint32(b)&0xff000000 == 0 { 193 b >>= 16 194 } else { 195 b = ^(b >> 31) 196 } 197 198 // use a temp slice to hint to the compiler that a single bounds check suffices 199 rgba := dpix[x : x+4 : len(dpix)] 200 rgba[0] = uint8(r) 201 rgba[1] = uint8(g) 202 rgba[2] = uint8(b) 203 rgba[3] = 255 204 } 205 } 206 207 case image.YCbCrSubsampleRatio440: 208 for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 { 209 dpix := dst.Pix[y*dst.Stride:] 210 yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X) 211 212 ci := (sy/2-src.Rect.Min.Y/2)*src.CStride + (sp.X - src.Rect.Min.X) 213 for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 { 214 // This is an inline version of image/color/ycbcr.go's func YCbCrToRGB. 215 yy1 := int32(src.Y[yi]) * 0x10101 216 cb1 := int32(src.Cb[ci]) - 128 217 cr1 := int32(src.Cr[ci]) - 128 218 219 // The bit twiddling below is equivalent to 220 // 221 // r := (yy1 + 91881*cr1) >> 16 222 // if r < 0 { 223 // r = 0 224 // } else if r > 0xff { 225 // r = ^int32(0) 226 // } 227 // 228 // but uses fewer branches and is faster. 229 // Note that the uint8 type conversion in the return 230 // statement will convert ^int32(0) to 0xff. 231 // The code below to compute g and b uses a similar pattern. 232 r := yy1 + 91881*cr1 233 if uint32(r)&0xff000000 == 0 { 234 r >>= 16 235 } else { 236 r = ^(r >> 31) 237 } 238 239 g := yy1 - 22554*cb1 - 46802*cr1 240 if uint32(g)&0xff000000 == 0 { 241 g >>= 16 242 } else { 243 g = ^(g >> 31) 244 } 245 246 b := yy1 + 116130*cb1 247 if uint32(b)&0xff000000 == 0 { 248 b >>= 16 249 } else { 250 b = ^(b >> 31) 251 } 252 253 // use a temp slice to hint to the compiler that a single bounds check suffices 254 rgba := dpix[x : x+4 : len(dpix)] 255 rgba[0] = uint8(r) 256 rgba[1] = uint8(g) 257 rgba[2] = uint8(b) 258 rgba[3] = 255 259 } 260 } 261 262 default: 263 return false 264 } 265 return true 266 }