j2k-native 0.7.3

Pure-Rust JPEG 2000 and HTJ2K codec engine for j2k
Documentation
#[cfg(feature = "std")]
use core::cell::RefCell;

#[cfg(feature = "std")]
use j2k_profile::{ProfileStageMode, StageModeCache};

pub(crate) use j2k_profile::{elapsed_us, profile_now, ProfileInstant};

#[cfg(all(test, feature = "std"))]
pub(crate) use j2k_profile::ProfileSummary;

#[cfg(feature = "std")]
const PROFILE_ENV_VAR: &str = "J2K_PROFILE_STAGES";

#[cfg(feature = "std")]
#[cfg(test)]
pub(crate) fn parse_profile_env_flag(value: Option<&str>) -> bool {
    j2k_profile::profile_stage_mode_from_value(value) != ProfileStageMode::Disabled
}

#[cfg(feature = "std")]
pub(crate) fn profile_stages_enabled() -> bool {
    profile_stage_mode() != ProfileStageMode::Disabled
}

#[cfg(feature = "std")]
fn profile_stage_mode() -> ProfileStageMode {
    static MODE: StageModeCache = StageModeCache::new();
    MODE.mode_from_env(PROFILE_ENV_VAR)
}

#[cfg(not(feature = "std"))]
pub(crate) fn profile_stages_enabled() -> bool {
    false
}

#[cfg(feature = "std")]
pub(crate) fn emit_profile_row(op: &str, path: &str, fields: &[(&str, u128)]) {
    j2k_profile::emit_profile_row_u128(
        profile_stage_mode(),
        &PROFILE_SUMMARY,
        "j2k",
        op,
        path,
        fields,
    );
}

#[cfg(not(feature = "std"))]
pub(crate) fn emit_profile_row(_op: &str, _path: &str, _fields: &[(&str, u128)]) {}

#[cfg(feature = "std")]
thread_local! {
    static PROFILE_SUMMARY: RefCell<j2k_profile::ProfileSummary> =
        RefCell::new(j2k_profile::ProfileSummary::default().emit_on_drop());
}

#[cfg(all(test, feature = "std"))]
mod tests {
    use super::*;

    #[test]
    fn parses_profile_env_flag_when_any_profile_mode_is_enabled() {
        assert!(parse_profile_env_flag(Some("1")));
        assert!(parse_profile_env_flag(Some("true")));
        assert!(parse_profile_env_flag(Some("summary")));
        assert!(parse_profile_env_flag(Some("aggregate")));
        assert!(!parse_profile_env_flag(None));
        assert!(!parse_profile_env_flag(Some("")));
        assert!(!parse_profile_env_flag(Some("0")));
    }

    #[test]
    fn profile_summary_groups_rows_and_averages_timing_fields() {
        let mut summary = ProfileSummary::default();
        summary
            .record_u128(
                "j2k",
                "encode",
                "cpu",
                &[
                    ("deinterleave_us", 10),
                    ("dwt_us", 30),
                    ("block_encode_us", 60),
                    ("total_us", 100),
                ],
            )
            .expect("first profile row should record");
        summary
            .record_u128(
                "j2k",
                "encode",
                "cpu",
                &[
                    ("deinterleave_us", 14),
                    ("dwt_us", 42),
                    ("block_encode_us", 72),
                    ("total_us", 128),
                ],
            )
            .expect("second profile row should record");

        assert_eq!(
            summary.format_rows().expect("summary should format"),
            vec![
                "j2k_profile_summary codec=j2k op=encode path=cpu count=2 block_encode_us_sum=132 block_encode_us_avg=66 deinterleave_us_sum=24 deinterleave_us_avg=12 dwt_us_sum=72 dwt_us_avg=36 total_us_sum=228 total_us_avg=114"
            ]
        );
    }
}