From d263f1ce20518933fb78f237fa715e78aec04181 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> Date: Mon, 14 Apr 2025 14:43:39 +0200 Subject: [PATCH 3/3] avcodec/mjpegenc_huffman: Already build codes I.e. do what ff_mjpeg_build_huffman_codes() does already in ff_mjpeg_encode_huffman_close(). This is more natural and traverses the array of values one less time. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libavcodec/mjpegenc.c | 33 ++++++++++++--------------------- libavcodec/mjpegenc_huffman.c | 24 ++++++++++++------------ libavcodec/mjpegenc_huffman.h | 17 +++++++++++++++-- 3 files changed, 39 insertions(+), 35 deletions(-) diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c index 214e2b0ec1..f05b4f88a5 100644 --- a/libavcodec/mjpegenc.c +++ b/libavcodec/mjpegenc.c @@ -196,33 +196,24 @@ static void mjpeg_build_optimal_huffman(MJpegContext *m) ff_mjpeg_encode_huffman_close(&dc_luminance_ctx, m->bits_dc_luminance, - m->val_dc_luminance, 12); + m->val_dc_luminance, 12, + m->huff_size_dc_luminance, + m->huff_code_dc_luminance); ff_mjpeg_encode_huffman_close(&dc_chrominance_ctx, m->bits_dc_chrominance, - m->val_dc_chrominance, 12); + m->val_dc_chrominance, 12, + m->huff_size_dc_chrominance, + m->huff_code_dc_chrominance); ff_mjpeg_encode_huffman_close(&ac_luminance_ctx, m->bits_ac_luminance, - m->val_ac_luminance, 256); + m->val_ac_luminance, 256, + m->huff_size_ac_luminance, + m->huff_code_ac_luminance); ff_mjpeg_encode_huffman_close(&ac_chrominance_ctx, m->bits_ac_chrominance, - m->val_ac_chrominance, 256); - - ff_mjpeg_build_huffman_codes(m->huff_size_dc_luminance, - m->huff_code_dc_luminance, - m->bits_dc_luminance, - m->val_dc_luminance); - ff_mjpeg_build_huffman_codes(m->huff_size_dc_chrominance, - m->huff_code_dc_chrominance, - m->bits_dc_chrominance, - m->val_dc_chrominance); - ff_mjpeg_build_huffman_codes(m->huff_size_ac_luminance, - m->huff_code_ac_luminance, - m->bits_ac_luminance, - m->val_ac_luminance); - ff_mjpeg_build_huffman_codes(m->huff_size_ac_chrominance, - m->huff_code_ac_chrominance, - m->bits_ac_chrominance, - m->val_ac_chrominance); + m->val_ac_chrominance, 256, + m->huff_size_ac_chrominance, + m->huff_code_ac_chrominance); } #endif diff --git a/libavcodec/mjpegenc_huffman.c b/libavcodec/mjpegenc_huffman.c index 7fd63a2569..732ae88b39 100644 --- a/libavcodec/mjpegenc_huffman.c +++ b/libavcodec/mjpegenc_huffman.c @@ -148,16 +148,9 @@ void ff_mjpeg_encode_huffman_init(MJpegEncHuffmanContext *s) memset(s->val_count, 0, sizeof(s->val_count)); } -/** - * Produces a Huffman encoding with a given input - * - * @param s input to encode - * @param bits output array where the ith character represents how many input values have i length encoding - * @param val output array of input values sorted by their encoded length - * @param max_nval maximum number of distinct input values - */ -void ff_mjpeg_encode_huffman_close(MJpegEncHuffmanContext *s, uint8_t bits[17], - uint8_t val[], int max_nval) +void ff_mjpeg_encode_huffman_close(const MJpegEncHuffmanContext *s, uint8_t bits[17], + uint8_t val[], int max_nval, + uint8_t huff_len[], uint16_t huff_code[]) { PTable val_counts[257]; @@ -181,6 +174,13 @@ void ff_mjpeg_encode_huffman_close(MJpegEncHuffmanContext *s, uint8_t bits[17], av_assert1(val_counts[0].prob == 0 && val_counts[0].value == 256); // The following loop puts the values with higher occurence first, // ensuring that they get the shorter codes. - for (int i = 0; i < nval; ++i) - val[i] = val_counts[nval - i].value; + unsigned code = 0; + for (int len = 1, i = 0; len <= 16; ++len) { + for (const int end = i + bits[len]; i < end; ++i) { + unsigned sym = val[i] = val_counts[nval - i].value; + huff_len[sym] = len; + huff_code[sym] = code++; + } + code <<= 1; + } } diff --git a/libavcodec/mjpegenc_huffman.h b/libavcodec/mjpegenc_huffman.h index 8822e468aa..b43f1a6017 100644 --- a/libavcodec/mjpegenc_huffman.h +++ b/libavcodec/mjpegenc_huffman.h @@ -40,8 +40,21 @@ static inline void ff_mjpeg_encode_huffman_increment(MJpegEncHuffmanContext *s, { s->val_count[val]++; } -void ff_mjpeg_encode_huffman_close(MJpegEncHuffmanContext *s, + +/** + * Produces a Huffman encoding with a given input + * + * @param s MJpegEncHuffmanContext with the input to encode + * @param bits[out] array where the ith character represents how many + * input values have i length encoding + * @param val[out] array of input values sorted by their encoded length + * @param max_nval maximum number of distinct input values + * @param huff_len[out] LUT of code lens as ff_mjpeg_build_huffman_codes() produces them + * @param huff_code[out] LUT of codes as ff_mjpeg_build_huffman_codes() produces them + */ +void ff_mjpeg_encode_huffman_close(const MJpegEncHuffmanContext *s, uint8_t bits[17], uint8_t val[], - int max_nval); + int max_nval, + uint8_t huff_len[], uint16_t huff_code[]); #endif /* AVCODEC_MJPEGENC_HUFFMAN_H */ -- 2.45.2