Ignite/frame/frame_uint16.go

95 lines
2.2 KiB
Go

package frame
import (
"errors"
"git.gammaspectra.live/S.O.N.G/Ignite/colorspace"
"runtime"
"unsafe"
)
type uint16Frame struct {
colorSpace colorspace.ColorSpace
width int
height int
Y []uint16
Cb []uint16
Cr []uint16
}
func NewUint16FrameFromBytes(space colorspace.ColorSpace, width, height int, data []byte) (*uint16Frame, error) {
if frameLength, _ := space.FrameSize(width, height); frameLength != len(data) {
return nil, errors.New("wrong length of data")
}
if space.BitDepth >= 16 {
return nil, errors.New("wrong bit depth")
}
buf := make([]uint16, len(data)/2)
copy(buf, unsafe.Slice((*uint16)(unsafe.Pointer(&data[0])), len(data)/2))
runtime.KeepAlive(data)
iY := space.PlaneLumaSamples(width, height)
iCb := space.PlaneCbSamples(width, height)
iCr := space.PlaneCrSamples(width, height)
return &uint16Frame{
colorSpace: space,
height: height,
width: width,
Y: buf[:iY],
Cb: buf[iY : iY+iCb],
Cr: buf[iY+iCb : iY+iCb+iCr],
}, nil
}
func (i *uint16Frame) Get16(x, y int) (Y uint16, Cb uint16, Cr uint16) {
cy, cb, cr := i.GetNative(x, y)
return cy << (16 - i.colorSpace.BitDepth), cb << (16 - i.colorSpace.BitDepth), cr << (16 - i.colorSpace.BitDepth)
}
func (i *uint16Frame) Get8(x, y int) (Y uint8, Cb uint8, Cr uint8) {
cy, cb, cr := i.GetNative(x, y)
return uint8(cy >> (i.colorSpace.BitDepth - 8)), uint8(cb >> (i.colorSpace.BitDepth - 8)), uint8(cr >> (i.colorSpace.BitDepth - 8))
}
func (i *uint16Frame) Width() int {
return i.width
}
func (i *uint16Frame) Height() int {
return i.height
}
func (i *uint16Frame) ColorSpace() colorspace.ColorSpace {
return i.colorSpace
}
func (i *uint16Frame) GetNative(x, y int) (Y uint16, Cb uint16, Cr uint16) {
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 *uint16Frame) GetNativeLuma() []uint16 {
return i.Y
}
func (i *uint16Frame) GetNativeCb() []uint16 {
return i.Cb
}
func (i *uint16Frame) GetNativeCr() []uint16 {
return i.Cr
}