1use enums::*;
2use image::*;
3use ofx_sys::*;
4use property::*;
5use result::*;
6use std::borrow::Borrow;
7use std::cell::RefCell;
8use std::ffi::{CStr, CString};
9use std::fmt;
10use std::marker::PhantomData;
11use std::rc::Rc;
12use types::*;
13
14#[derive(Debug, Clone)]
15pub struct PropertySetHandle {
16 inner: OfxPropertySetHandle,
17 property: Rc<OfxPropertySuiteV1>,
18}
19
20impl PropertySetHandle {
21 pub(crate) fn new(inner: OfxPropertySetHandle, property: Rc<OfxPropertySuiteV1>) -> Self {
22 PropertySetHandle { inner, property }
23 }
24
25 pub(crate) fn empty() -> Self {
26 panic!("Do not use, only for type validation testing");
27 PropertySetHandle {
28 inner: std::ptr::null::<OfxPropertySetStruct>() as *mut _,
29 property: unsafe { Rc::new(*std::ptr::null()) },
30 }
31 }
32}
33
34#[derive(Clone)]
35pub struct GenericPluginHandle {
36 inner: VoidPtr,
37 property: &'static OfxPropertySuiteV1,
38}
39
40#[derive(Clone)]
41pub struct HostHandle {
42 inner: OfxPropertySetHandle,
43 property: Rc<OfxPropertySuiteV1>,
44}
45
46impl HostHandle {
47 pub fn new(host: OfxPropertySetHandle, property: Rc<OfxPropertySuiteV1>) -> Self {
48 HostHandle {
49 inner: host,
50 property,
51 }
52 }
53}
54
55#[derive(Clone)]
56pub struct ImageEffectHandle {
57 inner: OfxImageEffectHandle,
58 property: Rc<OfxPropertySuiteV1>,
59 image_effect: Rc<OfxImageEffectSuiteV1>,
60 parameter: Rc<OfxParameterSuiteV1>,
61}
62
63#[derive(Clone)]
64pub struct ImageClipHandle {
65 inner: OfxImageClipHandle,
66 inner_properties: OfxPropertySetHandle,
67 property: Rc<OfxPropertySuiteV1>,
68 image_effect: Rc<OfxImageEffectSuiteV1>,
69}
70
71#[derive(Clone)]
72pub struct ImageHandle {
73 inner: OfxPropertySetHandle,
74 property: Rc<OfxPropertySuiteV1>,
75 image_effect: Rc<OfxImageEffectSuiteV1>,
76}
77
78pub trait ParamHandleValue: Default + Clone {}
79impl ParamHandleValue for Int {}
80impl ParamHandleValue for Bool {}
81impl ParamHandleValue for Double {}
82
83pub trait ParamHandleValueDefault: ParamHandleValue + Default {}
84impl ParamHandleValueDefault for Int {}
85impl ParamHandleValueDefault for Double {}
86
87#[derive(Clone)]
88pub struct ParamHandle<T>
89where
90 T: ParamHandleValue,
91{
92 inner: OfxParamHandle,
93 inner_properties: OfxPropertySetHandle,
94 property: Rc<OfxPropertySuiteV1>,
95 parameter: Rc<OfxParameterSuiteV1>,
96 _type: PhantomData<T>,
97}
98
99#[derive(Clone)]
100pub struct ParamSetHandle {
101 inner: OfxParamSetHandle,
102 property: Rc<OfxPropertySuiteV1>,
103 parameter: Rc<OfxParameterSuiteV1>,
104}
105
106macro_rules! trivial_debug {
108 ($($struct:ty),*) => {
109 $(impl fmt::Debug for $struct {
110 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
111 write!(f, "{} {{...}}", stringify!($struct))
112 }
113 })
114 *
115 }
116}
117
118trivial_debug!(
119 ImageClipHandle,
120 ImageEffectHandle,
121 GenericPluginHandle,
122 HostHandle
123);
124
125impl ImageEffectHandle {
126 pub fn new(
127 inner: OfxImageEffectHandle,
128 property: Rc<OfxPropertySuiteV1>,
129 image_effect: Rc<OfxImageEffectSuiteV1>,
130 parameter: Rc<OfxParameterSuiteV1>,
131 ) -> Self {
132 ImageEffectHandle {
133 inner,
134 property,
135 image_effect,
136 parameter,
137 }
138 }
139}
140
141impl<T> ParamHandle<T>
142where
143 T: ParamHandleValue + Default,
144{
145 pub fn new(
146 inner: OfxParamHandle,
147 inner_properties: OfxPropertySetHandle,
148 property: Rc<OfxPropertySuiteV1>,
149 parameter: Rc<OfxParameterSuiteV1>,
150 ) -> Self {
151 ParamHandle {
152 inner,
153 inner_properties,
154 property,
155 parameter,
156 _type: PhantomData,
157 }
158 }
159}
160
161impl<T> ParamHandle<T>
162where
163 T: ParamHandleValueDefault,
164{
165 pub fn get_value(&self) -> Result<T> {
166 let mut value: T = T::default();
167 suite_fn!(paramGetValue in self.parameter; self.inner, &mut value as *mut T)?;
168 Ok(value)
169 }
170
171 pub fn get_value_at_time(&self, time: Time) -> Result<T> {
172 let mut value: T = T::default();
173 suite_fn!(paramGetValueAtTime in self.parameter; self.inner, time, &mut value as *mut T)?;
174 Ok(value)
175 }
176}
177
178impl ParamHandle<Bool> {
179 pub fn get_value(&self) -> Result<Bool> {
180 let mut value: Int = 0;
181 suite_fn!(paramGetValue in self.parameter; self.inner, &mut value as *mut Int)?;
182 Ok(value != 0)
183 }
184
185 pub fn get_value_at_time(&self, time: Time) -> Result<Bool> {
186 let mut value: Int = 0;
187 suite_fn!(paramGetValueAtTime in self.parameter; self.inner, time, &mut value as *mut Int)?;
188 Ok(value != 0)
189 }
190}
191
192impl ImageClipHandle {
193 pub fn new(
194 inner: OfxImageClipHandle,
195 inner_properties: OfxPropertySetHandle,
196 property: Rc<OfxPropertySuiteV1>,
197 image_effect: Rc<OfxImageEffectSuiteV1>,
198 ) -> Self {
199 ImageClipHandle {
200 inner,
201 inner_properties,
202 property,
203 image_effect,
204 }
205 }
206
207 pub fn get_region_of_definition(&self, time: Time) -> Result<RectD> {
208 let mut value = RectD {
209 x1: 0.0,
210 y1: 0.0,
211 x2: 0.0,
212 y2: 0.0,
213 };
214 suite_fn!(clipGetRegionOfDefinition in self.image_effect; self.inner, time, &mut value as *mut RectD)?;
215 Ok(value)
216 }
217
218 pub fn get_image_mut(&mut self, time: Time) -> Result<Rc<RefCell<ImageHandle>>> {
219 self.get_image_rect_mut(time, None)
220 }
221
222 pub fn get_image(&self, time: Time) -> Result<Rc<ImageHandle>> {
223 self.get_image_rect(time, None)
224 }
225
226 pub fn get_image_rect(&self, time: Time, region: Option<RectD>) -> Result<Rc<ImageHandle>> {
227 let mut image: OfxPropertySetHandle = std::ptr::null_mut();
228 let region_ptr = region
229 .as_ref()
230 .map(|m| m as *const RectD)
231 .unwrap_or(std::ptr::null());
232 suite_fn!(clipGetImage in self.image_effect; self.inner, time, region_ptr, &mut image as *mut OfxPropertySetHandle)?;
233 Ok(Rc::new(ImageHandle::new(
234 image,
235 self.property.clone(),
236 self.image_effect.clone(),
237 )))
238 }
239
240 pub fn get_image_rect_mut(
241 &mut self,
242 time: Time,
243 region: Option<RectD>,
244 ) -> Result<Rc<RefCell<ImageHandle>>> {
245 let mut image: OfxPropertySetHandle = std::ptr::null_mut();
246 let region_ptr = region
247 .as_ref()
248 .map(|m| m as *const RectD)
249 .unwrap_or(std::ptr::null());
250 suite_fn!(clipGetImage in self.image_effect; self.inner, time, region_ptr, &mut image as *mut OfxPropertySetHandle)?;
251 Ok(Rc::new(RefCell::new(ImageHandle::new(
252 image,
253 self.property.clone(),
254 self.image_effect.clone(),
255 ))))
256 }
257}
258
259impl Drop for ImageHandle {
260 fn drop(&mut self) {
261 self.drop_image()
262 .expect("Unable to drop image handle. This is likely a bug");
263 }
264}
265
266impl ImageHandle {
267 pub fn new(
268 inner: OfxPropertySetHandle,
269 property: Rc<OfxPropertySuiteV1>,
270 image_effect: Rc<OfxImageEffectSuiteV1>,
271 ) -> Self {
272 ImageHandle {
273 inner,
274 property,
275 image_effect,
276 }
277 }
278
279 pub fn get_descriptor<T>(&self) -> Result<ImageDescriptor<T>>
280 where
281 T: PixelFormat,
282 {
283 let bounds = self.get_bounds()?;
284 let row_bytes = self.get_row_bytes()?;
285 let ptr = self.get_data()?;
286
287 Ok(ImageDescriptor::new(bounds, row_bytes, ptr))
288 }
289
290 fn get_descriptor_mut<T>(&mut self) -> Result<ImageDescriptorMut<T>>
291 where
292 T: PixelFormat,
293 {
294 let bounds = self.get_bounds()?;
295 let row_bytes = self.get_row_bytes()?;
296 let mut ptr = self.get_data()?;
297
298 Ok(ImageDescriptorMut::new(bounds, row_bytes, ptr))
299 }
300
301 pub fn get_tiles_mut<T>(&mut self, count: usize) -> Result<Vec<ImageTileMut<T>>>
302 where
303 T: PixelFormat,
304 {
305 let bounds = self.get_bounds()?;
306 let row_bytes = self.get_row_bytes()?;
307 let mut ptr = self.get_data()?;
308
309 Ok(ImageDescriptorMut::new(bounds, row_bytes, ptr).into_tiles(count))
310 }
311
312 fn drop_image(&mut self) -> Result<()> {
313 debug!("Releasing data for ImageHandle {:?}", self.inner);
314 suite_fn!(clipReleaseImage in self.image_effect; self.inner)
315 }
316}
317
318impl HasProperties<ClipProperties> for ImageClipHandle {
319 fn properties(&self) -> Result<ClipProperties> {
320 Ok(ClipProperties::new(
321 self.inner_properties,
322 self.property.clone(),
323 ))
324 }
325}
326
327trait IsPropertiesNewType {
328 fn wrap(inner: PropertySetHandle) -> Self;
329}
330
331pub trait PropertiesNewTypeConstructor {
332 fn build(host: OfxPropertySetHandle, property: Rc<OfxPropertySuiteV1>) -> Self;
333}
334
335#[inline]
336pub fn build_typed<T>(host: OfxPropertySetHandle, property: Rc<OfxPropertySuiteV1>) -> T
337where
338 T: PropertiesNewTypeConstructor,
339{
340 T::build(host, property)
341}
342
343macro_rules! properties_newtype {
344 ($name:ident) => {
345 #[derive(Clone)]
346 pub struct $name(PropertySetHandle);
347
348 impl IsPropertiesNewType for $name {
349 fn wrap(inner: PropertySetHandle) -> Self {
350 $name(inner)
351 }
352 }
353
354 impl PropertiesNewTypeConstructor for $name {
355 fn build(host: OfxPropertySetHandle, property: Rc<OfxPropertySuiteV1>) -> Self {
356 $name::new(host, property)
357 }
358 }
359
360 impl $name {
361 pub fn new(host: OfxPropertySetHandle, property: Rc<OfxPropertySuiteV1>) -> Self {
362 $name(PropertySetHandle::new(host, property))
363 }
364 }
365
366 impl<'a> AsProperties for $name {
367 fn handle(&self) -> OfxPropertySetHandle {
368 self.0.inner
369 }
370 fn suite(&self) -> *const OfxPropertySuiteV1 {
371 self.0.property.borrow() as *const _
372 }
373 }
374
375 trivial_debug!($name);
376 };
377}
378
379properties_newtype!(HostProperties);
380properties_newtype!(EffectDescriptorProperties);
381properties_newtype!(ImageEffectProperties);
382properties_newtype!(ClipProperties);
383
384properties_newtype!(DescribeInContextInArgs);
385
386properties_newtype!(GetRegionOfDefinitionInArgs);
387properties_newtype!(GetRegionOfDefinitionOutArgs);
388
389properties_newtype!(GetRegionsOfInterestInArgs);
390properties_newtype!(GetRegionsOfInterestOutArgs);
391
392properties_newtype!(GetClipPreferencesOutArgs);
393
394properties_newtype!(IsIdentityInArgs);
395properties_newtype!(IsIdentityOutArgs);
396
397properties_newtype!(BeginInstanceChangedInArgs);
398
399properties_newtype!(InstanceChangedInArgs);
400properties_newtype!(InstanceChangedOutArgs);
401
402properties_newtype!(EndInstanceChangedInArgs);
403properties_newtype!(EndInstanceChangedOutArgs);
404
405properties_newtype!(GetTimeDomainOutArgs);
406
407properties_newtype!(BeginSequenceRenderInArgs);
408properties_newtype!(RenderInArgs);
409properties_newtype!(EndSequenceRenderInArgs);
410
411properties_newtype!(ParamDoubleProperties);
412properties_newtype!(ParamIntProperties);
413properties_newtype!(ParamBooleanProperties);
414properties_newtype!(ParamPageProperties);
415properties_newtype!(ParamGroupProperties);
416
417impl DescribeInContextInArgs {}
418
419impl HasProperties<ImageEffectProperties> for ImageEffectHandle {
420 fn properties(&self) -> Result<ImageEffectProperties> {
421 let property_set_handle = {
422 let mut property_set_handle = std::ptr::null_mut();
423
424 suite_fn!(getPropertySet in self.image_effect; self.inner, &mut property_set_handle as *mut _)?;
425
426 property_set_handle
427 };
428 Ok(ImageEffectProperties(PropertySetHandle::new(
429 property_set_handle,
430 self.property.clone(),
431 )))
432 }
433}
434
435impl HasProperties<EffectDescriptorProperties> for ImageEffectHandle {
436 fn properties(&self) -> Result<EffectDescriptorProperties> {
437 let property_set_handle = {
438 let mut property_set_handle = std::ptr::null_mut();
439
440 suite_fn!(getPropertySet in self.image_effect; self.inner, &mut property_set_handle as *mut _)?;
441
442 property_set_handle
443 };
444 Ok(EffectDescriptorProperties(PropertySetHandle::new(
445 property_set_handle,
446 self.property.clone(),
447 )))
448 }
449}
450
451
452impl ImageEffectHandle {
453 fn clip_define(&self, clip_name: &[u8]) -> Result<ClipProperties> {
454 let property_set_handle = {
455 let mut property_set_handle = std::ptr::null_mut();
456 suite_fn!(clipDefine in self.image_effect;
457 self.inner, clip_name.as_ptr() as *const i8, &mut property_set_handle as *mut _)?;
458 property_set_handle
459 };
460 Ok(ClipProperties(PropertySetHandle::new(
461 property_set_handle,
462 self.property.clone(),
463 )))
464 }
465
466 fn clip_get_handle(&self, clip_name: &[u8]) -> Result<ImageClipHandle> {
467 let (clip_handle, clip_properties) = {
468 let mut clip_handle = std::ptr::null_mut();
469 let mut clip_properties = std::ptr::null_mut();
470 suite_fn!(clipGetHandle in self.image_effect;
471 self.inner, clip_name.as_ptr() as *const i8, &mut clip_handle as *mut _, &mut clip_properties as *mut _)?;
472 (clip_handle, clip_properties)
473 };
474 Ok(ImageClipHandle::new(
475 clip_handle,
476 clip_properties,
477 self.property.clone(),
478 self.image_effect.clone(),
479 ))
480 }
481
482 pub fn abort(&self) -> Result<Bool> {
483 Ok(suite_call!(abort in self.image_effect; self.inner) != 0)
484 }
485
486 pub fn parameter_set(&self) -> Result<ParamSetHandle> {
487 let parameters_set_handle = {
488 let mut parameters_set_handle = std::ptr::null_mut();
489 suite_fn!(getParamSet in self.image_effect; self.inner, &mut parameters_set_handle as *mut _)?;
490 parameters_set_handle
491 };
492 Ok(ParamSetHandle::new(
493 parameters_set_handle,
494 self.parameter.clone(),
495 self.property.clone(),
496 ))
497 }
498
499 pub fn get_output_clip(&self) -> Result<ImageClipHandle> {
500 self.clip_get_handle(ofx_sys::kOfxImageEffectOutputClipName)
501 }
502
503 pub fn get_simple_input_clip(&self) -> Result<ImageClipHandle> {
504 self.clip_get_handle(ofx_sys::kOfxImageEffectSimpleSourceClipName)
505 }
506
507 pub fn get_clip(&self, name: &str) -> Result<ImageClipHandle> {
508 let str_buf = CString::new(name)?.into_bytes_with_nul();
509 self.clip_get_handle(&str_buf)
510 }
511
512 pub fn new_output_clip(&self) -> Result<ClipProperties> {
513 self.clip_define(ofx_sys::kOfxImageEffectOutputClipName)
514 }
515
516 pub fn new_simple_input_clip(&self) -> Result<ClipProperties> {
517 self.clip_define(ofx_sys::kOfxImageEffectSimpleSourceClipName)
518 }
519
520 pub fn new_clip(&self, name: &str) -> Result<ClipProperties> {
521 let str_buf = CString::new(name)?.into_bytes_with_nul();
522 self.clip_define(&str_buf)
523 }
524
525 unsafe fn get_pointer(&self) -> Result<*mut [u8]> {
526 Err(Error::Unimplemented)
527 }
528
529 pub fn set_instance_data<T>(&mut self, data: T) -> Result<()>
530 where
531 T: Sized,
532 {
533 let mut effect_props: ImageEffectProperties = self.properties()?;
534 let data_box = Box::new(data);
535 let data_ptr = Box::into_raw(data_box);
536 let status = suite_fn!(propSetPointer in self.property;
537 effect_props.0.inner, kOfxPropInstanceData.as_ptr() as *const i8, 0, data_ptr as *mut _);
538 if status.is_err() {
539 unsafe {
540 Box::from_raw(data_ptr);
541 }
542 }
543 status
544 }
545
546 fn get_instance_data_ptr(&self) -> Result<VoidPtrMut> {
547 let mut effect_props: ImageEffectProperties = self.properties()?;
548 let mut data_ptr = std::ptr::null_mut();
549 to_result! { suite_call!(propGetPointer in self.property;
550 effect_props.0.inner, kOfxPropInstanceData.as_ptr() as *const i8, 0, &mut data_ptr)
551 => data_ptr }
552 }
553
554 pub fn get_instance_data<T>(&self) -> Result<&mut T>
556 where
557 T: Sized,
558 {
559 unsafe {
560 let mut ptr = self.get_instance_data_ptr()?;
561 let mut reference = ptr as *mut T;
562 Ok(&mut *reference)
563 }
564 }
565
566 pub fn drop_instance_data(&mut self) -> Result<()> {
567 unsafe {
568 let mut ptr = self.get_instance_data_ptr()?;
569 if !ptr.is_null() {
570 Box::from_raw(ptr);
571 }
572 }
573 Ok(())
574 }
575}
576
577impl ParamSetHandle {
578 pub fn new(
579 inner: OfxParamSetHandle,
580 parameter: Rc<OfxParameterSuiteV1>,
581 property: Rc<OfxPropertySuiteV1>,
582 ) -> Self {
583 ParamSetHandle {
584 inner,
585 parameter,
586 property,
587 }
588 }
589
590 fn param_define<T>(&mut self, param_type: ParamType, name: &str) -> Result<T>
591 where
592 T: IsPropertiesNewType,
593 {
594 let name_buf = CString::new(name)?.into_bytes_with_nul();
595 let property_set_handle = {
596 let mut property_set_handle = std::ptr::null_mut();
597 suite_fn!(paramDefine in self.parameter;
598 self.inner, param_type.as_ptr() as *const _, name_buf.as_ptr() as *const _, &mut property_set_handle as *mut _)?;
599
600 property_set_handle
601 };
602 Ok(T::wrap(PropertySetHandle::new(
603 property_set_handle,
604 self.property.clone(),
605 )))
606 }
607
608 pub fn parameter<T>(&self, name: &str) -> Result<ParamHandle<T>>
609 where
610 T: ParamHandleValue,
611 {
612 let name_buf = CString::new(name)?.into_bytes_with_nul();
613 let (param_handle, param_properties) = {
614 let mut param_handle = std::ptr::null_mut();
615 let mut param_properties = std::ptr::null_mut();
616 suite_fn!(paramGetHandle in self.parameter;
617 self.inner, name_buf.as_ptr() as *const _, &mut param_handle as *mut _, &mut param_properties as *mut _)?;
618 (param_handle, param_properties)
619 };
620 Ok(ParamHandle::new(
621 param_handle,
622 param_properties,
623 self.property.clone(),
624 self.parameter.clone(),
625 ))
626 }
627
628 pub fn param_define_double(&mut self, name: &str) -> Result<ParamDoubleProperties> {
629 self.param_define(ParamType::Double, name)
630 }
631
632 pub fn param_define_int(&mut self, name: &str) -> Result<ParamIntProperties> {
633 self.param_define(ParamType::Integer, name)
634 }
635
636 pub fn param_define_boolean(&mut self, name: &str) -> Result<ParamBooleanProperties> {
637 self.param_define(ParamType::Boolean, name)
638 }
639
640 pub fn param_define_group(&mut self, name: &str) -> Result<ParamGroupProperties> {
641 self.param_define(ParamType::Group, name)
642 }
643
644 pub fn param_define_page(&mut self, name: &str) -> Result<ParamPageProperties> {
645 self.param_define(ParamType::Page, name)
646 }
647}
648
649impl AsProperties for HostHandle {
650 fn handle(&self) -> OfxPropertySetHandle {
651 self.inner
652 }
653 fn suite(&self) -> *const OfxPropertySuiteV1 {
654 self.property.borrow() as *const _
655 }
656}
657
658impl AsProperties for ImageClipHandle {
659 fn handle(&self) -> OfxPropertySetHandle {
660 self.inner_properties
661 }
662 fn suite(&self) -> *const OfxPropertySuiteV1 {
663 self.property.borrow() as *const _
664 }
665}
666
667impl AsProperties for ImageHandle {
668 fn handle(&self) -> OfxPropertySetHandle {
669 self.inner
670 }
671 fn suite(&self) -> *const OfxPropertySuiteV1 {
672 self.property.borrow() as *const _
673 }
674}
675
676impl<T> AsProperties for ParamHandle<T>
677where
678 T: ParamHandleValue,
679{
680 fn handle(&self) -> OfxPropertySetHandle {
681 self.inner_properties
682 }
683 fn suite(&self) -> *const OfxPropertySuiteV1 {
684 self.property.borrow() as *const _
685 }
686}
687
688mod tests {
689 use super::*;
690 use property;
691 use property::*;
692
693 fn prop_host() {
695 let mut handle = ImageEffectProperties(PropertySetHandle::empty());
696
697 handle.get::<property::Type::Property>();
698 handle.get::<property::IsBackground::Property>();
699 }
700}