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