swscale: remove alp/chr/lumSrcOffset.
[ffmpeg.git] / libswscale / swscale.c
index fd64b81..d97c4e1 100644 (file)
@@ -258,17 +258,20 @@ yuv2yuvX16_c_template(const int16_t *lumFilter, const int16_t **lumSrc,
             output_pixel(&aDest[i], val);
         }
     }
+#undef output_pixel
 }
 
 #define yuv2NBPS(bits, BE_LE, is_be) \
-static void yuv2yuvX ## bits ## BE_LE ## _c(const int16_t *lumFilter, \
+static void yuv2yuvX ## bits ## BE_LE ## _c(SwsContext *c, const int16_t *lumFilter, \
                               const int16_t **lumSrc, int lumFilterSize, \
                               const int16_t *chrFilter, const int16_t **chrUSrc, \
                               const int16_t **chrVSrc, \
                               int chrFilterSize, const int16_t **alpSrc, \
-                              uint16_t *dest, uint16_t *uDest, uint16_t *vDest, \
-                              uint16_t *aDest, int dstW, int chrDstW) \
+                              uint8_t *_dest, uint8_t *_uDest, uint8_t *_vDest, \
+                              uint8_t *_aDest, int dstW, int chrDstW) \
 { \
+    uint16_t *dest  = (uint16_t *) _dest,  *uDest = (uint16_t *) _uDest, \
+             *vDest = (uint16_t *) _vDest, *aDest = (uint16_t *) _aDest; \
     yuv2yuvX16_c_template(lumFilter, lumSrc, lumFilterSize, \
                           chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
                           alpSrc, \
@@ -282,24 +285,24 @@ yuv2NBPS(10, LE, 0);
 yuv2NBPS(16, BE, 1);
 yuv2NBPS(16, LE, 0);
 
-static inline void yuv2yuvX16_c(const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
+static inline void yuv2yuvX16_c(SwsContext *c, const int16_t *lumFilter, const int16_t **lumSrc, int lumFilterSize,
                                 const int16_t *chrFilter, const int16_t **chrUSrc, const int16_t **chrVSrc, int chrFilterSize,
-                                const int16_t **alpSrc, uint16_t *dest, uint16_t *uDest, uint16_t *vDest, uint16_t *aDest, int dstW, int chrDstW,
+                                const int16_t **alpSrc, uint8_t *dest, uint8_t *uDest, uint8_t *vDest, uint8_t *aDest, int dstW, int chrDstW,
                                 enum PixelFormat dstFormat)
 {
 #define conv16(bits) \
     if (isBE(dstFormat)) { \
-        yuv2yuvX ## bits ## BE_c(lumFilter, lumSrc, lumFilterSize, \
-                               chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
-                               alpSrc, \
-                               dest, uDest, vDest, aDest, \
-                               dstW, chrDstW); \
+        yuv2yuvX ## bits ## BE_c(c, lumFilter, lumSrc, lumFilterSize, \
+                                 chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
+                                 alpSrc, \
+                                 dest, uDest, vDest, aDest, \
+                                 dstW, chrDstW); \
     } else { \
-        yuv2yuvX ## bits ## LE_c(lumFilter, lumSrc, lumFilterSize, \
-                               chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
-                               alpSrc, \
-                               dest, uDest, vDest, aDest, \
-                               dstW, chrDstW); \
+        yuv2yuvX ## bits ## LE_c(c, lumFilter, lumSrc, lumFilterSize, \
+                                 chrFilter, chrUSrc, chrVSrc, chrFilterSize, \
+                                 alpSrc, \
+                                 dest, uDest, vDest, aDest, \
+                                 dstW, chrDstW); \
     }
     if (is16BPS(dstFormat)) {
         conv16(16);
@@ -976,93 +979,58 @@ static void fillPlane(uint8_t* plane, int stride, int width, int height, int y,
     }
 }
 
-static void rgb48ToY_c(uint8_t *dst, const uint8_t *src, int width,
-                       uint32_t *unused)
-{
-    int i;
-    for (i = 0; i < width; i++) {
-        int r = src[i*6+0];
-        int g = src[i*6+2];
-        int b = src[i*6+4];
-
-        dst[i] = (RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
-    }
-}
-
-static void rgb48ToUV_c(uint8_t *dstU, uint8_t *dstV,
-                        const uint8_t *src1, const uint8_t *src2,
-                        int width, uint32_t *unused)
-{
-    int i;
-    assert(src1==src2);
-    for (i = 0; i < width; i++) {
-        int r = src1[6*i + 0];
-        int g = src1[6*i + 2];
-        int b = src1[6*i + 4];
-
-        dstU[i] = (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
-        dstV[i] = (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
-    }
-}
-
-static void rgb48ToUV_half_c(uint8_t *dstU, uint8_t *dstV,
-                             const uint8_t *src1, const uint8_t *src2,
-                             int width, uint32_t *unused)
-{
-    int i;
-    assert(src1==src2);
-    for (i = 0; i < width; i++) {
-        int r= src1[12*i + 0] + src1[12*i + 6];
-        int g= src1[12*i + 2] + src1[12*i + 8];
-        int b= src1[12*i + 4] + src1[12*i + 10];
-
-        dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1);
-        dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1);
-    }
-}
-
-static void bgr48ToY_c(uint8_t *dst, const uint8_t *src, int width,
-                       uint32_t *unused)
-{
-    int i;
-    for (i = 0; i < width; i++) {
-        int b = src[i*6+0];
-        int g = src[i*6+2];
-        int r = src[i*6+4];
-
-        dst[i] = (RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
-    }
-}
-
-static void bgr48ToUV_c(uint8_t *dstU, uint8_t *dstV,
-                        const uint8_t *src1, const uint8_t *src2,
-                        int width, uint32_t *unused)
-{
-    int i;
-    for (i = 0; i < width; i++) {
-        int b = src1[6*i + 0];
-        int g = src1[6*i + 2];
-        int r = src1[6*i + 4];
-
-        dstU[i] = (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
-        dstV[i] = (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT;
-    }
-}
-
-static void bgr48ToUV_half_c(uint8_t *dstU, uint8_t *dstV,
-                             const uint8_t *src1, const uint8_t *src2,
-                             int width, uint32_t *unused)
-{
-    int i;
-    for (i = 0; i < width; i++) {
-        int b= src1[12*i + 0] + src1[12*i + 6];
-        int g= src1[12*i + 2] + src1[12*i + 8];
-        int r= src1[12*i + 4] + src1[12*i + 10];
-
-        dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1);
-        dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1);
-    }
+#define rgb48funcs(LE_BE, rfunc, compA, compB, compC) \
+static void compA ## compB ## compC ## 48 ## LE_BE ## ToY_c( \
+                       uint8_t *dst, const uint8_t *src, int width, \
+                       uint32_t *unused) \
+{ \
+    int i; \
+    for (i = 0; i < width; i++) { \
+        int compA = rfunc(&src[i*6+0]) >> 8; \
+        int compB = rfunc(&src[i*6+2]) >> 8; \
+        int compC = rfunc(&src[i*6+4]) >> 8; \
+ \
+        dst[i] = (RY*r + GY*g + BY*b + (33<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT; \
+    } \
+} \
+ \
+static void compA ## compB ## compC ## 48 ## LE_BE ## ToUV_c( \
+                        uint8_t *dstU, uint8_t *dstV, \
+                        const uint8_t *src1, const uint8_t *src2, \
+                        int width, uint32_t *unused) \
+{ \
+    int i; \
+    assert(src1==src2); \
+    for (i = 0; i < width; i++) { \
+        int compA = rfunc(&src1[6*i + 0]) >> 8; \
+        int compB = rfunc(&src1[6*i + 2]) >> 8; \
+        int compC = rfunc(&src1[6*i + 4]) >> 8; \
+ \
+        dstU[i] = (RU*r + GU*g + BU*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT; \
+        dstV[i] = (RV*r + GV*g + BV*b + (257<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT; \
+    } \
+} \
+ \
+static void compA ## compB ## compC ## 48 ## LE_BE ## ToUV_half_c( \
+                            uint8_t *dstU, uint8_t *dstV, \
+                            const uint8_t *src1, const uint8_t *src2, \
+                            int width, uint32_t *unused) \
+{ \
+    int i; \
+    assert(src1==src2); \
+    for (i = 0; i < width; i++) { \
+        int compA = (rfunc(&src1[12*i + 0]) >> 8) + (rfunc(&src1[12*i + 6]) >> 8); \
+        int compB = (rfunc(&src1[12*i + 2]) >> 8) + (rfunc(&src1[12*i + 8]) >> 8); \
+        int compC = (rfunc(&src1[12*i + 4]) >> 8) + (rfunc(&src1[12*i + 10]) >> 8); \
+ \
+        dstU[i]= (RU*r + GU*g + BU*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1); \
+        dstV[i]= (RV*r + GV*g + BV*b + (257<<RGB2YUV_SHIFT)) >> (RGB2YUV_SHIFT+1); \
+    } \
 }
+rgb48funcs(LE, AV_RL16, r, g, b);
+rgb48funcs(BE, AV_RB16, r, g, b);
+rgb48funcs(LE, AV_RL16, b, g, r);
+rgb48funcs(BE, AV_RB16, b, g, r);
 
 #define BGR2Y(type, name, shr, shg, shb, maskr, maskg, maskb, RY, GY, BY, S)\
 static void name ## _c(uint8_t *dst, const uint8_t *src, \
@@ -1095,6 +1063,14 @@ static void abgrToA_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *unu
     }
 }
 
+static void rgbaToA_c(uint8_t *dst, const uint8_t *src, int width, uint32_t *unused)
+{
+    int i;
+    for (i=0; i<width; i++) {
+        dst[i]= src[4*i+3];
+    }
+}
+
 #define BGR2UV(type, name, shr, shg, shb, shp, maskr, maskg, maskb, RU, GU, BU, RV, GV, BV, S) \
 static void name ## _c(uint8_t *dstU, uint8_t *dstV, \
                        const uint8_t *src, const uint8_t *dummy, \
@@ -1529,8 +1505,6 @@ static inline void hyscale(SwsContext *c, uint16_t *dst, int dstWidth,
     void (*toYV12)(uint8_t *, const uint8_t *, int, uint32_t *) = isAlpha ? c->alpToYV12 : c->lumToYV12;
     void (*convertRange)(uint16_t *, int) = isAlpha ? NULL : c->lumConvertRange;
 
-    src += isAlpha ? c->alpSrcOffset : c->lumSrcOffset;
-
     if (toYV12) {
         toYV12(formatConvBuffer, src, srcW, pal);
         src= formatConvBuffer;
@@ -1567,10 +1541,6 @@ static inline void hcscale(SwsContext *c, uint16_t *dst1, uint16_t *dst2, int ds
                            const int16_t *hChrFilterPos, int hChrFilterSize,
                            uint8_t *formatConvBuffer, uint32_t *pal)
 {
-
-    src1 += c->chrSrcOffset;
-    src2 += c->chrSrcOffset;
-
     if (c->chrToYV12) {
         uint8_t *buf2 = formatConvBuffer + FFALIGN(srcW, 16);
         c->chrToYV12(formatConvBuffer, buf2, src1, src2, srcW, pal);
@@ -1783,14 +1753,7 @@ static int swScale(SwsContext *c, const uint8_t* src[],
             } else if (isPlanarYUV(dstFormat) || dstFormat==PIX_FMT_GRAY8) { //YV12 like
                 const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
                 if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
-                if (is16BPS(dstFormat) || is9_OR_10BPS(dstFormat)) {
-                    yuv2yuvX16_c(vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
-                                 vChrFilter+chrDstY*vChrFilterSize, chrUSrcPtr,
-                                 chrVSrcPtr, vChrFilterSize,
-                                 alpSrcPtr, (uint16_t *) dest, (uint16_t *) uDest,
-                                 (uint16_t *) vDest, (uint16_t *) aDest, dstW, chrDstW,
-                                 dstFormat);
-                } else if (vLumFilterSize == 1 && vChrFilterSize == 1) { // unscaled YV12
+                if (c->yuv2yuv1 && vLumFilterSize == 1 && vChrFilterSize == 1) { // unscaled YV12
                     const int16_t *lumBuf = lumSrcPtr[0];
                     const int16_t *chrUBuf= chrUSrcPtr[0];
                     const int16_t *chrVBuf= chrVSrcPtr[0];
@@ -1870,9 +1833,9 @@ static int swScale(SwsContext *c, const uint8_t* src[],
                 const int chrSkipMask= (1<<c->chrDstVSubSample)-1;
                 if ((dstY&chrSkipMask) || isGray(dstFormat)) uDest=vDest= NULL; //FIXME split functions in lumi / chromi
                 if (is16BPS(dstFormat) || is9_OR_10BPS(dstFormat)) {
-                    yuv2yuvX16_c(vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
+                    yuv2yuvX16_c(c, vLumFilter+dstY*vLumFilterSize   , lumSrcPtr, vLumFilterSize,
                                  vChrFilter+chrDstY*vChrFilterSize, chrUSrcPtr, chrVSrcPtr, vChrFilterSize,
-                                 alpSrcPtr, (uint16_t *) dest, (uint16_t *) uDest, (uint16_t *) vDest, (uint16_t *) aDest, dstW, chrDstW,
+                                 alpSrcPtr, dest, uDest, vDest, aDest, dstW, chrDstW,
                                  dstFormat);
                 } else {
                     yuv2yuvX_c(c, vLumFilter+dstY*vLumFilterSize,
@@ -1921,11 +1884,22 @@ static int swScale(SwsContext *c, const uint8_t* src[],
 
 static void sws_init_swScale_c(SwsContext *c)
 {
-    enum PixelFormat srcFormat = c->srcFormat;
+    enum PixelFormat srcFormat = c->srcFormat,
+                     dstFormat = c->dstFormat;
 
     c->yuv2nv12X    = yuv2nv12X_c;
-    c->yuv2yuv1     = yuv2yuv1_c;
-    c->yuv2yuvX     = yuv2yuvX_c;
+    if (is16BPS(dstFormat)) {
+        c->yuv2yuvX     = isBE(dstFormat) ? yuv2yuvX16BE_c  : yuv2yuvX16LE_c;
+    } else if (is9_OR_10BPS(dstFormat)) {
+        if (dstFormat == PIX_FMT_YUV420P9BE || dstFormat == PIX_FMT_YUV420P9LE) {
+            c->yuv2yuvX = isBE(dstFormat) ? yuv2yuvX9BE_c :  yuv2yuvX9LE_c;
+        } else {
+            c->yuv2yuvX = isBE(dstFormat) ? yuv2yuvX10BE_c : yuv2yuvX10LE_c;
+        }
+    } else {
+        c->yuv2yuv1     = yuv2yuv1_c;
+        c->yuv2yuvX     = yuv2yuvX_c;
+    }
     c->yuv2packed1  = yuv2packed1_c;
     c->yuv2packed2  = yuv2packed2_c;
     c->yuv2packedX  = yuv2packedX_c;
@@ -1962,10 +1936,10 @@ static void sws_init_swScale_c(SwsContext *c)
     }
     if (c->chrSrcHSubSample) {
         switch(srcFormat) {
-        case PIX_FMT_RGB48BE:
-        case PIX_FMT_RGB48LE: c->chrToYV12 = rgb48ToUV_half_c; break;
-        case PIX_FMT_BGR48BE:
-        case PIX_FMT_BGR48LE: c->chrToYV12 = bgr48ToUV_half_c; break;
+        case PIX_FMT_RGB48BE: c->chrToYV12 = rgb48BEToUV_half_c; break;
+        case PIX_FMT_RGB48LE: c->chrToYV12 = rgb48LEToUV_half_c; break;
+        case PIX_FMT_BGR48BE: c->chrToYV12 = bgr48BEToUV_half_c; break;
+        case PIX_FMT_BGR48LE: c->chrToYV12 = bgr48LEToUV_half_c; break;
         case PIX_FMT_RGB32  : c->chrToYV12 = bgr32ToUV_half_c;  break;
         case PIX_FMT_RGB32_1: c->chrToYV12 = bgr321ToUV_half_c; break;
         case PIX_FMT_BGR24  : c->chrToYV12 = bgr24ToUV_half_c; break;
@@ -1979,10 +1953,10 @@ static void sws_init_swScale_c(SwsContext *c)
         }
     } else {
         switch(srcFormat) {
-        case PIX_FMT_RGB48BE:
-        case PIX_FMT_RGB48LE: c->chrToYV12 = rgb48ToUV_c; break;
-        case PIX_FMT_BGR48BE:
-        case PIX_FMT_BGR48LE: c->chrToYV12 = bgr48ToUV_c; break;
+        case PIX_FMT_RGB48BE: c->chrToYV12 = rgb48BEToUV_c; break;
+        case PIX_FMT_RGB48LE: c->chrToYV12 = rgb48LEToUV_c; break;
+        case PIX_FMT_BGR48BE: c->chrToYV12 = bgr48BEToUV_c; break;
+        case PIX_FMT_BGR48LE: c->chrToYV12 = bgr48LEToUV_c; break;
         case PIX_FMT_RGB32  : c->chrToYV12 = bgr32ToUV_c;  break;
         case PIX_FMT_RGB32_1: c->chrToYV12 = bgr321ToUV_c; break;
         case PIX_FMT_BGR24  : c->chrToYV12 = bgr24ToUV_c; break;
@@ -2031,37 +2005,21 @@ static void sws_init_swScale_c(SwsContext *c)
     case PIX_FMT_RGB32_1: c->lumToYV12 = bgr321ToY_c; break;
     case PIX_FMT_BGR32  : c->lumToYV12 = rgb32ToY_c;  break;
     case PIX_FMT_BGR32_1: c->lumToYV12 = rgb321ToY_c; break;
-    case PIX_FMT_RGB48BE:
-    case PIX_FMT_RGB48LE: c->lumToYV12 = rgb48ToY_c; break;
-    case PIX_FMT_BGR48BE:
-    case PIX_FMT_BGR48LE: c->lumToYV12 = bgr48ToY_c; break;
+    case PIX_FMT_RGB48BE: c->lumToYV12 = rgb48BEToY_c; break;
+    case PIX_FMT_RGB48LE: c->lumToYV12 = rgb48LEToY_c; break;
+    case PIX_FMT_BGR48BE: c->lumToYV12 = bgr48BEToY_c; break;
+    case PIX_FMT_BGR48LE: c->lumToYV12 = bgr48LEToY_c; break;
     }
     if (c->alpPixBuf) {
         switch (srcFormat) {
-        case PIX_FMT_RGB32  :
-        case PIX_FMT_RGB32_1:
-        case PIX_FMT_BGR32  :
-        case PIX_FMT_BGR32_1: c->alpToYV12 = abgrToA_c; break;
-        case PIX_FMT_Y400A  : c->alpToYV12 = yuy2ToY_c; break;
+        case PIX_FMT_BGRA:
+        case PIX_FMT_RGBA:  c->alpToYV12 = rgbaToA_c; break;
+        case PIX_FMT_ABGR:
+        case PIX_FMT_ARGB:  c->alpToYV12 = abgrToA_c; break;
+        case PIX_FMT_Y400A: c->alpToYV12 = uyvyToY_c; break;
         }
     }
 
-    switch (srcFormat) {
-    case PIX_FMT_Y400A  :
-        c->alpSrcOffset = 1;
-        break;
-    case PIX_FMT_RGB32  :
-    case PIX_FMT_BGR32  :
-        c->alpSrcOffset = 3;
-        break;
-    case PIX_FMT_RGB48LE:
-    case PIX_FMT_BGR48LE:
-        c->lumSrcOffset = 1;
-        c->chrSrcOffset = 1;
-        c->alpSrcOffset = 1;
-        break;
-    }
-
     if (c->srcRange != c->dstRange && !isAnyRGB(c->dstFormat)) {
         if (c->srcRange) {
             c->lumConvertRange = lumRangeFromJpeg_c;