Source file src/pkg/image/ycbcr.go
1
2
3
4
5 package image
6
7 import (
8 "image/color"
9 )
10
11
12 type YCbCrSubsampleRatio int
13
14 const (
15 YCbCrSubsampleRatio444 YCbCrSubsampleRatio = iota
16 YCbCrSubsampleRatio422
17 YCbCrSubsampleRatio420
18 YCbCrSubsampleRatio440
19 )
20
21 func (s YCbCrSubsampleRatio) String() string {
22 switch s {
23 case YCbCrSubsampleRatio444:
24 return "YCbCrSubsampleRatio444"
25 case YCbCrSubsampleRatio422:
26 return "YCbCrSubsampleRatio422"
27 case YCbCrSubsampleRatio420:
28 return "YCbCrSubsampleRatio420"
29 case YCbCrSubsampleRatio440:
30 return "YCbCrSubsampleRatio440"
31 }
32 return "YCbCrSubsampleRatioUnknown"
33 }
34
35
36
37
38
39
40
41
42
43
44
45
46 type YCbCr struct {
47 Y, Cb, Cr []uint8
48 YStride int
49 CStride int
50 SubsampleRatio YCbCrSubsampleRatio
51 Rect Rectangle
52 }
53
54 func (p *YCbCr) ColorModel() color.Model {
55 return color.YCbCrModel
56 }
57
58 func (p *YCbCr) Bounds() Rectangle {
59 return p.Rect
60 }
61
62 func (p *YCbCr) At(x, y int) color.Color {
63 if !(Point{x, y}.In(p.Rect)) {
64 return color.YCbCr{}
65 }
66 yi := p.YOffset(x, y)
67 ci := p.COffset(x, y)
68 return color.YCbCr{
69 p.Y[yi],
70 p.Cb[ci],
71 p.Cr[ci],
72 }
73 }
74
75
76
77 func (p *YCbCr) YOffset(x, y int) int {
78 return (y-p.Rect.Min.Y)*p.YStride + (x - p.Rect.Min.X)
79 }
80
81
82
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)
91 }
92
93 return (y-p.Rect.Min.Y)*p.CStride + (x - p.Rect.Min.X)
94 }
95
96
97
98 func (p *YCbCr) SubImage(r Rectangle) Image {
99 r = r.Intersect(p.Rect)
100
101
102
103 if r.Empty() {
104 return &YCbCr{
105 SubsampleRatio: p.SubsampleRatio,
106 }
107 }
108 yi := p.YOffset(r.Min.X, r.Min.Y)
109 ci := p.COffset(r.Min.X, r.Min.Y)
110 return &YCbCr{
111 Y: p.Y[yi:],
112 Cb: p.Cb[ci:],
113 Cr: p.Cr[ci:],
114 SubsampleRatio: p.SubsampleRatio,
115 YStride: p.YStride,
116 CStride: p.CStride,
117 Rect: r,
118 }
119 }
120
121 func (p *YCbCr) Opaque() bool {
122 return true
123 }
124
125
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
131 ch = h
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:
136 cw = w
137 ch = (r.Max.Y+1)/2 - r.Min.Y/2
138 default:
139
140 cw = w
141 ch = h
142 }
143 b := make([]byte, w*h+2*cw*ch)
144 return &YCbCr{
145 Y: b[:w*h],
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,
149 YStride: w,
150 CStride: cw,
151 Rect: r,
152 }
153 }
View as plain text