* gcc.dg/guality/guality.exp: Skip on AIX.
[official-gcc.git] / libgo / go / image / ycbcr.go
blob5b73bef789581e21a684362dd8deec35ab0b3dfc
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.
5 package image
7 import (
8 "image/color"
11 // YCbCrSubsampleRatio is the chroma subsample ratio used in a YCbCr image.
12 type YCbCrSubsampleRatio int
14 const (
15 YCbCrSubsampleRatio444 YCbCrSubsampleRatio = iota
16 YCbCrSubsampleRatio422
17 YCbCrSubsampleRatio420
18 YCbCrSubsampleRatio440
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"
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.
46 type YCbCr struct {
47 Y, Cb, Cr []uint8
48 YStride int
49 CStride int
50 SubsampleRatio YCbCrSubsampleRatio
51 Rect Rectangle
54 func (p *YCbCr) ColorModel() color.Model {
55 return color.YCbCrModel
58 func (p *YCbCr) Bounds() Rectangle {
59 return p.Rect
62 func (p *YCbCr) At(x, y int) color.Color {
63 if !(Point{x, y}.In(p.Rect)) {
64 return color.YCbCr{}
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],
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.
103 if r.Empty() {
104 return &YCbCr{
105 SubsampleRatio: p.SubsampleRatio,
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,
121 func (p *YCbCr) Opaque() bool {
122 return true
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
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 // Default to 4:4:4 subsampling.
140 cw = w
141 ch = h
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,