📄 img_ycbcr422p_rgb565_c.c
字号:
/* 128 rather than signed values centered around 0, as noted above. */
/* */
/* In addition to performing plain color-space conversion, color */
/* saturation can be adjusted by scaling coeff[1] through coeff[4]. */
/* Similarly, brightness can be adjusted by scaling coeff[0]. */
/* General hue adjustment can not be performed, however, due to the */
/* two zeros hard-coded in the matrix. */
/* */
/* TECHNIQUES */
/* Pixel replication is performed implicitly on chroma data to */
/* reduce the total number of multiplies required. The chroma */
/* portion of the matrix is calculated once for each Cb, Cr pair, */
/* and the result is added to both Y' samples. */
/* */
/* SOURCE */
/* Poynton, Charles et al. "The Color FAQ," 1999. */
/* http://home.inforamp.net/~poynton/ColorFAQ.html */
/* */
/* ------------------------------------------------------------------------ */
/* Copyright (c) 2002 Texas Instruments, Incorporated. */
/* All Rights Reserved. */
/* ======================================================================== */
void IMG_ycbcr422p_rgb565_c
(
const short coeff[5], /* Matrix coefficients. */
const unsigned char *y_data, /* Luminence data (Y') */
const unsigned char *cb_data, /* Blue color-difference (B'-Y') */
const unsigned char *cr_data, /* Red color-difference (R'-Y') */
unsigned short *restrict rgb_data, /* RGB 5:6:5 packed pixel output. */
unsigned num_pixels /* # of luma pixels to process. */
)
{
int i; /* Loop counter */
int y0, y1; /* Individual Y components */
int cb, cr; /* Color difference components */
int y0t,y1t; /* Temporary Y values */
int rt, gt, bt; /* Temporary RGB values */
int r0, g0, b0; /* Individual RGB components */
int r1, g1, b1; /* Individual RGB components */
int r0t,g0t,b0t; /* Truncated RGB components */
int r1t,g1t,b1t; /* Truncated RGB components */
int r0s,g0s,b0s; /* Saturated RGB components */
int r1s,g1s,b1s; /* Saturated RGB components */
short luma = coeff[0]; /* Luma scaling coefficient. */
short r_cr = coeff[1]; /* Cr's contribution to Red. */
short g_cb = coeff[2]; /* Cb's contribution to Green. */
short g_cr = coeff[3]; /* Cr's contribution to Green. */
short b_cb = coeff[4]; /* Cb's contribution to Blue. */
unsigned short rgb0, rgb1; /* Packed RGB pixel data */
/* -------------------------------------------------------------------- */
/* Iterate for num_pixels/2 iters, since we process pixels in pairs. */
/* -------------------------------------------------------------------- */
i = num_pixels >> 1;
while (i-->0)
{
/* ---------------------------------------------------------------- */
/* Read in YCbCr data from the separate data planes. */
/* */
/* The Cb and Cr channels come in biased upwards by 128, so */
/* subtract the bias here before performing the multiplies for */
/* the color space conversion itself. Also handle Y's upward */
/* bias of 16 here. */
/* ---------------------------------------------------------------- */
y0 = *y_data++ - 16;
y1 = *y_data++ - 16;
cb = *cb_data++ - 128;
cr = *cr_data++ - 128;
/* ================================================================ */
/* Convert YCrCb data to RGB format using the following matrix: */
/* */
/* [ coeff[0] 0.0000 coeff[1] ] [ Y' - 16 ] [ R'] */
/* [ coeff[0] coeff[2] coeff[3] ] * [ Cb - 128 ] = [ G'] */
/* [ coeff[0] coeff[4] 0.0000 ] [ Cr - 128 ] [ B'] */
/* */
/* We use signed Q13 coefficients for the coefficients to make */
/* good use of our 16-bit multiplier. Although a larger Q-point */
/* may be used with unsigned coefficients, signed coefficients */
/* add a bit of flexibility to the kernel without significant */
/* loss of precision. */
/* ================================================================ */
/* ---------------------------------------------------------------- */
/* Calculate chroma channel's contribution to RGB. */
/* ---------------------------------------------------------------- */
rt = r_cr * (short)cr;
gt = g_cb * (short)cb + g_cr * (short)cr;
bt = b_cb * (short)cb;
/* ---------------------------------------------------------------- */
/* Calculate intermediate luma values. Include bias of 16 here. */
/* ---------------------------------------------------------------- */
y0t = luma * (short)y0;
y1t = luma * (short)y1;
/* ---------------------------------------------------------------- */
/* Mix luma, chroma channels. */
/* ---------------------------------------------------------------- */
r0 = y0t + rt; r1 = y1t + rt;
g0 = y0t + gt; g1 = y1t + gt;
b0 = y0t + bt; b1 = y1t + bt;
/* ================================================================ */
/* At this point in the calculation, the RGB components are */
/* nominally in the format below. If the color is outside the */
/* our RGB gamut, some of the sign bits may be non-zero, */
/* triggering saturation. */
/* */
/* 3 2 2 1 1 */
/* 1 1 0 3 2 0 */
/* [ SIGN | COLOR | FRACTION ] */
/* */
/* This gives us an 8-bit range for each of the R, G, and B */
/* components. (The transform matrix is designed to transform */
/* 8-bit Y/C values into 8-bit R,G,B values.) To get our final */
/* 5:6:5 result, we "divide" our R, G and B components by 4, 8, */
/* and 4, respectively, by reinterpreting the numbers in the */
/* format below: */
/* */
/* Red, 3 2 2 1 1 */
/* Blue 1 1 0 6 5 0 */
/* [ SIGN | COLOR | FRACTION ] */
/* */
/* 3 2 2 1 1 */
/* Green 1 1 0 5 4 0 */
/* [ SIGN | COLOR | FRACTION ] */
/* */
/* "Divide" is in quotation marks because this step requires no */
/* actual work. The code merely treats the numbers as having a */
/* different Q-point. */
/* ================================================================ */
/* ---------------------------------------------------------------- */
/* Shift away the fractional portion, and then saturate to the */
/* RGB 5:6:5 gamut. */
/* ---------------------------------------------------------------- */
r0t = r0 >> 16;
g0t = g0 >> 15;
b0t = b0 >> 16;
r1t = r1 >> 16;
g1t = g1 >> 15;
b1t = b1 >> 16;
r0s = r0t < 0 ? 0 : r0t > 31 ? 31 : r0t;
g0s = g0t < 0 ? 0 : g0t > 63 ? 63 : g0t;
b0s = b0t < 0 ? 0 : b0t > 31 ? 31 : b0t;
r1s = r1t < 0 ? 0 : r1t > 31 ? 31 : r1t;
g1s = g1t < 0 ? 0 : g1t > 63 ? 63 : g1t;
b1s = b1t < 0 ? 0 : b1t > 31 ? 31 : b1t;
/* ---------------------------------------------------------------- */
/* Merge values into output pixels. */
/* ---------------------------------------------------------------- */
rgb0 = (r0s << 11) + (g0s << 5) + (b0s << 0);
rgb1 = (r1s << 11) + (g1s << 5) + (b1s << 0);
/* ---------------------------------------------------------------- */
/* Store resulting pixels to memory. */
/* ---------------------------------------------------------------- */
*rgb_data++ = rgb0;
*rgb_data++ = rgb1;
}
return;
}
/* ======================================================================== */
/* End of file: img_ycbcr422p_rgb565.c */
/* ------------------------------------------------------------------------ */
/* Copyright (c) 2002 Texas Instruments, Incorporated. */
/* All Rights Reserved. */
/* ======================================================================== */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -