1 | //! How to read a set of resolution levels.
|
2 |
|
3 | use crate::meta::*;
|
4 | use crate::image::*;
|
5 | use crate::error::*;
|
6 | use crate::meta::attribute::*;
|
7 | use crate::image::read::any_channels::*;
|
8 | use crate::block::chunk::TileCoordinates;
|
9 | use crate::image::read::specific_channels::*;
|
10 | use crate::image::recursive::*;
|
11 | use crate::math::Vec2;
|
12 | use crate::block::lines::LineRef;
|
13 | use crate::block::samples::*;
|
14 | use 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)]
|
22 | pub 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
|
32 | impl<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)]
|
102 | pub struct ReadAllLevels<DeepOrFlatSamples> {
|
103 |
|
104 | /// The sample reading specification
|
105 | pub read_samples: DeepOrFlatSamples
|
106 | }
|
107 |
|
108 | impl<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)]
|
123 | pub struct AllLevelsReader<SamplesReader> {
|
124 | levels: Levels<SamplesReader>,
|
125 | }
|
126 |
|
127 | /// A template that creates a [`SamplesReader`] once for each resolution level.
|
128 | pub 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 |
|
138 | impl<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 |
|
192 | impl<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 | |