colorcvt.c
来自「symbian 下的helix player源代码」· C语言 代码 · 共 1,766 行 · 第 1/5 页
C
1,766 行
/* alignments: */
if (((unsigned)dest_ptr & 3) || (dest_pitch & 3) ||
((unsigned)src_ptr & 3) || (src_pitch & 3) ||
/* image sizes: */
dest_width <= 0 || dest_height <= 0 ||
src_width <= 0 || src_height <= 0 ||
/* rectangles: */
dest_x < 0 || dest_y < 0 || dest_dx <= 0 || dest_dy <= 0 ||
src_x < 0 || src_y < 0 || src_dx <= 0 || src_dy <= 0 ||
/* overlaps: */
dest_width < dest_x + dest_dx || dest_height < dest_y + dest_dy ||
src_width < src_x + src_dx || src_height < src_y + src_dy)
goto fail;
/* scale factors: */
if (dest_dx == src_dx) *p_scale_x = 1;
else if (dest_dx == 2 * src_dx) *p_scale_x = 2;
else goto fail;
if (dest_dy == src_dy) *p_scale_y = 1;
else if (dest_dy == 2 * src_dy) *p_scale_y = 2;
else goto fail;
/* success: */
return 1;
/* failure: */
fail:
return 0;
}
static int adjust_range (int *z1, int *dz1, int *z2, int *dz2, int inc2)
{
/* skip odd start pixel: */
if (*z1 & 1) {
*z1 += 1;
*dz1 -= 1;
*z2 += inc2;
*dz2 -= inc2;
}
/* clip the range: */
if (*dz1 & 1) {
*dz1 -= 1;
*dz2 -= inc2;
}
return (*dz1 > 0 && *dz2 > 0);
}
/*
* Format-conversion routines.
* Use:
* int XXXXtoYYYYEx (unsigned char *dest_ptr, int dest_width, int dest_height,
* int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
* unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
* int src_x, int src_y, int src_dx, int src_dy);
* Input:
* dest_ptr - pointer to a destination buffer
* dest_width, dest_height - width/height of the destination image (pixels)
* dest_pitch - pitch of the dest. buffer (in bytes; <0 - if bottom up image)
* dest_x, dest_y, dest_dx, dest_dy - destination rectangle (pixels)
* src_ptr - pointer to an input image
* src_width, src_height - width/height of the input image (pixels)
* src_pitch - pitch of the source buffer (in bytes; <0 - if bottom up image)
* src_x, src_y, src_dx, src_dy - source rectangle (pixels)
* Returns:
* 0 - if success; -1 if failure.
* Notes:
* a) In all cases, pointers to the source and destination buffers must be
* DWORD aligned, and both pitch parameters must be multiple of 4!!!
* b) Converters that deal with YUV 4:2:2, or 4:2:0 formats may also require
* rectangle parameters (x,y,dx,dy) to be multiple of 2. Failure to provide
* aligned rectangles will result in partially converted image.
* c) Currently only scale factors of 1:1 and 2:1 are supported; if the rates
* dest_dx/src_dx & dest_dy/src_dy are neither 1, or 2, the converters
* will fail.
*/
/*
* I420toI420() converter:
*/
int I420toI420 (unsigned char *dest_ptr, int dest_width, int dest_height,
int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
int src_x, int src_y, int src_dx, int src_dy)
{
/* scale factors: */
int scale_x, scale_y;
/* check arguments: */
if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
return -1;
/* remove odd destination pixels: */
if (!adjust_range (&dest_x, &dest_dx, &src_x, &src_dx, scale_x) ||
!adjust_range (&dest_y, &dest_dy, &src_y, &src_dy, scale_y))
return 0;
/* check if we have matching chroma components: */
if ((src_x & 1) || (src_y & 1))
return -1; /* can't shift chromas */
/* check if bottop-up images: */
if (dest_pitch <= 0 || src_pitch <= 0)
return -1; /* not supported for this format */
/* check if 1:1 scale: */
if (scale_x == 1 && scale_y == 1) {
/* check if no color adjustmenst: */
if (!(is_alpha | is_beta | is_gamma | is_kappa)) {
/* no color adjustments: */
unsigned char *s, *d;
int src_uv_offs, dest_uv_offs;
register int i;
/* copy Y plane: */
s = src_ptr + src_x + src_y * src_pitch;
d = dest_ptr + dest_x + dest_y * dest_pitch;
for (i = 0; i < dest_dy; i ++) {
memcpy (d, s, dest_dx); /* Flawfinder: ignore */
s += src_pitch;
d += dest_pitch;
}
/* get Cr/Cb offsets: */
src_uv_offs = src_height * src_pitch / 4;
dest_uv_offs = dest_height * dest_pitch / 4;
/* copy Cr/Cb planes: */
s = (src_ptr + src_height * src_pitch) + src_x/2 + src_y/2 * src_pitch/2;
d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
for (i = 0; i < dest_dy/2; i ++) {
memcpy (d, s, dest_dx/2); /* Flawfinder: ignore */
memcpy (d + dest_uv_offs, s + src_uv_offs, dest_dx/2); /* Flawfinder: ignore */
s += src_pitch/2;
d += dest_pitch/2;
}
} else {
/* adjust colors: */
unsigned char *s, *d;
int src_uv_offs, dest_uv_offs;
register int i, j;
/* convert Y plane: */
s = src_ptr + src_x + src_y * src_pitch;
d = dest_ptr + dest_x + dest_y * dest_pitch;
for (i = 0; i < dest_dy; i ++) {
/* convert pixels: */
for (j = 0; j < dest_dx; j ++)
d[j] = _yytab[s[j]];
s += src_pitch;
d += dest_pitch;
}
/* get Cr/Cb offsets: */
src_uv_offs = src_height * src_pitch / 4;
dest_uv_offs = dest_height * dest_pitch / 4;
/* get chroma pointers: */
s = (src_ptr + src_height * src_pitch) + src_x/2 + src_y/2 * src_pitch/2;
d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
/* check if no hue adjustment: */
if (!is_alpha) {
/* no chroma rotation: */
for (i = 0; i < dest_dy/2; i ++) {
/* convert pixels: */
for (j = 0; j < dest_dx/2; j ++) {
d[j] = _vvtab[s[j]];
d[j + dest_uv_offs] = _uutab[s[j + src_uv_offs]];
}
s += src_pitch/2;
d += dest_pitch/2;
}
} else {
/* adjust hue: */
for (i = 0; i < dest_dy/2; i ++) {
/* convert pixels: */
for (j = 0; j < dest_dx/2; j ++) {
register unsigned v = s[j], u = s[j + src_uv_offs];
d[j] = CLIP8[_vvtab[v] + _vutab[u]];
d[j + dest_uv_offs] = CLIP8[_uutab[u] + _uvtab[v]];
}
s += src_pitch/2;
d += dest_pitch/2;
}
}
}
return 0;
}
/* conversion is not supported */
return -1;
}
/*
* I420toYV12() converter:
*/
int I420toYV12 (unsigned char *dest_ptr, int dest_width, int dest_height,
int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
int src_x, int src_y, int src_dx, int src_dy)
{
/* scale factors: */
int scale_x, scale_y;
/* check arguments: */
if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
dest_x, dest_y, dest_dx, dest_dy, src_ptr, src_width, src_height,
src_pitch, src_x, src_y, src_dx, src_dy, &scale_x, &scale_y))
return -1;
/* remove odd destination pixels: */
if (!adjust_range (&dest_x, &dest_dx, &src_x, &src_dx, scale_x) ||
!adjust_range (&dest_y, &dest_dy, &src_y, &src_dy, scale_y))
return 0;
/* check if we have matching chroma components: */
if ((src_x & 1) || (src_y & 1))
return -1; /* can't shift chromas */
/* check if bottop-up images: */
if (dest_pitch <= 0 || src_pitch <= 0)
return -1; /* not supported for this format */
/* check if 1:1 scale: */
if (scale_x == 1 && scale_y == 1) {
/* check if no color adjustments: */
if (!(is_alpha | is_beta | is_gamma | is_kappa)) {
/* no color adjustments: */
unsigned char *s, *d;
int src_uv_offs, dest_uv_offs;
register int i;
/* copy Y plane: */
s = src_ptr + src_x + src_y * src_pitch;
d = dest_ptr + dest_x + dest_y * dest_pitch;
for (i = 0; i < dest_dy; i ++) {
memcpy (d, s, dest_dx); /* Flawfinder: ignore */
s += src_pitch;
d += dest_pitch;
}
/* get Cr/Cb offsets: */
src_uv_offs = src_height * src_pitch / 4;
dest_uv_offs = dest_height * dest_pitch / 4;
/* copy Cr/Cb planes: */
s = (src_ptr + src_height * src_pitch) + src_x/2 + src_y/2 * src_pitch/2;
d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
for (i = 0; i < dest_dy/2; i ++) {
memcpy (d, s + src_uv_offs, dest_dx/2); /* Flawfinder: ignore */
memcpy (d + dest_uv_offs, s, dest_dx/2); /* Flawfinder: ignore */
s += src_pitch/2;
d += dest_pitch/2;
}
} else {
/* adjust colors: */
unsigned char *s, *d;
int src_uv_offs, dest_uv_offs;
register int i, j;
/* convert Y plane: */
s = src_ptr + src_x + src_y * src_pitch;
d = dest_ptr + dest_x + dest_y * dest_pitch;
for (i = 0; i < dest_dy; i ++) {
/* convert pixels: */
for (j = 0; j < dest_dx; j ++)
d[j] = _yytab[s[j]];
s += src_pitch;
d += dest_pitch;
}
/* get Cr/Cb offsets: */
src_uv_offs = src_height * src_pitch / 4;
dest_uv_offs = dest_height * dest_pitch / 4;
/* get chroma pointers: */
s = (src_ptr + src_height * src_pitch) + src_x/2 + src_y/2 * src_pitch/2;
d = (dest_ptr + dest_height * dest_pitch) + dest_x/2 + dest_y/2 * dest_pitch/2;
/* check if no hue adjustment: */
if (!is_alpha) {
/* no chroma rotation: */
for (i = 0; i < dest_dy/2; i ++) {
/* convert pixels: */
for (j = 0; j < dest_dx/2; j ++) {
d[j] = _vvtab[s[j + src_uv_offs]];
d[j + dest_uv_offs] = _uutab[s[j]];
}
s += src_pitch/2;
d += dest_pitch/2;
}
} else {
/* adjust hue: */
for (i = 0; i < dest_dy/2; i ++) {
/* convert pixels: */
for (j = 0; j < dest_dx/2; j ++) {
register unsigned v = s[j + src_uv_offs], u = s[j];
d[j] = CLIP8[_vvtab[v] + _vutab[u]];
d[j + dest_uv_offs] = CLIP8[_uutab[u] + _uvtab[v]];
}
s += src_pitch/2;
d += dest_pitch/2;
}
}
}
return 0;
}
/* conversion is not supported */
return -1;
}
/*
* I420toYUY2() converter:
*/
int I420toYUY2 (unsigned char *dest_ptr, int dest_width, int dest_height,
int dest_pitch, int dest_x, int dest_y, int dest_dx, int dest_dy,
unsigned char *src_ptr, int src_width, int src_height, int src_pitch,
int src_x, int src_y, int src_dx, int src_dy)
{
/* scale factors: */
int scale_x, scale_y;
/* check arguments: */
if (!chk_args (dest_ptr, dest_width, dest_height, dest_pitch,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?