github.com/mdempsky/go@v0.0.0-20151201204031-5dd372bd1e70/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  
    46  				// This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
    47  				yy1 := int32(src.Y[yi]) * 0x10100 // Convert 0x12 to 0x121200.
    48  				cb1 := int32(src.Cb[ci]) - 128
    49  				cr1 := int32(src.Cr[ci]) - 128
    50  				r := (yy1 + 91881*cr1) >> 16
    51  				g := (yy1 - 22554*cb1 - 46802*cr1) >> 16
    52  				b := (yy1 + 116130*cb1) >> 16
    53  				if r < 0 {
    54  					r = 0
    55  				} else if r > 255 {
    56  					r = 255
    57  				}
    58  				if g < 0 {
    59  					g = 0
    60  				} else if g > 255 {
    61  					g = 255
    62  				}
    63  				if b < 0 {
    64  					b = 0
    65  				} else if b > 255 {
    66  					b = 255
    67  				}
    68  
    69  				dpix[x+0] = uint8(r)
    70  				dpix[x+1] = uint8(g)
    71  				dpix[x+2] = uint8(b)
    72  				dpix[x+3] = 255
    73  			}
    74  		}
    75  
    76  	case image.YCbCrSubsampleRatio422:
    77  		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
    78  			dpix := dst.Pix[y*dst.Stride:]
    79  			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
    80  
    81  			ciBase := (sy-src.Rect.Min.Y)*src.CStride - src.Rect.Min.X/2
    82  			for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
    83  				ci := ciBase + sx/2
    84  
    85  				// This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
    86  				yy1 := int32(src.Y[yi]) * 0x10100 // Convert 0x12 to 0x121200.
    87  				cb1 := int32(src.Cb[ci]) - 128
    88  				cr1 := int32(src.Cr[ci]) - 128
    89  				r := (yy1 + 91881*cr1) >> 16
    90  				g := (yy1 - 22554*cb1 - 46802*cr1) >> 16
    91  				b := (yy1 + 116130*cb1) >> 16
    92  				if r < 0 {
    93  					r = 0
    94  				} else if r > 255 {
    95  					r = 255
    96  				}
    97  				if g < 0 {
    98  					g = 0
    99  				} else if g > 255 {
   100  					g = 255
   101  				}
   102  				if b < 0 {
   103  					b = 0
   104  				} else if b > 255 {
   105  					b = 255
   106  				}
   107  
   108  				dpix[x+0] = uint8(r)
   109  				dpix[x+1] = uint8(g)
   110  				dpix[x+2] = uint8(b)
   111  				dpix[x+3] = 255
   112  			}
   113  		}
   114  
   115  	case image.YCbCrSubsampleRatio420:
   116  		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
   117  			dpix := dst.Pix[y*dst.Stride:]
   118  			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
   119  
   120  			ciBase := (sy/2-src.Rect.Min.Y/2)*src.CStride - src.Rect.Min.X/2
   121  			for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 {
   122  				ci := ciBase + sx/2
   123  
   124  				// This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
   125  				yy1 := int32(src.Y[yi]) * 0x10100 // Convert 0x12 to 0x121200.
   126  				cb1 := int32(src.Cb[ci]) - 128
   127  				cr1 := int32(src.Cr[ci]) - 128
   128  				r := (yy1 + 91881*cr1) >> 16
   129  				g := (yy1 - 22554*cb1 - 46802*cr1) >> 16
   130  				b := (yy1 + 116130*cb1) >> 16
   131  				if r < 0 {
   132  					r = 0
   133  				} else if r > 255 {
   134  					r = 255
   135  				}
   136  				if g < 0 {
   137  					g = 0
   138  				} else if g > 255 {
   139  					g = 255
   140  				}
   141  				if b < 0 {
   142  					b = 0
   143  				} else if b > 255 {
   144  					b = 255
   145  				}
   146  
   147  				dpix[x+0] = uint8(r)
   148  				dpix[x+1] = uint8(g)
   149  				dpix[x+2] = uint8(b)
   150  				dpix[x+3] = 255
   151  			}
   152  		}
   153  
   154  	case image.YCbCrSubsampleRatio440:
   155  		for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 {
   156  			dpix := dst.Pix[y*dst.Stride:]
   157  			yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X)
   158  
   159  			ci := (sy/2-src.Rect.Min.Y/2)*src.CStride + (sp.X - src.Rect.Min.X)
   160  			for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 {
   161  
   162  				// This is an inline version of image/color/ycbcr.go's func YCbCrToRGB.
   163  				yy1 := int32(src.Y[yi]) * 0x10100 // Convert 0x12 to 0x121200.
   164  				cb1 := int32(src.Cb[ci]) - 128
   165  				cr1 := int32(src.Cr[ci]) - 128
   166  				r := (yy1 + 91881*cr1) >> 16
   167  				g := (yy1 - 22554*cb1 - 46802*cr1) >> 16
   168  				b := (yy1 + 116130*cb1) >> 16
   169  				if r < 0 {
   170  					r = 0
   171  				} else if r > 255 {
   172  					r = 255
   173  				}
   174  				if g < 0 {
   175  					g = 0
   176  				} else if g > 255 {
   177  					g = 255
   178  				}
   179  				if b < 0 {
   180  					b = 0
   181  				} else if b > 255 {
   182  					b = 255
   183  				}
   184  
   185  				dpix[x+0] = uint8(r)
   186  				dpix[x+1] = uint8(g)
   187  				dpix[x+2] = uint8(b)
   188  				dpix[x+3] = 255
   189  			}
   190  		}
   191  
   192  	default:
   193  		return false
   194  	}
   195  	return true
   196  }