summaryrefslogtreecommitdiffstats
path: root/libswscale/swscale.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2013-04-28 19:28:42 +0200
committerMichael Niedermayer <michaelni@gmx.at>2013-04-28 19:30:01 +0200
commit0c47c9028be2cf4b1a557e653606fced5b959445 (patch)
tree5bdf78c411d5f3e7af35f674874afeeb5fa5c923 /libswscale/swscale.c
parent45f1cf88a85c3e17abe8244806d4161f062add88 (diff)
downloadffmpeg-streaming-0c47c9028be2cf4b1a557e653606fced5b959445.zip
ffmpeg-streaming-0c47c9028be2cf4b1a557e653606fced5b959445.tar.gz
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>
Diffstat (limited to 'libswscale/swscale.c')
-rw-r--r--libswscale/swscale.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/libswscale/swscale.c b/libswscale/swscale.c
index 0c20a71..190a7b9 100644
--- a/libswscale/swscale.c
+++ b/libswscale/swscale.c
@@ -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));
OpenPOWER on IntegriCloud