exr/image/read/
any_channels.rs1use crate::{
4 block::{chunk::TileCoordinates, lines::LineRef, UncompressedBlock},
5 error::{Result, UnitResult},
6 image::{
7 read::layers::{ChannelsReader, ReadChannels},
8 *,
9 },
10 math::Vec2,
11 meta::{
12 attribute::{ChannelDescription, Text},
13 header::Header,
14 },
15};
16
17#[derive(Debug, Clone, Eq, PartialEq)]
22pub struct ReadAnyChannels<ReadSamples> {
23 pub read_samples: ReadSamples,
25}
26
27pub trait ReadSamples {
30 type Reader: SamplesReader;
32
33 fn create_sample_reader(
35 &self,
36 header: &Header,
37 channel: &ChannelDescription,
38 ) -> Result<Self::Reader>;
39}
40
41#[derive(Debug, Clone, Eq, PartialEq)]
44pub struct AnyChannelsReader<SamplesReader> {
45 sample_channels_reader: SmallVec<[AnyChannelReader<SamplesReader>; 4]>,
47}
48
49#[derive(Debug, Clone, Eq, PartialEq)]
52pub struct AnyChannelReader<SamplesReader> {
53 samples: SamplesReader,
55
56 name: Text,
58
59 sampling_rate: Vec2<usize>,
61
62 quantize_linearly: bool,
64}
65
66pub trait SamplesReader {
70 type Samples;
72
73 fn filter_block(&self, tile: TileCoordinates) -> bool;
75
76 fn read_line(&mut self, line: LineRef<'_>) -> UnitResult;
79
80 fn into_samples(self) -> Self::Samples;
82}
83
84impl<'s, S: 's + ReadSamples> ReadChannels<'s> for ReadAnyChannels<S> {
85 type Reader = AnyChannelsReader<S::Reader>;
86
87 fn create_channels_reader(&self, header: &Header) -> Result<Self::Reader> {
88 let samples: Result<_> = header
89 .channels
90 .list
91 .iter()
92 .map(|channel: &ChannelDescription| {
93 Ok(AnyChannelReader {
94 samples: self.read_samples.create_sample_reader(header, channel)?,
95 name: channel.name.clone(),
96 sampling_rate: channel.sampling,
97 quantize_linearly: channel.quantize_linearly,
98 })
99 })
100 .collect();
101
102 Ok(AnyChannelsReader {
103 sample_channels_reader: samples?,
104 })
105 }
106}
107
108impl<S: SamplesReader> ChannelsReader for AnyChannelsReader<S> {
109 type Channels = AnyChannels<S::Samples>;
110
111 fn filter_block(&self, tile: TileCoordinates) -> bool {
112 self.sample_channels_reader.iter().any(|channel| channel.samples.filter_block(tile))
113 }
114
115 fn read_block(&mut self, header: &Header, decompressed: UncompressedBlock) -> UnitResult {
116 for line in decompressed.lines(&header.channels) {
123 self.sample_channels_reader[line.location.channel].samples.read_line(line)?;
124 }
125
126 Ok(())
127 }
128
129 fn into_channels(self) -> Self::Channels {
130 AnyChannels {
131 list: self
133 .sample_channels_reader
134 .into_iter()
135 .map(|channel| AnyChannel {
136 sample_data: channel.samples.into_samples(),
137
138 name: channel.name,
139 quantize_linearly: channel.quantize_linearly,
140 sampling: channel.sampling_rate,
141 })
142 .collect(),
143 }
144 }
145}