...

Source file src/pkg/image/internal/imageutil/impl.go

     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	

View as plain text