From 1d2322ea36ae7480c8e3e2fce3d8f9969f0691e5 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> Date: Thu, 13 Mar 2025 22:17:03 +0100 Subject: [PATCH 08/17] avcodec/hqx: Cache pointer to used dc table Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com> --- libavcodec/hqx.c | 32 ++++++++++++++++---------------- libavcodec/hqxvlc.h | 2 +- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/libavcodec/hqx.c b/libavcodec/hqx.c index e73a023c29..aab28a2156 100644 --- a/libavcodec/hqx.c +++ b/libavcodec/hqx.c @@ -68,7 +68,9 @@ typedef struct HQXContext { unsigned int data_size; uint32_t slice_off[17]; - VLC dc_vlc[3]; + const VLCElem *dc_vlc; + + VLC dc_vlcs[3]; } HQXContext; #define HQX_HEADER_SIZE 59 @@ -140,7 +142,7 @@ static inline void hqx_get_ac(GetBitContext *gb, const HQXAC *ac, *lev = level; } -static int decode_block(GetBitContext *gb, VLC *vlc, +static int decode_block(GetBitContext *gb, const VLCElem vlc[], const int *quants, int dcb, int16_t block[64], int *last_dc) { @@ -149,7 +151,7 @@ static int decode_block(GetBitContext *gb, VLC *vlc, int run, lev, pos = 0; memset(block, 0, 64 * sizeof(*block)); - dc = get_vlc2(gb, vlc->table, HQX_DC_VLC_BITS, 2); + dc = get_vlc2(gb, vlc, HQX_DC_VLC_BITS, 2); *last_dc += dc; block[0] = sign_extend(*last_dc << (12 - dcb), 12); @@ -196,10 +198,9 @@ static int hqx_decode_422(HQXContext *ctx, int slice_no, int x, int y) quants = hqx_quants[get_bits(gb, 4)]; for (i = 0; i < 8; i++) { - int vlc_index = ctx->dcb - 9; if (i == 0 || i == 4 || i == 6) last_dc = 0; - ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants, + ret = decode_block(gb, ctx->dc_vlc, quants, ctx->dcb, slice->block[i], &last_dc); if (ret < 0) return ret; @@ -244,8 +245,7 @@ static int hqx_decode_422a(HQXContext *ctx, int slice_no, int x, int y) if (i == 0 || i == 4 || i == 8 || i == 10) last_dc = 0; if (cbp & (1 << i)) { - int vlc_index = ctx->dcb - 9; - ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants, + ret = decode_block(gb, ctx->dc_vlc, quants, ctx->dcb, slice->block[i], &last_dc); if (ret < 0) return ret; @@ -280,10 +280,9 @@ static int hqx_decode_444(HQXContext *ctx, int slice_no, int x, int y) quants = hqx_quants[get_bits(gb, 4)]; for (i = 0; i < 12; i++) { - int vlc_index = ctx->dcb - 9; if (i == 0 || i == 4 || i == 8) last_dc = 0; - ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants, + ret = decode_block(gb, ctx->dc_vlc, quants, ctx->dcb, slice->block[i], &last_dc); if (ret < 0) return ret; @@ -327,8 +326,7 @@ static int hqx_decode_444a(HQXContext *ctx, int slice_no, int x, int y) if (i == 0 || i == 4 || i == 8 || i == 12) last_dc = 0; if (cbp & (1 << i)) { - int vlc_index = ctx->dcb - 9; - ret = decode_block(gb, &ctx->dc_vlc[vlc_index], quants, + ret = decode_block(gb, ctx->dc_vlc, quants, ctx->dcb, slice->block[i], &last_dc); if (ret < 0) return ret; @@ -434,7 +432,7 @@ static int hqx_decode_frame(AVCodecContext *avctx, AVFrame *frame, HQXContext *ctx = avctx->priv_data; const uint8_t *src = avpkt->data; uint32_t info_tag; - int data_start; + int data_start, dcb_code; int i, ret; if (avpkt->size < 4 + 4) { @@ -473,16 +471,18 @@ static int hqx_decode_frame(AVCodecContext *avctx, AVFrame *frame, } ctx->interlaced = !(src[2] & 0x80); ctx->format = src[2] & 7; - ctx->dcb = (src[3] & 3) + 8; + dcb_code = src[3] & 3; ctx->width = AV_RB16(src + 4); ctx->height = AV_RB16(src + 6); for (i = 0; i < 17; i++) ctx->slice_off[i] = AV_RB24(src + 8 + i * 3); - if (ctx->dcb == 8) { - av_log(avctx, AV_LOG_ERROR, "Invalid DC precision %d.\n", ctx->dcb); + if (dcb_code == 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid DC precision 8.\n"); return AVERROR_INVALIDDATA; } + ctx->dc_vlc = ctx->dc_vlcs[dcb_code - 1].table; + ctx->dcb = dcb_code + 8; ret = av_image_check_size(ctx->width, ctx->height, 0, avctx); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Invalid stored dimensions %dx%d.\n", @@ -543,7 +543,7 @@ static av_cold int hqx_decode_close(AVCodecContext *avctx) HQXContext *ctx = avctx->priv_data; for (i = 0; i < 3; i++) { - ff_vlc_free(&ctx->dc_vlc[i]); + ff_vlc_free(&ctx->dc_vlcs[i]); } return 0; diff --git a/libavcodec/hqxvlc.h b/libavcodec/hqxvlc.h index aa7fbcdc59..4bdc3cd191 100644 --- a/libavcodec/hqxvlc.h +++ b/libavcodec/hqxvlc.h @@ -1533,7 +1533,7 @@ static VLCElem cbp_vlc[(1 << HQX_CBP_VLC_BITS) + 15630 /* RL_VLC_ELEMS for hqx_a #define INIT_DC_TABLE(idx, name) \ do { \ - ret = vlc_init(&ctx->dc_vlc[idx], HQX_DC_VLC_BITS, \ + ret = vlc_init(&ctx->dc_vlcs[idx], HQX_DC_VLC_BITS, \ FF_ARRAY_ELEMS(name ## _vlc_lens), \ name ## _vlc_lens, 1, 1, \ name ## _vlc_bits, 2, 2, 0); \ -- 2.45.2