From a990de90fe41456a23e58bd087d2f107d321f3a1 Mon Sep 17 00:00:00 2001
From: Valentin Popov <valentin@popov.link>
Date: Fri, 19 Jul 2024 16:37:58 +0400
Subject: Deleted vendor folder

---
 vendor/image/src/codecs/openexr.rs | 592 -------------------------------------
 1 file changed, 592 deletions(-)
 delete mode 100644 vendor/image/src/codecs/openexr.rs

(limited to 'vendor/image/src/codecs/openexr.rs')

diff --git a/vendor/image/src/codecs/openexr.rs b/vendor/image/src/codecs/openexr.rs
deleted file mode 100644
index 52d6ba9..0000000
--- a/vendor/image/src/codecs/openexr.rs
+++ /dev/null
@@ -1,592 +0,0 @@
-//! Decoding of OpenEXR (.exr) Images
-//!
-//! OpenEXR is an image format that is widely used, especially in VFX,
-//! because it supports lossless and lossy compression for float data.
-//!
-//! This decoder only supports RGB and RGBA images.
-//! If an image does not contain alpha information,
-//! it is defaulted to `1.0` (no transparency).
-//!
-//! # Related Links
-//! * <https://www.openexr.com/documentation.html> - The OpenEXR reference.
-//!
-//!
-//! Current limitations (July 2021):
-//!     - only pixel type `Rgba32F` and `Rgba16F` are supported
-//!     - only non-deep rgb/rgba files supported, no conversion from/to YCbCr or similar
-//!     - only the first non-deep rgb layer is used
-//!     - only the largest mip map level is used
-//!     - pixels outside display window are lost
-//!     - meta data is lost
-//!     - dwaa/dwab compressed images not supported yet by the exr library
-//!     - (chroma) subsampling not supported yet by the exr library
-use exr::prelude::*;
-
-use crate::error::{DecodingError, EncodingError, ImageFormatHint};
-use crate::image::decoder_to_vec;
-use crate::{
-    ColorType, ExtendedColorType, ImageDecoder, ImageEncoder, ImageError, ImageFormat, ImageResult,
-    Progress,
-};
-use std::convert::TryInto;
-use std::io::{Cursor, Read, Seek, Write};
-
-/// An OpenEXR decoder. Immediately reads the meta data from the file.
-#[derive(Debug)]
-pub struct OpenExrDecoder<R> {
-    exr_reader: exr::block::reader::Reader<R>,
-
-    // select a header that is rgb and not deep
-    header_index: usize,
-
-    // decode either rgb or rgba.
-    // can be specified to include or discard alpha channels.
-    // if none, the alpha channel will only be allocated where the file contains data for it.
-    alpha_preference: Option<bool>,
-
-    alpha_present_in_file: bool,
-}
-
-impl<R: Read + Seek> OpenExrDecoder<R> {
-    /// Create a decoder. Consumes the first few bytes of the source to extract image dimensions.
-    /// Assumes the reader is buffered. In most cases,
-    /// you should wrap your reader in a `BufReader` for best performance.
-    /// Loads an alpha channel if the file has alpha samples.
-    /// Use `with_alpha_preference` if you want to load or not load alpha unconditionally.
-    pub fn new(source: R) -> ImageResult<Self> {
-        Self::with_alpha_preference(source, None)
-    }
-
-    /// Create a decoder. Consumes the first few bytes of the source to extract image dimensions.
-    /// Assumes the reader is buffered. In most cases,
-    /// you should wrap your reader in a `BufReader` for best performance.
-    /// If alpha preference is specified, an alpha channel will
-    /// always be present or always be not present in the returned image.
-    /// If alpha preference is none, the alpha channel will only be returned if it is found in the file.
-    pub fn with_alpha_preference(source: R, alpha_preference: Option<bool>) -> ImageResult<Self> {
-        // read meta data, then wait for further instructions, keeping the file open and ready
-        let exr_reader = exr::block::read(source, false).map_err(to_image_err)?;
-
-        let header_index = exr_reader
-            .headers()
-            .iter()
-            .position(|header| {
-                // check if r/g/b exists in the channels
-                let has_rgb = ["R", "G", "B"]
-                    .iter()
-                    .all(|&required|  // alpha will be optional
-                    header.channels.find_index_of_channel(&Text::from(required)).is_some());
-
-                // we currently dont support deep images, or images with other color spaces than rgb
-                !header.deep && has_rgb
-            })
-            .ok_or_else(|| {
-                ImageError::Decoding(DecodingError::new(
-                    ImageFormatHint::Exact(ImageFormat::OpenExr),
-                    "image does not contain non-deep rgb channels",
-                ))
-            })?;
-
-        let has_alpha = exr_reader.headers()[header_index]
-            .channels
-            .find_index_of_channel(&Text::from("A"))
-            .is_some();
-
-        Ok(Self {
-            alpha_preference,
-            exr_reader,
-            header_index,
-            alpha_present_in_file: has_alpha,
-        })
-    }
-
-    // does not leak exrs-specific meta data into public api, just does it for this module
-    fn selected_exr_header(&self) -> &exr::meta::header::Header {
-        &self.exr_reader.meta_data().headers[self.header_index]
-    }
-}
-
-impl<'a, R: 'a + Read + Seek> ImageDecoder<'a> for OpenExrDecoder<R> {
-    type Reader = Cursor<Vec<u8>>;
-
-    fn dimensions(&self) -> (u32, u32) {
-        let size = self
-            .selected_exr_header()
-            .shared_attributes
-            .display_window
-            .size;
-        (size.width() as u32, size.height() as u32)
-    }
-
-    fn color_type(&self) -> ColorType {
-        let returns_alpha = self.alpha_preference.unwrap_or(self.alpha_present_in_file);
-        if returns_alpha {
-            ColorType::Rgba32F
-        } else {
-            ColorType::Rgb32F
-        }
-    }
-
-    fn original_color_type(&self) -> ExtendedColorType {
-        if self.alpha_present_in_file {
-            ExtendedColorType::Rgba32F
-        } else {
-            ExtendedColorType::Rgb32F
-        }
-    }
-
-    /// Use `read_image` instead if possible,
-    /// as this method creates a whole new buffer just to contain the entire image.
-    fn into_reader(self) -> ImageResult<Self::Reader> {
-        Ok(Cursor::new(decoder_to_vec(self)?))
-    }
-
-    fn scanline_bytes(&self) -> u64 {
-        // we cannot always read individual scan lines for every file,
-        // as the tiles or lines in the file could be in random or reversed order.
-        // therefore we currently read all lines at once
-        // Todo: optimize for specific exr.line_order?
-        self.total_bytes()
-    }
-
-    // reads with or without alpha, depending on `self.alpha_preference` and `self.alpha_present_in_file`
-    fn read_image_with_progress<F: Fn(Progress)>(
-        self,
-        unaligned_bytes: &mut [u8],
-        progress_callback: F,
-    ) -> ImageResult<()> {
-        let blocks_in_header = self.selected_exr_header().chunk_count as u64;
-        let channel_count = self.color_type().channel_count() as usize;
-
-        let display_window = self.selected_exr_header().shared_attributes.display_window;
-        let data_window_offset =
-            self.selected_exr_header().own_attributes.layer_position - display_window.position;
-
-        {
-            // check whether the buffer is large enough for the dimensions of the file
-            let (width, height) = self.dimensions();
-            let bytes_per_pixel = self.color_type().bytes_per_pixel() as usize;
-            let expected_byte_count = (width as usize)
-                .checked_mul(height as usize)
-                .and_then(|size| size.checked_mul(bytes_per_pixel));
-
-            // if the width and height does not match the length of the bytes, the arguments are invalid
-            let has_invalid_size_or_overflowed = expected_byte_count
-                .map(|expected_byte_count| unaligned_bytes.len() != expected_byte_count)
-                // otherwise, size calculation overflowed, is bigger than memory,
-                // therefore data is too small, so it is invalid.
-                .unwrap_or(true);
-
-            if has_invalid_size_or_overflowed {
-                panic!("byte buffer not large enough for the specified dimensions and f32 pixels");
-            }
-        }
-
-        let result = read()
-            .no_deep_data()
-            .largest_resolution_level()
-            .rgba_channels(
-                move |_size, _channels| vec![0_f32; display_window.size.area() * channel_count],
-                move |buffer, index_in_data_window, (r, g, b, a_or_1): (f32, f32, f32, f32)| {
-                    let index_in_display_window =
-                        index_in_data_window.to_i32() + data_window_offset;
-
-                    // only keep pixels inside the data window
-                    // TODO filter chunks based on this
-                    if index_in_display_window.x() >= 0
-                        && index_in_display_window.y() >= 0
-                        && index_in_display_window.x() < display_window.size.width() as i32
-                        && index_in_display_window.y() < display_window.size.height() as i32
-                    {
-                        let index_in_display_window =
-                            index_in_display_window.to_usize("index bug").unwrap();
-                        let first_f32_index =
-                            index_in_display_window.flat_index_for_size(display_window.size);
-
-                        buffer[first_f32_index * channel_count
-                            ..(first_f32_index + 1) * channel_count]
-                            .copy_from_slice(&[r, g, b, a_or_1][0..channel_count]);
-
-                        // TODO white point chromaticities + srgb/linear conversion?
-                    }
-                },
-            )
-            .first_valid_layer() // TODO select exact layer by self.header_index?
-            .all_attributes()
-            .on_progress(|progress| {
-                progress_callback(
-                    Progress::new(
-                        (progress * blocks_in_header as f64) as u64,
-                        blocks_in_header,
-                    ), // TODO precision errors?
-                );
-            })
-            .from_chunks(self.exr_reader)
-            .map_err(to_image_err)?;
-
-        // TODO this copy is strictly not necessary, but the exr api is a little too simple for reading into a borrowed target slice
-
-        // this cast is safe and works with any alignment, as bytes are copied, and not f32 values.
-        // note: buffer slice length is checked in the beginning of this function and will be correct at this point
-        unaligned_bytes.copy_from_slice(bytemuck::cast_slice(
-            result.layer_data.channel_data.pixels.as_slice(),
-        ));
-        Ok(())
-    }
-}
-
-/// Write a raw byte buffer of pixels,
-/// returning an Error if it has an invalid length.
-///
-/// Assumes the writer is buffered. In most cases,
-/// you should wrap your writer in a `BufWriter` for best performance.
-// private. access via `OpenExrEncoder`
-fn write_buffer(
-    mut buffered_write: impl Write + Seek,
-    unaligned_bytes: &[u8],
-    width: u32,
-    height: u32,
-    color_type: ColorType,
-) -> ImageResult<()> {
-    let width = width as usize;
-    let height = height as usize;
-
-    {
-        // check whether the buffer is large enough for the specified dimensions
-        let expected_byte_count = width
-            .checked_mul(height)
-            .and_then(|size| size.checked_mul(color_type.bytes_per_pixel() as usize));
-
-        // if the width and height does not match the length of the bytes, the arguments are invalid
-        let has_invalid_size_or_overflowed = expected_byte_count
-            .map(|expected_byte_count| unaligned_bytes.len() < expected_byte_count)
-            // otherwise, size calculation overflowed, is bigger than memory,
-            // therefore data is too small, so it is invalid.
-            .unwrap_or(true);
-
-        if has_invalid_size_or_overflowed {
-            return Err(ImageError::Encoding(EncodingError::new(
-                ImageFormatHint::Exact(ImageFormat::OpenExr),
-                "byte buffer not large enough for the specified dimensions and f32 pixels",
-            )));
-        }
-    }
-
-    // bytes might be unaligned so we cannot cast the whole thing, instead lookup each f32 individually
-    let lookup_f32 = move |f32_index: usize| {
-        let unaligned_f32_bytes_slice = &unaligned_bytes[f32_index * 4..(f32_index + 1) * 4];
-        let f32_bytes_array = unaligned_f32_bytes_slice
-            .try_into()
-            .expect("indexing error");
-        f32::from_ne_bytes(f32_bytes_array)
-    };
-
-    match color_type {
-        ColorType::Rgb32F => {
-            exr::prelude::Image // TODO compression method zip??
-                ::from_channels(
-                (width, height),
-                SpecificChannels::rgb(|pixel: Vec2<usize>| {
-                    let pixel_index = 3 * pixel.flat_index_for_size(Vec2(width, height));
-                    (
-                        lookup_f32(pixel_index),
-                        lookup_f32(pixel_index + 1),
-                        lookup_f32(pixel_index + 2),
-                    )
-                }),
-            )
-            .write()
-            // .on_progress(|progress| todo!())
-            .to_buffered(&mut buffered_write)
-            .map_err(to_image_err)?;
-        }
-
-        ColorType::Rgba32F => {
-            exr::prelude::Image // TODO compression method zip??
-                ::from_channels(
-                (width, height),
-                SpecificChannels::rgba(|pixel: Vec2<usize>| {
-                    let pixel_index = 4 * pixel.flat_index_for_size(Vec2(width, height));
-                    (
-                        lookup_f32(pixel_index),
-                        lookup_f32(pixel_index + 1),
-                        lookup_f32(pixel_index + 2),
-                        lookup_f32(pixel_index + 3),
-                    )
-                }),
-            )
-            .write()
-            // .on_progress(|progress| todo!())
-            .to_buffered(&mut buffered_write)
-            .map_err(to_image_err)?;
-        }
-
-        // TODO other color types and channel types
-        unsupported_color_type => {
-            return Err(ImageError::Encoding(EncodingError::new(
-                ImageFormatHint::Exact(ImageFormat::OpenExr),
-                format!(
-                    "writing color type {:?} not yet supported",
-                    unsupported_color_type
-                ),
-            )))
-        }
-    }
-
-    Ok(())
-}
-
-// TODO is this struct and trait actually used anywhere?
-/// A thin wrapper that implements `ImageEncoder` for OpenEXR images. Will behave like `image::codecs::openexr::write_buffer`.
-#[derive(Debug)]
-pub struct OpenExrEncoder<W>(W);
-
-impl<W> OpenExrEncoder<W> {
-    /// Create an `ImageEncoder`. Does not write anything yet. Writing later will behave like `image::codecs::openexr::write_buffer`.
-    // use constructor, not public field, for future backwards-compatibility
-    pub fn new(write: W) -> Self {
-        Self(write)
-    }
-}
-
-impl<W> ImageEncoder for OpenExrEncoder<W>
-where
-    W: Write + Seek,
-{
-    /// Writes the complete image.
-    ///
-    /// Returns an Error if it has an invalid length.
-    /// Assumes the writer is buffered. In most cases,
-    /// you should wrap your writer in a `BufWriter` for best performance.
-    fn write_image(
-        self,
-        buf: &[u8],
-        width: u32,
-        height: u32,
-        color_type: ColorType,
-    ) -> ImageResult<()> {
-        write_buffer(self.0, buf, width, height, color_type)
-    }
-}
-
-fn to_image_err(exr_error: Error) -> ImageError {
-    ImageError::Decoding(DecodingError::new(
-        ImageFormatHint::Exact(ImageFormat::OpenExr),
-        exr_error.to_string(),
-    ))
-}
-
-#[cfg(test)]
-mod test {
-    use super::*;
-
-    use std::io::BufReader;
-    use std::path::{Path, PathBuf};
-
-    use crate::buffer_::{Rgb32FImage, Rgba32FImage};
-    use crate::error::{LimitError, LimitErrorKind};
-    use crate::{ImageBuffer, Rgb, Rgba};
-
-    const BASE_PATH: &[&str] = &[".", "tests", "images", "exr"];
-
-    /// Write an `Rgb32FImage`.
-    /// Assumes the writer is buffered. In most cases,
-    /// you should wrap your writer in a `BufWriter` for best performance.
-    fn write_rgb_image(write: impl Write + Seek, image: &Rgb32FImage) -> ImageResult<()> {
-        write_buffer(
-            write,
-            bytemuck::cast_slice(image.as_raw().as_slice()),
-            image.width(),
-            image.height(),
-            ColorType::Rgb32F,
-        )
-    }
-
-    /// Write an `Rgba32FImage`.
-    /// Assumes the writer is buffered. In most cases,
-    /// you should wrap your writer in a `BufWriter` for best performance.
-    fn write_rgba_image(write: impl Write + Seek, image: &Rgba32FImage) -> ImageResult<()> {
-        write_buffer(
-            write,
-            bytemuck::cast_slice(image.as_raw().as_slice()),
-            image.width(),
-            image.height(),
-            ColorType::Rgba32F,
-        )
-    }
-
-    /// Read the file from the specified path into an `Rgba32FImage`.
-    fn read_as_rgba_image_from_file(path: impl AsRef<Path>) -> ImageResult<Rgba32FImage> {
-        read_as_rgba_image(BufReader::new(std::fs::File::open(path)?))
-    }
-
-    /// Read the file from the specified path into an `Rgb32FImage`.
-    fn read_as_rgb_image_from_file(path: impl AsRef<Path>) -> ImageResult<Rgb32FImage> {
-        read_as_rgb_image(BufReader::new(std::fs::File::open(path)?))
-    }
-
-    /// Read the file from the specified path into an `Rgb32FImage`.
-    fn read_as_rgb_image(read: impl Read + Seek) -> ImageResult<Rgb32FImage> {
-        let decoder = OpenExrDecoder::with_alpha_preference(read, Some(false))?;
-        let (width, height) = decoder.dimensions();
-        let buffer: Vec<f32> = decoder_to_vec(decoder)?;
-
-        ImageBuffer::from_raw(width, height, buffer)
-            // this should be the only reason for the "from raw" call to fail,
-            // even though such a large allocation would probably cause an error much earlier
-            .ok_or_else(|| {
-                ImageError::Limits(LimitError::from_kind(LimitErrorKind::InsufficientMemory))
-            })
-    }
-
-    /// Read the file from the specified path into an `Rgba32FImage`.
-    fn read_as_rgba_image(read: impl Read + Seek) -> ImageResult<Rgba32FImage> {
-        let decoder = OpenExrDecoder::with_alpha_preference(read, Some(true))?;
-        let (width, height) = decoder.dimensions();
-        let buffer: Vec<f32> = decoder_to_vec(decoder)?;
-
-        ImageBuffer::from_raw(width, height, buffer)
-            // this should be the only reason for the "from raw" call to fail,
-            // even though such a large allocation would probably cause an error much earlier
-            .ok_or_else(|| {
-                ImageError::Limits(LimitError::from_kind(LimitErrorKind::InsufficientMemory))
-            })
-    }
-
-    #[test]
-    fn compare_exr_hdr() {
-        if cfg!(not(feature = "hdr")) {
-            eprintln!("warning: to run all the openexr tests, activate the hdr feature flag");
-        }
-
-        #[cfg(feature = "hdr")]
-        {
-            let folder = BASE_PATH.iter().collect::<PathBuf>();
-            let reference_path = folder.clone().join("overexposed gradient.hdr");
-            let exr_path = folder
-                .clone()
-                .join("overexposed gradient - data window equals display window.exr");
-
-            let hdr: Vec<Rgb<f32>> = crate::codecs::hdr::HdrDecoder::new(std::io::BufReader::new(
-                std::fs::File::open(&reference_path).unwrap(),
-            ))
-            .unwrap()
-            .read_image_hdr()
-            .unwrap();
-
-            let exr_pixels: Rgb32FImage = read_as_rgb_image_from_file(exr_path).unwrap();
-            assert_eq!(
-                exr_pixels.dimensions().0 * exr_pixels.dimensions().1,
-                hdr.len() as u32
-            );
-
-            for (expected, found) in hdr.iter().zip(exr_pixels.pixels()) {
-                for (expected, found) in expected.0.iter().zip(found.0.iter()) {
-                    // the large tolerance seems to be caused by
-                    // the RGBE u8x4 pixel quantization of the hdr image format
-                    assert!(
-                        (expected - found).abs() < 0.1,
-                        "expected {}, found {}",
-                        expected,
-                        found
-                    );
-                }
-            }
-        }
-    }
-
-    #[test]
-    fn roundtrip_rgba() {
-        let mut next_random = vec![1.0, 0.0, -1.0, -3.14, 27.0, 11.0, 31.0]
-            .into_iter()
-            .cycle();
-        let mut next_random = move || next_random.next().unwrap();
-
-        let generated_image: Rgba32FImage = ImageBuffer::from_fn(9, 31, |_x, _y| {
-            Rgba([next_random(), next_random(), next_random(), next_random()])
-        });
-
-        let mut bytes = vec![];
-        write_rgba_image(Cursor::new(&mut bytes), &generated_image).unwrap();
-        let decoded_image = read_as_rgba_image(Cursor::new(bytes)).unwrap();
-
-        debug_assert_eq!(generated_image, decoded_image);
-    }
-
-    #[test]
-    fn roundtrip_rgb() {
-        let mut next_random = vec![1.0, 0.0, -1.0, -3.14, 27.0, 11.0, 31.0]
-            .into_iter()
-            .cycle();
-        let mut next_random = move || next_random.next().unwrap();
-
-        let generated_image: Rgb32FImage = ImageBuffer::from_fn(9, 31, |_x, _y| {
-            Rgb([next_random(), next_random(), next_random()])
-        });
-
-        let mut bytes = vec![];
-        write_rgb_image(Cursor::new(&mut bytes), &generated_image).unwrap();
-        let decoded_image = read_as_rgb_image(Cursor::new(bytes)).unwrap();
-
-        debug_assert_eq!(generated_image, decoded_image);
-    }
-
-    #[test]
-    fn compare_rgba_rgb() {
-        let exr_path = BASE_PATH
-            .iter()
-            .collect::<PathBuf>()
-            .join("overexposed gradient - data window equals display window.exr");
-
-        let rgb: Rgb32FImage = read_as_rgb_image_from_file(&exr_path).unwrap();
-        let rgba: Rgba32FImage = read_as_rgba_image_from_file(&exr_path).unwrap();
-
-        assert_eq!(rgba.dimensions(), rgb.dimensions());
-
-        for (Rgb(rgb), Rgba(rgba)) in rgb.pixels().zip(rgba.pixels()) {
-            assert_eq!(rgb, &rgba[..3]);
-        }
-    }
-
-    #[test]
-    fn compare_cropped() {
-        // like in photoshop, exr images may have layers placed anywhere in a canvas.
-        // we don't want to load the pixels from the layer, but we want to load the pixels from the canvas.
-        // a layer might be smaller than the canvas, in that case the canvas should be transparent black
-        // where no layer was covering it. a layer might also be larger than the canvas,
-        // these pixels should be discarded.
-        //
-        // in this test we want to make sure that an
-        // auto-cropped image will be reproduced to the original.
-
-        let exr_path = BASE_PATH.iter().collect::<PathBuf>();
-        let original = exr_path.clone().join("cropping - uncropped original.exr");
-        let cropped = exr_path
-            .clone()
-            .join("cropping - data window differs display window.exr");
-
-        // smoke-check that the exr files are actually not the same
-        {
-            let original_exr = read_first_flat_layer_from_file(&original).unwrap();
-            let cropped_exr = read_first_flat_layer_from_file(&cropped).unwrap();
-            assert_eq!(
-                original_exr.attributes.display_window,
-                cropped_exr.attributes.display_window
-            );
-            assert_ne!(
-                original_exr.layer_data.attributes.layer_position,
-                cropped_exr.layer_data.attributes.layer_position
-            );
-            assert_ne!(original_exr.layer_data.size, cropped_exr.layer_data.size);
-        }
-
-        // check that they result in the same image
-        let original: Rgba32FImage = read_as_rgba_image_from_file(&original).unwrap();
-        let cropped: Rgba32FImage = read_as_rgba_image_from_file(&cropped).unwrap();
-        assert_eq!(original.dimensions(), cropped.dimensions());
-
-        // the following is not a simple assert_eq, as in case of an error,
-        // the whole image would be printed to the console, which takes forever
-        assert!(original.pixels().zip(cropped.pixels()).all(|(a, b)| a == b));
-    }
-}
-- 
cgit v1.2.3