Skip to main content

zenjxl_decoder/headers/
extra_channels.rs

1// Copyright (c) the JPEG XL Project Authors. All rights reserved.
2//
3// Use of this source code is governed by a BSD-style
4// license that can be found in the LICENSE file.
5
6use crate::{
7    bit_reader::BitReader,
8    error::Error,
9    headers::{bit_depth::BitDepth, encodings::*},
10};
11use jxl_macros::UnconditionalCoder;
12use num_derive::FromPrimitive;
13
14#[allow(clippy::upper_case_acronyms)]
15#[derive(UnconditionalCoder, Copy, Clone, PartialEq, Debug, FromPrimitive, Eq)]
16pub enum ExtraChannel {
17    Alpha,
18    Depth,
19    SpotColor,
20    SelectionMask,
21    Black,
22    CFA,
23    Thermal,
24    Reserved0,
25    Reserved1,
26    Reserved2,
27    Reserved3,
28    Reserved4,
29    Reserved5,
30    Reserved6,
31    Reserved7,
32    Unknown,
33    Optional,
34}
35
36// TODO(veluca): figure out if these fields should be unused.
37#[allow(dead_code)]
38#[derive(UnconditionalCoder, Debug, Clone)]
39#[validate]
40pub struct ExtraChannelInfo {
41    #[all_default]
42    all_default: bool,
43    #[default(ExtraChannel::Alpha)]
44    pub ec_type: ExtraChannel,
45    #[default(BitDepth::default(&field_nonserialized))]
46    bit_depth: BitDepth,
47    #[coder(u2S(0, 3, 4, Bits(3) + 1))]
48    #[default(0)]
49    dim_shift: u32,
50    name: String,
51    // TODO(veluca93): if using Option<bool>, this is None when all_default.
52    #[condition(ec_type == ExtraChannel::Alpha)]
53    #[default(false)]
54    alpha_associated: bool,
55    #[condition(ec_type == ExtraChannel::SpotColor)]
56    pub spot_color: Option<[f32; 4]>,
57    #[condition(ec_type == ExtraChannel::CFA)]
58    #[coder(u2S(1, Bits(2), Bits(4) + 3, Bits(8) + 19))]
59    cfa_channel: Option<u32>,
60}
61
62impl ExtraChannelInfo {
63    #[cfg(test)]
64    #[allow(clippy::too_many_arguments)]
65    pub fn new(
66        all_default: bool,
67        ec_type: ExtraChannel,
68        bit_depth: BitDepth,
69        dim_shift: u32,
70        name: String,
71        alpha_associated: bool,
72        spot_color: Option<[f32; 4]>,
73        cfa_channel: Option<u32>,
74    ) -> ExtraChannelInfo {
75        ExtraChannelInfo {
76            all_default,
77            ec_type,
78            bit_depth,
79            dim_shift,
80            name,
81            alpha_associated,
82            spot_color,
83            cfa_channel,
84        }
85    }
86    pub fn dim_shift(&self) -> u32 {
87        self.dim_shift
88    }
89    pub fn alpha_associated(&self) -> bool {
90        self.alpha_associated
91    }
92    pub fn bit_depth(&self) -> BitDepth {
93        self.bit_depth
94    }
95    /// Returns the name of this extra channel, or an empty string if unnamed.
96    pub fn name(&self) -> &str {
97        &self.name
98    }
99    fn check(&self, _: &Empty) -> Result<(), Error> {
100        if self.dim_shift > 3 {
101            Err(Error::DimShiftTooLarge(self.dim_shift))
102        } else {
103            Ok(())
104        }
105    }
106}