]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/rawdec.c
Merge commit 'b55566db4c51d920a6496455bb30a608e5a50a41'
[ffmpeg] / libavcodec / rawdec.c
index 765e567d1fac841f017f0f73f245ecd448489fe2..e53eb2eacc800aabee143097a6f6e0532489abbc 100644 (file)
@@ -204,8 +204,9 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
 
     desc = av_pix_fmt_desc_get(avctx->pix_fmt);
 
-    if ((avctx->bits_per_coded_sample == 8 || avctx->bits_per_coded_sample == 4
-            || avctx->bits_per_coded_sample <= 2) &&
+    if ((avctx->bits_per_coded_sample == 8 || avctx->bits_per_coded_sample == 4 ||
+         avctx->bits_per_coded_sample == 2 || avctx->bits_per_coded_sample == 1 ||
+         (avctx->bits_per_coded_sample == 0 && (context->is_nut_pal8 || context->is_mono)) ) &&
         (context->is_mono || context->is_pal8) &&
         (!avctx->codec_tag || avctx->codec_tag == MKTAG('r','a','w',' ') ||
                 context->is_nut_mono || context->is_nut_pal8)) {
@@ -363,22 +364,38 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
     }
 
     if (avctx->pix_fmt == AV_PIX_FMT_PAL8) {
+        int pal_size;
         const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE,
-                                                     NULL);
-        if (pal) {
-            av_buffer_unref(&context->palette);
+                                                     &pal_size);
+        int ret;
+
+        if (pal && pal_size != AVPALETTE_SIZE) {
+            av_log(avctx, AV_LOG_ERROR, "Palette size %d is wrong\n", pal_size);
+            pal = NULL;
+        }
+
+        if (!context->palette)
             context->palette = av_buffer_alloc(AVPALETTE_SIZE);
-            if (!context->palette) {
-                av_buffer_unref(&frame->buf[0]);
-                return AVERROR(ENOMEM);
-            }
+        if (!context->palette) {
+            av_buffer_unref(&frame->buf[0]);
+            return AVERROR(ENOMEM);
+        }
+        ret = av_buffer_make_writable(&context->palette);
+        if (ret < 0) {
+            av_buffer_unref(&frame->buf[0]);
+            return ret;
+        }
+
+        if (pal) {
             memcpy(context->palette->data, pal, AVPALETTE_SIZE);
             frame->palette_has_changed = 1;
         } else if (context->is_nut_pal8) {
             int vid_size = avctx->width * avctx->height;
-            if (avpkt->size - vid_size) {
+            int pal_size = avpkt->size - vid_size;
+
+            if (avpkt->size > vid_size && pal_size <= AVPALETTE_SIZE) {
                 pal = avpkt->data + vid_size;
-                memcpy(context->palette->data, pal, avpkt->size - vid_size);
+                memcpy(context->palette->data, pal, pal_size);
                 frame->palette_has_changed = 1;
             }
         }
@@ -444,6 +461,17 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame,
         }
     }
 
+    if (avctx->codec_tag == AV_RL32("b64a") &&
+        avctx->pix_fmt   == AV_PIX_FMT_RGBA64BE) {
+        uint8_t *dst = frame->data[0];
+        uint64_t v;
+        int x;
+        for (x = 0; x >> 3 < avctx->width * avctx->height; x += 8) {
+            v = AV_RB64(&dst[x]);
+            AV_WB64(&dst[x], v << 16 | v >> 48);
+        }
+    }
+
     if (avctx->field_order > AV_FIELD_PROGRESSIVE) { /* we have interlaced material flagged in container */
         frame->interlaced_frame = 1;
         if (avctx->field_order == AV_FIELD_TT || avctx->field_order == AV_FIELD_TB)