1 | //! How to read either a single or a list of layers.
|
2 |
|
3 | use crate::image::*;
|
4 | use crate::meta::header::{Header, LayerAttributes};
|
5 | use crate::error::{Result, UnitResult, Error};
|
6 | use crate::block::{UncompressedBlock, BlockIndex};
|
7 | use crate::math::Vec2;
|
8 | use crate::image::read::image::{ReadLayers, LayersReader};
|
9 | use crate::block::chunk::TileCoordinates;
|
10 | use crate::meta::MetaData;
|
11 |
|
12 | /// Specify to read all channels, aborting if any one is invalid.
|
13 | /// [`ReadRgbaChannels`] or [`ReadAnyChannels<ReadFlatSamples>`].
|
14 | #[derive (Debug, Clone, Eq, PartialEq)]
|
15 | pub struct ReadAllLayers<ReadChannels> {
|
16 |
|
17 | /// The channel reading specification
|
18 | pub read_channels: ReadChannels,
|
19 | }
|
20 |
|
21 | /// Specify to read only the first layer which meets the previously specified requirements
|
22 | // FIXME do not throw error on deep data but just skip it!
|
23 | #[derive (Debug, Clone, Eq, PartialEq)]
|
24 | pub struct ReadFirstValidLayer<ReadChannels> {
|
25 |
|
26 | /// The channel reading specification
|
27 | pub read_channels: ReadChannels,
|
28 | }
|
29 |
|
30 | /// A template that creates a [`ChannelsReader`] once for all channels per layer.
|
31 | pub trait ReadChannels<'s> {
|
32 |
|
33 | /// The type of the temporary channels reader
|
34 | type Reader: ChannelsReader;
|
35 |
|
36 | /// Create a single reader for all channels of a specific layer
|
37 | fn create_channels_reader(&'s self, header: &Header) -> Result<Self::Reader>;
|
38 |
|
39 |
|
40 | /// Read only the first layer which meets the previously specified requirements
|
41 | /// For example, skips layers with deep data, if specified earlier.
|
42 | /// Aborts if the image contains no layers.
|
43 | // TODO test if this filters non-deep layers while ignoring deep data layers!
|
44 | fn first_valid_layer(self) -> ReadFirstValidLayer<Self> where Self:Sized { ReadFirstValidLayer { read_channels: self } }
|
45 |
|
46 | // FIXME do not throw error on deep data but just skip it!
|
47 |
|
48 |
|
49 | /// Reads all layers, including an empty list. Aborts if any of the layers are invalid,
|
50 | /// even if only one of the layers contains unexpected data.
|
51 | fn all_layers(self) -> ReadAllLayers<Self> where Self:Sized { ReadAllLayers { read_channels: self } }
|
52 |
|
53 | // TODO pub fn all_valid_layers(self) -> ReadAllValidLayers<Self> { ReadAllValidLayers { read_channels: self } }
|
54 | }
|
55 |
|
56 |
|
57 | /// Processes pixel blocks from a file and accumulates them into a list of layers.
|
58 | /// For example, `ChannelsReader` can be
|
59 | /// [`SpecificChannelsReader`] or [`AnyChannelsReader<FlatSamplesReader>`].
|
60 | #[derive (Debug, Clone, PartialEq)]
|
61 | pub struct AllLayersReader<ChannelsReader> {
|
62 | layer_readers: SmallVec<[LayerReader<ChannelsReader>; 2]>, // TODO unpack struct?
|
63 | }
|
64 |
|
65 | /// Processes pixel blocks from a file and accumulates them into a single layers, using only the first.
|
66 | /// For example, `ChannelsReader` can be
|
67 | /// `SpecificChannelsReader` or `AnyChannelsReader<FlatSamplesReader>`.
|
68 | #[derive (Debug, Clone, PartialEq)]
|
69 | pub struct FirstValidLayerReader<ChannelsReader> {
|
70 | layer_reader: LayerReader<ChannelsReader>,
|
71 | layer_index: usize,
|
72 | }
|
73 |
|
74 | /// Processes pixel blocks from a file and accumulates them into a single layers.
|
75 | /// For example, `ChannelsReader` can be
|
76 | /// `SpecificChannelsReader` or `AnyChannelsReader<FlatSamplesReader>`.
|
77 | #[derive (Debug, Clone, PartialEq)]
|
78 | pub struct LayerReader<ChannelsReader> {
|
79 | channels_reader: ChannelsReader,
|
80 | attributes: LayerAttributes,
|
81 | size: Vec2<usize>,
|
82 | encoding: Encoding
|
83 | }
|
84 |
|
85 | /// Processes pixel blocks from a file and accumulates them into multiple channels per layer.
|
86 | pub trait ChannelsReader {
|
87 |
|
88 | /// The type of the resulting channel collection
|
89 | type Channels;
|
90 |
|
91 | /// Specify whether a single block of pixels should be loaded from the file
|
92 | fn filter_block(&self, tile: TileCoordinates) -> bool;
|
93 |
|
94 | /// Load a single pixel block, which has not been filtered, into the reader, accumulating the channel data
|
95 | fn read_block(&mut self, header: &Header, block: UncompressedBlock) -> UnitResult;
|
96 |
|
97 | /// Deliver the final accumulated channel collection for the image
|
98 | fn into_channels(self) -> Self::Channels;
|
99 | }
|
100 |
|
101 |
|
102 | impl<C> LayerReader<C> {
|
103 | fn new(header: &Header, channels_reader: C) -> Result<Self> {
|
104 | Ok(LayerReader {
|
105 | channels_reader,
|
106 | attributes: header.own_attributes.clone(),
|
107 | size: header.layer_size,
|
108 | encoding: Encoding {
|
109 | compression: header.compression,
|
110 | line_order: header.line_order,
|
111 | blocks: match header.blocks {
|
112 | crate::meta::BlockDescription::ScanLines => Blocks::ScanLines,
|
113 | crate::meta::BlockDescription::Tiles(TileDescription { tile_size: Vec2, .. }) => Blocks::Tiles(tile_size)
|
114 | },
|
115 | },
|
116 | })
|
117 | }
|
118 | }
|
119 |
|
120 | impl<'s, C> ReadLayers<'s> for ReadAllLayers<C> where C: ReadChannels<'s> {
|
121 | type Layers = Layers<<C::Reader as ChannelsReader>::Channels>;
|
122 | type Reader = AllLayersReader<C::Reader>;
|
123 |
|
124 | fn create_layers_reader(&'s self, headers: &[Header]) -> Result<Self::Reader> {
|
125 | let readers: Result<_> = headersimpl Iterator- >
.iter()
|
126 | .map(|header: &Header| LayerReader::new(header, self.read_channels.create_channels_reader(header)?))
|
127 | .collect();
|
128 |
|
129 | Ok(AllLayersReader {
|
130 | layer_readers: readers?
|
131 | })
|
132 | }
|
133 | }
|
134 |
|
135 | impl<C> LayersReader for AllLayersReader<C> where C: ChannelsReader {
|
136 | type Layers = Layers<C::Channels>;
|
137 |
|
138 | fn filter_block(&self, _: &MetaData, tile: TileCoordinates, block: BlockIndex) -> bool {
|
139 | let layer = self.layer_readers.get(block.layer).expect("invalid layer index argument" );
|
140 | layer.channels_reader.filter_block(tile)
|
141 | }
|
142 |
|
143 | fn read_block(&mut self, headers: &[Header], block: UncompressedBlock) -> UnitResult {
|
144 | self.layer_readers
|
145 | .get_mut(block.index.layer).expect("invalid layer index argument" )
|
146 | .channels_reader.read_block(headers.get(block.index.layer).expect("invalid header index in block" ), block)
|
147 | }
|
148 |
|
149 | fn into_layers(self) -> Self::Layers {
|
150 | self.layer_readers
|
151 | .into_iter()
|
152 | .map(|layer| Layer {
|
153 | channel_data: layer.channels_reader.into_channels(),
|
154 | attributes: layer.attributes,
|
155 | size: layer.size,
|
156 | encoding: layer.encoding
|
157 | })
|
158 | .collect()
|
159 | }
|
160 | }
|
161 |
|
162 |
|
163 | impl<'s, C> ReadLayers<'s> for ReadFirstValidLayer<C> where C: ReadChannels<'s> {
|
164 | type Layers = Layer<<C::Reader as ChannelsReader>::Channels>;
|
165 | type Reader = FirstValidLayerReader<C::Reader>;
|
166 |
|
167 | fn create_layers_reader(&'s self, headers: &[Header]) -> Result<Self::Reader> {
|
168 | headers.iter().enumerate()
|
169 | .flat_map(|(index, header)|
|
170 | self.read_channels.create_channels_reader(header)
|
171 | .and_then(|reader| Ok(FirstValidLayerReader {
|
172 | layer_reader: LayerReader::new(header, reader)?,
|
173 | layer_index: index
|
174 | }))
|
175 | .ok()
|
176 | )
|
177 | .next()
|
178 | .ok_or(err:Error::invalid(message:"no layer in the image matched your specified requirements" ))
|
179 | }
|
180 | }
|
181 |
|
182 |
|
183 | impl<C> LayersReader for FirstValidLayerReader<C> where C: ChannelsReader {
|
184 | type Layers = Layer<C::Channels>;
|
185 |
|
186 | fn filter_block(&self, _: &MetaData, tile: TileCoordinates, block: BlockIndex) -> bool {
|
187 | block.layer == self.layer_index && self.layer_reader.channels_reader.filter_block(tile)
|
188 | }
|
189 |
|
190 | fn read_block(&mut self, headers: &[Header], block: UncompressedBlock) -> UnitResult {
|
191 | debug_assert_eq!(block.index.layer, self.layer_index, "block should have been filtered out" );
|
192 | self.layer_reader.channels_reader.read_block(&headers[self.layer_index], block)
|
193 | }
|
194 |
|
195 | fn into_layers(self) -> Self::Layers {
|
196 | Layer {
|
197 | channel_data: self.layer_reader.channels_reader.into_channels(),
|
198 | attributes: self.layer_reader.attributes,
|
199 | size: self.layer_reader.size,
|
200 | encoding: self.layer_reader.encoding
|
201 | }
|
202 | }
|
203 | }
|
204 |
|
205 | |