Skip to main content

ryg_rans_rs_cli/container/
codec.rs

1//! # Codec registry — stable codec IDs for container format
2//!
3//! Codec IDs identify the **stream format** (number of states, renormalization
4//! unit, scale constraint).  They do NOT identify the arithmetic implementation
5//! (division vs reciprocal) or the decode backend (scalar vs SIMD).
6
7/// Codec ID constants.
8///
9/// | ID | Name | States | Scale | Renorm |
10/// |----|------|--------|-------|--------|
11/// | 1 | BYTE_SINGLE | 1 | 1..16 | 8-bit |
12/// | 2 | BYTE_INTERLEAVED2 | 2 | 1..16 | 8-bit |
13/// | 3 | R64_SINGLE | 1 | 1..31 | 32-bit |
14/// | 4 | R64_INTERLEAVED2 | 2 | 1..31 | 32-bit |
15/// | 5 | WORD_SINGLE | 1 | 12 | 16-bit |
16/// | 6 | WORD_INTERLEAVED2 | 2 | 12 | 16-bit |
17/// | 7 | WORD_INTERLEAVED8 | 8 | 12 | 16-bit |
18/// | 8 | WORD_INTERLEAVED16 | 16 | 12 | 16-bit |
19/// | 9 | ALIAS_SINGLE | 1 | 8..17 | 8-bit |
20/// | 10 | ALIAS_INTERLEAVED2 | 2 | 8..17 | 8-bit |
21pub mod ids {
22    pub const BYTE_SINGLE: u16 = 1;
23    pub const BYTE_INTERLEAVED2: u16 = 2;
24    pub const R64_SINGLE: u16 = 3;
25    pub const R64_INTERLEAVED2: u16 = 4;
26    pub const WORD_SINGLE: u16 = 5;
27    pub const WORD_INTERLEAVED2: u16 = 6;
28    pub const WORD_INTERLEAVED8: u16 = 7;
29    pub const WORD_INTERLEAVED16: u16 = 8;
30    pub const ALIAS_SINGLE: u16 = 9;
31    pub const ALIAS_INTERLEAVED2: u16 = 10;
32}
33
34/// Return the canonical name for a codec ID.
35pub fn codec_name(id: u16) -> &'static str {
36    match id {
37        ids::BYTE_SINGLE => "byte-single",
38        ids::BYTE_INTERLEAVED2 => "byte-interleaved2",
39        ids::R64_SINGLE => "r64-single",
40        ids::R64_INTERLEAVED2 => "r64-interleaved2",
41        ids::WORD_SINGLE => "word-single",
42        ids::WORD_INTERLEAVED2 => "word-interleaved2",
43        ids::WORD_INTERLEAVED8 => "word-interleaved8",
44        ids::WORD_INTERLEAVED16 => "word-interleaved16",
45        ids::ALIAS_SINGLE => "alias-single",
46        ids::ALIAS_INTERLEAVED2 => "alias-interleaved2",
47        _ => "unknown",
48    }
49}
50
51/// Return the expected state count for a codec ID.
52pub fn codec_states(id: u16) -> Option<u8> {
53    match id {
54        ids::BYTE_SINGLE | ids::R64_SINGLE | ids::WORD_SINGLE | ids::ALIAS_SINGLE => Some(1),
55        ids::BYTE_INTERLEAVED2
56        | ids::R64_INTERLEAVED2
57        | ids::WORD_INTERLEAVED2
58        | ids::ALIAS_INTERLEAVED2 => Some(2),
59        ids::WORD_INTERLEAVED8 => Some(8),
60        ids::WORD_INTERLEAVED16 => Some(16),
61        _ => None,
62    }
63}
64
65/// Validate scale_bits for a codec ID.
66pub fn validate_scale_bits(id: u16, scale_bits: u8) -> Result<(), &'static str> {
67    match id {
68        ids::BYTE_SINGLE | ids::BYTE_INTERLEAVED2 => {
69            if scale_bits >= 1 && scale_bits <= 16 {
70                Ok(())
71            } else {
72                Err("byte rANS requires scale_bits 1..=16")
73            }
74        }
75        ids::R64_SINGLE | ids::R64_INTERLEAVED2 => {
76            if scale_bits >= 1 && scale_bits <= 31 {
77                Ok(())
78            } else {
79                Err("R64 requires scale_bits 1..=31")
80            }
81        }
82        ids::WORD_SINGLE
83        | ids::WORD_INTERLEAVED2
84        | ids::WORD_INTERLEAVED8
85        | ids::WORD_INTERLEAVED16 => {
86            if scale_bits == 12 {
87                Ok(())
88            } else {
89                Err("word rANS requires scale_bits = 12")
90            }
91        }
92        ids::ALIAS_SINGLE | ids::ALIAS_INTERLEAVED2 => {
93            if scale_bits >= 8 && scale_bits <= 17 {
94                Ok(())
95            } else {
96                Err("alias requires scale_bits 8..=17")
97            }
98        }
99        _ => Err("unknown codec"),
100    }
101}
102
103/// Validate that a codec ID is known and supported.
104pub fn is_supported(id: u16) -> bool {
105    matches!(
106        id,
107        ids::BYTE_SINGLE
108            | ids::BYTE_INTERLEAVED2
109            | ids::R64_SINGLE
110            | ids::R64_INTERLEAVED2
111            | ids::WORD_SINGLE
112            | ids::WORD_INTERLEAVED2
113            | ids::WORD_INTERLEAVED8
114            | ids::WORD_INTERLEAVED16
115            | ids::ALIAS_SINGLE
116            | ids::ALIAS_INTERLEAVED2
117    )
118}