Skip to main content

j2k_types/packetization/
progression.rs

1// SPDX-License-Identifier: MIT OR Apache-2.0
2
3//! Packet progression order and descriptor ordering.
4
5use super::J2kPacketizationPacketDescriptor;
6
7/// JPEG 2000 packet progression order.
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum J2kPacketizationProgressionOrder {
10    /// Layer-resolution-component-position progression.
11    Lrcp,
12    /// Resolution-layer-component-position progression.
13    Rlcp,
14    /// Resolution-position-component-layer progression.
15    Rpcl,
16    /// Position-component-resolution-layer progression.
17    Pcrl,
18    /// Component-position-resolution-layer progression.
19    Cprl,
20}
21
22impl J2kPacketizationProgressionOrder {
23    /// Return the JPEG 2000 COD progression-order byte for this order.
24    pub const fn codestream_order_code(self) -> u8 {
25        match self {
26            Self::Lrcp => 0x00,
27            Self::Rlcp => 0x01,
28            Self::Rpcl => 0x02,
29            Self::Pcrl => 0x03,
30            Self::Cprl => 0x04,
31        }
32    }
33}
34
35/// Sort explicit packet descriptors according to a JPEG 2000 progression order.
36pub fn sort_packet_descriptors_for_progression(
37    descriptors: &mut [J2kPacketizationPacketDescriptor],
38    progression_order: J2kPacketizationProgressionOrder,
39) {
40    match progression_order {
41        J2kPacketizationProgressionOrder::Lrcp => descriptors.sort_by_key(|descriptor| {
42            (
43                descriptor.layer,
44                descriptor.resolution,
45                descriptor.component,
46                descriptor.precinct,
47            )
48        }),
49        J2kPacketizationProgressionOrder::Rlcp => descriptors.sort_by_key(|descriptor| {
50            (
51                descriptor.resolution,
52                descriptor.layer,
53                descriptor.component,
54                descriptor.precinct,
55            )
56        }),
57        J2kPacketizationProgressionOrder::Rpcl => descriptors.sort_by_key(|descriptor| {
58            (
59                descriptor.resolution,
60                descriptor.precinct,
61                descriptor.component,
62                descriptor.layer,
63            )
64        }),
65        J2kPacketizationProgressionOrder::Pcrl => descriptors.sort_by_key(|descriptor| {
66            (
67                descriptor.precinct,
68                descriptor.component,
69                descriptor.resolution,
70                descriptor.layer,
71            )
72        }),
73        J2kPacketizationProgressionOrder::Cprl => descriptors.sort_by_key(|descriptor| {
74            (
75                descriptor.component,
76                descriptor.precinct,
77                descriptor.resolution,
78                descriptor.layer,
79            )
80        }),
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use super::{
87        sort_packet_descriptors_for_progression, J2kPacketizationPacketDescriptor,
88        J2kPacketizationProgressionOrder,
89    };
90
91    fn descriptors() -> [J2kPacketizationPacketDescriptor; 3] {
92        [
93            J2kPacketizationPacketDescriptor {
94                packet_index: 0,
95                state_index: 0,
96                layer: 1,
97                resolution: 0,
98                component: 2,
99                precinct: 1,
100            },
101            J2kPacketizationPacketDescriptor {
102                packet_index: 1,
103                state_index: 1,
104                layer: 0,
105                resolution: 1,
106                component: 1,
107                precinct: 0,
108            },
109            J2kPacketizationPacketDescriptor {
110                packet_index: 2,
111                state_index: 2,
112                layer: 0,
113                resolution: 0,
114                component: 0,
115                precinct: 2,
116            },
117        ]
118    }
119
120    #[test]
121    fn progression_order_codes_match_codestream_values() {
122        assert_eq!(
123            J2kPacketizationProgressionOrder::Lrcp.codestream_order_code(),
124            0
125        );
126        assert_eq!(
127            J2kPacketizationProgressionOrder::Rlcp.codestream_order_code(),
128            1
129        );
130        assert_eq!(
131            J2kPacketizationProgressionOrder::Rpcl.codestream_order_code(),
132            2
133        );
134        assert_eq!(
135            J2kPacketizationProgressionOrder::Pcrl.codestream_order_code(),
136            3
137        );
138        assert_eq!(
139            J2kPacketizationProgressionOrder::Cprl.codestream_order_code(),
140            4
141        );
142    }
143
144    #[test]
145    fn packet_descriptor_sort_uses_requested_progression_order() {
146        let mut lrcp = descriptors();
147        sort_packet_descriptors_for_progression(&mut lrcp, J2kPacketizationProgressionOrder::Lrcp);
148        assert_eq!(lrcp.map(|descriptor| descriptor.packet_index), [2, 1, 0]);
149
150        let mut pcrl = descriptors();
151        sort_packet_descriptors_for_progression(&mut pcrl, J2kPacketizationProgressionOrder::Pcrl);
152        assert_eq!(pcrl.map(|descriptor| descriptor.packet_index), [1, 0, 2]);
153    }
154}