changeset 30459:9bb2ebbb52be

Implement shuffle_bytes_abcd() functions and use them for shuffling bytes when converting between RGB32 variants. In particular fix the argb -> rgba and abgr -> bgra conversions. See the thread: Subject: [FFmpeg-devel] [RFC] RGB32 / BGR32 ethernal bug Date: Tue, 26 Jan 2010 01:06:18 +0100
author stefano
date Wed, 03 Feb 2010 23:46:00 +0000
parents f6721168aee8
children 2675229bd06f
files libswscale/rgb2rgb.c libswscale/rgb2rgb.h libswscale/swscale.c
diffstat 3 files changed, 55 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/libswscale/rgb2rgb.c	Wed Feb 03 22:36:47 2010 +0000
+++ b/libswscale/rgb2rgb.c	Wed Feb 03 23:46:00 2010 +0000
@@ -442,3 +442,23 @@
         dst[i] = ((b<<1)&0x07) | ((g&0x07)<<3) | ((r&0x03)<<6);
     }
 }
+
+#define DEFINE_SHUFFLE_BYTES(a, b, c, d)                                \
+void shuffle_bytes_##a##b##c##d(const uint8_t *src, uint8_t *dst, long src_size) \
+{                                                                       \
+    long i;                                                             \
+                                                                        \
+    for (i = 0; i < src_size; i+=4) {                                   \
+        dst[i + 0] = src[i + a];                                        \
+        dst[i + 1] = src[i + b];                                        \
+        dst[i + 2] = src[i + c];                                        \
+        dst[i + 3] = src[i + d];                                        \
+    }                                                                   \
+}
+
+DEFINE_SHUFFLE_BYTES(0, 3, 2, 1);
+DEFINE_SHUFFLE_BYTES(1, 2, 3, 0);
+DEFINE_SHUFFLE_BYTES(2, 1, 0, 3);
+DEFINE_SHUFFLE_BYTES(3, 0, 1, 2);
+DEFINE_SHUFFLE_BYTES(3, 2, 1, 0);
+
--- a/libswscale/rgb2rgb.h	Wed Feb 03 22:36:47 2010 +0000
+++ b/libswscale/rgb2rgb.h	Wed Feb 03 23:46:00 2010 +0000
@@ -60,6 +60,11 @@
 void rgb15tobgr15(const uint8_t *src, uint8_t *dst, long src_size);
 void bgr8torgb8  (const uint8_t *src, uint8_t *dst, long src_size);
 
+void shuffle_bytes_0321(const uint8_t *src, uint8_t *dst, long src_size);
+void shuffle_bytes_1230(const uint8_t *src, uint8_t *dst, long src_size);
+void shuffle_bytes_2103(const uint8_t *src, uint8_t *dst, long src_size);
+void shuffle_bytes_3012(const uint8_t *src, uint8_t *dst, long src_size);
+void shuffle_bytes_3210(const uint8_t *src, uint8_t *dst, long src_size);
 
 void palette8topacked32(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
 void palette8topacked24(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette);
--- a/libswscale/swscale.c	Wed Feb 03 22:36:47 2010 +0000
+++ b/libswscale/swscale.c	Wed Feb 03 23:46:00 2010 +0000
@@ -1423,6 +1423,13 @@
     return srcSliceH;
 }
 
+#define isRGBA32(x) (            \
+           (x) == PIX_FMT_ARGB   \
+        || (x) == PIX_FMT_RGBA   \
+        || (x) == PIX_FMT_BGRA   \
+        || (x) == PIX_FMT_ABGR   \
+        )
+
 /* {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[])
@@ -1435,6 +1442,22 @@
     const int dstId= c->dstFormatBpp >> 2;
     void (*conv)(const uint8_t *src, uint8_t *dst, long src_size)=NULL;
 
+#define CONV_IS(src, dst) (srcFormat == PIX_FMT_##src && dstFormat == PIX_FMT_##dst)
+
+    if (isRGBA32(srcFormat) && isRGBA32(dstFormat)) {
+        if (     CONV_IS(ABGR, RGBA)
+              || CONV_IS(ARGB, BGRA)
+              || CONV_IS(BGRA, ARGB)
+              || CONV_IS(RGBA, ABGR)) conv = shuffle_bytes_3210;
+        else if (CONV_IS(ABGR, ARGB)
+              || CONV_IS(ARGB, ABGR)) conv = shuffle_bytes_0321;
+        else if (CONV_IS(ABGR, BGRA)
+              || CONV_IS(ARGB, RGBA)) conv = shuffle_bytes_1230;
+        else if (CONV_IS(BGRA, RGBA)
+              || CONV_IS(RGBA, BGRA)) conv = shuffle_bytes_2103;
+        else if (CONV_IS(BGRA, ABGR)
+              || CONV_IS(RGBA, ARGB)) conv = shuffle_bytes_3012;
+    } else
     /* BGR -> BGR */
     if (  (isBGRinInt(srcFormat) && isBGRinInt(dstFormat))
        || (isRGBinInt(srcFormat) && isRGBinInt(dstFormat))) {
@@ -1470,7 +1493,6 @@
         case 0x83: conv= rgb15tobgr32; break;
         case 0x84: conv= rgb16tobgr32; break;
         case 0x86: conv= rgb24tobgr32; break;
-        case 0x88: conv= rgb32tobgr32; break;
         }
     }
 
@@ -1479,14 +1501,18 @@
                sws_format_name(srcFormat), sws_format_name(dstFormat));
     } else {
         const uint8_t *srcPtr= src[0];
-        if(srcFormat == PIX_FMT_RGB32_1 || srcFormat == PIX_FMT_BGR32_1)
+              uint8_t *dstPtr= dst[0];
+        if ((srcFormat == PIX_FMT_RGB32_1 || srcFormat == PIX_FMT_BGR32_1) && !isRGBA32(dstFormat))
             srcPtr += ALT32_CORR;
 
+        if ((dstFormat == PIX_FMT_RGB32_1 || dstFormat == PIX_FMT_BGR32_1) && !isRGBA32(srcFormat))
+            dstPtr += ALT32_CORR;
+
         if (dstStride[0]*srcBpp == srcStride[0]*dstBpp && srcStride[0] > 0)
-            conv(srcPtr, dst[0] + dstStride[0]*srcSliceY, srcSliceH*srcStride[0]);
+            conv(srcPtr, dstPtr + dstStride[0]*srcSliceY, srcSliceH*srcStride[0]);
         else {
             int i;
-            uint8_t *dstPtr= dst[0] + dstStride[0]*srcSliceY;
+            dstPtr += dstStride[0]*srcSliceY;
 
             for (i=0; i<srcSliceH; i++) {
                 conv(srcPtr, dstPtr, c->srcW*srcBpp);
@@ -1692,8 +1718,6 @@
         && 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
-                                          && dstFormat != PIX_FMT_RGB32_1
-                                          && dstFormat != PIX_FMT_BGR32_1
         && srcFormat != PIX_FMT_RGB48LE   && dstFormat != PIX_FMT_RGB48LE
         && srcFormat != PIX_FMT_RGB48BE   && dstFormat != PIX_FMT_RGB48BE
         && (!needsDither || (c->flags&(SWS_FAST_BILINEAR|SWS_POINT))))