exr/image/read/
any_channels.rs1use crate::image::*;
4use crate::meta::header::{Header};
5use crate::error::{Result, UnitResult};
6use crate::block::UncompressedBlock;
7use crate::block::lines::{LineRef};
8use crate::math::Vec2;
9use crate::meta::attribute::{Text, ChannelDescription};
10use crate::image::read::layers::{ReadChannels, ChannelsReader};
11use crate::block::chunk::TileCoordinates;
12
13#[derive(Debug, Clone, Eq, PartialEq)]
17pub struct ReadAnyChannels<ReadSamples> {
18
19 pub read_samples: ReadSamples
21}
22
23pub trait ReadSamples {
25
26 type Reader: SamplesReader;
28
29 fn create_sample_reader(&self, header: &Header, channel: &ChannelDescription) -> Result<Self::Reader>;
31}
32
33#[derive(Debug, Clone, Eq, PartialEq)]
36pub struct AnyChannelsReader<SamplesReader> {
37
38 sample_channels_reader: SmallVec<[AnyChannelReader<SamplesReader>; 4]>,
40}
41
42#[derive(Debug, Clone, Eq, PartialEq)]
44pub struct AnyChannelReader<SamplesReader> {
45
46 samples: SamplesReader,
48
49 name: Text,
51
52 sampling_rate: Vec2<usize>,
54
55 quantize_linearly: bool,
57}
58
59pub trait SamplesReader {
62
63 type Samples;
65
66 fn filter_block(&self, tile: TileCoordinates) -> bool;
68
69 fn read_line(&mut self, line: LineRef<'_>) -> UnitResult;
71
72 fn into_samples(self) -> Self::Samples;
74}
75
76
77impl<'s, S: 's + ReadSamples> ReadChannels<'s> for ReadAnyChannels<S> {
78 type Reader = AnyChannelsReader<S::Reader>;
79
80 fn create_channels_reader(&self, header: &Header) -> Result<Self::Reader> {
81 let samples: Result<_> = header.channels.list.iter()
82 .map(|channel: &ChannelDescription| Ok(AnyChannelReader {
83 samples: self.read_samples.create_sample_reader(header, channel)?,
84 name: channel.name.clone(),
85 sampling_rate: channel.sampling,
86 quantize_linearly: channel.quantize_linearly
87 }))
88 .collect();
89
90 Ok(AnyChannelsReader { sample_channels_reader: samples? })
91 }
92}
93
94impl<S: SamplesReader> ChannelsReader for AnyChannelsReader<S> {
95 type Channels = AnyChannels<S::Samples>;
96
97 fn filter_block(&self, tile: TileCoordinates) -> bool {
98 self.sample_channels_reader.iter().any(|channel| channel.samples.filter_block(tile))
99 }
100
101 fn read_block(&mut self, header: &Header, decompressed: UncompressedBlock) -> UnitResult {
102 for line in decompressed.lines(&header.channels) {
109 self.sample_channels_reader[line.location.channel].samples.read_line(line)?;
110 }
111
112 Ok(())
113 }
114
115 fn into_channels(self) -> Self::Channels {
116 AnyChannels { list: self.sample_channels_reader.into_iter()
118 .map(|channel| AnyChannel {
119 sample_data: channel.samples.into_samples(),
120
121 name: channel.name,
122 quantize_linearly: channel.quantize_linearly,
123 sampling: channel.sampling_rate
124 })
125 .collect()
126 }
127 }
128}