jxl_frame/data/
hf_global.rs

1use jxl_bitstream::Bitstream;
2use jxl_grid::AllocTracker;
3use jxl_image::ImageMetadata;
4use jxl_modular::{MaConfig, Sample};
5use jxl_oxide_common::Bundle;
6use jxl_threadpool::JxlThreadPool;
7use jxl_vardct::{DequantMatrixSet, DequantMatrixSetParams, HfBlockContext, HfPass, HfPassParams};
8
9use super::LfGlobal;
10use crate::{FrameHeader, Result};
11
12#[derive(Debug, Copy, Clone)]
13pub struct HfGlobalParams<'a, 'b> {
14    metadata: &'a ImageMetadata,
15    frame_header: &'a FrameHeader,
16    ma_config: Option<&'a MaConfig>,
17    hf_block_ctx: &'a HfBlockContext,
18    tracker: Option<&'b AllocTracker>,
19    pool: &'a JxlThreadPool,
20}
21
22impl<'a, 'b> HfGlobalParams<'a, 'b> {
23    pub fn new<S: Sample>(
24        metadata: &'a ImageMetadata,
25        frame_header: &'a FrameHeader,
26        lf_global: &'a LfGlobal<S>,
27        tracker: Option<&'b AllocTracker>,
28        pool: &'a JxlThreadPool,
29    ) -> Self {
30        let Some(lf_vardct) = &lf_global.vardct else {
31            panic!("VarDCT not initialized")
32        };
33        Self {
34            metadata,
35            frame_header,
36            ma_config: lf_global.gmodular.ma_config.as_ref(),
37            hf_block_ctx: &lf_vardct.hf_block_ctx,
38            tracker,
39            pool,
40        }
41    }
42}
43
44#[derive(Debug)]
45pub struct HfGlobal {
46    pub dequant_matrices: DequantMatrixSet,
47    pub num_hf_presets: u32,
48    pub hf_passes: Vec<HfPass>,
49}
50
51impl Bundle<HfGlobalParams<'_, '_>> for HfGlobal {
52    type Error = crate::Error;
53
54    fn parse(bitstream: &mut Bitstream, params: HfGlobalParams) -> Result<Self> {
55        let HfGlobalParams {
56            metadata,
57            frame_header,
58            ma_config,
59            hf_block_ctx,
60            tracker,
61            pool,
62        } = params;
63        let dequant_matrix_params = DequantMatrixSetParams::new(
64            metadata.bit_depth.bits_per_sample(),
65            frame_header.num_lf_groups(),
66            ma_config,
67            tracker,
68            pool,
69        );
70        let dequant_matrices = DequantMatrixSet::parse(bitstream, dequant_matrix_params)?;
71
72        let num_groups = frame_header.num_groups();
73        let num_hf_presets =
74            bitstream.read_bits(num_groups.next_power_of_two().trailing_zeros() as usize)? + 1;
75
76        let hf_pass_params = HfPassParams::new(hf_block_ctx, num_hf_presets);
77        let hf_passes = std::iter::repeat_with(|| HfPass::parse(bitstream, hf_pass_params))
78            .take(frame_header.passes.num_passes as usize)
79            .collect::<std::result::Result<Vec<_>, _>>()?;
80
81        Ok(Self {
82            dequant_matrices,
83            num_hf_presets,
84            hf_passes,
85        })
86    }
87}