use crate::meta::*;
use crate::image::*;
use crate::error::*;
use crate::meta::attribute::*;
use crate::image::read::any_channels::*;
use crate::block::chunk::TileCoordinates;
use crate::image::read::specific_channels::*;
use crate::image::recursive::*;
use crate::math::Vec2;
use crate::block::lines::LineRef;
use crate::block::samples::*;
use crate::meta::header::{Header};
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ReadLargestLevel<DeepOrFlatSamples> {
pub read_samples: DeepOrFlatSamples
}
impl<DeepOrFlatSamples> ReadLargestLevel<DeepOrFlatSamples> {
pub fn all_channels(self) -> ReadAnyChannels<DeepOrFlatSamples> { ReadAnyChannels { read_samples: self.read_samples } }
pub fn rgba_channels<R,G,B,A, Create, Set, Pixels>(
self, create_pixels: Create, set_pixel: Set
) -> CollectPixels<
ReadOptionalChannel<ReadRequiredChannel<ReadRequiredChannel<ReadRequiredChannel<NoneMore, R>, G>, B>, A>,
(R, G, B, A), Pixels, Create, Set
>
where
R: FromNativeSample, G: FromNativeSample, B: FromNativeSample, A: FromNativeSample,
Create: Fn(Vec2<usize>, &RgbaChannels) -> Pixels,
Set: Fn(&mut Pixels, Vec2<usize>, (R,G,B,A)),
{
self.specific_channels()
.required("R").required("G").required("B")
.optional("A", A::from_f32(1.0))
.collect_pixels(create_pixels, set_pixel)
}
pub fn rgb_channels<R,G,B, Create, Set, Pixels>(
self, create_pixels: Create, set_pixel: Set
) -> CollectPixels<
ReadRequiredChannel<ReadRequiredChannel<ReadRequiredChannel<NoneMore, R>, G>, B>,
(R, G, B), Pixels, Create, Set
>
where
R: FromNativeSample, G: FromNativeSample, B: FromNativeSample,
Create: Fn(Vec2<usize>, &RgbChannels) -> Pixels,
Set: Fn(&mut Pixels, Vec2<usize>, (R,G,B)),
{
self.specific_channels()
.required("R").required("G").required("B")
.collect_pixels(create_pixels, set_pixel)
}
pub fn specific_channels(self) -> ReadZeroChannels {
ReadZeroChannels { }
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ReadAllLevels<DeepOrFlatSamples> {
pub read_samples: DeepOrFlatSamples
}
impl<ReadDeepOrFlatSamples> ReadAllLevels<ReadDeepOrFlatSamples> {
pub fn all_channels(self) -> ReadAnyChannels<Self> { ReadAnyChannels { read_samples: self } }
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct AllLevelsReader<SamplesReader> {
levels: Levels<SamplesReader>,
}
pub trait ReadSamplesLevel {
type Reader: SamplesReader;
fn create_samples_level_reader(&self, header: &Header, channel: &ChannelDescription, level: Vec2<usize>, resolution: Vec2<usize>) -> Result<Self::Reader>;
}
impl<S: ReadSamplesLevel> ReadSamples for ReadAllLevels<S> {
type Reader = AllLevelsReader<S::Reader>;
fn create_sample_reader(&self, header: &Header, channel: &ChannelDescription) -> Result<Self::Reader> {
let data_size = header.layer_size / channel.sampling;
let levels = {
if let crate::meta::BlockDescription::Tiles(tiles) = &header.blocks {
match tiles.level_mode {
LevelMode::Singular => Levels::Singular(self.read_samples.create_samples_level_reader(header, channel, Vec2(0,0), header.layer_size)?),
LevelMode::MipMap => Levels::Mip {
rounding_mode: tiles.rounding_mode,
level_data: {
let round = tiles.rounding_mode;
let maps: Result<LevelMaps<S::Reader>> = mip_map_levels(round, data_size)
.map(|(index, level_size)| self.read_samples.create_samples_level_reader(header, channel, Vec2(index, index), level_size))
.collect();
maps?
},
},
LevelMode::RipMap => Levels::Rip {
rounding_mode: tiles.rounding_mode,
level_data: {
let round = tiles.rounding_mode;
let level_count_x = compute_level_count(round, data_size.width());
let level_count_y = compute_level_count(round, data_size.height());
let maps: Result<LevelMaps<S::Reader>> = rip_map_levels(round, data_size)
.map(|(index, level_size)| self.read_samples.create_samples_level_reader(header, channel, index, level_size))
.collect();
RipMaps {
map_data: maps?,
level_count: Vec2(level_count_x, level_count_y)
}
},
},
}
}
else {
Levels::Singular(self.read_samples.create_samples_level_reader(header, channel, Vec2(0, 0), data_size)?)
}
};
Ok(AllLevelsReader { levels })
}
}
impl<S: SamplesReader> SamplesReader for AllLevelsReader<S> {
type Samples = Levels<S::Samples>;
fn filter_block(&self, _: TileCoordinates) -> bool {
true
}
fn read_line(&mut self, line: LineRef<'_>) -> UnitResult {
self.levels.get_level_mut(line.location.level)?.read_line(line)
}
fn into_samples(self) -> Self::Samples {
match self.levels {
Levels::Singular(level) => Levels::Singular(level.into_samples()),
Levels::Mip { rounding_mode, level_data } => Levels::Mip {
rounding_mode, level_data: level_data.into_iter().map(|s| s.into_samples()).collect(),
},
Levels::Rip { rounding_mode, level_data } => Levels::Rip {
rounding_mode,
level_data: RipMaps {
level_count: level_data.level_count,
map_data: level_data.map_data.into_iter().map(|s| s.into_samples()).collect(),
}
},
}
}
}