ggstd 0.1.0

Partial implementation of Go standard library
Documentation
// // 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
// 	YCbCrSubsampleRatio411
// 	YCbCrSubsampleRatio410
// )

// func (s YCbCrSubsampleRatio) String() string {
// 	switch s {
// 	case YCbCrSubsampleRatio444:
// 		return "YCbCrSubsampleRatio444"
// 	case YCbCrSubsampleRatio422:
// 		return "YCbCrSubsampleRatio422"
// 	case YCbCrSubsampleRatio420:
// 		return "YCbCrSubsampleRatio420"
// 	case YCbCrSubsampleRatio440:
// 		return "YCbCrSubsampleRatio440"
// 	case YCbCrSubsampleRatio411:
// 		return "YCbCrSubsampleRatio411"
// 	case YCbCrSubsampleRatio410:
// 		return "YCbCrSubsampleRatio410"
// 	}
// 	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.
// //	For 4:1:1, CStride == YStride/4 && len(Cb) == len(Cr) == len(Y)/4.
// //	For 4:1:0, CStride == YStride/4 && len(Cb) == len(Cr) == len(Y)/8.
// 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) RGBA64At(x, y int) color.RGBA64 {
// 	r, g, b, a := p.YCbCrAt(x, y).rgba()
// 	return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
// }

// func (p *YCbCr) YCbCrAt(x, y int) color.YCbCr {
// 	if !(Point{x, y}.inside(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)
// 	case YCbCrSubsampleRatio411:
// 		return (y-p.Rect.min.y)*p.CStride + (x/4 - p.Rect.min.x/4)
// 	case YCbCrSubsampleRatio410:
// 		return (y/2-p.Rect.min.y/2)*p.CStride + (x/4 - p.Rect.min.x/4)
// 	}
// 	// 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
// }

// func yCbCrSize(r Rectangle, subsampleRatio YCbCrSubsampleRatio) (w, h, cw, ch int) {
// 	w, h = r.Dx(), r.Dy()
// 	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
// 	case YCbCrSubsampleRatio411:
// 		cw = (r.max.x+3)/4 - r.min.x/4
// 		ch = h
// 	case YCbCrSubsampleRatio410:
// 		cw = (r.max.x+3)/4 - r.min.x/4
// 		ch = (r.max.y+1)/2 - r.min.y/2
// 	default:
// 		// Default to 4:4:4 subsampling.
// 		cw = w
// 		ch = h
// 	}
// 	return
// }

// // NewYCbCr returns a new YCbCr image with the given bounds and subsample
// // ratio.
// func NewYCbCr(r Rectangle, subsampleRatio YCbCrSubsampleRatio) *YCbCr {
// 	w, h, cw, ch := yCbCrSize(r, subsampleRatio)

// 	// totalLength should be the same as i2, below, for a valid Rectangle r.
// 	totalLength := add2NonNeg(
// 		mul3NonNeg(1, w, h),
// 		mul3NonNeg(2, cw, ch),
// 	)
// 	if totalLength < 0 {
// 		panic("image: NewYCbCr Rectangle has huge or negative dimensions")
// 	}

// 	i0 := w*h + 0*cw*ch
// 	i1 := w*h + 1*cw*ch
// 	i2 := w*h + 2*cw*ch
// 	b := make([]byte, i2)
// 	return &YCbCr{
// 		Y:              b[:i0:i0],
// 		Cb:             b[i0:i1:i1],
// 		Cr:             b[i1:i2:i2],
// 		SubsampleRatio: subsampleRatio,
// 		YStride:        w,
// 		CStride:        cw,
// 		Rect:           r,
// 	}
// }

// // NYCbCrA is an in-memory image of non-alpha-premultiplied Y'CbCr-with-alpha
// // colors. A and AStride are analogous to the Y and YStride fields of the
// // embedded YCbCr.
// type NYCbCrA struct {
// 	YCbCr
// 	A       []uint8
// 	AStride int
// }

// func (p *NYCbCrA) ColorModel() color::Model {
// 	return color.NYCbCrAModel
// }

// func (p *NYCbCrA) At(x, y int) color.Color {
// 	return p.NYCbCrAAt(x, y)
// }

// func (p *NYCbCrA) RGBA64At(x, y int) color.RGBA64 {
// 	r, g, b, a := p.NYCbCrAAt(x, y).rgba()
// 	return color.RGBA64{uint16(r), uint16(g), uint16(b), uint16(a)}
// }

// func (p *NYCbCrA) NYCbCrAAt(x, y int) color.NYCbCrA {
// 	if !(Point{X: x, Y: y}.inside(p.Rect)) {
// 		return color.NYCbCrA{}
// 	}
// 	yi := p.YOffset(x, y)
// 	ci := p.COffset(x, y)
// 	ai := p.AOffset(x, y)
// 	return color.NYCbCrA{
// 		color.YCbCr{
// 			Y:  p.y[yi],
// 			Cb: p.Cb[ci],
// 			Cr: p.Cr[ci],
// 		},
// 		p.A[ai],
// 	}
// }

// // AOffset returns the index of the first element of A that corresponds to the
// // pixel at (x, y).
// func (p *NYCbCrA) AOffset(x, y int) int {
// 	return (y-p.Rect.min.y)*p.AStride + (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 *NYCbCrA) 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 &NYCbCrA{
// 			YCbCr: YCbCr{
// 				SubsampleRatio: p.SubsampleRatio,
// 			},
// 		}
// 	}
// 	yi := p.YOffset(r.min.x, r.min.y)
// 	ci := p.COffset(r.min.x, r.min.y)
// 	ai := p.AOffset(r.min.x, r.min.y)
// 	return &NYCbCrA{
// 		YCbCr: YCbCr{
// 			Y:              p.y[yi:],
// 			Cb:             p.Cb[ci:],
// 			Cr:             p.Cr[ci:],
// 			SubsampleRatio: p.SubsampleRatio,
// 			YStride:        p.YStride,
// 			CStride:        p.CStride,
// 			Rect:           r,
// 		},
// 		A:       p.A[ai:],
// 		AStride: p.AStride,
// 	}
// }

// // Opaque scans the entire image and reports whether it is fully opaque.
// func (p *NYCbCrA) Opaque() bool {
// 	if p.Rect.Empty() {
// 		return true
// 	}
// 	i0, i1 := 0, p.Rect.Dx()
// 	for y := p.Rect.min.y; y < p.Rect.max.y; y++ {
// 		for _, a := range p.A[i0:i1] {
// 			if a != 0xff {
// 				return false
// 			}
// 		}
// 		i0 += p.AStride
// 		i1 += p.AStride
// 	}
// 	return true
// }

// // NewNYCbCrA returns a new NYCbCrA image with the given bounds and subsample
// // ratio.
// func NewNYCbCrA(r Rectangle, subsampleRatio YCbCrSubsampleRatio) *NYCbCrA {
// 	w, h, cw, ch := yCbCrSize(r, subsampleRatio)

// 	// totalLength should be the same as i3, below, for a valid Rectangle r.
// 	totalLength := add2NonNeg(
// 		mul3NonNeg(2, w, h),
// 		mul3NonNeg(2, cw, ch),
// 	)
// 	if totalLength < 0 {
// 		panic("image: NewNYCbCrA Rectangle has huge or negative dimension")
// 	}

// 	i0 := 1*w*h + 0*cw*ch
// 	i1 := 1*w*h + 1*cw*ch
// 	i2 := 1*w*h + 2*cw*ch
// 	i3 := 2*w*h + 2*cw*ch
// 	b := make([]byte, i3)
// 	return &NYCbCrA{
// 		YCbCr: YCbCr{
// 			Y:              b[:i0:i0],
// 			Cb:             b[i0:i1:i1],
// 			Cr:             b[i1:i2:i2],
// 			SubsampleRatio: subsampleRatio,
// 			YStride:        w,
// 			CStride:        cw,
// 			Rect:           r,
// 		},
// 		A:       b[i2:],
// 		AStride: w,
// 	}
// }