]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/iff.c
mlpdec: fix channel order for wide 7.1 truehd layouts
[ffmpeg] / libavcodec / iff.c
index 31aa6f094749ba9e95374b3eb77e89223233f479..7a11d4310ea3902977311854087bbaf30ebd2ebf 100644 (file)
@@ -137,6 +137,7 @@ static av_always_inline uint32_t gray2rgb(const uint32_t x) {
  */
 static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
 {
+    IffContext *s = avctx->priv_data;
     int count, i;
     const uint8_t *const palette = avctx->extradata + AV_RB16(avctx->extradata);
     int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata);
@@ -153,6 +154,10 @@ static int ff_cmap_read_palette(AVCodecContext *avctx, uint32_t *pal)
         for (i=0; i < count; i++) {
             pal[i] = 0xFF000000 | AV_RB24(palette + i*3);
         }
+        if (s->flags && count >= 32) { // EHB
+            for (i = 0; i < 32; i++)
+                pal[i + 32] = 0xFF000000 | (AV_RB24(palette + i*3) & 0xFEFEFE) >> 1;
+        }
     } else { // Create gray-scale color palette for bps < 8
         count = 1 << avctx->bits_per_coded_sample;
 
@@ -266,9 +271,6 @@ static int extract_header(AVCodecContext *const avctx,
                 s->ham_palbuf[(i+count*2)*2+1] = tmp;
                 s->ham_palbuf[(i+count*3)*2+1] = tmp << 8;
             }
-        } else if (s->flags & 1) { // EHB (ExtraHalfBrite) color palette
-            av_log(avctx, AV_LOG_ERROR, "ExtraHalfBrite (EHB) mode not supported\n");
-            return AVERROR_PATCHWELCOME;
         }
     }
 
@@ -302,7 +304,7 @@ static av_cold int decode_init(AVCodecContext *avctx)
 
     if ((err = extract_header(avctx, NULL)) < 0)
         return err;
-    s->frame.reference = 1;
+    s->frame.reference = 3;
 
     return 0;
 }
@@ -440,7 +442,31 @@ static int decode_frame_ilbm(AVCodecContext *avctx,
     }
     s->init = 1;
 
-    if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
+    if (avctx->codec_tag == MKTAG('A','C','B','M')) {
+        if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
+            memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
+            for (plane = 0; plane < s->bpp; plane++) {
+                for(y = 0; y < avctx->height && buf < buf_end; y++ ) {
+                    uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
+                    decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);
+                    buf += s->planesize;
+                }
+            }
+        } else if (s->ham) { // HAM to PIX_FMT_BGR32
+            memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);
+            for(y = 0; y < avctx->height; y++) {
+                uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];
+                memset(s->ham_buf, 0, s->planesize * 8);
+                for (plane = 0; plane < s->bpp; plane++) {
+                    const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;
+                    if (start >= buf_end)
+                        break;
+                    decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);
+                }
+                decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);
+            }
+        }
+    } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved
         if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {
             for(y = 0; y < avctx->height; y++ ) {
                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
@@ -453,7 +479,7 @@ static int decode_frame_ilbm(AVCodecContext *avctx,
         } else if (s->ham) { // HAM to PIX_FMT_BGR32
             for (y = 0; y < avctx->height; y++) {
                 uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];
-                memset(s->ham_buf, 0, avctx->width);
+                memset(s->ham_buf, 0, s->planesize * 8);
                 for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {
                     decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);
                     buf += s->planesize;
@@ -529,7 +555,7 @@ static int decode_frame_byterun1(AVCodecContext *avctx,
         } else if (s->ham) { // HAM to PIX_FMT_BGR32
             for (y = 0; y < avctx->height ; y++) {
                 uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];
-                memset(s->ham_buf, 0, avctx->width);
+                memset(s->ham_buf, 0, s->planesize * 8);
                 for (plane = 0; plane < s->bpp; plane++) {
                     buf += decode_byterun(s->planebuf, s->planesize, buf, buf_end);
                     decodeplane8(s->ham_buf, s->planebuf, s->planesize, plane);