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 } 197