exr/image/read/
levels.rs

1//! How to read a set of resolution levels.
2
3use crate::meta::*;
4use crate::image::*;
5use crate::error::*;
6use crate::meta::attribute::*;
7use crate::image::read::any_channels::*;
8use crate::block::chunk::TileCoordinates;
9use crate::image::read::specific_channels::*;
10use crate::image::recursive::*;
11use crate::math::Vec2;
12use crate::block::lines::LineRef;
13use crate::block::samples::*;
14use crate::meta::header::{Header};
15
16
17// Note: In the resulting image, the `FlatSamples` are placed
18// directly inside the channels, without `LargestLevel<>` indirection
19/// Specify to read only the highest resolution level, skipping all smaller variations.
20/// The sample storage can be [`ReadFlatSamples`].
21#[derive(Debug, Clone, Eq, PartialEq)]
22pub struct ReadLargestLevel<DeepOrFlatSamples> {
23
24    /// The sample reading specification
25    pub read_samples: DeepOrFlatSamples
26}
27
28
29// FIXME rgba levels???
30
31// Read the largest level, directly, without intermediate structs
32impl<DeepOrFlatSamples> ReadLargestLevel<DeepOrFlatSamples> {
33
34    /// Read all arbitrary channels in each layer.
35    pub fn all_channels(self) -> ReadAnyChannels<DeepOrFlatSamples> { ReadAnyChannels { read_samples: self.read_samples } } // Instead of Self, the `FlatSamples` are used directly
36
37    /// Read only layers that contain rgba channels. Skips any other channels in the layer.
38    /// The alpha channel will contain the value `1.0` if no alpha channel can be found in the image.
39    ///
40    /// Using two closures, define how to store the pixels.
41    /// The first closure creates an image, and the second closure inserts a single pixel.
42    /// The type of the pixel can be defined by the second closure;
43    /// it must be a tuple containing four values, each being either `f16`, `f32`, `u32` or `Sample`.
44    ///
45    /// Throws an error for images with deep data or subsampling.
46    /// Use `specific_channels` or `all_channels` if you want to read something other than rgba.
47    pub fn rgba_channels<R,G,B,A, Create, Set, Pixels>(
48        self, create_pixels: Create, set_pixel: Set
49    ) -> CollectPixels<
50        ReadOptionalChannel<ReadRequiredChannel<ReadRequiredChannel<ReadRequiredChannel<NoneMore, R>, G>, B>, A>,
51        (R, G, B, A), Pixels, Create, Set
52    >
53        where
54            R: FromNativeSample, G: FromNativeSample, B: FromNativeSample, A: FromNativeSample,
55            Create: Fn(Vec2<usize>, &RgbaChannels) -> Pixels,
56            Set: Fn(&mut Pixels, Vec2<usize>, (R,G,B,A)),
57    {
58        self.specific_channels()
59            .required("R").required("G").required("B")
60            .optional("A", A::from_f32(1.0))
61            .collect_pixels(create_pixels, set_pixel)
62    }
63
64    /// Read only layers that contain rgb channels. Skips any other channels in the layer.
65    ///
66    /// Using two closures, define how to store the pixels.
67    /// The first closure creates an image, and the second closure inserts a single pixel.
68    /// The type of the pixel can be defined by the second closure;
69    /// it must be a tuple containing three values, each being either `f16`, `f32`, `u32` or `Sample`.
70    ///
71    /// Throws an error for images with deep data or subsampling.
72    /// Use `specific_channels` or `all_channels` if you want to read something other than rgb.
73    pub fn rgb_channels<R,G,B, Create, Set, Pixels>(
74        self, create_pixels: Create, set_pixel: Set
75    ) -> CollectPixels<
76        ReadRequiredChannel<ReadRequiredChannel<ReadRequiredChannel<NoneMore, R>, G>, B>,
77        (R, G, B), Pixels, Create, Set
78    >
79        where
80            R: FromNativeSample, G: FromNativeSample, B: FromNativeSample,
81            Create: Fn(Vec2<usize>, &RgbChannels) -> Pixels,
82            Set: Fn(&mut Pixels, Vec2<usize>, (R,G,B)),
83    {
84        self.specific_channels()
85            .required("R").required("G").required("B")
86            .collect_pixels(create_pixels, set_pixel)
87    }
88
89    /// Read only layers that contain the specified channels, skipping any other channels in the layer.
90    /// Further specify which channels should be included by calling `.required("ChannelName")`
91    /// or `.optional("ChannelName", default_value)` on the result of this function.
92    /// Call `collect_pixels` afterwards to define the pixel container for your set of channels.
93    ///
94    /// Throws an error for images with deep data or subsampling.
95    pub fn specific_channels(self) -> ReadZeroChannels {
96        ReadZeroChannels { }
97    }
98}
99
100/// Specify to read all contained resolution levels from the image, if any.
101#[derive(Debug, Clone, Eq, PartialEq)]
102pub struct ReadAllLevels<DeepOrFlatSamples> {
103
104    /// The sample reading specification
105    pub read_samples: DeepOrFlatSamples
106}
107
108impl<ReadDeepOrFlatSamples> ReadAllLevels<ReadDeepOrFlatSamples> {
109
110    /// Read all arbitrary channels in each layer.
111    pub fn all_channels(self) -> ReadAnyChannels<Self> { ReadAnyChannels { read_samples: self } }
112
113    // TODO specific channels for multiple resolution levels
114
115}
116
117/*pub struct ReadLevels<S> {
118    read_samples: S,
119}*/
120
121/// Processes pixel blocks from a file and accumulates them into multiple levels per channel.
122#[derive(Debug, Clone, Eq, PartialEq)]
123pub struct AllLevelsReader<SamplesReader> {
124    levels: Levels<SamplesReader>,
125}
126
127/// A template that creates a [`SamplesReader`] once for each resolution level.
128pub trait ReadSamplesLevel {
129
130    /// The type of the temporary level reader
131    type Reader: SamplesReader;
132
133    /// Create a single reader for a single resolution level
134    fn create_samples_level_reader(&self, header: &Header, channel: &ChannelDescription, level: Vec2<usize>, resolution: Vec2<usize>) -> Result<Self::Reader>;
135}
136
137
138impl<S: ReadSamplesLevel> ReadSamples for ReadAllLevels<S> {
139    type Reader = AllLevelsReader<S::Reader>;
140
141    fn create_sample_reader(&self, header: &Header, channel: &ChannelDescription) -> Result<Self::Reader> {
142        let data_size = header.layer_size / channel.sampling;
143
144        let levels = {
145            if let crate::meta::BlockDescription::Tiles(tiles) = &header.blocks {
146                match tiles.level_mode {
147                    LevelMode::Singular => Levels::Singular(self.read_samples.create_samples_level_reader(header, channel, Vec2(0,0), header.layer_size)?),
148
149                    LevelMode::MipMap => Levels::Mip {
150                        rounding_mode: tiles.rounding_mode,
151                        level_data: {
152                            let round = tiles.rounding_mode;
153                            let maps: Result<LevelMaps<S::Reader>> = mip_map_levels(round, data_size)
154                                .map(|(index, level_size)| self.read_samples.create_samples_level_reader(header, channel, Vec2(index, index), level_size))
155                                .collect();
156
157                            maps?
158                        },
159                    },
160
161                    // TODO put this into Levels::new(..) ?
162                    LevelMode::RipMap => Levels::Rip {
163                        rounding_mode: tiles.rounding_mode,
164                        level_data: {
165                            let round = tiles.rounding_mode;
166                            let level_count_x = compute_level_count(round, data_size.width());
167                            let level_count_y = compute_level_count(round, data_size.height());
168                            let maps: Result<LevelMaps<S::Reader>> = rip_map_levels(round, data_size)
169                                .map(|(index, level_size)| self.read_samples.create_samples_level_reader(header, channel, index, level_size))
170                                .collect();
171
172                            RipMaps {
173                                map_data: maps?,
174                                level_count: Vec2(level_count_x, level_count_y)
175                            }
176                        },
177                    },
178                }
179            }
180
181            // scan line blocks never have mip maps
182            else {
183                Levels::Singular(self.read_samples.create_samples_level_reader(header, channel, Vec2(0, 0), data_size)?)
184            }
185        };
186
187        Ok(AllLevelsReader { levels })
188    }
189}
190
191
192impl<S: SamplesReader> SamplesReader for AllLevelsReader<S> {
193    type Samples = Levels<S::Samples>;
194
195    fn filter_block(&self, _: TileCoordinates) -> bool {
196        true
197    }
198
199    fn read_line(&mut self, line: LineRef<'_>) -> UnitResult {
200        self.levels.get_level_mut(line.location.level)?.read_line(line)
201    }
202
203    fn into_samples(self) -> Self::Samples {
204        match self.levels {
205            Levels::Singular(level) => Levels::Singular(level.into_samples()),
206            Levels::Mip { rounding_mode, level_data } => Levels::Mip {
207                rounding_mode, level_data: level_data.into_iter().map(|s| s.into_samples()).collect(),
208            },
209
210            Levels::Rip { rounding_mode, level_data } => Levels::Rip {
211                rounding_mode,
212                level_data: RipMaps {
213                    level_count: level_data.level_count,
214                    map_data: level_data.map_data.into_iter().map(|s| s.into_samples()).collect(),
215                }
216            },
217        }
218    }
219}