package  image 
 
import  ( 
	"image/color"  
) 
 
 
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"  
} 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 }.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 ], 
	} 
} 
 
 
 
func  (p  *YCbCr ) YOffset (x , y  int ) int  { 
	return  (y -p .Rect .Min .Y )*p .YStride  + (x  - p .Rect .Min .X ) 
} 
 
 
 
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 ) 
	} 
	 
	return  (y -p .Rect .Min .Y )*p .CStride  + (x  - p .Rect .Min .X ) 
} 
 
 
 
func  (p  *YCbCr ) SubImage (r  Rectangle ) Image  { 
	r  = r .Intersect (p .Rect ) 
	 
 
 
	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 : 
		 
		cw  = w  
		ch  = h  
	} 
	return  
} 
 
 
 
func  NewYCbCr  (r  Rectangle , subsampleRatio  YCbCrSubsampleRatio ) *YCbCr  { 
	w , h , cw , ch  := yCbCrSize (r , subsampleRatio ) 
 
	 
	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 , 
	} 
} 
 
 
 
 
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 }.In (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 ], 
	} 
} 
 
 
 
func  (p  *NYCbCrA ) AOffset (x , y  int ) int  { 
	return  (y -p .Rect .Min .Y )*p .AStride  + (x  - p .Rect .Min .X ) 
} 
 
 
 
func  (p  *NYCbCrA ) SubImage (r  Rectangle ) Image  { 
	r  = r .Intersect (p .Rect ) 
	 
 
 
	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 , 
	} 
} 
 
 
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  
} 
 
 
 
func  NewNYCbCrA  (r  Rectangle , subsampleRatio  YCbCrSubsampleRatio ) *NYCbCrA  { 
	w , h , cw , ch  := yCbCrSize (r , subsampleRatio ) 
 
	 
	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 , 
	} 
} 
  
The pages are generated with Golds   v0.7.9-preview . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101  (reachable from the left QR code) to get the latest news of Golds .