sws: support xyz input
The implementation is heavily based on Matthias Buerchers and Nicolas Bertrands vf_xyz2rgb.c Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
@@ -791,6 +791,62 @@ static int check_image_pointers(const uint8_t * const data[4], enum AVPixelForma
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void xyz12Torgb48(struct SwsContext *c, uint16_t *dst,
|
||||
const uint16_t *src, int stride, int h)
|
||||
{
|
||||
int xp,yp;
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat);
|
||||
|
||||
for (yp=0; yp<h; yp++) {
|
||||
for (xp=0; xp+2<stride; xp+=3) {
|
||||
int x, y, z, r, g, b;
|
||||
|
||||
if (desc->flags & PIX_FMT_BE) {
|
||||
x = AV_RB16(src + xp + 0);
|
||||
y = AV_RB16(src + xp + 1);
|
||||
z = AV_RB16(src + xp + 2);
|
||||
} else {
|
||||
x = AV_RL16(src + xp + 0);
|
||||
y = AV_RL16(src + xp + 1);
|
||||
z = AV_RL16(src + xp + 2);
|
||||
}
|
||||
|
||||
x = c->xyzgamma[x>>4];
|
||||
y = c->xyzgamma[y>>4];
|
||||
z = c->xyzgamma[z>>4];
|
||||
|
||||
// convert from XYZlinear to sRGBlinear
|
||||
r = c->xyz2rgb_matrix[0][0] * x +
|
||||
c->xyz2rgb_matrix[0][1] * y +
|
||||
c->xyz2rgb_matrix[0][2] * z >> 12;
|
||||
g = c->xyz2rgb_matrix[1][0] * x +
|
||||
c->xyz2rgb_matrix[1][1] * y +
|
||||
c->xyz2rgb_matrix[1][2] * z >> 12;
|
||||
b = c->xyz2rgb_matrix[2][0] * x +
|
||||
c->xyz2rgb_matrix[1][2] * y +
|
||||
c->xyz2rgb_matrix[2][2] * z >> 12;
|
||||
|
||||
// limit values to 12-bit depth
|
||||
r = av_clip_c(r,0,4095);
|
||||
g = av_clip_c(g,0,4095);
|
||||
b = av_clip_c(b,0,4095);
|
||||
|
||||
// convert from sRGBlinear to RGB and scale from 12bit to 16bit
|
||||
if (desc->flags & PIX_FMT_BE) {
|
||||
AV_WB16(dst + xp + 0, c->rgbgamma[r] << 4);
|
||||
AV_WB16(dst + xp + 1, c->rgbgamma[g] << 4);
|
||||
AV_WB16(dst + xp + 2, c->rgbgamma[b] << 4);
|
||||
} else {
|
||||
AV_WL16(dst + xp + 0, c->rgbgamma[r] << 4);
|
||||
AV_WL16(dst + xp + 1, c->rgbgamma[g] << 4);
|
||||
AV_WL16(dst + xp + 2, c->rgbgamma[b] << 4);
|
||||
}
|
||||
}
|
||||
src += stride;
|
||||
dst += stride;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* swscale wrapper, so we don't need to export the SwsContext.
|
||||
* Assumes planar YUV to be in YUV order instead of YVU.
|
||||
@@ -922,6 +978,15 @@ int attribute_align_arg sws_scale(struct SwsContext *c,
|
||||
src2[0] = base;
|
||||
}
|
||||
|
||||
if (c->srcXYZ && !(c->dstXYZ && c->srcW==c->dstW && c->srcH==c->dstH)) {
|
||||
uint8_t *base;
|
||||
rgb0_tmp = av_malloc(FFABS(srcStride[0]) * srcSliceH + 32);
|
||||
base = srcStride[0] < 0 ? rgb0_tmp - srcStride[0] * (srcSliceH-1) : rgb0_tmp;
|
||||
|
||||
xyz12Torgb48(c, base, src2[0], srcStride[0]/2, srcSliceH);
|
||||
src2[0] = base;
|
||||
}
|
||||
|
||||
if (!srcSliceY && (c->flags & SWS_BITEXACT) && (c->flags & SWS_ERROR_DIFFUSION) && c->dither_error[0])
|
||||
for (i = 0; i < 4; i++)
|
||||
memset(c->dither_error[i], 0, sizeof(c->dither_error[0][0]) * (c->dstW+2));
|
||||
|
||||
Reference in New Issue
Block a user