From 1c910d2f112948bf0c0c309a2049a0e3cdd290e3 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 22 Jan 2012 06:06:22 +0100 Subject: [PATCH] sws: Fix RGB0->alpha containing formats. Fixes Ticket869 Signed-off-by: Michael Niedermayer --- libswscale/swscale_internal.h | 2 ++ libswscale/swscale_unscaled.c | 24 +++++++++++++++++++++--- libswscale/utils.c | 21 +++++++++++++++++---- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index f4220a9eba..3c4f3953c1 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -330,6 +330,8 @@ typedef struct SwsContext { int dstColorspaceTable[4]; int srcRange; ///< 0 = MPG YUV range, 1 = JPG YUV range (source image). int dstRange; ///< 0 = MPG YUV range, 1 = JPG YUV range (destination image). + int src0Alpha; + int dst0Alpha; int yuv2rgb_y_offset; int yuv2rgb_y_coeff; int yuv2rgb_v2r_coeff; diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index b4686f7eff..e1ba79926d 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -909,9 +909,10 @@ int attribute_align_arg sws_scale(struct SwsContext *c, int srcSliceH, uint8_t *const dst[], const int dstStride[]) { - int i; + int i, ret; const uint8_t *src2[4] = { srcSlice[0], srcSlice[1], srcSlice[2], srcSlice[3] }; uint8_t *dst2[4] = { dst[0], dst[1], dst[2], dst[3] }; + uint8_t *rgb0_tmp = NULL; // do not mess up sliceDir if we have a "trailing" 0-size slice if (srcSliceH == 0) @@ -997,6 +998,20 @@ int attribute_align_arg sws_scale(struct SwsContext *c, } } + if (c->src0Alpha && !c->dst0Alpha && isALPHA(c->dstFormat)) { + uint8_t *base; + int x,y; + rgb0_tmp = av_malloc(FFABS(srcStride[0]) * srcSliceH + 32); + base = srcStride[0] < 0 ? rgb0_tmp - srcStride[0] * (srcSliceH-1) : rgb0_tmp; + for (y=0; ysrcW); + for (x=c->src0Alpha-1; x<4*c->srcW; x+=4) { + base[ srcStride[0]*y + x] = 0xFF; + } + } + src2[0] = base; + } + // copy strides, so they can safely be modified if (c->sliceDir == 1) { // slices go from top to bottom @@ -1012,7 +1027,7 @@ int attribute_align_arg sws_scale(struct SwsContext *c, if (srcSliceY + srcSliceH == c->srcH) c->sliceDir = 0; - return c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2, + ret = c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2, dstStride2); } else { // slices go from bottom to top => we flip the image internally @@ -1038,9 +1053,12 @@ int attribute_align_arg sws_scale(struct SwsContext *c, if (!srcSliceY) c->sliceDir = 0; - return c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH, + ret = c->swScale(c, src2, srcStride2, c->srcH-srcSliceY-srcSliceH, srcSliceH, dst2, dstStride2); } + + av_free(rgb0_tmp); + return ret; } /* Convert the palette to the same packed 32-bit format as the palette */ diff --git a/libswscale/utils.c b/libswscale/utils.c index 3ddc15d50c..5826c17e31 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -748,10 +748,17 @@ static int handle_jpeg(enum PixelFormat *format) case PIX_FMT_YUVJ422P: *format = PIX_FMT_YUV422P; return 1; case PIX_FMT_YUVJ444P: *format = PIX_FMT_YUV444P; return 1; case PIX_FMT_YUVJ440P: *format = PIX_FMT_YUV440P; return 1; - case PIX_FMT_0BGR : *format = PIX_FMT_ABGR ; return 0; - case PIX_FMT_BGR0 : *format = PIX_FMT_BGRA ; return 0; - case PIX_FMT_0RGB : *format = PIX_FMT_ARGB ; return 0; - case PIX_FMT_RGB0 : *format = PIX_FMT_RGBA ; return 0; + default: return 0; + } +} + +static int handle_0alpha(enum PixelFormat *format) +{ + switch (*format) { + case PIX_FMT_0BGR : *format = PIX_FMT_ABGR ; return 1; + case PIX_FMT_BGR0 : *format = PIX_FMT_BGRA ; return 4; + case PIX_FMT_0RGB : *format = PIX_FMT_ARGB ; return 1; + case PIX_FMT_RGB0 : *format = PIX_FMT_RGBA ; return 4; default: return 0; } } @@ -790,6 +797,8 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) handle_jpeg(&srcFormat); handle_jpeg(&dstFormat); + handle_0alpha(&srcFormat); + handle_0alpha(&dstFormat); if(srcFormat!=c->srcFormat || dstFormat!=c->dstFormat){ av_log(c, AV_LOG_WARNING, "deprecated pixel format used, make sure you did set range correctly\n"); @@ -1147,6 +1156,8 @@ SwsContext *sws_getContext(int srcW, int srcH, enum PixelFormat srcFormat, c->dstH= dstH; c->srcRange = handle_jpeg(&srcFormat); c->dstRange = handle_jpeg(&dstFormat); + c->src0Alpha = handle_0alpha(&srcFormat); + c->dst0Alpha = handle_0alpha(&dstFormat); c->srcFormat= srcFormat; c->dstFormat= dstFormat; @@ -1545,10 +1556,12 @@ struct SwsContext *sws_getCachedContext(struct SwsContext *context, context->srcW = srcW; context->srcH = srcH; context->srcRange = handle_jpeg(&srcFormat); + context->src0Alpha = handle_0alpha(&srcFormat); context->srcFormat = srcFormat; context->dstW = dstW; context->dstH = dstH; context->dstRange = handle_jpeg(&dstFormat); + context->dst0Alpha = handle_0alpha(&dstFormat); context->dstFormat = dstFormat; context->flags = flags; context->param[0] = param[0];