aboutsummaryrefslogtreecommitdiff
path: root/vendor/exr/src/block/chunk.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/exr/src/block/chunk.rs')
-rw-r--r--vendor/exr/src/block/chunk.rs379
1 files changed, 0 insertions, 379 deletions
diff --git a/vendor/exr/src/block/chunk.rs b/vendor/exr/src/block/chunk.rs
deleted file mode 100644
index ff138f8..0000000
--- a/vendor/exr/src/block/chunk.rs
+++ /dev/null
@@ -1,379 +0,0 @@
-
-//! Read and write already compressed pixel data blocks.
-//! Does not include the process of compression and decompression.
-
-use crate::meta::attribute::{IntegerBounds};
-
-/// A generic block of pixel information.
-/// Contains pixel data and an index to the corresponding header.
-/// All pixel data in a file is split into a list of chunks.
-/// Also contains positioning information that locates this
-/// data block in the referenced layer.
-#[derive(Debug, Clone)]
-pub struct Chunk {
-
- /// The index of the layer that the block belongs to.
- /// This is required as the pixel data can appear in any order in a file.
- // PDF says u64, but source code seems to be i32
- pub layer_index: usize,
-
- /// The compressed pixel contents.
- pub compressed_block: CompressedBlock,
-}
-
-/// The raw, possibly compressed pixel data of a file.
-/// Each layer in a file can have a different type.
-/// Also contains positioning information that locates this
-/// data block in the corresponding layer.
-/// Exists inside a `Chunk`.
-#[derive(Debug, Clone)]
-pub enum CompressedBlock {
-
- /// Scan line blocks of flat data.
- ScanLine(CompressedScanLineBlock),
-
- /// Tiles of flat data.
- Tile(CompressedTileBlock),
-
- /// Scan line blocks of deep data.
- DeepScanLine(CompressedDeepScanLineBlock),
-
- /// Tiles of deep data.
- DeepTile(CompressedDeepTileBlock),
-}
-
-/// A `Block` of possibly compressed flat scan lines.
-/// Corresponds to type attribute `scanlineimage`.
-#[derive(Debug, Clone)]
-pub struct CompressedScanLineBlock {
-
- /// The block's y coordinate is the pixel space y coordinate of the top scan line in the block.
- /// The top scan line block in the image is aligned with the top edge of the data window.
- pub y_coordinate: i32,
-
- /// One or more scan lines may be stored together as a scan line block.
- /// The number of scan lines per block depends on how the pixel data are compressed.
- /// For each line in the tile, for each channel, the row values are contiguous.
- pub compressed_pixels: Vec<u8>,
-}
-
-/// This `Block` is a tile of flat (non-deep) data.
-/// Corresponds to type attribute `tiledimage`.
-#[derive(Debug, Clone)]
-pub struct CompressedTileBlock {
-
- /// The tile location.
- pub coordinates: TileCoordinates,
-
- /// One or more scan lines may be stored together as a scan line block.
- /// The number of scan lines per block depends on how the pixel data are compressed.
- /// For each line in the tile, for each channel, the row values are contiguous.
- pub compressed_pixels: Vec<u8>,
-}
-
-/// Indicates the position and resolution level of a `TileBlock` or `DeepTileBlock`.
-#[derive(Copy, Clone, Debug, Hash, Eq, PartialEq)]
-pub struct TileCoordinates {
-
- /// Index of the tile, not pixel position.
- pub tile_index: Vec2<usize>,
-
- /// Index of the Mip/Rip level.
- pub level_index: Vec2<usize>,
-}
-
-/// This `Block` consists of one or more deep scan lines.
-/// Corresponds to type attribute `deepscanline`.
-#[derive(Debug, Clone)]
-pub struct CompressedDeepScanLineBlock {
-
- /// The block's y coordinate is the pixel space y coordinate of the top scan line in the block.
- /// The top scan line block in the image is aligned with the top edge of the data window.
- pub y_coordinate: i32,
-
- /// Count of samples.
- pub decompressed_sample_data_size: usize,
-
- /// The pixel offset table is a list of integers, one for each pixel column within the data window.
- /// Each entry in the table indicates the total number of samples required
- /// to store the pixel in it as well as all pixels to the left of it.
- pub compressed_pixel_offset_table: Vec<i8>,
-
- /// One or more scan lines may be stored together as a scan line block.
- /// The number of scan lines per block depends on how the pixel data are compressed.
- /// For each line in the tile, for each channel, the row values are contiguous.
- pub compressed_sample_data: Vec<u8>,
-}
-
-/// This `Block` is a tile of deep data.
-/// Corresponds to type attribute `deeptile`.
-#[derive(Debug, Clone)]
-pub struct CompressedDeepTileBlock {
-
- /// The tile location.
- pub coordinates: TileCoordinates,
-
- /// Count of samples.
- pub decompressed_sample_data_size: usize,
-
- /// The pixel offset table is a list of integers, one for each pixel column within the data window.
- /// Each entry in the table indicates the total number of samples required
- /// to store the pixel in it as well as all pixels to the left of it.
- pub compressed_pixel_offset_table: Vec<i8>,
-
- /// One or more scan lines may be stored together as a scan line block.
- /// The number of scan lines per block depends on how the pixel data are compressed.
- /// For each line in the tile, for each channel, the row values are contiguous.
- pub compressed_sample_data: Vec<u8>,
-}
-
-
-use crate::io::*;
-
-impl TileCoordinates {
-
- /// Without validation, write this instance to the byte stream.
- pub fn write<W: Write>(&self, write: &mut W) -> UnitResult {
- i32::write(usize_to_i32(self.tile_index.x()), write)?;
- i32::write(usize_to_i32(self.tile_index.y()), write)?;
- i32::write(usize_to_i32(self.level_index.x()), write)?;
- i32::write(usize_to_i32(self.level_index.y()), write)?;
- Ok(())
- }
-
- /// Read the value without validating.
- pub fn read(read: &mut impl Read) -> Result<Self> {
- let tile_x = i32::read(read)?;
- let tile_y = i32::read(read)?;
-
- let level_x = i32::read(read)?;
- let level_y = i32::read(read)?;
-
- if level_x > 31 || level_y > 31 {
- // there can be at most 31 levels, because the largest level would have a size of 2^31,
- // which exceeds the maximum 32-bit integer value.
- return Err(Error::invalid("level index exceeding integer maximum"));
- }
-
- Ok(TileCoordinates {
- tile_index: Vec2(tile_x, tile_y).to_usize("tile coordinate index")?,
- level_index: Vec2(level_x, level_y).to_usize("tile coordinate level")?
- })
- }
-
- /// The indices which can be used to index into the arrays of a data window.
- /// These coordinates are only valid inside the corresponding one header.
- /// Will start at 0 and always be positive.
- pub fn to_data_indices(&self, tile_size: Vec2<usize>, max: Vec2<usize>) -> Result<IntegerBounds> {
- let x = self.tile_index.x() * tile_size.width();
- let y = self.tile_index.y() * tile_size.height();
-
- if x >= max.x() || y >= max.y() {
- Err(Error::invalid("tile index"))
- }
- else {
- Ok(IntegerBounds {
- position: Vec2(usize_to_i32(x), usize_to_i32(y)),
- size: Vec2(
- calculate_block_size(max.x(), tile_size.width(), x)?,
- calculate_block_size(max.y(), tile_size.height(), y)?,
- ),
- })
- }
- }
-
- /// Absolute coordinates inside the global 2D space of a file, may be negative.
- pub fn to_absolute_indices(&self, tile_size: Vec2<usize>, data_window: IntegerBounds) -> Result<IntegerBounds> {
- let data = self.to_data_indices(tile_size, data_window.size)?;
- Ok(data.with_origin(data_window.position))
- }
-
- /// Returns if this is the original resolution or a smaller copy.
- pub fn is_largest_resolution_level(&self) -> bool {
- self.level_index == Vec2(0, 0)
- }
-}
-
-
-
-use crate::meta::{MetaData, BlockDescription, calculate_block_size};
-
-impl CompressedScanLineBlock {
-
- /// Without validation, write this instance to the byte stream.
- pub fn write<W: Write>(&self, write: &mut W) -> UnitResult {
- debug_assert_ne!(self.compressed_pixels.len(), 0, "empty blocks should not be put in the file bug");
-
- i32::write(self.y_coordinate, write)?;
- u8::write_i32_sized_slice(write, &self.compressed_pixels)?;
- Ok(())
- }
-
- /// Read the value without validating.
- pub fn read(read: &mut impl Read, max_block_byte_size: usize) -> Result<Self> {
- let y_coordinate = i32::read(read)?;
- let compressed_pixels = u8::read_i32_sized_vec(read, max_block_byte_size, Some(max_block_byte_size), "scan line block sample count")?;
- Ok(CompressedScanLineBlock { y_coordinate, compressed_pixels })
- }
-}
-
-impl CompressedTileBlock {
-
- /// Without validation, write this instance to the byte stream.
- pub fn write<W: Write>(&self, write: &mut W) -> UnitResult {
- debug_assert_ne!(self.compressed_pixels.len(), 0, "empty blocks should not be put in the file bug");
-
- self.coordinates.write(write)?;
- u8::write_i32_sized_slice(write, &self.compressed_pixels)?;
- Ok(())
- }
-
- /// Read the value without validating.
- pub fn read(read: &mut impl Read, max_block_byte_size: usize) -> Result<Self> {
- let coordinates = TileCoordinates::read(read)?;
- let compressed_pixels = u8::read_i32_sized_vec(read, max_block_byte_size, Some(max_block_byte_size), "tile block sample count")?;
- Ok(CompressedTileBlock { coordinates, compressed_pixels })
- }
-}
-
-impl CompressedDeepScanLineBlock {
-
- /// Without validation, write this instance to the byte stream.
- pub fn write<W: Write>(&self, write: &mut W) -> UnitResult {
- debug_assert_ne!(self.compressed_sample_data.len(), 0, "empty blocks should not be put in the file bug");
-
- i32::write(self.y_coordinate, write)?;
- u64::write(self.compressed_pixel_offset_table.len() as u64, write)?;
- u64::write(self.compressed_sample_data.len() as u64, write)?; // TODO just guessed
- u64::write(self.decompressed_sample_data_size as u64, write)?;
- i8::write_slice(write, &self.compressed_pixel_offset_table)?;
- u8::write_slice(write, &self.compressed_sample_data)?;
- Ok(())
- }
-
- /// Read the value without validating.
- pub fn read(read: &mut impl Read, max_block_byte_size: usize) -> Result<Self> {
- let y_coordinate = i32::read(read)?;
- let compressed_pixel_offset_table_size = u64_to_usize(u64::read(read)?);
- let compressed_sample_data_size = u64_to_usize(u64::read(read)?);
- let decompressed_sample_data_size = u64_to_usize(u64::read(read)?);
-
- // doc said i32, try u8
- let compressed_pixel_offset_table = i8::read_vec(
- read, compressed_pixel_offset_table_size,
- 6 * u16::MAX as usize, Some(max_block_byte_size),
- "deep scan line block table size"
- )?;
-
- let compressed_sample_data = u8::read_vec(
- read, compressed_sample_data_size,
- 6 * u16::MAX as usize, Some(max_block_byte_size),
- "deep scan line block sample count"
- )?;
-
- Ok(CompressedDeepScanLineBlock {
- y_coordinate,
- decompressed_sample_data_size,
- compressed_pixel_offset_table,
- compressed_sample_data,
- })
- }
-}
-
-
-impl CompressedDeepTileBlock {
-
- /// Without validation, write this instance to the byte stream.
- pub fn write<W: Write>(&self, write: &mut W) -> UnitResult {
- debug_assert_ne!(self.compressed_sample_data.len(), 0, "empty blocks should not be put in the file bug");
-
- self.coordinates.write(write)?;
- u64::write(self.compressed_pixel_offset_table.len() as u64, write)?;
- u64::write(self.compressed_sample_data.len() as u64, write)?; // TODO just guessed
- u64::write(self.decompressed_sample_data_size as u64, write)?;
- i8::write_slice(write, &self.compressed_pixel_offset_table)?;
- u8::write_slice(write, &self.compressed_sample_data)?;
- Ok(())
- }
-
- /// Read the value without validating.
- pub fn read(read: &mut impl Read, hard_max_block_byte_size: usize) -> Result<Self> {
- let coordinates = TileCoordinates::read(read)?;
- let compressed_pixel_offset_table_size = u64_to_usize(u64::read(read)?);
- let compressed_sample_data_size = u64_to_usize(u64::read(read)?); // TODO u64 just guessed
- let decompressed_sample_data_size = u64_to_usize(u64::read(read)?);
-
- let compressed_pixel_offset_table = i8::read_vec(
- read, compressed_pixel_offset_table_size,
- 6 * u16::MAX as usize, Some(hard_max_block_byte_size),
- "deep tile block table size"
- )?;
-
- let compressed_sample_data = u8::read_vec(
- read, compressed_sample_data_size,
- 6 * u16::MAX as usize, Some(hard_max_block_byte_size),
- "deep tile block sample count"
- )?;
-
- Ok(CompressedDeepTileBlock {
- coordinates,
- decompressed_sample_data_size,
- compressed_pixel_offset_table,
- compressed_sample_data,
- })
- }
-}
-
-use crate::error::{UnitResult, Result, Error, u64_to_usize, usize_to_i32, i32_to_usize};
-use crate::math::Vec2;
-
-/// Validation of chunks is done while reading and writing the actual data. (For example in exr::full_image)
-impl Chunk {
-
- /// Without validation, write this instance to the byte stream.
- pub fn write(&self, write: &mut impl Write, header_count: usize) -> UnitResult {
- debug_assert!(self.layer_index < header_count, "layer index bug"); // validation is done in full_image or simple_image
-
- if header_count != 1 { usize_to_i32(self.layer_index).write(write)?; }
- else { assert_eq!(self.layer_index, 0, "invalid header index for single layer file"); }
-
- match self.compressed_block {
- CompressedBlock::ScanLine (ref value) => value.write(write),
- CompressedBlock::Tile (ref value) => value.write(write),
- CompressedBlock::DeepScanLine (ref value) => value.write(write),
- CompressedBlock::DeepTile (ref value) => value.write(write),
- }
- }
-
- /// Read the value without validating.
- pub fn read(read: &mut impl Read, meta_data: &MetaData) -> Result<Self> {
- let layer_number = i32_to_usize(
- if meta_data.requirements.is_multilayer() { i32::read(read)? } // documentation says u64, but is i32
- else { 0_i32 }, // reference the first header for single-layer images
- "chunk data part number"
- )?;
-
- if layer_number >= meta_data.headers.len() {
- return Err(Error::invalid("chunk data part number"));
- }
-
- let header = &meta_data.headers[layer_number];
- let max_block_byte_size = header.max_block_byte_size();
-
- let chunk = Chunk {
- layer_index: layer_number,
- compressed_block: match header.blocks {
- // flat data
- BlockDescription::ScanLines if !header.deep => CompressedBlock::ScanLine(CompressedScanLineBlock::read(read, max_block_byte_size)?),
- BlockDescription::Tiles(_) if !header.deep => CompressedBlock::Tile(CompressedTileBlock::read(read, max_block_byte_size)?),
-
- // deep data
- BlockDescription::ScanLines => CompressedBlock::DeepScanLine(CompressedDeepScanLineBlock::read(read, max_block_byte_size)?),
- BlockDescription::Tiles(_) => CompressedBlock::DeepTile(CompressedDeepTileBlock::read(read, max_block_byte_size)?),
- },
- };
-
- Ok(chunk)
- }
-}
-