| | |
| |
|
| | package imageutil |
| |
|
| | import ( |
| | "image" |
| | ) |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | func DrawYCbCr(dst *image.RGBA, r image.Rectangle, src *image.YCbCr, sp image.Point) (ok bool) { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | x0 := (r.Min.X - dst.Rect.Min.X) * 4 |
| | x1 := (r.Max.X - dst.Rect.Min.X) * 4 |
| | y0 := r.Min.Y - dst.Rect.Min.Y |
| | y1 := r.Max.Y - dst.Rect.Min.Y |
| | switch src.SubsampleRatio { |
| |
|
| | case image.YCbCrSubsampleRatio444: |
| | for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 { |
| | dpix := dst.Pix[y*dst.Stride:] |
| | yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X) |
| |
|
| | ci := (sy-src.Rect.Min.Y)*src.CStride + (sp.X - src.Rect.Min.X) |
| | for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 { |
| |
|
| | |
| | yy1 := int32(src.Y[yi]) * 0x10101 |
| | cb1 := int32(src.Cb[ci]) - 128 |
| | cr1 := int32(src.Cr[ci]) - 128 |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | r := yy1 + 91881*cr1 |
| | if uint32(r)&0xff000000 == 0 { |
| | r >>= 16 |
| | } else { |
| | r = ^(r >> 31) |
| | } |
| |
|
| | g := yy1 - 22554*cb1 - 46802*cr1 |
| | if uint32(g)&0xff000000 == 0 { |
| | g >>= 16 |
| | } else { |
| | g = ^(g >> 31) |
| | } |
| |
|
| | b := yy1 + 116130*cb1 |
| | if uint32(b)&0xff000000 == 0 { |
| | b >>= 16 |
| | } else { |
| | b = ^(b >> 31) |
| | } |
| |
|
| | |
| | rgba := dpix[x : x+4 : len(dpix)] |
| | rgba[0] = uint8(r) |
| | rgba[1] = uint8(g) |
| | rgba[2] = uint8(b) |
| | rgba[3] = 255 |
| | } |
| | } |
| |
|
| | case image.YCbCrSubsampleRatio422: |
| | for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 { |
| | dpix := dst.Pix[y*dst.Stride:] |
| | yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X) |
| |
|
| | ciBase := (sy-src.Rect.Min.Y)*src.CStride - src.Rect.Min.X/2 |
| | for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 { |
| | ci := ciBase + sx/2 |
| |
|
| | |
| | yy1 := int32(src.Y[yi]) * 0x10101 |
| | cb1 := int32(src.Cb[ci]) - 128 |
| | cr1 := int32(src.Cr[ci]) - 128 |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | r := yy1 + 91881*cr1 |
| | if uint32(r)&0xff000000 == 0 { |
| | r >>= 16 |
| | } else { |
| | r = ^(r >> 31) |
| | } |
| |
|
| | g := yy1 - 22554*cb1 - 46802*cr1 |
| | if uint32(g)&0xff000000 == 0 { |
| | g >>= 16 |
| | } else { |
| | g = ^(g >> 31) |
| | } |
| |
|
| | b := yy1 + 116130*cb1 |
| | if uint32(b)&0xff000000 == 0 { |
| | b >>= 16 |
| | } else { |
| | b = ^(b >> 31) |
| | } |
| |
|
| | |
| | rgba := dpix[x : x+4 : len(dpix)] |
| | rgba[0] = uint8(r) |
| | rgba[1] = uint8(g) |
| | rgba[2] = uint8(b) |
| | rgba[3] = 255 |
| | } |
| | } |
| |
|
| | case image.YCbCrSubsampleRatio420: |
| | for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 { |
| | dpix := dst.Pix[y*dst.Stride:] |
| | yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X) |
| |
|
| | ciBase := (sy/2-src.Rect.Min.Y/2)*src.CStride - src.Rect.Min.X/2 |
| | for x, sx := x0, sp.X; x != x1; x, sx, yi = x+4, sx+1, yi+1 { |
| | ci := ciBase + sx/2 |
| |
|
| | |
| | yy1 := int32(src.Y[yi]) * 0x10101 |
| | cb1 := int32(src.Cb[ci]) - 128 |
| | cr1 := int32(src.Cr[ci]) - 128 |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | r := yy1 + 91881*cr1 |
| | if uint32(r)&0xff000000 == 0 { |
| | r >>= 16 |
| | } else { |
| | r = ^(r >> 31) |
| | } |
| |
|
| | g := yy1 - 22554*cb1 - 46802*cr1 |
| | if uint32(g)&0xff000000 == 0 { |
| | g >>= 16 |
| | } else { |
| | g = ^(g >> 31) |
| | } |
| |
|
| | b := yy1 + 116130*cb1 |
| | if uint32(b)&0xff000000 == 0 { |
| | b >>= 16 |
| | } else { |
| | b = ^(b >> 31) |
| | } |
| |
|
| | |
| | rgba := dpix[x : x+4 : len(dpix)] |
| | rgba[0] = uint8(r) |
| | rgba[1] = uint8(g) |
| | rgba[2] = uint8(b) |
| | rgba[3] = 255 |
| | } |
| | } |
| |
|
| | case image.YCbCrSubsampleRatio440: |
| | for y, sy := y0, sp.Y; y != y1; y, sy = y+1, sy+1 { |
| | dpix := dst.Pix[y*dst.Stride:] |
| | yi := (sy-src.Rect.Min.Y)*src.YStride + (sp.X - src.Rect.Min.X) |
| |
|
| | ci := (sy/2-src.Rect.Min.Y/2)*src.CStride + (sp.X - src.Rect.Min.X) |
| | for x := x0; x != x1; x, yi, ci = x+4, yi+1, ci+1 { |
| |
|
| | |
| | yy1 := int32(src.Y[yi]) * 0x10101 |
| | cb1 := int32(src.Cb[ci]) - 128 |
| | cr1 := int32(src.Cr[ci]) - 128 |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | r := yy1 + 91881*cr1 |
| | if uint32(r)&0xff000000 == 0 { |
| | r >>= 16 |
| | } else { |
| | r = ^(r >> 31) |
| | } |
| |
|
| | g := yy1 - 22554*cb1 - 46802*cr1 |
| | if uint32(g)&0xff000000 == 0 { |
| | g >>= 16 |
| | } else { |
| | g = ^(g >> 31) |
| | } |
| |
|
| | b := yy1 + 116130*cb1 |
| | if uint32(b)&0xff000000 == 0 { |
| | b >>= 16 |
| | } else { |
| | b = ^(b >> 31) |
| | } |
| |
|
| | |
| | rgba := dpix[x : x+4 : len(dpix)] |
| | rgba[0] = uint8(r) |
| | rgba[1] = uint8(g) |
| | rgba[2] = uint8(b) |
| | rgba[3] = 255 |
| | } |
| | } |
| |
|
| | default: |
| | return false |
| | } |
| | return true |
| | } |
| |
|