How can I make a plugin for 8-bit, 16-bit, and 32-bit projects share the same internal codebase?
I developed a plugin whose functionality requires reading and judging precise RGB values, and ultimately calculating and exporting HEX color data.
Therefore, I want all internal computations to be performed strictly in an 8-bit environment.
However, when an After Effects project is set to 16-bit or 32-bit color, AE automatically converts the pixel depth for plugins that only support 8-bit input.
This conversion introduces unwanted color noise (as shown in the GIF below), which is not the behavior I want.
In addition, my plugin contains many functions and processing steps, and I don’t want to duplicate the same logic two more times just to support 16-bit and 32-bit modes.
So, my question is:
Is there a way to make the plugin compatible with 8-bit, 16-bit, and 32-bit projects while still using a single shared set of functions?
For example, could I convert the 16-bit or 32-bit input down to 8-bit inside the plugin itself?
Letting After Effects handle the bit-depth conversion automatically causes the unwanted color noise mentioned earlier, which in turn makes the plugin’s internal color detection inaccurate.
Here’s a simplified excerpt from my Render() function:
ERR(suites.Iterate8Suite2()->iterate(in_data, 0, linesL, ¶ms[ID_INPUT]->u.ld, NULL, NULL, MakeWhiteWorld8, reinterpret_cast<PF_LayerDef*>(&whiteWorld)));
ERR(suites.Iterate8Suite2()->iterate(in_data, 0, linesL, reinterpret_cast<PF_LayerDef*>(&whiteWorld), NULL, reinterpret_cast<void*>(&giP), ProcessPixelMaskFromWhite8, reinterpret_cast<PF_LayerDef*>(&bwWorld1)));
if (giP.hasMatch) {
Fill_EdgeConnectedBlack8_ToGray(&bwWorld1);
if (viewSel == 3)
ERR(suites.Iterate8Suite2()->iterate(in_data, 0, linesL, reinterpret_cast<PF_LayerDef*>(&bwWorld1), NULL, reinterpret_cast<void*>(&giP), CopyPixel8_WithColorMap, output));
ERR(suites.Iterate8Suite2()->iterate(in_data, 0, linesL, reinterpret_cast<PF_LayerDef*>(&whiteWorld), NULL, reinterpret_cast<void*>(&giP), ApplyExcludeInPlace8, reinterpret_cast<PF_LayerDef*>(&bwWorld1)));
if (viewSel == 4)
ERR(suites.Iterate8Suite2()->iterate(in_data, 0, linesL, reinterpret_cast<PF_LayerDef*>(&bwWorld1), NULL, reinterpret_cast<void*>(&giP), CopyPixel8_WithColorMap, output));
Morphology_MinThenMax8_Alpha_XY_Binary_ROI(&bwWorld1, (int)giP.trimWidth, (int)(giP.trimWidth + giP.expandWidth));
if (viewSel == 5)
ERR(suites.Iterate8Suite2()->iterate(in_data, 0, linesL, reinterpret_cast<PF_LayerDef*>(&bwWorld1), NULL, reinterpret_cast<void*>(&giP), CopyPixel8_WithColorMap, output));
BuildGroups8(&bwWorld1, &whiteWorld, groupC);
SortGroup8(groupC, (int)giP.colorGroupSort, (int)giP.colorSort, (int)giP.colorAnchor);
DrawDebug8(&eWorld, groupC);
BuildHexGroups8(groupC, content);
if (viewSel == 7) {
ERR(suites.Iterate8Suite2()->iterate(in_data, 0, linesL, reinterpret_cast<PF_LayerDef*>(&eWorld), NULL, reinterpret_cast<void*>(&giP), ColorizeDebug8, output));
}
if (viewSel == 8) {
ERR(suites.Iterate8Suite2()->iterate(in_data, 0, linesL, reinterpret_cast<PF_LayerDef*>(&bwWorld1), NULL, reinterpret_cast<void*>(&giP), CopyPixel8_WithColorMap, output));
ERR(suites.Iterate8Suite2()->iterate(in_data, 0, linesL, reinterpret_cast<PF_LayerDef*>(&eWorld), NULL, reinterpret_cast<void*>(&giP), ColorizeDebug8_Overlay, output));
}
if (viewSel == 9) {
ERR(suites.Iterate8Suite2()->iterate(in_data, 0, linesL, reinterpret_cast<PF_LayerDef*>(&whiteWorld), NULL, NULL, CopyPixel8, output));
ERR(suites.Iterate8Suite2()->iterate(in_data, 0, linesL, reinterpret_cast<PF_LayerDef*>(&eWorld), NULL, reinterpret_cast<void*>(&giP), ColorizeDebug8_Overlay, output));
}
if (viewSel != 3 && viewSel != 4 && viewSel != 5 && viewSel != 7 && viewSel != 8 && viewSel != 9)
ERR(suites.Iterate8Suite2()->iterate(in_data, 0, linesL, reinterpret_cast<PF_LayerDef*>(&whiteWorld), NULL, NULL, CopyPixel8, output));
}
else {
ERR(suites.Iterate8Suite2()->iterate(in_data, 0, linesL, reinterpret_cast<PF_LayerDef*>(&whiteWorld), NULL, NULL, CopyPixel8, output));
}
