diff options
Diffstat (limited to 'vendor/exr/src/block/lines.rs')
-rw-r--r-- | vendor/exr/src/block/lines.rs | 197 |
1 files changed, 0 insertions, 197 deletions
diff --git a/vendor/exr/src/block/lines.rs b/vendor/exr/src/block/lines.rs deleted file mode 100644 index 1cdf8ee..0000000 --- a/vendor/exr/src/block/lines.rs +++ /dev/null @@ -1,197 +0,0 @@ -//! Extract lines from a block of pixel bytes. - -use crate::math::*; -use std::io::{Cursor}; -use crate::error::{Result, UnitResult}; -use smallvec::SmallVec; -use std::ops::Range; -use crate::block::{BlockIndex}; -use crate::meta::attribute::ChannelList; - - -/// A single line of pixels. -/// Use [LineRef] or [LineRefMut] for easier type names. -#[derive(Clone, Copy, Eq, PartialEq, Debug)] -pub struct LineSlice<T> { - - // TODO also store enum SampleType, as it would always be matched in every place it is used - - /// Where this line is located inside the image. - pub location: LineIndex, - - /// The raw bytes of the pixel line, either `&[u8]` or `&mut [u8]`. - /// Must be re-interpreted as slice of f16, f32, or u32, - /// according to the channel data type. - pub value: T, -} - - -/// An reference to a single line of pixels. -/// May go across the whole image or just a tile section of it. -/// -/// This line contains an immutable slice that all samples will be read from. -pub type LineRef<'s> = LineSlice<&'s [u8]>; - -/// A reference to a single mutable line of pixels. -/// May go across the whole image or just a tile section of it. -/// -/// This line contains a mutable slice that all samples will be written to. -pub type LineRefMut<'s> = LineSlice<&'s mut [u8]>; - - -/// Specifies where a row of pixels lies inside an image. -/// This is a globally unique identifier which includes -/// the layer, channel index, and pixel location. -#[derive(Clone, Copy, Eq, PartialEq, Debug, Hash)] -pub struct LineIndex { - - /// Index of the layer. - pub layer: usize, - - /// The channel index of the layer. - pub channel: usize, - - /// Index of the mip or rip level in the image. - pub level: Vec2<usize>, - - /// Position of the most left pixel of the row. - pub position: Vec2<usize>, - - /// The width of the line; the number of samples in this row, - /// that is, the number of f16, f32, or u32 values. - pub sample_count: usize, -} - - -impl LineIndex { - - /// Iterates the lines of this block index in interleaved fashion: - /// For each line in this block, this iterator steps once through each channel. - /// This is how lines are stored in a pixel data block. - /// - /// Does not check whether `self.layer_index`, `self.level`, `self.size` and `self.position` are valid indices.__ - // TODO be sure this cannot produce incorrect data, as this is not further checked but only handled with panics - #[inline] - #[must_use] - pub fn lines_in_block(block: BlockIndex, channels: &ChannelList) -> impl Iterator<Item=(Range<usize>, LineIndex)> { - struct LineIter { - layer: usize, level: Vec2<usize>, width: usize, - end_y: usize, x: usize, channel_sizes: SmallVec<[usize; 8]>, - byte: usize, channel: usize, y: usize, - } - - // FIXME what about sub sampling?? - - impl Iterator for LineIter { - type Item = (Range<usize>, LineIndex); - // TODO size hint? - - fn next(&mut self) -> Option<Self::Item> { - if self.y < self.end_y { - - // compute return value before incrementing - let byte_len = self.channel_sizes[self.channel]; - let return_value = ( - (self.byte .. self.byte + byte_len), - LineIndex { - channel: self.channel, - layer: self.layer, - level: self.level, - position: Vec2(self.x, self.y), - sample_count: self.width, - } - ); - - { // increment indices - self.byte += byte_len; - self.channel += 1; - - if self.channel == self.channel_sizes.len() { - self.channel = 0; - self.y += 1; - } - } - - Some(return_value) - } - - else { - None - } - } - } - - let channel_line_sizes: SmallVec<[usize; 8]> = channels.list.iter() - .map(move |channel| block.pixel_size.0 * channel.sample_type.bytes_per_sample()) // FIXME is it fewer samples per tile or just fewer tiles for sampled images??? - .collect(); - - LineIter { - layer: block.layer, - level: block.level, - width: block.pixel_size.0, - x: block.pixel_position.0, - end_y: block.pixel_position.y() + block.pixel_size.height(), - channel_sizes: channel_line_sizes, - - byte: 0, - channel: 0, - y: block.pixel_position.y() - } - } -} - - - -impl<'s> LineRefMut<'s> { - - /// Writes the samples (f16, f32, u32 values) into this line value reference. - /// Use `write_samples` if there is not slice available. - #[inline] - #[must_use] - pub fn write_samples_from_slice<T: crate::io::Data>(self, slice: &[T]) -> UnitResult { - debug_assert_eq!(slice.len(), self.location.sample_count, "slice size does not match the line width"); - debug_assert_eq!(self.value.len(), self.location.sample_count * T::BYTE_SIZE, "sample type size does not match line byte size"); - - T::write_slice(&mut Cursor::new(self.value), slice) - } - - /// Iterate over all samples in this line, from left to right. - /// The supplied `get_line` function returns the sample value - /// for a given sample index within the line, - /// which starts at zero for each individual line. - /// Use `write_samples_from_slice` if you already have a slice of samples. - #[inline] - #[must_use] - pub fn write_samples<T: crate::io::Data>(self, mut get_sample: impl FnMut(usize) -> T) -> UnitResult { - debug_assert_eq!(self.value.len(), self.location.sample_count * T::BYTE_SIZE, "sample type size does not match line byte size"); - - let mut write = Cursor::new(self.value); - - for index in 0..self.location.sample_count { - T::write(get_sample(index), &mut write)?; - } - - Ok(()) - } -} - -impl LineRef<'_> { - - /// Read the samples (f16, f32, u32 values) from this line value reference. - /// Use `read_samples` if there is not slice available. - pub fn read_samples_into_slice<T: crate::io::Data>(self, slice: &mut [T]) -> UnitResult { - debug_assert_eq!(slice.len(), self.location.sample_count, "slice size does not match the line width"); - debug_assert_eq!(self.value.len(), self.location.sample_count * T::BYTE_SIZE, "sample type size does not match line byte size"); - - T::read_slice(&mut Cursor::new(self.value), slice) - } - - /// Iterate over all samples in this line, from left to right. - /// Use `read_sample_into_slice` if you already have a slice of samples. - pub fn read_samples<T: crate::io::Data>(&self) -> impl Iterator<Item = Result<T>> + '_ { - debug_assert_eq!(self.value.len(), self.location.sample_count * T::BYTE_SIZE, "sample type size does not match line byte size"); - - let mut read = self.value.clone(); // FIXME deep data - (0..self.location.sample_count).map(move |_| T::read(&mut read)) - } -}
\ No newline at end of file |