At this stage of the imaging pipeline the pixel data is represented in full-range RGB color space with 12-bit precision per component, as produced by the CMX stage (gen5-cmx).
The purpose of this block is to apply UVC gamma adjustment in RGB space by applying the same LUT to all three channels (baseline implementation). This avoids the undesired desaturation artifacts caused by applying a nonlinear transfer function to luma-only in YCbCr.
This block is intended to be implemented in FPGA logic and therefore avoids runtime floating-point arithmetic.
After this stage completes, the next pipeline stage is the RGB-to-YCbCr conversion stage (gen5-rgb-to-yuv).
The input consists of RGB pixels with the following properties:
\[ R12 \in [0..4095]\\ G12 \in [0..4095]\\ B12 \in [0..4095] \]
All values are unsigned 12-bit integers.
The output format is identical to the input format:
\[ R12^{\gamma} \in [0..4095]\\ G12^{\gamma} \in [0..4095]\\ B12^{\gamma} \in [0..4095] \]
All three channels are modified by the gamma adjustment stage.
Gamma adjustment is applied independently to each RGB channel \(R12\), \(G12\), and \(B12\) using the same transfer function / LUT.
The UVC gamma transfer function is defined in the following document: UVC Gamma Correction Specification
No additional interpretation or modification of the transfer function is performed at this stage.
For FPGA implementation, the UVC gamma adjustment shall be realized using a LUT with 4096 entries, indexed by the 12-bit channel value.
Each LUT entry maps a 12-bit input channel value to a 12-bit output channel value:
X_in = i // i in range [0..4095] X_out = LUT[i] // gamma-adjusted channel value
The same LUT instance (same contents) is used for all channels.
To simplify and standardize LUT generation, the following online tool may be used: Sub2r Gamma LUT Generator
The tool generates FPGA-ready gamma tables compatible with a 12-bit input and 12-bit output pipeline.
For each pixel, the output components are constructed as:
\[ R12^{\gamma} = LUT[R12]\\ G12^{\gamma} = LUT[G12]\\ B12^{\gamma} = LUT[B12] \]
No additional scaling, offsetting, or clamping is required beyond the LUT bounds.
This block is placed as follows:
... -> CMX -> RGB UVC Gamma -> RGB-to-YCbCr -> ...
The downstream RGB-to-YCbCr block consumes \(R12^{\gamma}\), \(G12^{\gamma}\), and \(B12^{\gamma}\) as its inputs.