package frame import ( "errors" "git.gammaspectra.live/S.O.N.G/Ignite/colorspace" ) type uint8Frame struct { colorSpace colorspace.ColorSpace width int height int Y []uint8 Cb []uint8 Cr []uint8 } func NewUint8FrameFromBytes(space colorspace.ColorSpace, width, height int, data []byte) (*uint8Frame, error) { if frameLength, _ := space.FrameSize(width, height); frameLength != len(data) { return nil, errors.New("wrong length of data") } if space.BitDepth > 8 { return nil, errors.New("wrong bit depth") } iY := space.PlaneLumaSamples(width, height) iCb := space.PlaneCbSamples(width, height) iCr := space.PlaneCrSamples(width, height) return &uint8Frame{ colorSpace: space, height: height, width: width, Y: data[:iY], Cb: data[iY : iY+iCb], Cr: data[iY+iCb : iY+iCb+iCr], }, nil } func (i *uint8Frame) Get16(x, y int) (Y uint16, Cb uint16, Cr uint16) { cy, cb, cr := i.GetNative(x, y) return uint16(cy) << (16 - i.colorSpace.BitDepth), uint16(cb) << (16 - i.colorSpace.BitDepth), uint16(cr) << (16 - i.colorSpace.BitDepth) } func (i *uint8Frame) Get8(x, y int) (Y uint8, Cb uint8, Cr uint8) { return i.GetNative(x, y) } func (i *uint8Frame) Width() int { return i.width } func (i *uint8Frame) Height() int { return i.height } func (i *uint8Frame) ColorSpace() colorspace.ColorSpace { return i.colorSpace } func (i *uint8Frame) GetNative(x, y int) (Y uint8, Cb uint8, Cr uint8) { Yindex := x + y*i.width Cwidth := (i.width * int(i.colorSpace.Subsampling.A)) / int(i.colorSpace.Subsampling.J) if i.colorSpace.Subsampling.B == 0 { y /= 2 } Cindex := (x*int(i.colorSpace.Subsampling.A))/int(i.colorSpace.Subsampling.J) + y*Cwidth Y = i.Y[Yindex] Cb = i.Cb[Cindex] Cr = i.Cr[Cindex] return } func (i *uint8Frame) GetNativeLuma() []uint8 { return i.Y } func (i *uint8Frame) GetNativeCb() []uint8 { return i.Cb } func (i *uint8Frame) GetNativeCr() []uint8 { return i.Cr }