====== YUV 4:4:4 UVC Contrast ====== At this stage of the imaging pipeline the pixel data is represented in full-range YCbCr 4:4:4 color space with 12-bit precision per component. The purpose of this block is to apply **UVC Contrast adjustment** by modifying the luma component relative to a neutral midpoint, while preserving chroma. ===== Conceptual model ===== The UVC Contrast control is defined in terms of an HSL-based model in [[https://wiki.sub2r.com/doku.php/isp:contrast|UVC Contrast]] Conceptually, UVC Contrast scales the distance of a pixel’s lightness from a neutral midpoint. In a YCbCr pipeline using full-range coding, this behavior maps directly to a **linear scaling of the luma component around the mid-level**, while chroma components remain unchanged. This document specifies that mapping explicitly for FPGA implementation. ===== Input format ===== The input consists of YCbCr pixels with the following properties: \[ Y12 \in [0..4095]\\ C_b12 \in [0..4095]\text{, neutral at }2048\\ C_r12 \in [0..4095]\text{, neutral at }2048 \] All values are unsigned 12-bit integers using full-range (computer-range) coding. ===== Output format ===== The output format is identical to the input format: \[ Y12^{\text{contrast}} \in [0..4095]\\ C_b12^{\text{contrast}} = C_b12\\ C_r12^{\text{contrast}} = C_r12 \] Only the luma component is modified by the contrast stage. ===== Contrast factor definition ===== The UVC Contrast control provides a **contrast factor** \(C\), defined and scaled as specified in [[https://wiki.sub2r.com/doku.php/isp:contrast|UVC Contrast]] That document defines: * the control range, * the neutral (unity) position, * and the mapping from control value to contrast factor. ===== UVC Contrast implementation ===== Contrast is applied by scaling the luma value relative to the neutral midpoint of the full-range Y domain. For 12-bit full-range luma, the neutral midpoint is: \[ Y_{\text{mid}} = 2048 \] The contrast-adjusted luma is computed as: \[ Y12^{\text{contrast}} = \mathrm{clamp12}\left( (Y12 - Y_{\text{mid}}) \times C + Y_{\text{mid}} \right) \] Where: * \(Y12\) is the input luma value, * \(C\) is the contrast factor, * and `clamp12(x)` clamps the result to the range \([0..4095]\). The chroma components are passed through unchanged: \[ C_b12^{\text{contrast}} = C_b12\\ C_r12^{\text{contrast}} = C_r12 \] ===== FPGA implementation considerations ===== * Contrast adjustment shall be implemented using **signed arithmetic**. * The subtraction from and addition to the midpoint must be performed at sufficient bit width to avoid overflow before clamping. * The contrast factor \(C\) is expected to be implemented as a fixed-point value derived from the UVC control. * Clamping is applied **after** scaling and offsetting. * Implementations may use a multiplier or a small LUT-based approximation, depending on resource and performance constraints. ===== Notes ===== * This block operates entirely in **YCbCr space**. * Contrast adjustment affects **only luma**, preserving chroma relationships. * A contrast factor of unity leaves the image unchanged. * Contrast values greater than unity increase dynamic range around mid-level; values less than unity reduce contrast. * Extreme contrast values may cause luma clipping, which is expected behavior. * This stage assumes **full-range (computer-range) YCbCr** coding.