changeset 1202:8b49a7ee4e4e libavcodec

YUV formats/gray formats are correctly defined - added format loss information - preliminary JPEG YUV formats support
author bellard
date Sun, 20 Apr 2003 16:18:44 +0000
parents e0fc95a6eb4e
children 80c73b9b0ba2
files imgconvert.c
diffstat 1 files changed, 372 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/imgconvert.c	Sun Apr 20 16:16:52 2003 +0000
+++ b/imgconvert.c	Sun Apr 20 16:18:44 2003 +0000
@@ -34,16 +34,21 @@
 #include "i386/mmx.h"
 #endif
 
+#define FF_COLOR_RGB      0 /* RGB color space */
+#define FF_COLOR_GRAY     1 /* gray color space */
+#define FF_COLOR_YUV      2 /* YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */
+#define FF_COLOR_YUV_JPEG 3 /* YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */
+
 typedef struct PixFmtInfo {
     const char *name;
     uint8_t nb_components;     /* number of components in AVPicture array  */
-    uint8_t is_yuv : 1;    /* true if YUV instead of RGB color space */
+    uint8_t color_type;        /* color type (see FF_COLOR_xxx constants) */
     uint8_t is_packed : 1; /* true if multiple components in same word */
     uint8_t is_paletted : 1; /* true if paletted */
     uint8_t is_alpha : 1;    /* true if alpha can be specified */
-    uint8_t is_gray : 1;     /* true if gray or monochrome format */
     uint8_t x_chroma_shift; /* X chroma subsampling factor is 2 ^ shift */
     uint8_t y_chroma_shift; /* Y chroma subsampling factor is 2 ^ shift */
+    uint8_t depth;          /* bit depth of the color components */
 } PixFmtInfo;
 
 /* this table gives more information about formats */
@@ -51,87 +56,135 @@
     /* YUV formats */
     [PIX_FMT_YUV420P] = {
         .name = "yuv420p",
-        .nb_components = 3, .is_yuv = 1,
+        .nb_components = 3,
+        .color_type = FF_COLOR_YUV,
+        .depth = 8,
         .x_chroma_shift = 1, .y_chroma_shift = 1, 
     },
     [PIX_FMT_YUV422P] = {
         .name = "yuv422p",
-        .nb_components = 3, .is_yuv = 1,
+        .nb_components = 3,
+        .color_type = FF_COLOR_YUV,
+        .depth = 8,
         .x_chroma_shift = 1, .y_chroma_shift = 0, 
     },
     [PIX_FMT_YUV444P] = {
         .name = "yuv444p",
-        .nb_components = 3, .is_yuv = 1,
+        .nb_components = 3,
+        .color_type = FF_COLOR_YUV,
+        .depth = 8,
         .x_chroma_shift = 0, .y_chroma_shift = 0, 
     },
     [PIX_FMT_YUV422] = {
         .name = "yuv422",
-        .nb_components = 1, .is_yuv = 1, .is_packed = 1,
+        .nb_components = 1, .is_packed = 1,
+        .color_type = FF_COLOR_YUV,
+        .depth = 8,
         .x_chroma_shift = 1, .y_chroma_shift = 0,
     },
     [PIX_FMT_YUV410P] = {
         .name = "yuv410p",
-        .nb_components = 3, .is_yuv = 1,
+        .nb_components = 3,
+        .color_type = FF_COLOR_YUV,
+        .depth = 8,
         .x_chroma_shift = 2, .y_chroma_shift = 2,
     },
     [PIX_FMT_YUV411P] = {
         .name = "yuv411p",
-        .nb_components = 3, .is_yuv = 1,
+        .nb_components = 3,
+        .color_type = FF_COLOR_YUV,
+        .depth = 8,
         .x_chroma_shift = 2, .y_chroma_shift = 0,
     },
 
+    /* JPEG YUV */
+    [PIX_FMT_YUVJ420P] = {
+        .name = "yuvj420p",
+        .nb_components = 3,
+        .color_type = FF_COLOR_YUV_JPEG,
+        .depth = 8,
+        .x_chroma_shift = 1, .y_chroma_shift = 1, 
+    },
+    [PIX_FMT_YUVJ422P] = {
+        .name = "yuvj422p",
+        .nb_components = 3,
+        .color_type = FF_COLOR_YUV_JPEG,
+        .depth = 8,
+        .x_chroma_shift = 1, .y_chroma_shift = 0, 
+    },
+    [PIX_FMT_YUVJ444P] = {
+        .name = "yuvj444p",
+        .nb_components = 3,
+        .color_type = FF_COLOR_YUV_JPEG,
+        .depth = 8,
+        .x_chroma_shift = 0, .y_chroma_shift = 0, 
+    },
+
     /* RGB formats */
     [PIX_FMT_RGB24] = {
         .name = "rgb24",
         .nb_components = 1, .is_packed = 1,
+        .color_type = FF_COLOR_RGB,
+        .depth = 8,
     },
     [PIX_FMT_BGR24] = {
         .name = "bgr24",
         .nb_components = 1, .is_packed = 1,
+        .color_type = FF_COLOR_RGB,
+        .depth = 8,
     },
     [PIX_FMT_RGBA32] = {
         .name = "rgba32",
         .nb_components = 1, .is_packed = 1, .is_alpha = 1,
+        .color_type = FF_COLOR_RGB,
+        .depth = 8,
     },
     [PIX_FMT_RGB565] = {
         .name = "rgb565",
         .nb_components = 1, .is_packed = 1,
+        .color_type = FF_COLOR_RGB,
+        .depth = 5,
     },
     [PIX_FMT_RGB555] = {
         .name = "rgb555",
         .nb_components = 1, .is_packed = 1, .is_alpha = 1,
+        .color_type = FF_COLOR_RGB,
+        .depth = 5,
     },
 
     /* gray / mono formats */
     [PIX_FMT_GRAY8] = {
         .name = "gray",
-        .nb_components = 1, .is_gray = 1,
+        .nb_components = 1,
+        .color_type = FF_COLOR_GRAY,
+        .depth = 8,
     },
     [PIX_FMT_MONOWHITE] = {
         .name = "monow",
-        .nb_components = 1, .is_packed = 1, .is_gray = 1,
+        .nb_components = 1,
+        .color_type = FF_COLOR_GRAY,
+        .depth = 1,
     },
     [PIX_FMT_MONOBLACK] = {
         .name = "monob",
-        .nb_components = 1, .is_packed = 1, .is_gray = 1,
+        .nb_components = 1,
+        .color_type = FF_COLOR_GRAY,
+        .depth = 1,
     },
 
     /* paletted formats */
     [PIX_FMT_PAL8] = {
         .name = "pal8",
         .nb_components = 1, .is_packed = 1, .is_alpha = 1, .is_paletted = 1,
+        .color_type = FF_COLOR_RGB,
+        .depth = 8,
     },
 };
 
 void avcodec_get_chroma_sub_sample(int pix_fmt, int *h_shift, int *v_shift)
 {
-    if (pix_fmt_info[pix_fmt].is_yuv) {
-        *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
-        *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
-    } else {
-        *h_shift=0;
-        *v_shift=0;
-    }
+    *h_shift = pix_fmt_info[pix_fmt].x_chroma_shift;
+    *v_shift = pix_fmt_info[pix_fmt].y_chroma_shift;
 }
 
 const char *avcodec_get_pix_fmt_name(int pix_fmt)
@@ -224,6 +277,155 @@
     return avpicture_fill(&dummy_pict, NULL, pix_fmt, width, height);
 }
 
+/**
+ * compute the loss when converting from a pixel format to another 
+ */
+int avcodec_get_pix_fmt_loss(int dst_pix_fmt, int src_pix_fmt,
+                             int has_alpha)
+{
+    const PixFmtInfo *pf, *ps;
+    int loss;
+
+    ps = &pix_fmt_info[src_pix_fmt];
+    pf = &pix_fmt_info[dst_pix_fmt];
+
+    /* compute loss */
+    loss = 0;
+    pf = &pix_fmt_info[dst_pix_fmt];
+    if (pf->depth < ps->depth)
+        loss |= FF_LOSS_DEPTH;
+    if (pf->x_chroma_shift >= ps->x_chroma_shift ||
+        pf->y_chroma_shift >= ps->y_chroma_shift)
+        loss |= FF_LOSS_RESOLUTION;
+    switch(pf->color_type) {
+    case FF_COLOR_RGB:
+        if (ps->color_type != FF_COLOR_RGB &&
+            ps->color_type != FF_COLOR_GRAY)
+            loss |= FF_LOSS_COLORSPACE;
+        break;
+    case FF_COLOR_GRAY:
+        if (ps->color_type != FF_COLOR_GRAY)
+            loss |= FF_LOSS_COLORSPACE;
+        break;
+    case FF_COLOR_YUV:
+        if (ps->color_type != FF_COLOR_YUV)
+            loss |= FF_LOSS_COLORSPACE;
+        break;
+    case FF_COLOR_YUV_JPEG:
+        if (ps->color_type != FF_COLOR_YUV_JPEG &&
+            ps->color_type != FF_COLOR_YUV)
+            loss |= FF_LOSS_COLORSPACE;
+        break;
+    default:
+        /* fail safe test */
+        if (ps->color_type != pf->color_type)
+            loss |= FF_LOSS_COLORSPACE;
+        break;
+    }
+    if (pf->color_type == FF_COLOR_GRAY &&
+        ps->color_type != FF_COLOR_GRAY)
+        loss |= FF_LOSS_CHROMA;
+    if (!pf->is_alpha && (ps->is_alpha && has_alpha))
+        loss |= FF_LOSS_ALPHA;
+    if (pf->is_paletted && (!ps->is_paletted && ps->color_type != FF_COLOR_GRAY))
+        loss |= FF_LOSS_COLORQUANT;
+    return loss;
+}
+
+static int avg_bits_per_pixel(int pix_fmt)
+{
+    int bits;
+    const PixFmtInfo *pf;
+
+    pf = &pix_fmt_info[pix_fmt];
+    if (pf->is_packed) {
+        switch(pix_fmt) {
+        case PIX_FMT_RGB24:
+        case PIX_FMT_BGR24:
+            bits = 24;
+            break;
+        case PIX_FMT_RGBA32:
+            bits = 32;
+                        break;
+        case PIX_FMT_RGB565:
+        case PIX_FMT_RGB555:
+            bits = 16;
+                        break;
+        case PIX_FMT_PAL8:
+            bits = 8;
+            break;
+        default:
+            bits = 32;
+            break;
+        }
+    } else {
+        bits = pf->depth;
+        bits += (2 * pf->depth >> 
+                 (pf->x_chroma_shift + pf->x_chroma_shift));
+    }
+    return bits;
+}
+
+static int avcodec_find_best_pix_fmt1(int pix_fmt_mask, 
+                                      int src_pix_fmt,
+                                      int has_alpha,
+                                      int loss_mask)
+{
+    int dist, i, loss, min_dist, dst_pix_fmt;
+
+    /* find exact color match with smallest size */
+    dst_pix_fmt = -1;
+    min_dist = 0x7fffffff;
+    for(i = 0;i < PIX_FMT_NB; i++) {
+        if (pix_fmt_mask & (1 << i)) {
+            loss = avcodec_get_pix_fmt_loss(i, src_pix_fmt, has_alpha) & loss_mask;
+            if (loss == 0) {
+                dist = avg_bits_per_pixel(i);
+                if (dist < min_dist) {
+                    min_dist = dist;
+                    dst_pix_fmt = i;
+                }
+            }
+        }
+    }
+    return dst_pix_fmt;
+}
+
+/** 
+ * find best pixel format to convert to. Return -1 if none found 
+ */
+int avcodec_find_best_pix_fmt(int pix_fmt_mask, int src_pix_fmt,
+                              int has_alpha, int *loss_ptr)
+{
+    int dst_pix_fmt, loss_mask, i;
+    static const int loss_mask_order[] = {
+        ~0, /* no loss first */
+        ~FF_LOSS_ALPHA,
+        ~FF_LOSS_RESOLUTION,
+        ~(FF_LOSS_COLORSPACE | FF_LOSS_RESOLUTION),
+        ~FF_LOSS_COLORQUANT,
+        ~FF_LOSS_DEPTH,
+        0,
+    };
+
+    /* try with successive loss */
+    i = 0;
+    for(;;) {
+        loss_mask = loss_mask_order[i++];
+        dst_pix_fmt = avcodec_find_best_pix_fmt1(pix_fmt_mask, src_pix_fmt, 
+                                                 has_alpha, loss_mask);
+        if (dst_pix_fmt >= 0)
+            goto found;
+        if (loss_mask == 0)
+            break;
+    }
+    return -1;
+ found:
+    if (loss_ptr)
+        *loss_ptr = avcodec_get_pix_fmt_loss(dst_pix_fmt, src_pix_fmt, has_alpha);
+    return dst_pix_fmt;
+}
+
 
 /* XXX: totally non optimized */
 
@@ -263,6 +465,120 @@
 #define ONE_HALF  (1 << (SCALEBITS - 1))
 #define FIX(x)		((int) ((x) * (1L<<SCALEBITS) + 0.5))
 
+#define SCALE_BITS 10
+
+#define C_Y  (76309 >> (16 - SCALE_BITS))
+#define C_RV (117504 >> (16 - SCALE_BITS))
+#define C_BU (138453 >> (16 - SCALE_BITS))
+#define C_GU (13954 >> (16 - SCALE_BITS))
+#define C_GV (34903 >> (16 - SCALE_BITS))
+
+#define YUV_TO_RGB2(r, g, b, y1)\
+{\
+    y = (y1 - 16) * C_Y;\
+    r = cm[(y + r_add) >> SCALE_BITS];\
+    g = cm[(y + g_add) >> SCALE_BITS];\
+    b = cm[(y + b_add) >> SCALE_BITS];\
+}
+
+/* XXX: use a table ? */
+#define CCIR_TO_GRAY(y)\
+ cm[((y) * FIX(255.0/219.0) + (ONE_HALF - 16 * FIX(255.0/219.0))) >> SCALEBITS]
+
+#define GRAY_TO_CCIR(y)\
+ (((y) * FIX(219.0/255.0) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
+
+#define RGB_TO_Y(r, g, b) \
+((FIX(0.29900) * (r) + FIX(0.58700) * (g) + \
+  FIX(0.11400) * (b) + ONE_HALF) >> SCALEBITS)
+
+#define RGB4_TO_U(r1, g1, b1)\
+(((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +         \
+     FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128)
+
+#define RGB4_TO_V(r1, g1, b1)\
+(((FIX(0.50000) * r1 - FIX(0.41869) * g1 -           \
+   FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128)
+
+#define RGB_TO_Y_CCIR(r, g, b) \
+((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
+  FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
+
+#define RGB4_TO_U_CCIR(r1, g1, b1)\
+(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 +         \
+     FIX(0.50000*224.0/255.0) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128)
+
+#define RGB4_TO_V_CCIR(r1, g1, b1)\
+(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 -           \
+   FIX(0.08131*224.0/255.0) * b1 + 4 * ONE_HALF - 1) >> (SCALEBITS + 2)) + 128)
+
+/* convert from CCIR luma (16 <= Y <= 235) to full scale gray (0 <= Y <= 255) */
+static void luma_ccir_to_gray(uint8_t *dst, int dst_wrap, 
+                              uint8_t *src, int src_wrap,
+                              int width, int height)
+{
+    int n;
+    const uint8_t *s;
+    uint8_t *d;
+    uint8_t *cm = cropTbl + MAX_NEG_CROP;
+
+    for(;height > 0; height--) {
+        s = src;
+        d = dst;
+        n = width;
+        while (n >= 4) {
+            d[0] = CCIR_TO_GRAY(s[0]);
+            d[1] = CCIR_TO_GRAY(s[1]);
+            d[2] = CCIR_TO_GRAY(s[2]);
+            d[3] = CCIR_TO_GRAY(s[3]);
+            d += 4;
+            s += 4;
+            n -= 4;
+        }
+        while (n > 0) {
+            d[0] = CCIR_TO_GRAY(s[0]);
+            d++;
+            s++;
+            n--;
+        }
+        dst += dst_wrap;
+        src += src_wrap;
+    }
+}
+
+/* convert from full scale gray (0 <= Y <= 255) to CCIR luma (16 <= Y <= 235) */
+static void gray_to_luma_ccir(uint8_t *dst, int dst_wrap, 
+                              uint8_t *src, int src_wrap,
+                              int width, int height)
+{
+    int n;
+    const uint8_t *s;
+    uint8_t *d;
+
+    for(;height > 0; height--) {
+        s = src;
+        d = dst;
+        n = width;
+        while (n >= 4) {
+            d[0] = GRAY_TO_CCIR(s[0]);
+            d[1] = GRAY_TO_CCIR(s[1]);
+            d[2] = GRAY_TO_CCIR(s[2]);
+            d[3] = GRAY_TO_CCIR(s[3]);
+            d += 4;
+            s += 4;
+            n -= 4;
+        }
+        while (n > 0) {
+            d[0] = GRAY_TO_CCIR(s[0]);
+            d++;
+            s++;
+            n--;
+        }
+        dst += dst_wrap;
+        src += src_wrap;
+    }
+}
+
 /* XXX: use generic filter ? */
 /* 1x2 -> 1x1 */
 static void shrink2(uint8_t *dst, int dst_wrap, 
@@ -394,22 +710,6 @@
     }
 }
 
-#define SCALE_BITS 10
-
-#define C_Y  (76309 >> (16 - SCALE_BITS))
-#define C_RV (117504 >> (16 - SCALE_BITS))
-#define C_BU (138453 >> (16 - SCALE_BITS))
-#define C_GU (13954 >> (16 - SCALE_BITS))
-#define C_GV (34903 >> (16 - SCALE_BITS))
-
-#define YUV_TO_RGB2(r, g, b, y1)\
-{\
-    y = (y1 - 16) * C_Y;\
-    r = cm[(y + r_add) >> SCALE_BITS];\
-    g = cm[(y + g_add) >> SCALE_BITS];\
-    b = cm[(y + b_add) >> SCALE_BITS];\
-}
-
 /* XXX: no chroma interpolating is done */
 #define RGB_FUNCTIONS(rgb_name)                                         \
                                                                         \
@@ -607,14 +907,13 @@
             r1 = r;                                                     \
             g1 = g;                                                     \
             b1 = b;                                                     \
-            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +             \
-                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;        \
+            lum[0] = RGB_TO_Y_CCIR(r, g, b);        \
+\
             RGB_IN(r, g, b, p + BPP);                                   \
             r1 += r;                                                    \
             g1 += g;                                                    \
             b1 += b;                                                    \
-            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +             \
-                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;        \
+            lum[1] = RGB_TO_Y_CCIR(r, g, b);        \
             p += wrap3;                                                 \
             lum += wrap;                                                \
                                                                         \
@@ -622,22 +921,16 @@
             r1 += r;                                                    \
             g1 += g;                                                    \
             b1 += b;                                                    \
-            lum[0] = (FIX(0.29900) * r + FIX(0.58700) * g +             \
-                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;        \
-                                                                        \
+            lum[0] = RGB_TO_Y_CCIR(r, g, b);        \
+\
             RGB_IN(r, g, b, p + BPP);                                   \
             r1 += r;                                                    \
             g1 += g;                                                    \
             b1 += b;                                                    \
-            lum[1] = (FIX(0.29900) * r + FIX(0.58700) * g +             \
-                      FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;        \
+            lum[1] = RGB_TO_Y_CCIR(r, g, b);        \
                                                                         \
-            cb[0] = ((- FIX(0.16874) * r1 - FIX(0.33126) * g1 +         \
-                      FIX(0.50000) * b1 + 4 * ONE_HALF - 1) >>          \
-                     (SCALEBITS + 2)) + 128;                            \
-            cr[0] = ((FIX(0.50000) * r1 - FIX(0.41869) * g1 -           \
-                     FIX(0.08131) * b1 + 4 * ONE_HALF - 1) >>           \
-                     (SCALEBITS + 2)) + 128;                            \
+            cb[0] = RGB4_TO_U_CCIR(r1, g1, b1);                         \
+            cr[0] = RGB4_TO_V_CCIR(r1, g1, b1);                         \
                                                                         \
             cb++;                                                       \
             cr++;                                                       \
@@ -668,8 +961,7 @@
     for(y=0;y<height;y++) {                                             \
         for(x=0;x<width;x++) {                                          \
             RGB_IN(r, g, b, p);                                         \
-            q[0] = (FIX(0.29900) * r + FIX(0.58700) * g +               \
-                    FIX(0.11400) * b + ONE_HALF) >> SCALEBITS;          \
+            q[0] = RGB_TO_Y(r, g, b);          \
             q++;                                                        \
             p += BPP;                                                   \
         }                                                               \
@@ -1317,7 +1609,9 @@
             int w, h;
             w = dst_width;
             h = dst_height;
-            if (dst_pix->is_yuv && (i == 1 || i == 2)) {
+            if ((dst_pix->color_type == FF_COLOR_YUV || 
+                 dst_pix->color_type == FF_COLOR_YUV_JPEG) &&
+                (i == 1 || i == 2)) {
                 w >>= dst_pix->x_chroma_shift;
                 h >>= dst_pix->y_chroma_shift;
             }
@@ -1336,13 +1630,21 @@
     }
 
     /* gray to YUV */
-    if (dst_pix->is_yuv && src_pix_fmt == PIX_FMT_GRAY8) {
+    if ((dst_pix->color_type == FF_COLOR_YUV ||
+         dst_pix->color_type == FF_COLOR_YUV_JPEG) &&
+        src_pix_fmt == PIX_FMT_GRAY8) {
         int w, h, y;
         uint8_t *d;
 
-        img_copy(dst->data[0], dst->linesize[0],
-                 src->data[0], src->linesize[0],
-                 dst_width, dst_height);
+        if (dst_pix->color_type == FF_COLOR_YUV_JPEG) {
+            img_copy(dst->data[0], dst->linesize[0],
+                     src->data[0], src->linesize[0],
+                     dst_width, dst_height);
+        } else {
+            gray_to_luma_ccir(dst->data[0], dst->linesize[0],
+                              src->data[0], src->linesize[0],
+                              dst_width, dst_height);
+        }
         /* fill U and V with 128 */
         w = dst_width;
         h = dst_height;
@@ -1359,15 +1661,24 @@
     }
 
     /* YUV to gray */
-    if (src_pix->is_yuv && dst_pix_fmt == PIX_FMT_GRAY8) {
-        img_copy(dst->data[0], dst->linesize[0],
-                 src->data[0], src->linesize[0],
-                 dst_width, dst_height);
+    if ((src_pix->color_type == FF_COLOR_YUV ||
+         src_pix->color_type == FF_COLOR_YUV_JPEG) && 
+        dst_pix_fmt == PIX_FMT_GRAY8) {
+        if (src_pix->color_type == FF_COLOR_YUV_JPEG) {
+            img_copy(dst->data[0], dst->linesize[0],
+                     src->data[0], src->linesize[0],
+                     dst_width, dst_height);
+        } else {
+            luma_ccir_to_gray(dst->data[0], dst->linesize[0],
+                              src->data[0], src->linesize[0],
+                              dst_width, dst_height);
+        }
         return 0;
     }
 
     /* YUV to YUV */
-    if (dst_pix->is_yuv && src_pix->is_yuv) {
+    if (dst_pix->color_type == FF_COLOR_YUV &&
+        dst_pix->color_type == src_pix->color_type) {
         int x_shift, y_shift, w, h;
         void (*resize_func)(uint8_t *dst, int dst_wrap, 
                             uint8_t *src, int src_wrap,