Commit 46e1af3b authored by Kostya Shishkov's avatar Kostya Shishkov Committed by Luca Barbato

utvideo: handle empty Huffman trees

If the frame is filled with the same colour, encoder may produce no data
and the fill value is indicated by zero code length (the rest of symbols
will have 0xFF for code length, meaning invalid).  So such Huffman trees
should be treated specially.
Signed-off-by: 's avatarLuca Barbato <lu_zero@gentoo.org>
parent 425a8435
...@@ -66,7 +66,7 @@ static int huff_cmp(const void *a, const void *b) ...@@ -66,7 +66,7 @@ static int huff_cmp(const void *a, const void *b)
return (aa->len - bb->len)*256 + aa->sym - bb->sym; return (aa->len - bb->len)*256 + aa->sym - bb->sym;
} }
static int build_huff(const uint8_t *src, VLC *vlc) static int build_huff(const uint8_t *src, VLC *vlc, int *fsym)
{ {
int i; int i;
HuffEntry he[256]; HuffEntry he[256];
...@@ -76,13 +76,18 @@ static int build_huff(const uint8_t *src, VLC *vlc) ...@@ -76,13 +76,18 @@ static int build_huff(const uint8_t *src, VLC *vlc)
uint8_t syms[256]; uint8_t syms[256];
uint32_t code; uint32_t code;
*fsym = -1;
for (i = 0; i < 256; i++) { for (i = 0; i < 256; i++) {
he[i].sym = i; he[i].sym = i;
he[i].len = *src++; he[i].len = *src++;
} }
qsort(he, 256, sizeof(*he), huff_cmp); qsort(he, 256, sizeof(*he), huff_cmp);
if (!he[0].len || he[0].len > 32) if (!he[0].len) {
*fsym = he[0].sym;
return 0;
}
if (he[0].len > 32)
return -1; return -1;
last = 255; last = 255;
...@@ -112,13 +117,37 @@ static int decode_plane(UtvideoContext *c, int plane_no, ...@@ -112,13 +117,37 @@ static int decode_plane(UtvideoContext *c, int plane_no,
int sstart, send; int sstart, send;
VLC vlc; VLC vlc;
GetBitContext gb; GetBitContext gb;
int prev; int prev, fsym;
const int cmask = ~(!plane_no && c->avctx->pix_fmt == PIX_FMT_YUV420P); const int cmask = ~(!plane_no && c->avctx->pix_fmt == PIX_FMT_YUV420P);
if (build_huff(src, &vlc)) { if (build_huff(src, &vlc, &fsym)) {
av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n"); av_log(c->avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n");
return AVERROR_INVALIDDATA; return AVERROR_INVALIDDATA;
} }
if (fsym >= 0) { // build_huff reported a symbol to fill slices with
send = 0;
for (slice = 0; slice < c->slices; slice++) {
uint8_t *dest;
sstart = send;
send = (height * (slice + 1) / c->slices) & cmask;
dest = dst + sstart * stride;
prev = 0x80;
for (j = sstart; j < send; j++) {
for (i = 0; i < width * step; i += step) {
pix = fsym;
if (use_pred) {
prev += pix;
pix = prev;
}
dest[i] = pix;
}
dest += stride;
}
}
return 0;
}
src += 256; src += 256;
src_size -= 256; src_size -= 256;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment