From: Themaister <[email protected]>

Signed-off-by: Michael Niedermayer <[email protected]>
Signed-off-by: Derek Buitenhuis <[email protected]>
---
 libswscale/swscale_internal.h |    3 +-
 libswscale/swscale_unscaled.c |  105 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 107 insertions(+), 1 deletion(-)

diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h
index 29fe4ff..7730442 100644
--- a/libswscale/swscale_internal.h
+++ b/libswscale/swscale_internal.h
@@ -612,7 +612,8 @@ const char *sws_format_name(enum PixelFormat format);
 
 #define isAnyRGB(x)                    \
     (isRGBinInt(x)              ||     \
-     isBGRinInt(x))
+     isBGRinInt(x)              ||     \
+     (x) == PIX_FMT_GBRP)
 
 #define isALPHA(x)                                            \
     (av_pix_fmt_descriptors[x].nb_components == 2          || \
diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c
index 5fe2b14..1d24031 100644
--- a/libswscale/swscale_unscaled.c
+++ b/libswscale/swscale_unscaled.c
@@ -344,6 +344,107 @@ static int palToRgbWrapper(SwsContext *c, const uint8_t 
*src[], int srcStride[],
     return srcSliceH;
 }
 
+static void gbr24ptopacked24(const uint8_t *src[], int srcStride[],
+                             uint8_t *dst, int dstStride, int srcSliceH,
+                             int width)
+{
+    int x, h, i;
+    for (h = 0; h < srcSliceH; h++) {
+        uint8_t *dest = dst + dstStride * h;
+        for (x = 0; x < width; x++) {
+            *dest++ = src[0][x];
+            *dest++ = src[1][x];
+            *dest++ = src[2][x];
+        }
+
+        for (i = 0; i < 3; i++)
+            src[i] += srcStride[i];
+    }
+}
+
+static void gbr24ptopacked32(const uint8_t *src[], int srcStride[],
+                             uint8_t *dst, int dstStride, int srcSliceH,
+                             int alpha_first, int width)
+{
+    int x, h, i;
+    for (h = 0; h < srcSliceH; h++) {
+        uint8_t *dest = dst + dstStride * h;
+
+        if (alpha_first) {
+            for (x = 0; x < width; x++) {
+                *dest++ = 0xff;
+                *dest++ = src[0][x];
+                *dest++ = src[1][x];
+                *dest++ = src[2][x];
+            }
+        } else {
+            for (x = 0; x < width; x++) {
+                *dest++ = src[0][x];
+                *dest++ = src[1][x];
+                *dest++ = src[2][x];
+                *dest++ = 0xff;
+            }
+        }
+
+        for (i = 0; i < 3; i++)
+            src[i] += srcStride[i];
+    }
+}
+
+static int planarRgbToRgbWrapper(SwsContext *c, const uint8_t *src[],
+                                 int srcStride[], int srcSliceY, int srcSliceH,
+                                 uint8_t *dst[], int dstStride[])
+{
+    int alpha_first = 0;
+    if (c->srcFormat != PIX_FMT_GBRP) {
+        av_log(c, AV_LOG_ERROR, "unsupported planar RGB conversion %s -> %s\n",
+              av_get_pix_fmt_name(c->srcFormat), 
av_get_pix_fmt_name(c->dstFormat));
+        return srcSliceH;
+    }
+
+    switch (c->dstFormat) {
+        case PIX_FMT_BGR24:
+            gbr24ptopacked24((const uint8_t* []) {src[1], src[0], src[2]},
+                             (int []) {srcStride[1], srcStride[0], 
srcStride[2]},
+                             dst[0] + srcSliceY * dstStride[0], dstStride[0],
+                             srcSliceH, c->srcW);
+            break;
+
+        case PIX_FMT_RGB24:
+            gbr24ptopacked24((const uint8_t* []) {src[2], src[0], src[1]},
+                             (int []) {srcStride[2], srcStride[0], 
srcStride[1]},
+                             dst[0] + srcSliceY * dstStride[0], dstStride[0],
+                             srcSliceH, c->srcW);
+            break;
+
+        case PIX_FMT_ARGB:
+            alpha_first = 1;
+        case PIX_FMT_RGBA:
+            gbr24ptopacked32((const uint8_t* []) {src[2], src[0], src[1]},
+                             (int []) {srcStride[2], srcStride[0], 
srcStride[1]},
+                             dst[0] + srcSliceY * dstStride[0], dstStride[0],
+                             srcSliceH, alpha_first, c->srcW);
+            break;
+
+        case PIX_FMT_ABGR:
+            alpha_first = 1;
+        case PIX_FMT_BGRA:
+            gbr24ptopacked32((const uint8_t* []) {src[1], src[0], src[2]},
+                             (int []) {srcStride[1], srcStride[0], 
srcStride[2]},
+                             dst[0] + srcSliceY * dstStride[0], dstStride[0],
+                             srcSliceH, alpha_first, c->srcW);
+            break;
+
+        default:
+            av_log(c, AV_LOG_ERROR,
+                   "unsupported planar RGB conversion %s -> %s\n",
+                    av_get_pix_fmt_name(c->srcFormat),
+                    av_get_pix_fmt_name(c->dstFormat));
+    }
+
+    return srcSliceH;
+}
+
 #define isRGBA32(x) (            \
            (x) == PIX_FMT_ARGB   \
         || (x) == PIX_FMT_RGBA   \
@@ -797,6 +898,10 @@ void ff_get_unscaled_swscale(SwsContext *c)
         && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))
         c->swScale= rgbToRgbWrapper;
 
+    if (isAnyRGB(srcFormat) && isPlanar(srcFormat)
+        && isAnyRGB(dstFormat) && !isPlanar(dstFormat))
+        c->swScale = planarRgbToRgbWrapper;
+
     /* bswap 16 bits per pixel/component packed formats */
     if (IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_BGR444) ||
         IS_DIFFERENT_ENDIANESS(srcFormat, dstFormat, PIX_FMT_BGR48)  ||
-- 
1.7.9.5

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

Reply via email to