summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libavcodec/utvideo.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/libavcodec/utvideo.c b/libavcodec/utvideo.c
index 5faaa15a0c..4c3b2a1621 100644
--- a/libavcodec/utvideo.c
+++ b/libavcodec/utvideo.c
@@ -66,7 +66,7 @@ static int huff_cmp(const void *a, const void *b)
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;
HuffEntry he[256];
@@ -76,13 +76,18 @@ static int build_huff(const uint8_t *src, VLC *vlc)
uint8_t syms[256];
uint32_t code;
+ *fsym = -1;
for (i = 0; i < 256; i++) {
he[i].sym = i;
he[i].len = *src++;
}
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;
last = 255;
@@ -112,13 +117,37 @@ static int decode_plane(UtvideoContext *c, int plane_no,
int sstart, send;
VLC vlc;
GetBitContext gb;
- int prev;
+ int prev, fsym;
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");
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_size -= 256;