} Prediction;
typedef struct HuffEntry {
- uint8_t sym;
uint8_t len;
uint32_t code;
} HuffEntry;
return 0;
}
-static int magy_huff_cmp_len(const void *a, const void *b)
+static void calculate_codes(HuffEntry *he, uint16_t codes_count[33])
{
- const HuffEntry *aa = a, *bb = b;
- return (aa->len - bb->len) * 256 + aa->sym - bb->sym;
-}
-
-static int huff_cmp_sym(const void *a, const void *b)
-{
- const HuffEntry *aa = a, *bb = b;
- return bb->sym - aa->sym;
-}
-
-static void calculate_codes(HuffEntry *he)
-{
- uint32_t code;
- int i;
-
- AV_QSORT(he, 256, HuffEntry, magy_huff_cmp_len);
-
- code = 1;
- for (i = 255; i >= 0; i--) {
- he[i].code = code >> (32 - he[i].len);
- code += 0x80000000u >> (he[i].len - 1);
+ for (unsigned i = 32, nb_codes = 0; 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
}
- AV_QSORT(he, 256, HuffEntry, huff_cmp_sym);
+ for (unsigned i = 0; i < 256; i++) {
+ he[i].code = codes_count[he[i].len];
+ codes_count[he[i].len]++;
+ }
}
static void count_usage(uint8_t *src, int width,
static int compare_by_prob(const void *a, const void *b)
{
- PTable a_val = *(PTable *)a;
- PTable b_val = *(PTable *)b;
- return a_val.prob - b_val.prob;
+ const PTable *a2 = a;
+ const PTable *b2 = b;
+ return a2->prob - b2->prob;
}
static void magy_huffman_compute_bits(PTable *prob_table, HuffEntry *distincts,
+ uint16_t codes_counts[33],
int size, int max_length)
{
PackageMergerList list_a, list_b, *to = &list_a, *from = &list_b, *temp;
}
for (i = 0; i < size; i++) {
- distincts[i].sym = i;
distincts[i].len = nbits[i];
+ codes_counts[nbits[i]]++;
}
}
PutBitContext *pb, HuffEntry *he)
{
PTable counts[256] = { {0} };
+ uint16_t codes_counts[33] = { 0 };
int i;
count_usage(dst, width, height, counts);
for (i = 0; i < 256; i++) {
counts[i].prob++;
- counts[i].value = 255 - i;
+ counts[i].value = i;
}
- magy_huffman_compute_bits(counts, he, 256, 12);
+ magy_huffman_compute_bits(counts, he, codes_counts, 256, 12);
- calculate_codes(he);
+ calculate_codes(he, codes_counts);
for (i = 0; i < 256; i++) {
put_bits(pb, 1, 0);
if (count)
put_bits(&pb, 32 - count, 0);
- count = put_bits_count(&pb);
-
flush_put_bits(&pb);
- return count >> 3;
+ return put_bytes_output(&pb);
}
static int magy_encode_frame(AVCodecContext *avctx, AVPacket *pkt,
AV_CEIL_RSHIFT(frame->height, s->vshift[i]),
&s->pb, s->he[i]);
}
- s->tables_size = (put_bits_count(&s->pb) + 7) >> 3;
+ s->tables_size = put_bytes_count(&s->pb, 1);
bytestream2_skip_p(&pb, s->tables_size);
for (i = 0; i < s->planes; i++) {
.version = LIBAVUTIL_VERSION_INT,
};
-AVCodec ff_magicyuv_encoder = {
+const AVCodec ff_magicyuv_encoder = {
.name = "magicyuv",
.long_name = NULL_IF_CONFIG_SMALL("MagicYUV video"),
.type = AVMEDIA_TYPE_VIDEO,