1 // Copyright 2011 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
11 // YCbCrSubsampleRatio is the chroma subsample ratio used in a YCbCr image.
12 type YCbCrSubsampleRatio
int
15 YCbCrSubsampleRatio444 YCbCrSubsampleRatio
= iota
16 YCbCrSubsampleRatio422
17 YCbCrSubsampleRatio420
18 YCbCrSubsampleRatio440
21 func (s YCbCrSubsampleRatio
) String() string {
23 case YCbCrSubsampleRatio444
:
24 return "YCbCrSubsampleRatio444"
25 case YCbCrSubsampleRatio422
:
26 return "YCbCrSubsampleRatio422"
27 case YCbCrSubsampleRatio420
:
28 return "YCbCrSubsampleRatio420"
29 case YCbCrSubsampleRatio440
:
30 return "YCbCrSubsampleRatio440"
32 return "YCbCrSubsampleRatioUnknown"
35 // YCbCr is an in-memory image of Y'CbCr colors. There is one Y sample per
36 // pixel, but each Cb and Cr sample can span one or more pixels.
37 // YStride is the Y slice index delta between vertically adjacent pixels.
38 // CStride is the Cb and Cr slice index delta between vertically adjacent pixels
39 // that map to separate chroma samples.
40 // It is not an absolute requirement, but YStride and len(Y) are typically
41 // multiples of 8, and:
42 // For 4:4:4, CStride == YStride/1 && len(Cb) == len(Cr) == len(Y)/1.
43 // For 4:2:2, CStride == YStride/2 && len(Cb) == len(Cr) == len(Y)/2.
44 // For 4:2:0, CStride == YStride/2 && len(Cb) == len(Cr) == len(Y)/4.
45 // For 4:4:0, CStride == YStride/1 && len(Cb) == len(Cr) == len(Y)/2.
50 SubsampleRatio YCbCrSubsampleRatio
54 func (p
*YCbCr
) ColorModel() color
.Model
{
55 return color
.YCbCrModel
58 func (p
*YCbCr
) Bounds() Rectangle
{
62 func (p
*YCbCr
) At(x
, y
int) color
.Color
{
63 if !(Point
{x
, y
}.In(p
.Rect
)) {
75 // YOffset returns the index of the first element of Y that corresponds to
76 // the pixel at (x, y).
77 func (p
*YCbCr
) YOffset(x
, y
int) int {
78 return (y
-p
.Rect
.Min
.Y
)*p
.YStride
+ (x
- p
.Rect
.Min
.X
)
81 // COffset returns the index of the first element of Cb or Cr that corresponds
82 // to the pixel at (x, y).
83 func (p
*YCbCr
) COffset(x
, y
int) int {
84 switch p
.SubsampleRatio
{
85 case YCbCrSubsampleRatio422
:
86 return (y
-p
.Rect
.Min
.Y
)*p
.CStride
+ (x
/2 - p
.Rect
.Min
.X
/2)
87 case YCbCrSubsampleRatio420
:
88 return (y
/2-p
.Rect
.Min
.Y
/2)*p
.CStride
+ (x
/2 - p
.Rect
.Min
.X
/2)
89 case YCbCrSubsampleRatio440
:
90 return (y
/2-p
.Rect
.Min
.Y
/2)*p
.CStride
+ (x
- p
.Rect
.Min
.X
)
92 // Default to 4:4:4 subsampling.
93 return (y
-p
.Rect
.Min
.Y
)*p
.CStride
+ (x
- p
.Rect
.Min
.X
)
96 // SubImage returns an image representing the portion of the image p visible
97 // through r. The returned value shares pixels with the original image.
98 func (p
*YCbCr
) SubImage(r Rectangle
) Image
{
99 r
= r
.Intersect(p
.Rect
)
100 // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
101 // either r1 or r2 if the intersection is empty. Without explicitly checking for
102 // this, the Pix[i:] expression below can panic.
105 SubsampleRatio
: p
.SubsampleRatio
,
108 yi
:= p
.YOffset(r
.Min
.X
, r
.Min
.Y
)
109 ci
:= p
.COffset(r
.Min
.X
, r
.Min
.Y
)
114 SubsampleRatio
: p
.SubsampleRatio
,
121 func (p
*YCbCr
) Opaque() bool {
125 // NewYCbCr returns a new YCbCr with the given bounds and subsample ratio.
126 func NewYCbCr(r Rectangle
, subsampleRatio YCbCrSubsampleRatio
) *YCbCr
{
127 w
, h
, cw
, ch
:= r
.Dx(), r
.Dy(), 0, 0
128 switch subsampleRatio
{
129 case YCbCrSubsampleRatio422
:
130 cw
= (r
.Max
.X
+1)/2 - r
.Min
.X
/2
132 case YCbCrSubsampleRatio420
:
133 cw
= (r
.Max
.X
+1)/2 - r
.Min
.X
/2
134 ch
= (r
.Max
.Y
+1)/2 - r
.Min
.Y
/2
135 case YCbCrSubsampleRatio440
:
137 ch
= (r
.Max
.Y
+1)/2 - r
.Min
.Y
/2
139 // Default to 4:4:4 subsampling.
143 b
:= make([]byte, w
*h
+2*cw
*ch
)
146 Cb
: b
[w
*h
+0*cw
*ch
: w
*h
+1*cw
*ch
],
147 Cr
: b
[w
*h
+1*cw
*ch
: w
*h
+2*cw
*ch
],
148 SubsampleRatio
: subsampleRatio
,