81 lines
2.2 KiB
Go
81 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"git.gammaspectra.live/WeebDataHoarder/xyz2yuv/colorspace"
|
|
"git.gammaspectra.live/WeebDataHoarder/xyz2yuv/conv"
|
|
"gonum.org/v1/gonum/mat"
|
|
)
|
|
|
|
var useCConverter, useFloat bool
|
|
|
|
func ConvertFrame(in []uint32, y, cb, cr []uint16, width, height int) {
|
|
if useCConverter {
|
|
if useFloat {
|
|
conv.ConvertFrameDCIXYZToYUV16Float(in, y, cb, cr, width, height)
|
|
} else {
|
|
conv.ConvertFrameDCIXYZToYUV16Double(in, y, cb, cr, width, height)
|
|
}
|
|
return
|
|
}
|
|
|
|
for i := 0; i < height; i++ {
|
|
ConvertLine(in, y, cb, cr, width, height)
|
|
|
|
in = in[width*3:]
|
|
|
|
y = y[width:]
|
|
cb = cb[width:]
|
|
cr = cr[width:]
|
|
}
|
|
}
|
|
|
|
func ConvertLine(in []uint32, y, cb, cr []uint16, width, height int) {
|
|
if useCConverter {
|
|
if useFloat {
|
|
conv.ConvertLineDCIXYZToYUV16Float(in, y, cb, cr, width, height)
|
|
} else {
|
|
conv.ConvertLineDCIXYZToYUV16Double(in, y, cb, cr, width, height)
|
|
}
|
|
return
|
|
}
|
|
|
|
var r, g, b float64
|
|
xyz, rgb, yuv := mat.NewVecDense(3, nil), mat.NewVecDense(3, nil), mat.NewVecDense(3, nil)
|
|
|
|
for j := 0; j < width; j++ {
|
|
// LUT
|
|
xyz.SetVec(0, colorspace.DCIXYZSystem.ToLinearLUT[uint16(in[j*3])<<4])
|
|
xyz.SetVec(1, colorspace.DCIXYZSystem.ToLinearLUT[uint16(in[j*3+1])<<4])
|
|
xyz.SetVec(2, colorspace.DCIXYZSystem.ToLinearLUT[uint16(in[j*3+2])<<4])
|
|
|
|
//TODO: apply white point correction here if necessary (but after denorm)
|
|
|
|
//denormalize + xyz2rgb
|
|
rgb.MulVec(xyz2rgbDenorm, xyz)
|
|
|
|
//todo: some out of bounds r,g,b come up from here, maybe just fine
|
|
//clamp values into proper values. necessary due to XYZ ranges, todo: check conversion matrix for preserving this
|
|
r = min(1.0, max(0, rgb.AtVec(0)))
|
|
g = min(1.0, max(0, rgb.AtVec(1)))
|
|
b = min(1.0, max(0, rgb.AtVec(2)))
|
|
|
|
// companding / adjustment with gamma curve
|
|
//TODO: why is it not using normal Rec709 and instead using straight gamma curve
|
|
r = space.FromLinear(r)
|
|
g = space.FromLinear(g)
|
|
b = space.FromLinear(b)
|
|
|
|
rgb.SetVec(0, r)
|
|
rgb.SetVec(1, g)
|
|
rgb.SetVec(2, b)
|
|
|
|
yuv.MulVec(rgb2yuv, rgb)
|
|
|
|
// map RGB to components
|
|
// scale float range to 16bit precision, in full swing
|
|
y[j] = LumaToFull16(yuv.AtVec(0))
|
|
cb[j] = ChromaToFull16(yuv.AtVec(1))
|
|
cr[j] = ChromaToFull16(yuv.AtVec(2))
|
|
}
|
|
}
|