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}
220