PF_EffectWorld / PF_LayerDef¶
After Effects represents images using PF_EffectWorlds, also called PF_LayerDefs.
PF_EffectWorld Structure¶
Item |
Description |
---|---|
|
Currently, the only flags are:
Normally effects cannot alter input image data; only output. |
|
Pointer to image data, stored as a Do not access directly; use the PF_PixelPtr Accessor Macros. Image data in After Effects is always organized in sequential words each containing Alpha, Red, Green, Blue from the low byte to the high byte. |
|
The length, in bytes, of each row in the image's block of pixels. The block of pixels contains height lines each with width pixels followed by some bytes of padding. The width pixels (times four, because each pixel is four bytes long) plus optional extra padding adds up to rowbytes bytes. Use this value to traverse the image data. Platform-specific padding at the end of rows makes it unwise to traverse the entire buffer. Instead, find the beginning of each row using height and rowbytes. Note This value does not vary based on whether field rendering is active. Note Input and output worlds with the same dimensions can use different rowbytes values. |
|
Width and height of the pixel buffer. |
|
|
|
The smallest rectangle encompassing all opaque (non-zero alpha) pixels in the layer. This defines the area which needs to be output. If your plug-in varies with extent (like a diffusion dither), ignore this and render the full frame each time. |
|
The pixel aspect ratio expressed as a Note Effects can use this value for checked out layers, but must use |
|
No longer used in CS5. Platform-specific reference information. On Windows, this contains an opaque value. On macOS, Note You cannot acquire a |
|
For layer parameters only. Either |
New In 16.0¶
During PF_Cmd_SMART_RENDER_GPU, PF_LayerDef will be filled out the same as it is for regular CPU renders, but PF_LayerDef.data will be null; all other fields will be valid.
Rowbytes In PF_EffectWorlds¶
Don't assume that you can get to the next scanline of a PF_EffectWorld
using (width * sizeof(current_pixel_type)) + 4
, or whatever; use the PF_EffectWorld's rowbytes
instead.
Never write outside the indicated region of a PF_EffectWorld; this can corrupt cached image buffers that don't belong to you.
To test whether your effects are honoring the PF_EffectWorld>rowbytes
, apply the Grow Bounds effect after your effect.
The output buffer will have larger rowbytes than the input (though it will still have the same logical size).
Byte Alignment¶
The pixels in a PF_EffectWorld
are not guaranteed to be 16-byte-aligned. An effect may get a subregion of a larger PF_EffectWorld. Users of Apple's sample code for pixel processing optimization, you have been warned.
Beyond 8-bit per channel color, After Effects supports 16 bit and 32-bit float per-channel color.
Effects will never receive input and output worlds with differing bit depths, nor will they receive worlds with higher bit depth than they have claimed to be able to handle.
Accessor Macros For Opaque (Data Type) Pixels¶
Use the following macros to access the data within (opaque) PF_PixelPtrs.
It is, emphatically, not safe to simply cast pointers of one type into another! To make it work at all requires a cast, and there's nothing that prevents you from casting it incorrectly. We may change its implementation at a later date (at which time you'll thank us for forcing this level of abstraction).
PF_PixelPtr Accessor Macros¶
Macro |
Purpose |
---|---|
|
Obtain a pointer to a 16-bpc pixel within the specified world. The returned pixel pointer will be NULL if the world is not 16-bpc. The second parameter is optional; if it is not NULL, the returned pixel will be an interpretation of the values in the passed-in pixel, as if it were in the specified PF_EffectWorld.
|
|
Obtain a pointer to a 8-bpc pixel within the specified world. The returned pixel pointer will be NULL if the world is not 8- bpc. The second parameter is optional; if it is not NULL, the returned pixel will be an interpretation of the values in the passed-in pixel, as if it were in the specified PF_EffectWorld.
|
Think of PF_GET_PIXEL_DATA16
and PF_GET_PIXEL_DATA8
as safe (ahem) casting routines.
The code required is actually very simple to get a PF_Pixel16*
out of the PF_EffectWorld output:
{
PF_Pixel16 *deep_pixelP = NULL;
PF_Err err = PF_Err_NONE;
err = PF_GET_PIXEL_DATA16(output, NULL, &deep_pixelP);
}
This returns deep_pixelP as NULL if the world does not have deep pixels.
The second parameter is not used very often and should be passed as NULL; pass a PF_PixelPtr that is not contained in a PF_EffectWorld to coerce it to the depth of that PF_EffectWorld).