aboutsummaryrefslogtreecommitdiff
path: root/vendor/exr/src/block/samples.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/exr/src/block/samples.rs')
-rw-r--r--vendor/exr/src/block/samples.rs248
1 files changed, 0 insertions, 248 deletions
diff --git a/vendor/exr/src/block/samples.rs b/vendor/exr/src/block/samples.rs
deleted file mode 100644
index 4352b11..0000000
--- a/vendor/exr/src/block/samples.rs
+++ /dev/null
@@ -1,248 +0,0 @@
-//! Extract pixel samples from a block of pixel bytes.
-
-use crate::prelude::*;
-use half::prelude::HalfFloatSliceExt;
-
-
-/// A single red, green, blue, or alpha value.
-#[derive(Copy, Clone, Debug)]
-pub enum Sample {
-
- /// A 16-bit float sample.
- F16(f16),
-
- /// A 32-bit float sample.
- F32(f32),
-
- /// An unsigned integer sample.
- U32(u32)
-}
-
-impl Sample {
-
- /// Create a sample containing a 32-bit float.
- pub fn f32(f32: f32) -> Self { Sample::F32(f32) }
-
- /// Create a sample containing a 16-bit float.
- pub fn f16(f16: f16) -> Self { Sample::F16(f16) }
-
- /// Create a sample containing a 32-bit integer.
- pub fn u32(u32: u32) -> Self { Sample::U32(u32) }
-
- /// Convert the sample to an f16 value. This has lower precision than f32.
- /// Note: An f32 can only represent integers up to `1024` as precise as a u32 could.
- #[inline]
- pub fn to_f16(self) -> f16 {
- match self {
- Sample::F16(sample) => sample,
- Sample::F32(sample) => f16::from_f32(sample),
- Sample::U32(sample) => f16::from_f32(sample as f32),
- }
- }
-
- /// Convert the sample to an f32 value.
- /// Note: An f32 can only represent integers up to `8388608` as precise as a u32 could.
- #[inline]
- pub fn to_f32(self) -> f32 {
- match self {
- Sample::F32(sample) => sample,
- Sample::F16(sample) => sample.to_f32(),
- Sample::U32(sample) => sample as f32,
- }
- }
-
- /// Convert the sample to a u32. Rounds floats to integers the same way that `3.1 as u32` does.
- #[inline]
- pub fn to_u32(self) -> u32 {
- match self {
- Sample::F16(sample) => sample.to_f32() as u32,
- Sample::F32(sample) => sample as u32,
- Sample::U32(sample) => sample,
- }
- }
-
- /// Is this value not a number?
- #[inline]
- pub fn is_nan(self) -> bool {
- match self {
- Sample::F16(value) => value.is_nan(),
- Sample::F32(value) => value.is_nan(),
- Sample::U32(_) => false,
- }
- }
-
- /// Is this value zero or negative zero?
- #[inline]
- pub fn is_zero(&self) -> bool {
- match *self {
- Sample::F16(value) => value == f16::ZERO || value == f16::NEG_ZERO,
- Sample::F32(value) => value == 0.0,
- Sample::U32(value) => value == 0,
- }
- }
-}
-
-impl PartialEq for Sample {
- fn eq(&self, other: &Self) -> bool {
- match *self {
- Sample::F16(num) => num == other.to_f16(),
- Sample::F32(num) => num == other.to_f32(),
- Sample::U32(num) => num == other.to_u32(),
- }
- }
-}
-
-// this is not recommended because it may hide whether a color is transparent or opaque and might be undesired for depth channels
-impl Default for Sample {
- fn default() -> Self { Sample::F32(0.0) }
-}
-
-impl From<f16> for Sample { #[inline] fn from(f: f16) -> Self { Sample::F16(f) } }
-impl From<f32> for Sample { #[inline] fn from(f: f32) -> Self { Sample::F32(f) } }
-impl From<u32> for Sample { #[inline] fn from(f: u32) -> Self { Sample::U32(f) } }
-
-impl<T> From<Option<T>> for Sample where T: Into<Sample> + Default {
- #[inline] fn from(num: Option<T>) -> Self { num.unwrap_or_default().into() }
-}
-
-
-impl From<Sample> for f16 { #[inline] fn from(s: Sample) -> Self { s.to_f16() } }
-impl From<Sample> for f32 { #[inline] fn from(s: Sample) -> Self { s.to_f32() } }
-impl From<Sample> for u32 { #[inline] fn from(s: Sample) -> Self { s.to_u32() } }
-
-
-/// Create an arbitrary sample type from one of the defined sample types.
-/// Should be compiled to a no-op where the file contains the predicted sample type.
-/// The slice functions should be optimized into a `memcpy` where there is no conversion needed.
-pub trait FromNativeSample: Sized + Copy + Default + 'static {
-
- /// Create this sample from a f16, trying to represent the same numerical value
- fn from_f16(value: f16) -> Self;
-
- /// Create this sample from a f32, trying to represent the same numerical value
- fn from_f32(value: f32) -> Self;
-
- /// Create this sample from a u32, trying to represent the same numerical value
- fn from_u32(value: u32) -> Self;
-
- /// Convert all values from the slice into this type.
- /// This function exists to allow the compiler to perform a vectorization optimization.
- /// Note that this default implementation will **not** be vectorized by the compiler automatically.
- /// For maximum performance you will need to override this function and implement it via
- /// an explicit batched conversion such as [`convert_to_f32_slice`](https://docs.rs/half/2.3.1/half/slice/trait.HalfFloatSliceExt.html#tymethod.convert_to_f32_slice)
- #[inline]
- fn from_f16s(from: &[f16], to: &mut [Self]) {
- assert_eq!(from.len(), to.len(), "slices must have the same length");
- for (from, to) in from.iter().zip(to.iter_mut()) {
- *to = Self::from_f16(*from);
- }
- }
-
- /// Convert all values from the slice into this type.
- /// This function exists to allow the compiler to perform a vectorization optimization.
- /// Note that this default implementation will be vectorized by the compiler automatically.
- #[inline]
- fn from_f32s(from: &[f32], to: &mut [Self]) {
- assert_eq!(from.len(), to.len(), "slices must have the same length");
- for (from, to) in from.iter().zip(to.iter_mut()) {
- *to = Self::from_f32(*from);
- }
- }
-
- /// Convert all values from the slice into this type.
- /// This function exists to allow the compiler to perform a vectorization optimization.
- /// Note that this default implementation will be vectorized by the compiler automatically,
- /// provided that the CPU supports the necessary conversion instructions.
- /// For example, x86_64 lacks the instructions to convert `u32` to floats,
- /// so this will inevitably be slow on x86_64.
- #[inline]
- fn from_u32s(from: &[u32], to: &mut [Self]) {
- assert_eq!(from.len(), to.len(), "slices must have the same length");
- for (from, to) in from.iter().zip(to.iter_mut()) {
- *to = Self::from_u32(*from);
- }
- }
-}
-
-// TODO haven't i implemented this exact behaviour already somewhere else in this library...??
-impl FromNativeSample for f32 {
- #[inline] fn from_f16(value: f16) -> Self { value.to_f32() }
- #[inline] fn from_f32(value: f32) -> Self { value }
- #[inline] fn from_u32(value: u32) -> Self { value as f32 }
-
- // f16 is a custom type
- // so the compiler can not automatically vectorize the conversion
- // that's why we need to specialize this function
- #[inline]
- fn from_f16s(from: &[f16], to: &mut [Self]) {
- from.convert_to_f32_slice(to);
- }
-}
-
-impl FromNativeSample for u32 {
- #[inline] fn from_f16(value: f16) -> Self { value.to_f32() as u32 }
- #[inline] fn from_f32(value: f32) -> Self { value as u32 }
- #[inline] fn from_u32(value: u32) -> Self { value }
-}
-
-impl FromNativeSample for f16 {
- #[inline] fn from_f16(value: f16) -> Self { value }
- #[inline] fn from_f32(value: f32) -> Self { f16::from_f32(value) }
- #[inline] fn from_u32(value: u32) -> Self { f16::from_f32(value as f32) }
-
- // f16 is a custom type
- // so the compiler can not automatically vectorize the conversion
- // that's why we need to specialize this function
- #[inline]
- fn from_f32s(from: &[f32], to: &mut [Self]) {
- to.convert_from_f32_slice(from)
- }
-}
-
-impl FromNativeSample for Sample {
- #[inline] fn from_f16(value: f16) -> Self { Self::from(value) }
- #[inline] fn from_f32(value: f32) -> Self { Self::from(value) }
- #[inline] fn from_u32(value: u32) -> Self { Self::from(value) }
-}
-
-
-/// Convert any type into one of the supported sample types.
-/// Should be compiled to a no-op where the file contains the predicted sample type
-pub trait IntoNativeSample: Copy + Default + Sync + 'static {
-
- /// Convert this sample to an f16, trying to represent the same numerical value.
- fn to_f16(&self) -> f16;
-
- /// Convert this sample to an f32, trying to represent the same numerical value.
- fn to_f32(&self) -> f32;
-
- /// Convert this sample to an u16, trying to represent the same numerical value.
- fn to_u32(&self) -> u32;
-}
-
-impl IntoNativeSample for f16 {
- fn to_f16(&self) -> f16 { f16::from_f16(*self) }
- fn to_f32(&self) -> f32 { f32::from_f16(*self) }
- fn to_u32(&self) -> u32 { u32::from_f16(*self) }
-}
-
-impl IntoNativeSample for f32 {
- fn to_f16(&self) -> f16 { f16::from_f32(*self) }
- fn to_f32(&self) -> f32 { f32::from_f32(*self) }
- fn to_u32(&self) -> u32 { u32::from_f32(*self) }
-}
-
-impl IntoNativeSample for u32 {
- fn to_f16(&self) -> f16 { f16::from_u32(*self) }
- fn to_f32(&self) -> f32 { f32::from_u32(*self) }
- fn to_u32(&self) -> u32 { u32::from_u32(*self) }
-}
-
-impl IntoNativeSample for Sample {
- fn to_f16(&self) -> f16 { Sample::to_f16(*self) }
- fn to_f32(&self) -> f32 { Sample::to_f32(*self) }
- fn to_u32(&self) -> u32 { Sample::to_u32(*self) }
-}
-
-
-