typedef struct HuffEntry {
uint8_t len;
- uint16_t code;
+ uint16_t sym;
} HuffEntry;
typedef struct MagicYUVContext {
LLVidDSPContext llviddsp;
} MagicYUVContext;
-static int huff_build(HuffEntry he[], uint16_t codes_count[33],
- 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)
{
- unsigned nb_codes = 0, max = 0;
-
- for (int i = 32; i > 0; i--) {
- uint16_t curr = codes_count[i]; // # of leafs of length i
- codes_count[i] = nb_codes / 2; // # of non-leaf nodes on level i
- nb_codes = codes_count[i] + curr; // # of nodes on level i
- if (curr && !max)
- max = i;
- }
+ HuffEntry he[4096];
- for (unsigned i = 0; i < nb_elems; i++) {
- he[i].code = codes_count[he[i].len];
- codes_count[he[i].len]++;
- }
- return init_vlc(vlc, FFMIN(max, 12), nb_elems,
- &he[0].len, sizeof(he[0]), sizeof(he[0].len),
- &he[0].code, sizeof(he[0]), sizeof(he[0].code), 0);
+ for (int i = 31; i > 0; i--)
+ codes_pos[i] += codes_pos[i + 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_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;
length_count[x] += l;
for (; j < k; j++)
- he[j].len = x;
+ len[j] = x;
if (j == max) {
j = 0;
- if (huff_build(he, length_count, &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;
}
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,