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;
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct ReadAnyChannels<ReadSamples> {
pub read_samples: ReadSamples
}
pub trait ReadSamples {
type Reader: SamplesReader;
fn create_sample_reader(&self, header: &Header, channel: &ChannelDescription) -> Result<Self::Reader>;
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct AnyChannelsReader<SamplesReader> {
sample_channels_reader: SmallVec<[AnyChannelReader<SamplesReader>; 4]>,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct AnyChannelReader<SamplesReader> {
samples: SamplesReader,
name: Text,
sampling_rate: Vec2<usize>,
quantize_linearly: bool,
}
pub trait SamplesReader {
type Samples;
fn filter_block(&self, tile: TileCoordinates) -> bool;
fn read_line(&mut self, line: LineRef<'_>) -> UnitResult;
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 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 { 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()
}
}
}