use openexr_sys as sys;
use std::os::raw::{c_char, c_int};
bitflags::bitflags! {
pub struct VersionFlags: i32 {
const TILED = 0x00000200;
const LONG_NAMES = 0x00000400;
const NON_IMAGE = 0x00000800;
const MULTI_PART_FILE = 0x00001000;
const ALL = Self::TILED.bits | Self::LONG_NAMES.bits | Self::NON_IMAGE.bits | Self::MULTI_PART_FILE.bits;
}
}
impl VersionFlags {
pub fn supports_flags(&self) -> bool {
let mut result: bool = false;
unsafe {
sys::Imf_supportsFlags(&mut result, self.bits);
}
result
}
}
#[derive(Debug, Copy, Clone)]
pub struct Version {
inner: c_int,
}
impl Version {
pub fn new(version: i32, flags: VersionFlags) -> Self {
assert!(
(0..=0x000000ff).contains(&version),
"Version must be between 0 and 255"
);
Self {
inner: version | flags.bits,
}
}
pub fn from_c_int(version: c_int) -> Self {
Self { inner: version }
}
pub fn is_tiled(&self) -> bool {
let mut result = false;
unsafe {
sys::Imf_isTiled(&mut result, self.inner);
}
result
}
pub fn is_multi_part(&self) -> bool {
let mut result = false;
unsafe {
sys::Imf_isMultiPart(&mut result, self.inner);
}
result
}
pub fn is_non_image(&self) -> bool {
let mut result = false;
unsafe {
sys::Imf_isNonImage(&mut result, self.inner);
}
result
}
pub fn make_tiled(&self) -> Self {
let mut result: c_int = 0;
unsafe {
sys::Imf_makeTiled(&mut result, self.inner);
}
Self { inner: result }
}
pub fn make_non_tiled(&self) -> Self {
let mut result: c_int = 0;
unsafe {
sys::Imf_makeNotTiled(&mut result, self.inner);
}
Self { inner: result }
}
pub fn version(&self) -> i32 {
let mut result: c_int = 0;
unsafe {
sys::Imf_getVersion(&mut result, self.inner);
}
result
}
pub fn flags(&self) -> VersionFlags {
let mut result: c_int = 0;
unsafe {
sys::Imf_getFlags(&mut result, self.inner);
}
VersionFlags { bits: result }
}
}
pub fn is_imf_magic(bytes: &[c_char; 4]) -> bool {
let mut result: bool = false;
unsafe {
sys::Imf_isImfMagic(&mut result, bytes.as_ptr());
}
result
}
#[cfg(test)]
mod tests {
#[test]
fn test_version_new_success() {
super::Version::new(0, super::VersionFlags { bits: 0 });
super::Version::new(1, super::VersionFlags { bits: 0 });
super::Version::new(255, super::VersionFlags { bits: 0 });
}
#[test]
#[should_panic]
fn test_version_new_failure_version_less_than_0() {
super::Version::new(-1, super::VersionFlags { bits: 0 });
}
#[test]
#[should_panic]
fn test_version_new_failure_version_greater_than_255() {
super::Version::new(256, super::VersionFlags { bits: 0 });
}
#[test]
fn test_is_tiled_true() {
let version = super::Version::new(1, super::VersionFlags::TILED);
let result = version.is_tiled();
assert_eq!(result, true);
}
#[test]
fn test_is_tiled_false() {
let version = super::Version::new(1, super::VersionFlags { bits: 0 });
let result = version.is_tiled();
assert_eq!(result, false);
}
#[test]
fn test_is_multi_part_true() {
let version =
super::Version::new(1, super::VersionFlags::MULTI_PART_FILE);
let result = version.is_multi_part();
assert_eq!(result, true);
}
#[test]
fn test_is_multi_part_false() {
let version = super::Version::new(1, super::VersionFlags { bits: 0 });
let result = version.is_multi_part();
assert_eq!(result, false);
}
#[test]
fn test_is_non_image_true() {
let version = super::Version::new(1, super::VersionFlags::NON_IMAGE);
let result = version.is_non_image();
assert_eq!(result, true);
}
#[test]
fn test_is_non_image_false() {
let version = super::Version::new(1, super::VersionFlags { bits: 0 });
let result = version.is_non_image();
assert_eq!(result, false);
}
#[test]
fn test_make_tiled_success() {
let version = super::Version::new(1, super::VersionFlags { bits: 0 })
.make_tiled();
assert_eq!(version.is_tiled(), true);
}
#[test]
fn test_make_non_tiled_success() {
let version =
super::Version::new(1, super::VersionFlags::TILED).make_non_tiled();
assert_eq!(version.is_tiled(), false);
}
#[test]
fn test_get_version_success() {
#[allow(overflowing_literals)]
let version = super::Version::from_c_int(0xffffffff);
let result = version.version();
assert_eq!(result, 0x000000ff);
}
#[test]
fn test_get_flags_success() {
#[allow(overflowing_literals)]
let version = super::Version::from_c_int(0xffffffff);
let result = version.flags();
#[allow(overflowing_literals)]
let expected = super::VersionFlags { bits: 0xffffff00 };
assert_eq!(result, expected);
}
#[test]
fn test_supports_flags_true() {
let result = super::VersionFlags::ALL.supports_flags();
assert_eq!(result, true);
}
#[test]
fn test_supports_flags_false() {
let result = super::VersionFlags { bits: 0x10000000 }.supports_flags();
assert_eq!(result, false);
}
#[test]
fn test_is_imf_magic_true() {
let result = super::is_imf_magic(&[118, 47, 49, 1]);
assert_eq!(result, true);
}
#[test]
fn test_is_imf_magic_false() {
let result = super::is_imf_magic(&[0, 0, 0, 0]);
assert_eq!(result, false);
}
}