118 lines
2.7 KiB
Rust
118 lines
2.7 KiB
Rust
use crate::core::geometry::{Bounds2i, Point2i};
|
|
use crate::core::pbrt::Float;
|
|
use crate::spectra::colorspace::RGBColorSpace;
|
|
use crate::utils::math::SquareMatrix;
|
|
use smallvec::SmallVec;
|
|
use std::collections::HashMap;
|
|
|
|
use std::ops::{Deref, DerefMut};
|
|
|
|
#[derive(Clone, Debug, Default)]
|
|
pub struct ImageChannelValues(pub SmallVec<[Float; 4]>);
|
|
|
|
impl ImageChannelValues {
|
|
pub fn average(&self) -> Float {
|
|
if self.0.is_empty() {
|
|
return 0.0;
|
|
}
|
|
let sum: Float = self.0.iter().sum();
|
|
sum / (self.0.len() as Float)
|
|
}
|
|
|
|
pub fn max_value(&self) -> Float {
|
|
self.0.iter().fold(Float::MIN, |a, &b| a.max(b))
|
|
}
|
|
}
|
|
|
|
impl From<&[Float]> for ImageChannelValues {
|
|
fn from(slice: &[Float]) -> Self {
|
|
Self(SmallVec::from_slice(slice))
|
|
}
|
|
}
|
|
|
|
impl From<Vec<Float>> for ImageChannelValues {
|
|
fn from(vec: Vec<Float>) -> Self {
|
|
Self(SmallVec::from_vec(vec))
|
|
}
|
|
}
|
|
|
|
impl<const N: usize> From<[Float; N]> for ImageChannelValues {
|
|
fn from(arr: [Float; N]) -> Self {
|
|
Self(SmallVec::from_slice(&arr))
|
|
}
|
|
}
|
|
|
|
impl Deref for ImageChannelValues {
|
|
type Target = SmallVec<[Float; 4]>;
|
|
fn deref(&self) -> &Self::Target {
|
|
&self.0
|
|
}
|
|
}
|
|
|
|
impl DerefMut for ImageChannelValues {
|
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
|
&mut self.0
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
pub enum WrapMode {
|
|
Black,
|
|
Clamp,
|
|
Repeat,
|
|
OctahedralSphere,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
|
pub struct WrapMode2D {
|
|
pub uv: [WrapMode; 2],
|
|
}
|
|
|
|
impl From<WrapMode> for WrapMode2D {
|
|
fn from(w: WrapMode) -> Self {
|
|
Self { uv: [w, w] }
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Default)]
|
|
pub struct ImageChannelDesc {
|
|
pub offset: Vec<usize>,
|
|
}
|
|
|
|
impl ImageChannelDesc {
|
|
pub fn new(offset: &[usize]) -> Self {
|
|
Self {
|
|
offset: offset.into(),
|
|
}
|
|
}
|
|
|
|
pub fn size(&self) -> usize {
|
|
self.offset.len()
|
|
}
|
|
|
|
pub fn is_empty(&self) -> bool {
|
|
self.offset.is_empty()
|
|
}
|
|
pub fn is_identity(&self) -> bool {
|
|
for i in 0..self.size() {
|
|
if self.offset[i] != i {
|
|
return false;
|
|
}
|
|
}
|
|
true
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Default)]
|
|
pub struct ImageMetadata {
|
|
pub render_time_seconds: Option<Float>,
|
|
pub camera_from_world: Option<SquareMatrix<Float, 4>>,
|
|
pub ndc_from_world: Option<SquareMatrix<Float, 4>>,
|
|
pub pixel_bounds: Option<Bounds2i>,
|
|
pub full_resolution: Option<Point2i>,
|
|
pub samples_per_pixel: Option<i32>,
|
|
pub mse: Option<Float>,
|
|
pub colorspace: Option<RGBColorSpace>,
|
|
pub strings: HashMap<String, String>,
|
|
pub string_vectors: HashMap<String, Vec<String>>,
|
|
}
|