1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
//! How to read arbitrary channels.
use crate::image::*;
use crate::meta::header::{Header};
use crate::error::{Result, UnitResult};
use crate::block::UncompressedBlock;
use crate::block::lines::{LineRef};
use crate::math::Vec2;
use crate::meta::attribute::{Text, ChannelDescription};
use crate::image::read::layers::{ReadChannels, ChannelsReader};
use crate::block::chunk::TileCoordinates;
/// A template that creates an [AnyChannelsReader] for each layer in the image.
/// This loads all channels for each layer.
/// The `ReadSamples` can, for example, be [ReadFlatSamples] or [ReadAllLevels<ReadFlatSamples>].
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ReadAnyChannels<ReadSamples> {
/// The sample reading specification
pub read_samples: ReadSamples
}
/// A template that creates a new [`SampleReader`] for each channel in each layer.
pub trait ReadSamples {
/// The type of the temporary samples reader
type Reader: SamplesReader;
/// Create a single reader for a single channel of a layer
fn create_sample_reader(&self, header: &Header, channel: &ChannelDescription) -> Result<Self::Reader>;
}
/// Processes pixel blocks from a file and accumulates them into a collection of arbitrary channels.
/// Loads all channels for each layer.
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct AnyChannelsReader<SamplesReader> {
/// Stores a separate sample reader per channel in the layer
sample_channels_reader: SmallVec<[AnyChannelReader<SamplesReader>; 4]>,
}
/// Processes pixel blocks from a file and accumulates them into a single arbitrary channel.
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct AnyChannelReader<SamplesReader> {
/// The custom reader that accumulates the pixel data for a single channel
samples: SamplesReader,
/// Temporarily accumulated meta data.
name: Text,
/// Temporarily accumulated meta data.
sampling_rate: Vec2<usize>,
/// Temporarily accumulated meta data.
quantize_linearly: bool,
}
/// Processes pixel blocks from a file and accumulates them into a single pixel channel.
/// For example, stores thousands of "Red" pixel values for a single layer.
pub trait SamplesReader {
/// The type of resulting sample storage
type Samples;
/// Specify whether a single block of pixels should be loaded from the file
fn filter_block(&self, tile: TileCoordinates) -> bool;
/// Load a single pixel line, which has not been filtered, into the reader, accumulating the sample data
fn read_line(&mut self, line: LineRef<'_>) -> UnitResult;
/// Deliver the final accumulated sample storage for the image
fn into_samples(self) -> Self::Samples;
}
impl<'s, S: 's + ReadSamples> ReadChannels<'s> for ReadAnyChannels<S> {
type Reader = AnyChannelsReader<S::Reader>;
fn create_channels_reader(&self, header: &Header) -> Result<Self::Reader> {
let samples: Result<_> = header.channels.list.iter()
.map(|channel: &ChannelDescription| Ok(AnyChannelReader {
samples: self.read_samples.create_sample_reader(header, channel)?,
name: channel.name.clone(),
sampling_rate: channel.sampling,
quantize_linearly: channel.quantize_linearly
}))
.collect();
Ok(AnyChannelsReader { sample_channels_reader: samples? })
}
}
impl<S: SamplesReader> ChannelsReader for AnyChannelsReader<S> {
type Channels = AnyChannels<S::Samples>;
fn filter_block(&self, tile: TileCoordinates) -> bool {
self.sample_channels_reader.iter().any(|channel| channel.samples.filter_block(tile))
}
fn read_block(&mut self, header: &Header, decompressed: UncompressedBlock) -> UnitResult {
/*for (bytes, line) in LineIndex::lines_in_block(decompressed.index, header) {
let channel = self.sample_channels_reader.get_mut(line.channel).unwrap();
channel.samples.read_line(LineSlice { location: line, value: &decompressed.data[bytes] })?;
}
Ok(())*/
for line in decompressed.lines(&header.channels) {
self.sample_channels_reader[line.location.channel].samples.read_line(line)?;
}
Ok(())
}
fn into_channels(self) -> Self::Channels {
AnyChannels { // not using `new()` as the channels are already sorted
list: self.sample_channels_reader.into_iter()
.map(|channel| AnyChannel {
sample_data: channel.samples.into_samples(),
name: channel.name,
quantize_linearly: channel.quantize_linearly,
sampling: channel.sampling_rate
})
.collect()
}
}
}
|