From b9b1a2c3e47091eff07e4fc506e4f876a3209aed Mon Sep 17 00:00:00 2001 From: clook Date: Sun, 14 Jul 2013 03:30:38 +0000 Subject: libswscale: Adding RGB => XYZ support --- libswscale/swscale.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) (limited to 'libswscale/swscale.c') diff --git a/libswscale/swscale.c b/libswscale/swscale.c index cec4288..6721dc3 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -849,6 +849,62 @@ static void xyz12Torgb48(struct SwsContext *c, uint16_t *dst, } } +static void rgb48Toxyz12(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; ypflags & AV_PIX_FMT_FLAG_BE) { + r = AV_RB16(src + xp + 0); + g = AV_RB16(src + xp + 1); + b = AV_RB16(src + xp + 2); + } else { + r = AV_RL16(src + xp + 0); + g = AV_RL16(src + xp + 1); + b = AV_RL16(src + xp + 2); + } + + r = c->rgbgammainv[r>>4]; + g = c->rgbgammainv[g>>4]; + b = c->rgbgammainv[b>>4]; + + // convert from sRGBlinear to XYZlinear + x = c->rgb2xyz_matrix[0][0] * r + + c->rgb2xyz_matrix[0][1] * g + + c->rgb2xyz_matrix[0][2] * b >> 12; + y = c->rgb2xyz_matrix[1][0] * r + + c->rgb2xyz_matrix[1][1] * g + + c->rgb2xyz_matrix[1][2] * b >> 12; + z = c->rgb2xyz_matrix[2][0] * r + + c->rgb2xyz_matrix[2][1] * g + + c->rgb2xyz_matrix[2][2] * b >> 12; + + // limit values to 12-bit depth + x = av_clip_c(x,0,4095); + y = av_clip_c(y,0,4095); + z = av_clip_c(z,0,4095); + + // convert from XYZlinear to X'Y'Z' and scale from 12bit to 16bit + if (desc->flags & AV_PIX_FMT_FLAG_BE) { + AV_WB16(dst + xp + 0, c->xyzgammainv[x] << 4); + AV_WB16(dst + xp + 1, c->xyzgammainv[y] << 4); + AV_WB16(dst + xp + 2, c->xyzgammainv[z] << 4); + } else { + AV_WL16(dst + xp + 0, c->xyzgammainv[x] << 4); + AV_WL16(dst + xp + 1, c->xyzgammainv[y] << 4); + AV_WL16(dst + xp + 2, c->xyzgammainv[z] << 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. @@ -1045,6 +1101,12 @@ int attribute_align_arg sws_scale(struct SwsContext *c, srcSliceH, dst2, dstStride2); } + + if (c->dstXYZ && !(c->srcXYZ && c->srcW==c->dstW && c->srcH==c->dstH)) { + /* replace on the same data */ + rgb48Toxyz12(c, (uint16_t*)dst2[0], (const uint16_t*)dst2[0], dstStride[0]/2, ret); + } + av_free(rgb0_tmp); return ret; } -- cgit v1.1