use crate::*;
use ae_sys::*;
define_suite!(
ChannelSuite,
PF_ChannelSuite1,
kPFChannelSuite1,
kPFChannelSuiteVersion1
);
impl ChannelSuite {
pub fn new() -> Result<Self, Error> {
crate::Suite::new()
}
pub fn layer_channel_count(&self, effect_ref: impl AsPtr<PF_ProgPtr>, param_index: i32) -> Result<i32, Error> {
Ok(call_suite_fn_single!(self, PF_GetLayerChannelCount -> ae_sys::A_long, effect_ref.as_ptr(), param_index)? as _)
}
pub fn layer_channel_indexed_ref_and_desc(&self, effect_ref: impl AsPtr<PF_ProgPtr>, param_index: i32, channel_index: i32) -> Result<Option<(PF_ChannelRef, PF_ChannelDesc)>, Error> {
let mut found: PF_Boolean = 0;
let mut channel_ref = unsafe { std::mem::zeroed() };
let mut channel_desc = unsafe { std::mem::zeroed() };
call_suite_fn!(self, PF_GetLayerChannelIndexedRefAndDesc, effect_ref.as_ptr(), param_index, channel_index, &mut found, &mut channel_ref, &mut channel_desc)?;
if found == 1 {
Ok(Some((channel_ref, channel_desc)))
} else {
Ok(None)
}
}
pub fn layer_channel_typed_ref_and_desc(&self, effect_ref: impl AsPtr<PF_ProgPtr>, param_index: i32, channel_type: ChannelType) -> Result<Option<(PF_ChannelRef, PF_ChannelDesc)>, Error> {
let mut found: PF_Boolean = 0;
let mut channel_ref = unsafe { std::mem::zeroed() };
let mut channel_desc = unsafe { std::mem::zeroed() };
call_suite_fn!(self, PF_GetLayerChannelTypedRefAndDesc, effect_ref.as_ptr(), param_index, channel_type.into(), &mut found, &mut channel_ref, &mut channel_desc)?;
if found == 1 {
Ok(Some((channel_ref, channel_desc)))
} else {
Ok(None)
}
}
pub fn checkout_layer_channel(&self, effect_ref: impl AsPtr<PF_ProgPtr>, channel_ref: &PF_ChannelRef, what_time: i32, duration: i32, time_scale: u32, data_type: DataType) -> Result<ChannelChunk, Error> {
Ok(ChannelChunk(call_suite_fn_single!(self, PF_CheckoutLayerChannel -> PF_ChannelChunk, effect_ref.as_ptr(), channel_ref as *const _ as _, what_time, duration, time_scale, data_type.into())?))
}
pub fn checkin_layer_channel(&self, effect_ref: impl AsPtr<PF_ProgPtr>, channel_ref: &PF_ChannelRef, channel_chunk: &ChannelChunk) -> Result<(), Error> {
call_suite_fn!(self, PF_CheckinLayerChannel, effect_ref.as_ptr(), channel_ref as *const _ as _, channel_chunk as *const _ as _)
}
}
define_enum! {
ae_sys::PF_ChannelType,
ChannelType {
Depth = PF_CHANNELTYPE_DEPTH,
DepthAA = PF_CHANNELTYPE_DEPTHAA,
Normals = PF_CHANNELTYPE_NORMALS,
ObjectID = PF_CHANNELTYPE_OBJECTID,
MotionVector = PF_CHANNELTYPE_MOTIONVECTOR,
BackgroundColor = PF_CHANNELTYPE_BK_COLOR,
Texture = PF_CHANNELTYPE_TEXTURE,
Coverage = PF_CHANNELTYPE_COVERAGE,
Node = PF_CHANNELTYPE_NODE,
Material = PF_CHANNELTYPE_MATERIAL,
Unclamped = PF_CHANNELTYPE_UNCLAMPED,
Unknown = PF_CHANNELTYPE_UNKNOWN,
}
}
define_enum! {
ae_sys::PF_DataType,
DataType {
Float = PF_DATATYPE_FLOAT,
Double = PF_DATATYPE_DOUBLE,
Long = PF_DATATYPE_LONG,
Short = PF_DATATYPE_SHORT,
Fixed16_16 = PF_DATATYPE_FIXED_16_16,
Char = PF_DATATYPE_CHAR,
UByte = PF_DATATYPE_U_BYTE,
UShort = PF_DATATYPE_U_SHORT,
UFixed16_16 = PF_DATATYPE_U_FIXED_16_16,
Rgb = PF_DATATYPE_RGB,
}
}
const PF_CHANNELTYPE_DEPTH: i32 = i32::from_be_bytes(*b"DPTH");
const PF_CHANNELTYPE_DEPTHAA: i32 = i32::from_be_bytes(*b"DPAA"); const PF_CHANNELTYPE_NORMALS: i32 = i32::from_be_bytes(*b"NRML");
const PF_CHANNELTYPE_OBJECTID: i32 = i32::from_be_bytes(*b"OBID");
const PF_CHANNELTYPE_MOTIONVECTOR: i32 = i32::from_be_bytes(*b"MTVR");
const PF_CHANNELTYPE_BK_COLOR: i32 = i32::from_be_bytes(*b"BKCR");
const PF_CHANNELTYPE_TEXTURE: i32 = i32::from_be_bytes(*b"TEXR");
const PF_CHANNELTYPE_COVERAGE: i32 = i32::from_be_bytes(*b"COVR");
const PF_CHANNELTYPE_NODE: i32 = i32::from_be_bytes(*b"NODE");
const PF_CHANNELTYPE_MATERIAL: i32 = i32::from_be_bytes(*b"MATR");
const PF_CHANNELTYPE_UNCLAMPED: i32 = i32::from_be_bytes(*b"UNCP");
const PF_CHANNELTYPE_UNKNOWN: i32 = i32::from_be_bytes(*b"UNKN");
const PF_DATATYPE_FLOAT: i32 = i32::from_be_bytes(*b"FLT4"); const PF_DATATYPE_DOUBLE: i32 = i32::from_be_bytes(*b"DBL8"); const PF_DATATYPE_LONG: i32 = i32::from_be_bytes(*b"LON4"); const PF_DATATYPE_SHORT: i32 = i32::from_be_bytes(*b"SHT2"); const PF_DATATYPE_FIXED_16_16: i32 = i32::from_be_bytes(*b"FIX4"); const PF_DATATYPE_CHAR: i32 = i32::from_be_bytes(*b"CHR1"); const PF_DATATYPE_U_BYTE: i32 = i32::from_be_bytes(*b"UBT1"); const PF_DATATYPE_U_SHORT: i32 = i32::from_be_bytes(*b"UST2"); const PF_DATATYPE_U_FIXED_16_16: i32 = i32::from_be_bytes(*b"UFX4"); const PF_DATATYPE_RGB: i32 = i32::from_be_bytes(*b"RBG ");
#[repr(transparent)]
pub struct ChannelChunk(ae_sys::PF_ChannelChunk);
impl std::ops::Deref for ChannelChunk {
type Target = ae_sys::PF_ChannelChunk;
fn deref(&self) -> &Self::Target { &self.0 }
}
#[derive(Debug, Clone, Copy)]
pub enum ChannelDataType {
Float(*mut f32),
Double(*mut f64),
Long(*mut i32),
Short(*mut i16),
Fixed16_16(*mut i32),
Char(*mut i8),
UByte(*mut u8),
UShort(*mut u16),
UFixed16_16(*mut u32),
Rgb(*mut u8),
}
impl ChannelChunk {
pub fn channel_data(&self) -> ChannelDataType {
match self.0.data_type {
PF_DATATYPE_FLOAT => ChannelDataType::Float( self.0.dataPV as *mut _),
PF_DATATYPE_DOUBLE => ChannelDataType::Double( self.0.dataPV as *mut _),
PF_DATATYPE_LONG => ChannelDataType::Long( self.0.dataPV as *mut _),
PF_DATATYPE_SHORT => ChannelDataType::Short( self.0.dataPV as *mut _),
PF_DATATYPE_FIXED_16_16 => ChannelDataType::Fixed16_16( self.0.dataPV as *mut _),
PF_DATATYPE_CHAR => ChannelDataType::Char( self.0.dataPV as *mut _),
PF_DATATYPE_U_BYTE => ChannelDataType::UByte( self.0.dataPV as *mut _),
PF_DATATYPE_U_SHORT => ChannelDataType::UShort( self.0.dataPV as *mut _),
PF_DATATYPE_U_FIXED_16_16 => ChannelDataType::UFixed16_16(self.0.dataPV as *mut _),
PF_DATATYPE_RGB => ChannelDataType::Rgb( self.0.dataPV as *mut _),
_ => unreachable!(),
}
}
pub fn channel_row_data(&self, row: i32) -> ChannelDataType {
if row < 0 || row >= self.0.heightL {
panic!("Invalid row: {row}, height: {}", self.0.heightL);
}
let offset = row as isize * self.0.row_bytesL as isize;
match self.0.data_type {
PF_DATATYPE_FLOAT => ChannelDataType::Float( unsafe { (self.0.dataPV as *mut f32).byte_offset(offset) }),
PF_DATATYPE_DOUBLE => ChannelDataType::Double( unsafe { (self.0.dataPV as *mut f64).byte_offset(offset) }),
PF_DATATYPE_LONG => ChannelDataType::Long( unsafe { (self.0.dataPV as *mut i32).byte_offset(offset) }),
PF_DATATYPE_SHORT => ChannelDataType::Short( unsafe { (self.0.dataPV as *mut i16).byte_offset(offset) }),
PF_DATATYPE_FIXED_16_16 => ChannelDataType::Fixed16_16( unsafe { (self.0.dataPV as *mut i32).byte_offset(offset) }),
PF_DATATYPE_CHAR => ChannelDataType::Char( unsafe { (self.0.dataPV as *mut i8 ).byte_offset(offset) }),
PF_DATATYPE_U_BYTE => ChannelDataType::UByte( unsafe { (self.0.dataPV as *mut u8 ).byte_offset(offset) }),
PF_DATATYPE_U_SHORT => ChannelDataType::UShort( unsafe { (self.0.dataPV as *mut u16).byte_offset(offset) }),
PF_DATATYPE_U_FIXED_16_16 => ChannelDataType::UFixed16_16(unsafe { (self.0.dataPV as *mut u32).byte_offset(offset) }),
PF_DATATYPE_RGB => ChannelDataType::Rgb( unsafe { (self.0.dataPV as *mut u8 ).byte_offset(offset) }),
_ => unreachable!(),
}
}
pub fn channel_row_col_data(&self, row: i32, col: i32) -> ChannelDataType {
if row < 0 || row >= self.0.heightL {
panic!("Invalid row: {row}, height: {}", self.0.heightL);
}
if col < 0 || col >= self.0.widthL {
panic!("Invalid col: {col}, width: {}", self.0.widthL);
}
let row_offset = row as isize * self.0.row_bytesL as isize;
let col_offset = col as isize * self.0.dimensionL as isize;
match self.0.data_type {
PF_DATATYPE_FLOAT => ChannelDataType::Float( unsafe { (self.0.dataPV as *mut f32).byte_offset(row_offset).offset(col_offset) }),
PF_DATATYPE_DOUBLE => ChannelDataType::Double( unsafe { (self.0.dataPV as *mut f64).byte_offset(row_offset).offset(col_offset) }),
PF_DATATYPE_LONG => ChannelDataType::Long( unsafe { (self.0.dataPV as *mut i32).byte_offset(row_offset).offset(col_offset) }),
PF_DATATYPE_SHORT => ChannelDataType::Short( unsafe { (self.0.dataPV as *mut i16).byte_offset(row_offset).offset(col_offset) }),
PF_DATATYPE_FIXED_16_16 => ChannelDataType::Fixed16_16( unsafe { (self.0.dataPV as *mut i32).byte_offset(row_offset).offset(col_offset) }),
PF_DATATYPE_CHAR => ChannelDataType::Char( unsafe { (self.0.dataPV as *mut i8 ).byte_offset(row_offset).offset(col_offset) }),
PF_DATATYPE_U_BYTE => ChannelDataType::UByte( unsafe { (self.0.dataPV as *mut u8 ).byte_offset(row_offset).offset(col_offset) }),
PF_DATATYPE_U_SHORT => ChannelDataType::UShort( unsafe { (self.0.dataPV as *mut u16).byte_offset(row_offset).offset(col_offset) }),
PF_DATATYPE_U_FIXED_16_16 => ChannelDataType::UFixed16_16(unsafe { (self.0.dataPV as *mut u32).byte_offset(row_offset).offset(col_offset) }),
PF_DATATYPE_RGB => ChannelDataType::Rgb( unsafe { (self.0.dataPV as *mut u8 ).byte_offset(row_offset).offset(col_offset) }),
_ => unreachable!(),
}
}
}