mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-13 21:28:01 +02:00
avcodec/mjpegdec: improve decoding of DNG files
That have unused symbols coded in DHT.
This commit is contained in:
parent
da5b3d0028
commit
1249698e1b
@ -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;
|
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;
|
k = 0;
|
||||||
code = 0;
|
code = 0;
|
||||||
for(i=1;i<=16;i++) {
|
for(i=1;i<=16;i++) {
|
||||||
nb = bits_table[i];
|
nb = bits_table[i];
|
||||||
for(j=0;j<nb;j++) {
|
for(j=0;j<nb;j++) {
|
||||||
sym = val_table[k++];
|
sym = val_table[k++];
|
||||||
if (sym != 0 || huff_size[sym] == 0) { /* see comment above */
|
huff_size[sym] = i;
|
||||||
huff_size[sym] = i;
|
huff_code[sym] = code;
|
||||||
huff_code[sym] = code;
|
|
||||||
}
|
|
||||||
code++;
|
code++;
|
||||||
}
|
}
|
||||||
code <<= 1;
|
code <<= 1;
|
||||||
|
@ -50,6 +50,21 @@
|
|||||||
#include "bytestream.h"
|
#include "bytestream.h"
|
||||||
|
|
||||||
|
|
||||||
|
static void build_huffman_codes(uint8_t *huff_size, uint16_t *huff_code,
|
||||||
|
const uint8_t *bits_table)
|
||||||
|
{
|
||||||
|
for (int i = 1, code = 0, k = 0; i <= 16; i++) {
|
||||||
|
int nb = bits_table[i];
|
||||||
|
for (int 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,
|
static int build_vlc(VLC *vlc, const uint8_t *bits_table,
|
||||||
const uint8_t *val_table, int nb_codes,
|
const uint8_t *val_table, int nb_codes,
|
||||||
int use_static, int is_ac)
|
int use_static, int is_ac)
|
||||||
@ -61,13 +76,14 @@ static int build_vlc(VLC *vlc, const uint8_t *bits_table,
|
|||||||
|
|
||||||
av_assert0(nb_codes <= 256);
|
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++)
|
for (i = 0; i < 256; i++) {
|
||||||
huff_sym[i] = i + 16 * is_ac;
|
huff_sym[i] = val_table[i] + 16 * is_ac;
|
||||||
|
|
||||||
if (is_ac)
|
if (is_ac && !val_table[i])
|
||||||
huff_sym[0] = 16 * 256;
|
huff_sym[i] = 16 * 256;
|
||||||
|
}
|
||||||
|
|
||||||
return ff_init_vlc_sparse(vlc, 9, nb_codes, huff_size, 1, 1,
|
return ff_init_vlc_sparse(vlc, 9, nb_codes, huff_size, 1, 1,
|
||||||
huff_code, 2, 2, huff_sym, 2, 2, use_static);
|
huff_code, 2, 2, huff_sym, 2, 2, use_static);
|
||||||
@ -240,7 +256,7 @@ int ff_mjpeg_decode_dqt(MJpegDecodeContext *s)
|
|||||||
/* decode huffman tables and build VLC decoders */
|
/* decode huffman tables and build VLC decoders */
|
||||||
int ff_mjpeg_decode_dht(MJpegDecodeContext *s)
|
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 bits_table[17];
|
||||||
uint8_t val_table[256];
|
uint8_t val_table[256];
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -270,11 +286,8 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s)
|
|||||||
if (len < n || n > 256)
|
if (len < n || n > 256)
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
|
|
||||||
code_max = 0;
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
v = get_bits(&s->gb, 8);
|
v = get_bits(&s->gb, 8);
|
||||||
if (v > code_max)
|
|
||||||
code_max = v;
|
|
||||||
val_table[i] = v;
|
val_table[i] = v;
|
||||||
}
|
}
|
||||||
len -= n;
|
len -= n;
|
||||||
@ -282,15 +295,15 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s)
|
|||||||
/* build VLC and flush previous vlc if present */
|
/* build VLC and flush previous vlc if present */
|
||||||
ff_free_vlc(&s->vlcs[class][index]);
|
ff_free_vlc(&s->vlcs[class][index]);
|
||||||
av_log(s->avctx, AV_LOG_DEBUG, "class=%d index=%d nb_codes=%d\n",
|
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,
|
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;
|
return ret;
|
||||||
|
|
||||||
if (class > 0) {
|
if (class > 0) {
|
||||||
ff_free_vlc(&s->vlcs[2][index]);
|
ff_free_vlc(&s->vlcs[2][index]);
|
||||||
if ((ret = build_vlc(&s->vlcs[2][index], bits_table, val_table,
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user