]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/xan.c
well that does not need to be there anymore
[ffmpeg] / libavcodec / xan.c
index e2e3e56e4143007ce81a26f739709c9f6e45a705..f98a06bca94a5720827a903e8e2e8b987b3b7902 100644 (file)
@@ -58,13 +58,6 @@ typedef struct XanContext {
 
 } XanContext;
 
-#define BE_16(x)  ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
-#define LE_16(x)  ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0])
-#define LE_32(x)  ((((uint8_t*)(x))[3] << 24) | \
-                   (((uint8_t*)(x))[2] << 16) | \
-                   (((uint8_t*)(x))[1] << 8) | \
-                    ((uint8_t*)(x))[0])
-
 /* RGB -> YUV conversion stuff */
 #define SCALEFACTOR 65536
 #define CENTERSAMPLE 128
@@ -115,9 +108,8 @@ static int xan_decode_init(AVCodecContext *avctx)
     s->avctx = avctx;
 
     if ((avctx->codec->id == CODEC_ID_XAN_WC3) && 
-        (s->avctx->extradata_size != sizeof(AVPaletteControl))) {
-        printf (" WC3 Xan video: expected extradata_size of %d\n",
-            sizeof(AVPaletteControl));
+        (s->avctx->palctrl == NULL)) {
+        av_log(avctx, AV_LOG_ERROR, " WC3 Xan video: palette expected.\n");
         return -1;
     }
 
@@ -253,12 +245,13 @@ static void xan_unpack(unsigned char *dest, unsigned char *src)
 }
 
 static void inline xan_wc3_build_palette(XanContext *s, 
-    unsigned char *palette_data)
+    unsigned int *palette_data)
 {
     int i;
     unsigned char r, g, b;
     unsigned short *palette16;
     unsigned int *palette32;
+    unsigned int pal_elem;
 
     /* transform the palette passed through the palette control structure
      * into the necessary internal format depending on colorspace */
@@ -268,42 +261,49 @@ static void inline xan_wc3_build_palette(XanContext *s,
     case PIX_FMT_RGB555:
         palette16 = (unsigned short *)s->palette;
         for (i = 0; i < PALETTE_COUNT; i++) {
-            r = *palette_data++;
-            g = *palette_data++;
-            b = *palette_data++;
+            pal_elem = palette_data[i];
+            r = (pal_elem >> 16) & 0xff;
+            g = (pal_elem >> 8) & 0xff;
+            b = pal_elem & 0xff;
             palette16[i] = 
                 ((r >> 3) << 10) |
                 ((g >> 3) <<  5) |
-                ((g >> 3) <<  0);
+                ((b >> 3) <<  0);
         }
         break;
 
     case PIX_FMT_RGB565:
         palette16 = (unsigned short *)s->palette;
         for (i = 0; i < PALETTE_COUNT; i++) {
-            r = *palette_data++;
-            g = *palette_data++;
-            b = *palette_data++;
+            pal_elem = palette_data[i];
+            r = (pal_elem >> 16) & 0xff;
+            g = (pal_elem >> 8) & 0xff;
+            b = pal_elem & 0xff;
             palette16[i] = 
                 ((r >> 3) << 11) |
                 ((g >> 2) <<  5) |
-                ((g >> 3) <<  0);
+                ((b >> 3) <<  0);
         }
         break;
 
     case PIX_FMT_RGB24:
         for (i = 0; i < PALETTE_COUNT; i++) {
-            s->palette[i * 4 + 0] = *palette_data++;
-            s->palette[i * 4 + 1] = *palette_data++;
-            s->palette[i * 4 + 2] = *palette_data++;
+            pal_elem = palette_data[i];
+            r = (pal_elem >> 16) & 0xff;
+            g = (pal_elem >> 8) & 0xff;
+            b = pal_elem & 0xff;
+            s->palette[i * 4 + 0] = r;
+            s->palette[i * 4 + 1] = g;
+            s->palette[i * 4 + 2] = b;
         }
         break;
 
     case PIX_FMT_BGR24:
         for (i = 0; i < PALETTE_COUNT; i++) {
-            r = *palette_data++;
-            g = *palette_data++;
-            b = *palette_data++;
+            pal_elem = palette_data[i];
+            r = (pal_elem >> 16) & 0xff;
+            g = (pal_elem >> 8) & 0xff;
+            b = pal_elem & 0xff;
             s->palette[i * 4 + 0] = b;
             s->palette[i * 4 + 1] = g;
             s->palette[i * 4 + 2] = r;
@@ -313,19 +313,15 @@ static void inline xan_wc3_build_palette(XanContext *s,
     case PIX_FMT_PAL8:
     case PIX_FMT_RGBA32:
         palette32 = (unsigned int *)s->palette;
-        for (i = 0; i < PALETTE_COUNT; i++) {
-            r = *palette_data++;
-            g = *palette_data++;
-            b = *palette_data++;
-            palette32[i] = (r << 16) | (g << 8) | (b);
-        }
+        memcpy (palette32, palette_data, PALETTE_COUNT * sizeof(unsigned int));
         break;
 
     case PIX_FMT_YUV444P:
         for (i = 0; i < PALETTE_COUNT; i++) {
-            r = *palette_data++;
-            g = *palette_data++;
-            b = *palette_data++;
+            pal_elem = palette_data[i];
+            r = (pal_elem >> 16) & 0xff;
+            g = (pal_elem >> 8) & 0xff;
+            b = pal_elem & 0xff;
             s->palette[i * 4 + 0] = COMPUTE_Y(r, g, b);
             s->palette[i * 4 + 1] = COMPUTE_U(r, g, b);
             s->palette[i * 4 + 2] = COMPUTE_V(r, g, b);
@@ -333,11 +329,20 @@ static void inline xan_wc3_build_palette(XanContext *s,
         break;
 
     default:
-        printf (" Xan WC3: Unhandled colorspace\n");
+        av_log(s->avctx, AV_LOG_ERROR, " Xan WC3: Unhandled colorspace\n");
         break;
     }
 }
 
+/* advance current_x variable; reset accounting variables if current_x
+ * moves beyond width */
+#define ADVANCE_CURRENT_X() \
+    current_x++; \
+    if (current_x >= width) { \
+        index += line_inc; \
+        current_x = 0; \
+    }
+
 static void inline xan_wc3_output_pixel_run(XanContext *s, 
     unsigned char *pixel_buffer, int x, int y, int pixel_count)
 {
@@ -346,7 +351,7 @@ static void inline xan_wc3_output_pixel_run(XanContext *s,
     int index;
     int current_x;
     int width = s->avctx->width;
-    unsigned char pixel;
+    unsigned char pix;
     unsigned char *palette_plane;
     unsigned char *y_plane;
     unsigned char *u_plane;
@@ -371,12 +376,7 @@ static void inline xan_wc3_output_pixel_run(XanContext *s,
              * frame of data and the stride needs to be accounted for */
             palette_plane[index++] = *pixel_buffer++;
 
-            current_x++;
-            if (current_x >= width) {
-                /* reset accounting variables */
-                index += line_inc;
-                current_x = 0;
-            }
+            ADVANCE_CURRENT_X();
         }
         break;
 
@@ -392,12 +392,7 @@ static void inline xan_wc3_output_pixel_run(XanContext *s,
 
             rgb16_plane[index++] = palette16[*pixel_buffer++];
 
-            current_x++;
-            if (current_x >= width) {
-                /* reset accounting variables */
-                index += line_inc;
-                current_x = 0;
-            }
+            ADVANCE_CURRENT_X();
         }
         break;
 
@@ -409,18 +404,13 @@ static void inline xan_wc3_output_pixel_run(XanContext *s,
         index = y * stride + x * 3;
         current_x = x;
         while(pixel_count--) {
-            pixel = *pixel_buffer++;
+            pix = *pixel_buffer++;
 
-            rgb_plane[index++] = s->palette[pixel * 4 + 0];
-            rgb_plane[index++] = s->palette[pixel * 4 + 1];
-            rgb_plane[index++] = s->palette[pixel * 4 + 2];
+            rgb_plane[index++] = s->palette[pix * 4 + 0];
+            rgb_plane[index++] = s->palette[pix * 4 + 1];
+            rgb_plane[index++] = s->palette[pix * 4 + 2];
 
-            current_x++;
-            if (current_x >= width) {
-                /* reset accounting variables */
-                index += line_inc;
-                current_x = 0;
-            }
+            ADVANCE_CURRENT_X();
         }
         break;
 
@@ -435,12 +425,7 @@ static void inline xan_wc3_output_pixel_run(XanContext *s,
 
             rgb32_plane[index++] = palette32[*pixel_buffer++];
 
-            current_x++;
-            if (current_x >= width) {
-                /* reset accounting variables */
-                index += line_inc;
-                current_x = 0;
-            }
+            ADVANCE_CURRENT_X();
         }
         break;
 
@@ -453,28 +438,37 @@ static void inline xan_wc3_output_pixel_run(XanContext *s,
         index = y * stride + x;
         current_x = x;
         while(pixel_count--) {
-            pixel = *pixel_buffer++;
+            pix = *pixel_buffer++;
 
-            y_plane[index] = s->palette[pixel * 4 + 0];
-            u_plane[index] = s->palette[pixel * 4 + 1];
-            v_plane[index] = s->palette[pixel * 4 + 2];
+            y_plane[index] = s->palette[pix * 4 + 0];
+            u_plane[index] = s->palette[pix * 4 + 1];
+            v_plane[index] = s->palette[pix * 4 + 2];
 
             index++;
-            current_x++;
-            if (current_x >= width) {
-                /* reset accounting variables */
-                index += line_inc;
-                current_x = 0;
-            }
+            ADVANCE_CURRENT_X();
         }
         break;
 
     default:
-        printf (" Xan WC3: Unhandled colorspace\n");
+        av_log(s->avctx, AV_LOG_ERROR, " Xan WC3: Unhandled colorspace\n");
         break;
     }
 }
 
+#define ADVANCE_CURFRAME_X() \
+    curframe_x++; \
+    if (curframe_x >= width) { \
+        curframe_index += line_inc; \
+        curframe_x = 0; \
+    }
+
+#define ADVANCE_PREVFRAME_X() \
+    prevframe_x++; \
+    if (prevframe_x >= width) { \
+        prevframe_index += line_inc; \
+        prevframe_x = 0; \
+    }
+
 static void inline xan_wc3_copy_pixel_run(XanContext *s, 
     int x, int y, int pixel_count, int motion_x, int motion_y)
 {
@@ -506,19 +500,8 @@ static void inline xan_wc3_copy_pixel_run(XanContext *s,
             palette_plane[curframe_index++] = 
                 prev_palette_plane[prevframe_index++];
 
-            curframe_x++;
-            if (curframe_x >= width) {
-                /* reset accounting variables */
-                curframe_index += line_inc;
-                curframe_x = 0;
-            }
-
-            prevframe_x++;
-            if (prevframe_x >= width) {
-                /* reset accounting variables */
-                prevframe_index += line_inc;
-                prevframe_x = 0;
-            }
+            ADVANCE_CURFRAME_X();
+            ADVANCE_PREVFRAME_X();
         }
         break;
 
@@ -537,19 +520,8 @@ static void inline xan_wc3_copy_pixel_run(XanContext *s,
             rgb16_plane[curframe_index++] = 
                 prev_rgb16_plane[prevframe_index++];
 
-            curframe_x++;
-            if (curframe_x >= width) {
-                /* reset accounting variables */
-                curframe_index += line_inc;
-                curframe_x = 0;
-            }
-
-            prevframe_x++;
-            if (prevframe_x >= width) {
-                /* reset accounting variables */
-                prevframe_index += line_inc;
-                prevframe_x = 0;
-            }
+            ADVANCE_CURFRAME_X();
+            ADVANCE_PREVFRAME_X();
         }
         break;
 
@@ -570,19 +542,8 @@ static void inline xan_wc3_copy_pixel_run(XanContext *s,
             rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
             rgb_plane[curframe_index++] = prev_rgb_plane[prevframe_index++];
 
-            curframe_x++;
-            if (curframe_x >= width) {
-                /* reset accounting variables */
-                curframe_index += line_inc;
-                curframe_x = 0;
-            }
-
-            prevframe_x++;
-            if (prevframe_x >= width) {
-                /* reset accounting variables */
-                prevframe_index += line_inc;
-                prevframe_x = 0;
-            }
+            ADVANCE_CURFRAME_X();
+            ADVANCE_PREVFRAME_X();
         }
         break;
 
@@ -600,19 +561,8 @@ static void inline xan_wc3_copy_pixel_run(XanContext *s,
             rgb32_plane[curframe_index++] = 
                 prev_rgb32_plane[prevframe_index++];
 
-            curframe_x++;
-            if (curframe_x >= width) {
-                /* reset accounting variables */
-                curframe_index += line_inc;
-                curframe_x = 0;
-            }
-
-            prevframe_x++;
-            if (prevframe_x >= width) {
-                /* reset accounting variables */
-                prevframe_index += line_inc;
-                prevframe_x = 0;
-            }
+            ADVANCE_CURFRAME_X();
+            ADVANCE_PREVFRAME_X();
         }
         break;
 
@@ -636,25 +586,14 @@ static void inline xan_wc3_copy_pixel_run(XanContext *s,
             v_plane[curframe_index] = prev_v_plane[prevframe_index];
 
             curframe_index++;
-            curframe_x++;
-            if (curframe_x >= width) {
-                /* reset accounting variables */
-                curframe_index += line_inc;
-                curframe_x = 0;
-            }
-
+            ADVANCE_CURFRAME_X();
             prevframe_index++;
-            prevframe_x++;
-            if (prevframe_x >= width) {
-                /* reset accounting variables */
-                prevframe_index += line_inc;
-                prevframe_x = 0;
-            }
+            ADVANCE_PREVFRAME_X();
         }
         break;
 
     default:
-        printf (" Xan WC3: Unhandled colorspace\n");
+        av_log(s->avctx, AV_LOG_ERROR, " Xan WC3: Unhandled colorspace\n");
         break;
     }
 }
@@ -787,8 +726,11 @@ static void xan_wc3_decode_frame(XanContext *s) {
     }
 
     /* for PAL8, make the palette available on the way out */
-    if (s->avctx->pix_fmt == PIX_FMT_PAL8)
+    if (s->avctx->pix_fmt == PIX_FMT_PAL8) {
         memcpy(s->current_frame.data[1], s->palette, PALETTE_COUNT * 4);
+        s->current_frame.palette_has_changed = 1;
+        s->avctx->palctrl->palette_changed = 0;
+    }
 }
 
 static void xan_wc4_decode_frame(XanContext *s) {
@@ -799,18 +741,20 @@ static int xan_decode_frame(AVCodecContext *avctx,
                             uint8_t *buf, int buf_size)
 {
     XanContext *s = avctx->priv_data;
-    AVPaletteControl *palette_control = (AVPaletteControl *)avctx->extradata;
+    AVPaletteControl *palette_control = avctx->palctrl;
     int keyframe = 0;
 
     if (palette_control->palette_changed) {
         /* load the new palette and reset the palette control */
         xan_wc3_build_palette(s, palette_control->palette);
-        palette_control->palette_changed = 0;
+        /* If pal8 we clear flag when we copy palette */
+        if (s->avctx->pix_fmt != PIX_FMT_PAL8)
+            palette_control->palette_changed = 0;
         keyframe = 1;
     }
 
     if (avctx->get_buffer(avctx, &s->current_frame)) {
-        printf ("  Xan Video: get_buffer() failed\n");
+        av_log(s->avctx, AV_LOG_ERROR, "  Xan Video: get_buffer() failed\n");
         return -1;
     }
     s->current_frame.reference = 3;