f8d9fa9e80
This upgrades all of libgo other than the runtime package to the Go 1.4 release. In Go 1.4 much of the runtime was rewritten into Go. Merging that code will take more time and will not change the API, so I'm putting it off for now. There are a few runtime changes anyhow, to accomodate other packages that rely on minor modifications to the runtime support. The compiler changes slightly to add a one-bit flag to each type descriptor kind that is stored directly in an interface, which for gccgo is currently only pointer types. Another one-bit flag (gcprog) is reserved because it is used by the gc compiler, but gccgo does not currently use it. There is another error check in the compiler since I ran across it during testing. gotools/: * Makefile.am (go_cmd_go_files): Sort entries. Add generate.go. * Makefile.in: Rebuild. From-SVN: r219627
158 lines
4.4 KiB
Go
158 lines
4.4 KiB
Go
// Copyright 2011 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package image
|
|
|
|
import (
|
|
"image/color"
|
|
)
|
|
|
|
// YCbCrSubsampleRatio is the chroma subsample ratio used in a YCbCr image.
|
|
type YCbCrSubsampleRatio int
|
|
|
|
const (
|
|
YCbCrSubsampleRatio444 YCbCrSubsampleRatio = iota
|
|
YCbCrSubsampleRatio422
|
|
YCbCrSubsampleRatio420
|
|
YCbCrSubsampleRatio440
|
|
)
|
|
|
|
func (s YCbCrSubsampleRatio) String() string {
|
|
switch s {
|
|
case YCbCrSubsampleRatio444:
|
|
return "YCbCrSubsampleRatio444"
|
|
case YCbCrSubsampleRatio422:
|
|
return "YCbCrSubsampleRatio422"
|
|
case YCbCrSubsampleRatio420:
|
|
return "YCbCrSubsampleRatio420"
|
|
case YCbCrSubsampleRatio440:
|
|
return "YCbCrSubsampleRatio440"
|
|
}
|
|
return "YCbCrSubsampleRatioUnknown"
|
|
}
|
|
|
|
// YCbCr is an in-memory image of Y'CbCr colors. There is one Y sample per
|
|
// pixel, but each Cb and Cr sample can span one or more pixels.
|
|
// YStride is the Y slice index delta between vertically adjacent pixels.
|
|
// CStride is the Cb and Cr slice index delta between vertically adjacent pixels
|
|
// that map to separate chroma samples.
|
|
// It is not an absolute requirement, but YStride and len(Y) are typically
|
|
// multiples of 8, and:
|
|
// For 4:4:4, CStride == YStride/1 && len(Cb) == len(Cr) == len(Y)/1.
|
|
// For 4:2:2, CStride == YStride/2 && len(Cb) == len(Cr) == len(Y)/2.
|
|
// For 4:2:0, CStride == YStride/2 && len(Cb) == len(Cr) == len(Y)/4.
|
|
// For 4:4:0, CStride == YStride/1 && len(Cb) == len(Cr) == len(Y)/2.
|
|
type YCbCr struct {
|
|
Y, Cb, Cr []uint8
|
|
YStride int
|
|
CStride int
|
|
SubsampleRatio YCbCrSubsampleRatio
|
|
Rect Rectangle
|
|
}
|
|
|
|
func (p *YCbCr) ColorModel() color.Model {
|
|
return color.YCbCrModel
|
|
}
|
|
|
|
func (p *YCbCr) Bounds() Rectangle {
|
|
return p.Rect
|
|
}
|
|
|
|
func (p *YCbCr) At(x, y int) color.Color {
|
|
return p.YCbCrAt(x, y)
|
|
}
|
|
|
|
func (p *YCbCr) YCbCrAt(x, y int) color.YCbCr {
|
|
if !(Point{x, y}.In(p.Rect)) {
|
|
return color.YCbCr{}
|
|
}
|
|
yi := p.YOffset(x, y)
|
|
ci := p.COffset(x, y)
|
|
return color.YCbCr{
|
|
p.Y[yi],
|
|
p.Cb[ci],
|
|
p.Cr[ci],
|
|
}
|
|
}
|
|
|
|
// YOffset returns the index of the first element of Y that corresponds to
|
|
// the pixel at (x, y).
|
|
func (p *YCbCr) YOffset(x, y int) int {
|
|
return (y-p.Rect.Min.Y)*p.YStride + (x - p.Rect.Min.X)
|
|
}
|
|
|
|
// COffset returns the index of the first element of Cb or Cr that corresponds
|
|
// to the pixel at (x, y).
|
|
func (p *YCbCr) COffset(x, y int) int {
|
|
switch p.SubsampleRatio {
|
|
case YCbCrSubsampleRatio422:
|
|
return (y-p.Rect.Min.Y)*p.CStride + (x/2 - p.Rect.Min.X/2)
|
|
case YCbCrSubsampleRatio420:
|
|
return (y/2-p.Rect.Min.Y/2)*p.CStride + (x/2 - p.Rect.Min.X/2)
|
|
case YCbCrSubsampleRatio440:
|
|
return (y/2-p.Rect.Min.Y/2)*p.CStride + (x - p.Rect.Min.X)
|
|
}
|
|
// Default to 4:4:4 subsampling.
|
|
return (y-p.Rect.Min.Y)*p.CStride + (x - p.Rect.Min.X)
|
|
}
|
|
|
|
// SubImage returns an image representing the portion of the image p visible
|
|
// through r. The returned value shares pixels with the original image.
|
|
func (p *YCbCr) SubImage(r Rectangle) Image {
|
|
r = r.Intersect(p.Rect)
|
|
// If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside
|
|
// either r1 or r2 if the intersection is empty. Without explicitly checking for
|
|
// this, the Pix[i:] expression below can panic.
|
|
if r.Empty() {
|
|
return &YCbCr{
|
|
SubsampleRatio: p.SubsampleRatio,
|
|
}
|
|
}
|
|
yi := p.YOffset(r.Min.X, r.Min.Y)
|
|
ci := p.COffset(r.Min.X, r.Min.Y)
|
|
return &YCbCr{
|
|
Y: p.Y[yi:],
|
|
Cb: p.Cb[ci:],
|
|
Cr: p.Cr[ci:],
|
|
SubsampleRatio: p.SubsampleRatio,
|
|
YStride: p.YStride,
|
|
CStride: p.CStride,
|
|
Rect: r,
|
|
}
|
|
}
|
|
|
|
func (p *YCbCr) Opaque() bool {
|
|
return true
|
|
}
|
|
|
|
// NewYCbCr returns a new YCbCr with the given bounds and subsample ratio.
|
|
func NewYCbCr(r Rectangle, subsampleRatio YCbCrSubsampleRatio) *YCbCr {
|
|
w, h, cw, ch := r.Dx(), r.Dy(), 0, 0
|
|
switch subsampleRatio {
|
|
case YCbCrSubsampleRatio422:
|
|
cw = (r.Max.X+1)/2 - r.Min.X/2
|
|
ch = h
|
|
case YCbCrSubsampleRatio420:
|
|
cw = (r.Max.X+1)/2 - r.Min.X/2
|
|
ch = (r.Max.Y+1)/2 - r.Min.Y/2
|
|
case YCbCrSubsampleRatio440:
|
|
cw = w
|
|
ch = (r.Max.Y+1)/2 - r.Min.Y/2
|
|
default:
|
|
// Default to 4:4:4 subsampling.
|
|
cw = w
|
|
ch = h
|
|
}
|
|
b := make([]byte, w*h+2*cw*ch)
|
|
return &YCbCr{
|
|
Y: b[:w*h],
|
|
Cb: b[w*h+0*cw*ch : w*h+1*cw*ch],
|
|
Cr: b[w*h+1*cw*ch : w*h+2*cw*ch],
|
|
SubsampleRatio: subsampleRatio,
|
|
YStride: w,
|
|
CStride: cw,
|
|
Rect: r,
|
|
}
|
|
}
|