From: "Ronald S. Bultje" <[email protected]>

Fixes problems in swscale-test where it gives a 3-member array to a
function expecting a 4-member array. Secondly, fixes problems where
rgbToRgbWrapper() is called even though it doesn't support this
particular conversion (e.g. converting from RGB444 to anything).
Thirdly, fixes issues where rgbToRgbWrapper() is called for non-native
endiannness conversions (e.g. RGB555BE on a LE system). Fourthly,
fixes crashes when converting from e.g. monowhite to monowhite, which
calls planarCopyWrapper() and overwrites/reads because a n_bytes !=
n_pixels.
---
 libswscale/swscale-test.c     |    4 +-
 libswscale/swscale_unscaled.c |   49 ++++++++++++++++++++++++----------------
 2 files changed, 31 insertions(+), 22 deletions(-)

diff --git a/libswscale/swscale-test.c b/libswscale/swscale-test.c
index 7ea01a6..3497dff 100644
--- a/libswscale/swscale-test.c
+++ b/libswscale/swscale-test.c
@@ -337,8 +337,8 @@ int main(int argc, char **argv)
     enum PixelFormat srcFormat = PIX_FMT_NONE;
     enum PixelFormat dstFormat = PIX_FMT_NONE;
     uint8_t *rgb_data   = av_malloc(W * H * 4);
-    uint8_t *rgb_src[3] = { rgb_data, NULL, NULL };
-    int rgb_stride[3]   = { 4 * W, 0, 0 };
+    uint8_t *rgb_src[4] = { rgb_data, NULL, NULL, NULL };
+    int rgb_stride[4]   = { 4 * W, 0, 0, 0 };
     uint8_t *data       = av_malloc(4 * W * H);
     uint8_t *src[4]     = { data, data + W * H, data + W * H * 2, data + W * H 
* 3 };
     int stride[4]       = { W, W, W, W };
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index a1b7199..e497fef 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -352,17 +352,22 @@ static int palToRgbWrapper(SwsContext *c, const uint8_t 
*src[], int srcStride[],
         )
 
 /* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
-static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int 
srcStride[],
-                           int srcSliceY, int srcSliceH, uint8_t *dst[],
-                           int dstStride[])
+typedef void (* rgbConvFn) (const uint8_t *, uint8_t *, int);
+static rgbConvFn findRgbConvFn(SwsContext *c)
 {
     const enum PixelFormat srcFormat = c->srcFormat;
     const enum PixelFormat dstFormat = c->dstFormat;
-    const int srcBpp = (c->srcFormatBpp + 7) >> 3;
-    const int dstBpp = (c->dstFormatBpp + 7) >> 3;
     const int srcId = c->srcFormatBpp;
     const int dstId = c->dstFormatBpp;
-    void (*conv)(const uint8_t *src, uint8_t *dst, int src_size) = NULL;
+    rgbConvFn conv = NULL;
+
+#define IS_NOT_NE(bpp, fmt) \
+    (((bpp + 7) >> 3) == 2 && \
+     (!(av_pix_fmt_descriptors[fmt].flags & PIX_FMT_BE) != !HAVE_BIGENDIAN))
+
+    /* if this is non-native rgb444/555/565, don't handle it here. */
+    if (IS_NOT_NE(srcId, srcFormat) || IS_NOT_NE(dstId, dstFormat))
+        return NULL;
 
 #define CONV_IS(src, dst) (srcFormat == PIX_FMT_##src && dstFormat == 
PIX_FMT_##dst)
 
@@ -419,6 +424,21 @@ static int rgbToRgbWrapper(SwsContext *c, const uint8_t 
*src[], int srcStride[],
         }
     }
 
+    return conv;
+}
+
+/* {RGB,BGR}{15,16,24,32,32_1} -> {RGB,BGR}{15,16,24,32} */
+static int rgbToRgbWrapper(SwsContext *c, const uint8_t *src[], int 
srcStride[],
+                           int srcSliceY, int srcSliceH, uint8_t *dst[],
+                           int dstStride[])
+
+{
+    const enum PixelFormat srcFormat = c->srcFormat;
+    const enum PixelFormat dstFormat = c->dstFormat;
+    const int srcBpp = (c->srcFormatBpp + 7) >> 3;
+    const int dstBpp = (c->dstFormatBpp + 7) >> 3;
+    rgbConvFn conv = findRgbConvFn(c);
+
     if (!conv) {
         av_log(c, AV_LOG_ERROR, "internal error %s -> %s converter\n",
                sws_format_name(srcFormat), sws_format_name(dstFormat));
@@ -716,6 +736,8 @@ static int planarCopyWrapper(SwsContext *c, const uint8_t 
*src[],
             } else {
                 if (is16BPS(c->srcFormat) && is16BPS(c->dstFormat))
                     length *= 2;
+                else if 
(!av_pix_fmt_descriptors[c->srcFormat].comp[0].depth_minus1)
+                    length >>= 3; // monowhite/black
                 for (i = 0; i < height; i++) {
                     memcpy(dstPtr, srcPtr, length);
                     srcPtr += srcStride[plane];
@@ -770,20 +792,7 @@ void ff_get_unscaled_swscale(SwsContext *c)
         c->swScale = bgr24ToYv12Wrapper;
 
     /* RGB/BGR -> RGB/BGR (no dither needed forms) */
-    if (   isAnyRGB(srcFormat)
-        && isAnyRGB(dstFormat)
-        && srcFormat != PIX_FMT_BGR8      && dstFormat != PIX_FMT_BGR8
-        && srcFormat != PIX_FMT_RGB8      && dstFormat != PIX_FMT_RGB8
-        && srcFormat != PIX_FMT_BGR4      && dstFormat != PIX_FMT_BGR4
-        && srcFormat != PIX_FMT_RGB4      && dstFormat != PIX_FMT_RGB4
-        && srcFormat != PIX_FMT_BGR4_BYTE && dstFormat != PIX_FMT_BGR4_BYTE
-        && srcFormat != PIX_FMT_RGB4_BYTE && dstFormat != PIX_FMT_RGB4_BYTE
-        && srcFormat != PIX_FMT_MONOBLACK && dstFormat != PIX_FMT_MONOBLACK
-        && srcFormat != PIX_FMT_MONOWHITE && dstFormat != PIX_FMT_MONOWHITE
-        && srcFormat != PIX_FMT_RGB48LE   && dstFormat != PIX_FMT_RGB48LE
-        && srcFormat != PIX_FMT_RGB48BE   && dstFormat != PIX_FMT_RGB48BE
-        && srcFormat != PIX_FMT_BGR48LE   && dstFormat != PIX_FMT_BGR48LE
-        && srcFormat != PIX_FMT_BGR48BE   && dstFormat != PIX_FMT_BGR48BE
+    if (isAnyRGB(srcFormat) && isAnyRGB(dstFormat) && findRgbConvFn(c)
         && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
         c->swScale= rgbToRgbWrapper;
 
-- 
1.7.7.4

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to