impl.mx raw

   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