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
|
//! How to read samples (a grid of `f32`, `f16` or `u32` values).
use crate::image::*;
use crate::meta::header::{Header};
use crate::error::{Result, UnitResult};
use crate::block::lines::LineRef;
use crate::math::Vec2;
use crate::meta::attribute::{ChannelDescription, SampleType};
use crate::image::read::any_channels::{SamplesReader, ReadSamples};
use crate::image::read::levels::{ReadSamplesLevel, ReadAllLevels, ReadLargestLevel};
use crate::block::chunk::TileCoordinates;
// use crate::image::read::layers::ReadChannels;
/// Specify to read only flat samples and no "deep data"
// FIXME do not throw error on deep data but just skip it!
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub struct ReadFlatSamples;
// pub struct ReadAnySamples;
impl ReadFlatSamples {
// TODO
// e. g. `let sum = reader.any_channels_with(|sample, sum| sum += sample)`
// pub fn any_channels_with <S> (self, storage: S) -> { }
/// Specify to read only the highest resolution level, skipping all smaller variations.
pub fn largest_resolution_level(self) -> ReadLargestLevel<Self> { ReadLargestLevel { read_samples: self } }
/// Specify to read all contained resolution levels from the image, if any.
pub fn all_resolution_levels(self) -> ReadAllLevels<Self> { ReadAllLevels { read_samples: self } }
// TODO pub fn specific_resolution_level<F: Fn(&[Vec2<usize>])->usize >(self, select_level: F) -> ReadLevelBy<Self> { ReadAllLevels { read_samples: self } }
}
/*pub struct AnySamplesReader { TODO
resolution: Vec2<usize>,
samples: DeepAndFlatSamples
}*/
/// Processes pixel blocks from a file and accumulates them into a grid of samples, for example "Red" or "Alpha".
#[derive(Debug, Clone, PartialEq)]
pub struct FlatSamplesReader {
level: Vec2<usize>,
resolution: Vec2<usize>,
samples: FlatSamples
}
// only used when samples is directly inside a channel, without levels
impl ReadSamples for ReadFlatSamples {
type Reader = FlatSamplesReader;
fn create_sample_reader(&self, header: &Header, channel: &ChannelDescription) -> Result<Self::Reader> {
self.create_samples_level_reader(header, channel, Vec2(0, 0), header.layer_size)
}
}
impl ReadSamplesLevel for ReadFlatSamples {
type Reader = FlatSamplesReader;
fn create_samples_level_reader(&self, _header: &Header, channel: &ChannelDescription, level: Vec2<usize>, resolution: Vec2<usize>) -> Result<Self::Reader> {
Ok(FlatSamplesReader {
level, resolution, // TODO sampling
samples: match channel.sample_type {
SampleType::F16 => FlatSamples::F16(vec![f16::ZERO; resolution.area()]),
SampleType::F32 => FlatSamples::F32(vec![0.0; resolution.area()]),
SampleType::U32 => FlatSamples::U32(vec![0; resolution.area()]),
}
})
}
}
impl SamplesReader for FlatSamplesReader {
type Samples = FlatSamples;
fn filter_block(&self, tile: TileCoordinates) -> bool {
tile.level_index == self.level
}
fn read_line(&mut self, line: LineRef<'_>) -> UnitResult {
let index = line.location;
let resolution = self.resolution;
// the index is generated by ourselves and must always be correct
debug_assert_eq!(index.level, self.level, "line should have been filtered");
debug_assert!(index.position.x() + index.sample_count <= resolution.width(), "line index calculation bug");
debug_assert!(index.position.y() < resolution.height(), "line index calculation bug");
debug_assert_ne!(resolution.0, 0, "sample size bug");
let start_index = index.position.y() * resolution.width() + index.position.x();
let end_index = start_index + index.sample_count;
debug_assert!(
start_index < end_index && end_index <= self.samples.len(),
"for resolution {:?}, this is an invalid line: {:?}",
self.resolution, line.location
);
match &mut self.samples {
FlatSamples::F16(samples) =>
line.read_samples_into_slice(&mut samples[start_index .. end_index])
.expect("writing line bytes failed"),
FlatSamples::F32(samples) =>
line.read_samples_into_slice(&mut samples[start_index .. end_index])
.expect("writing line bytes failed"),
FlatSamples::U32(samples) =>
line.read_samples_into_slice(&mut samples[start_index .. end_index])
.expect("writing line bytes failed"),
}
Ok(())
}
fn into_samples(self) -> FlatSamples {
self.samples
}
}
|