Fixes Ticket869 Signed-off-by: Michael Niedermayer <michaelni@gmx.at>tags/n0.10
| @@ -330,6 +330,8 @@ typedef struct SwsContext { | |||||
| int dstColorspaceTable[4]; | int dstColorspaceTable[4]; | ||||
| int srcRange; ///< 0 = MPG YUV range, 1 = JPG YUV range (source image). | 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 dstRange; ///< 0 = MPG YUV range, 1 = JPG YUV range (destination image). | ||||
| int src0Alpha; | |||||
| int dst0Alpha; | |||||
| int yuv2rgb_y_offset; | int yuv2rgb_y_offset; | ||||
| int yuv2rgb_y_coeff; | int yuv2rgb_y_coeff; | ||||
| int yuv2rgb_v2r_coeff; | int yuv2rgb_v2r_coeff; | ||||
| @@ -909,9 +909,10 @@ int attribute_align_arg sws_scale(struct SwsContext *c, | |||||
| int srcSliceH, uint8_t *const dst[], | int srcSliceH, uint8_t *const dst[], | ||||
| const int dstStride[]) | const int dstStride[]) | ||||
| { | { | ||||
| int i; | |||||
| int i, ret; | |||||
| const uint8_t *src2[4] = { srcSlice[0], srcSlice[1], srcSlice[2], srcSlice[3] }; | 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 *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 | // do not mess up sliceDir if we have a "trailing" 0-size slice | ||||
| if (srcSliceH == 0) | 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; 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 | // copy strides, so they can safely be modified | ||||
| if (c->sliceDir == 1) { | if (c->sliceDir == 1) { | ||||
| // slices go from top to bottom | // slices go from top to bottom | ||||
| @@ -1012,7 +1027,7 @@ int attribute_align_arg sws_scale(struct SwsContext *c, | |||||
| if (srcSliceY + srcSliceH == c->srcH) | if (srcSliceY + srcSliceH == c->srcH) | ||||
| c->sliceDir = 0; | c->sliceDir = 0; | ||||
| return c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2, | |||||
| ret = c->swScale(c, src2, srcStride2, srcSliceY, srcSliceH, dst2, | |||||
| dstStride2); | dstStride2); | ||||
| } else { | } else { | ||||
| // slices go from bottom to top => we flip the image internally | // 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) | if (!srcSliceY) | ||||
| c->sliceDir = 0; | 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); | srcSliceH, dst2, dstStride2); | ||||
| } | } | ||||
| av_free(rgb0_tmp); | |||||
| return ret; | |||||
| } | } | ||||
| /* Convert the palette to the same packed 32-bit format as the palette */ | /* Convert the palette to the same packed 32-bit format as the palette */ | ||||
| @@ -748,10 +748,17 @@ static int handle_jpeg(enum PixelFormat *format) | |||||
| case PIX_FMT_YUVJ422P: *format = PIX_FMT_YUV422P; return 1; | case PIX_FMT_YUVJ422P: *format = PIX_FMT_YUV422P; return 1; | ||||
| case PIX_FMT_YUVJ444P: *format = PIX_FMT_YUV444P; 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_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; | default: return 0; | ||||
| } | } | ||||
| } | } | ||||
| @@ -790,6 +797,8 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) | |||||
| handle_jpeg(&srcFormat); | handle_jpeg(&srcFormat); | ||||
| handle_jpeg(&dstFormat); | handle_jpeg(&dstFormat); | ||||
| handle_0alpha(&srcFormat); | |||||
| handle_0alpha(&dstFormat); | |||||
| if(srcFormat!=c->srcFormat || dstFormat!=c->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"); | 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->dstH= dstH; | ||||
| c->srcRange = handle_jpeg(&srcFormat); | c->srcRange = handle_jpeg(&srcFormat); | ||||
| c->dstRange = handle_jpeg(&dstFormat); | c->dstRange = handle_jpeg(&dstFormat); | ||||
| c->src0Alpha = handle_0alpha(&srcFormat); | |||||
| c->dst0Alpha = handle_0alpha(&dstFormat); | |||||
| c->srcFormat= srcFormat; | c->srcFormat= srcFormat; | ||||
| c->dstFormat= dstFormat; | c->dstFormat= dstFormat; | ||||
| @@ -1545,10 +1556,12 @@ struct SwsContext *sws_getCachedContext(struct SwsContext *context, | |||||
| context->srcW = srcW; | context->srcW = srcW; | ||||
| context->srcH = srcH; | context->srcH = srcH; | ||||
| context->srcRange = handle_jpeg(&srcFormat); | context->srcRange = handle_jpeg(&srcFormat); | ||||
| context->src0Alpha = handle_0alpha(&srcFormat); | |||||
| context->srcFormat = srcFormat; | context->srcFormat = srcFormat; | ||||
| context->dstW = dstW; | context->dstW = dstW; | ||||
| context->dstH = dstH; | context->dstH = dstH; | ||||
| context->dstRange = handle_jpeg(&dstFormat); | context->dstRange = handle_jpeg(&dstFormat); | ||||
| context->dst0Alpha = handle_0alpha(&dstFormat); | |||||
| context->dstFormat = dstFormat; | context->dstFormat = dstFormat; | ||||
| context->flags = flags; | context->flags = flags; | ||||
| context->param[0] = param[0]; | context->param[0] = param[0]; | ||||