#define CACHED_BITSTREAM_READER !ARCH_X86_32
#include "libavutil/pixdesc.h"
-#include "libavutil/qsort.h"
#include "avcodec.h"
#include "bytestream.h"
} Prediction;
typedef struct HuffEntry {
- uint16_t sym;
uint8_t len;
- uint32_t code;
+ uint16_t sym;
} HuffEntry;
typedef struct MagicYUVContext {
LLVidDSPContext llviddsp;
} MagicYUVContext;
-static int huff_cmp_len(const void *a, const void *b)
-{
- const HuffEntry *aa = a, *bb = b;
- return (aa->len - bb->len) * 4096 + bb->sym - aa->sym;
-}
-
-static int huff_build(HuffEntry he[], VLC *vlc, int nb_elems)
+static int huff_build(const uint8_t len[], uint16_t codes_pos[33],
+ VLC *vlc, int nb_elems, void *logctx)
{
- uint32_t code;
- int i;
+ HuffEntry he[4096];
- AV_QSORT(he, nb_elems, HuffEntry, huff_cmp_len);
+ for (int i = 31; i > 0; i--)
+ codes_pos[i] += codes_pos[i + 1];
- code = 1;
- for (i = nb_elems - 1; i >= 0; i--) {
- he[i].code = code >> (32 - he[i].len);
- code += 0x80000000u >> (he[i].len - 1);
- }
+ for (unsigned i = nb_elems; i-- > 0;)
+ he[--codes_pos[len[i]]] = (HuffEntry){ len[i], i };
ff_free_vlc(vlc);
- return ff_init_vlc_sparse(vlc, FFMIN(he[nb_elems - 1].len, 12), nb_elems,
- &he[0].len, sizeof(he[0]), sizeof(he[0].len),
- &he[0].code, sizeof(he[0]), sizeof(he[0].code),
- &he[0].sym, sizeof(he[0]), sizeof(he[0].sym), 0);
+ return ff_init_vlc_from_lengths(vlc, FFMIN(he[0].len, 12), nb_elems,
+ &he[0].len, sizeof(he[0]),
+ &he[0].sym, sizeof(he[0]), sizeof(he[0].sym),
+ 0, 0, logctx);
}
static void magicyuv_median_pred16(uint16_t *dst, const uint16_t *src1,
{
MagicYUVContext *s = avctx->priv_data;
GetByteContext gb;
- HuffEntry he[4096];
+ uint8_t len[4096];
+ uint16_t length_count[33] = { 0 };
int i = 0, j = 0, k;
bytestream2_init(&gb, table, table_size);
return AVERROR_INVALIDDATA;
}
- for (; j < k; j++) {
- he[j].sym = j;
- he[j].len = x;
- }
+ length_count[x] += l;
+ for (; j < k; j++)
+ len[j] = x;
if (j == max) {
j = 0;
- if (huff_build(he, &s->vlc[i], max)) {
+ if (huff_build(len, length_count, &s->vlc[i], max, avctx)) {
av_log(avctx, AV_LOG_ERROR, "Cannot build Huffman codes\n");
return AVERROR_INVALIDDATA;
}
if (i == s->planes) {
break;
}
+ memset(length_count, 0, sizeof(length_count));
}
}
s->slices[i][j].start = offset + header_size;
s->slices[i][j].size = avpkt->size - s->slices[i][j].start;
+
+ if (s->slices[i][j].size < 2)
+ return AVERROR_INVALIDDATA;
}
if (bytestream2_get_byteu(&gb) != s->planes)
return 0;
}
-AVCodec ff_magicyuv_decoder = {
+const AVCodec ff_magicyuv_decoder = {
.name = "magicyuv",
.long_name = NULL_IF_CONFIG_SMALL("MagicYUV video"),
.type = AVMEDIA_TYPE_VIDEO,