[FFmpeg-devel] [PATCH 1/2] sws: Fix RGB0->alpha containing formats.
Michael Niedermayer
michaelni at gmx.at
Sun Jan 22 06:56:44 CET 2012
Fixes Ticket869
Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
---
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 f4220a9..3c4f395 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 b5b0574..c2f8dd5 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -892,9 +892,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)
@@ -980,6 +981,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; y<srcSliceH; y++){
+ memcpy(base + srcStride[0]*y, src2[0] + srcStride[0]*y, 4*c->srcW);
+ 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
@@ -995,7 +1010,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
@@ -1021,9 +1036,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 46ebb7f..f744ea2 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];
--
1.7.5.4
More information about the ffmpeg-devel
mailing list