diff mbox series

[FFmpeg-devel] avcodec/mjpegdec: improve decoding of DNG files

Message ID 20201003123814.25402-1-onemda@gmail.com
State Accepted
Headers show
Series [FFmpeg-devel] avcodec/mjpegdec: improve decoding of DNG files | expand

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

Paul B Mahol Oct. 3, 2020, 12:38 p.m. UTC
That have unused symbols coded in DHT.

Signed-off-by: Paul B Mahol <onemda@gmail.com>
---
 libavcodec/jpegtables.c | 15 ++-------------
 libavcodec/mjpegdec.c   | 41 +++++++++++++++++++++++++++++------------
 2 files changed, 31 insertions(+), 25 deletions(-)
diff mbox series

Patch

diff --git a/libavcodec/jpegtables.c b/libavcodec/jpegtables.c
index fa5c6f9fc5..e44bc7a22a 100644
--- a/libavcodec/jpegtables.c
+++ b/libavcodec/jpegtables.c
@@ -130,25 +130,14 @@  void ff_mjpeg_build_huffman_codes(uint8_t *huff_size, uint16_t *huff_code,
 {
     int i, j, k,nb, code, sym;
 
-    /* Some badly encoded files [1] map 2 different codes to symbol 0.
-       Only the first one is valid, so we zero-initialize this here and
-       make sure we only set it once (the first time) in the loop below.
-
-       [1]: Embedded JPEGs in "X7 RAW" and "X7 CinemaDNG" samples here:
-            https://www.dji.com/gr/zenmuse-x7/info#downloads
-     */
-    huff_size[0] = 0;
-
     k = 0;
     code = 0;
     for(i=1;i<=16;i++) {
         nb = bits_table[i];
         for(j=0;j<nb;j++) {
             sym = val_table[k++];
-            if (sym != 0 || huff_size[sym] == 0) { /* see comment above */
-                huff_size[sym] = i;
-                huff_code[sym] = code;
-            }
+            huff_size[sym] = i;
+            huff_code[sym] = code;
             code++;
         }
         code <<= 1;
diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c
index e7a4e08c1c..d4286684df 100644
--- a/libavcodec/mjpegdec.c
+++ b/libavcodec/mjpegdec.c
@@ -50,6 +50,25 @@ 
 #include "bytestream.h"
 
 
+static void build_huffman_codes(uint8_t *huff_size, uint16_t *huff_code,
+                                const uint8_t *bits_table)
+{
+    int i, j, k,nb, code;
+
+    k = 0;
+    code = 0;
+    for(i=1;i<=16;i++) {
+        nb = bits_table[i];
+        for(j=0;j<nb;j++) {
+            huff_size[k] = i;
+            huff_code[k] = code;
+            code++;
+            k++;
+        }
+        code <<= 1;
+    }
+}
+
 static int build_vlc(VLC *vlc, const uint8_t *bits_table,
                      const uint8_t *val_table, int nb_codes,
                      int use_static, int is_ac)
@@ -61,13 +80,14 @@  static int build_vlc(VLC *vlc, const uint8_t *bits_table,
 
     av_assert0(nb_codes <= 256);
 
-    ff_mjpeg_build_huffman_codes(huff_size, huff_code, bits_table, val_table);
+    build_huffman_codes(huff_size, huff_code, bits_table);
 
-    for (i = 0; i < 256; i++)
-        huff_sym[i] = i + 16 * is_ac;
+    for (i = 0; i < 256; i++) {
+        huff_sym[i] = val_table[i] + 16 * is_ac;
 
-    if (is_ac)
-        huff_sym[0] = 16 * 256;
+        if (is_ac && !val_table[i])
+            huff_sym[i] = 16 * 256;
+    }
 
     return ff_init_vlc_sparse(vlc, 9, nb_codes, huff_size, 1, 1,
                               huff_code, 2, 2, huff_sym, 2, 2, use_static);
@@ -240,7 +260,7 @@  int ff_mjpeg_decode_dqt(MJpegDecodeContext *s)
 /* decode huffman tables and build VLC decoders */
 int ff_mjpeg_decode_dht(MJpegDecodeContext *s)
 {
-    int len, index, i, class, n, v, code_max;
+    int len, index, i, class, n, v;
     uint8_t bits_table[17];
     uint8_t val_table[256];
     int ret = 0;
@@ -270,11 +290,8 @@  int ff_mjpeg_decode_dht(MJpegDecodeContext *s)
         if (len < n || n > 256)
             return AVERROR_INVALIDDATA;
 
-        code_max = 0;
         for (i = 0; i < n; i++) {
             v = get_bits(&s->gb, 8);
-            if (v > code_max)
-                code_max = v;
             val_table[i] = v;
         }
         len -= n;
@@ -282,15 +299,15 @@  int ff_mjpeg_decode_dht(MJpegDecodeContext *s)
         /* build VLC and flush previous vlc if present */
         ff_free_vlc(&s->vlcs[class][index]);
         av_log(s->avctx, AV_LOG_DEBUG, "class=%d index=%d nb_codes=%d\n",
-               class, index, code_max + 1);
+               class, index, n + 1);
         if ((ret = build_vlc(&s->vlcs[class][index], bits_table, val_table,
-                             code_max + 1, 0, class > 0)) < 0)
+                             n + 1, 0, class > 0)) < 0)
             return ret;
 
         if (class > 0) {
             ff_free_vlc(&s->vlcs[2][index]);
             if ((ret = build_vlc(&s->vlcs[2][index], bits_table, val_table,
-                                 code_max + 1, 0, 0)) < 0)
+                                 n + 1, 0, 0)) < 0)
                 return ret;
         }