Skip to main content
H-FITS
Participant
November 12, 2025
Answered

How can I make a plugin for 8-bit, 16-bit, and 32-bit projects share the same internal codebase?

  • November 12, 2025
  • 1 reply
  • 70 views

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, &params[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));
	}

 

Correct answer shachar carmi

c++ templates are a popular choice for that. you can create 3 instances of your algorithm with different data types and range constants.

1 reply

shachar carmiCommunity ExpertCorrect answer
Community Expert
November 12, 2025

c++ templates are a popular choice for that. you can create 3 instances of your algorithm with different data types and range constants.