📄 rgb2yuv.c
字号:
/*
* Actual double-row converters:
*/
DBLROW_FUNC(I420, RGB32, CHROMA_11_11)
DBLROW_FUNC(I420, RGB32, CHROMA_11_00)
DBLROW_FUNC(I420, RGB32, CHROMA_00_11)
DBLROW_FUNC(I420, BGR_32, CHROMA_11_11)
DBLROW_FUNC(I420, BGR_32, CHROMA_11_00)
DBLROW_FUNC(I420, BGR_32, CHROMA_00_11)
DBLROW_FUNC(I420, RGB24, CHROMA_11_11)
DBLROW_FUNC(I420, RGB24, CHROMA_11_00)
DBLROW_FUNC(I420, RGB24, CHROMA_00_11)
DBLROW_FUNC(I420, BGR24, CHROMA_11_11)
DBLROW_FUNC(I420, BGR24, CHROMA_11_00)
DBLROW_FUNC(I420, BGR24, CHROMA_00_11)
DBLROW_FUNC(I420, RGB565, CHROMA_11_11)
DBLROW_FUNC(I420, RGB565, CHROMA_11_00)
DBLROW_FUNC(I420, RGB565, CHROMA_00_11)
DBLROW_FUNC(I420, RGB555, CHROMA_11_11)
DBLROW_FUNC(I420, RGB555, CHROMA_11_00)
DBLROW_FUNC(I420, RGB555, CHROMA_00_11)
DBLROW_FUNC(I420, RGB8, CHROMA_11_11)
DBLROW_FUNC(I420, RGB8, CHROMA_11_00)
DBLROW_FUNC(I420, RGB8, CHROMA_00_11)
/*
* Double-row scale function selection tables:
* [source format][chroma resampling type]
*/
static void (* DblRowFuncs [RGB_FORMATS+2][CHROMA_RESAMPLING_MODES]) (
unsigned char *, unsigned char *, unsigned char *, unsigned char *,
unsigned char *, unsigned char *, int) =
{
{
DBLROW_FN(I420, RGB32, CHROMA_11_11),
DBLROW_FN(I420, RGB32, CHROMA_11_00),
DBLROW_FN(I420, RGB32, CHROMA_00_11)
},
{ /* BGR32: */
0, 0, 0
},
{
DBLROW_FN(I420, RGB24, CHROMA_11_11),
DBLROW_FN(I420, RGB24, CHROMA_11_00),
DBLROW_FN(I420, RGB24, CHROMA_00_11)
},
{
DBLROW_FN(I420, RGB565, CHROMA_11_11),
DBLROW_FN(I420, RGB565, CHROMA_11_00),
DBLROW_FN(I420, RGB565, CHROMA_00_11)
},
{
DBLROW_FN(I420, RGB555, CHROMA_11_11),
DBLROW_FN(I420, RGB555, CHROMA_11_00),
DBLROW_FN(I420, RGB555, CHROMA_00_11)
},
{ /* RGB444: */
0, 0, 0
},
{
DBLROW_FN(I420, RGB8, CHROMA_11_11),
DBLROW_FN(I420, RGB8, CHROMA_11_00),
DBLROW_FN(I420, RGB8, CHROMA_00_11)
},
{
DBLROW_FN(I420, BGR_32, CHROMA_11_11),
DBLROW_FN(I420, BGR_32, CHROMA_11_00),
DBLROW_FN(I420, BGR_32, CHROMA_00_11)
},
{
DBLROW_FN(I420, BGR24, CHROMA_11_11),
DBLROW_FN(I420, BGR24, CHROMA_11_00),
DBLROW_FN(I420, BGR24, CHROMA_00_11)
}
};
/*
* Bytes per pixel (bpp) table:
*/
static int bpp [RGB_FORMATS+2] =
{
BPP(RGB32),
BPP(BGR32),
BPP(RGB24),
BPP(RGB565),
BPP(RGB555),
BPP(RGB444),
BPP(RGB8),
BPP(BGR_32),
BPP(BGR24)
};
/*
* The main RGBtoYUV converter:
*/
static int RGBtoYUV (
/* destination image parameters: */
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,
/* source format: */
int src_format,
/* source image parametersBto: */
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)
{
/* pointer to a double-row converter to use: */
void (*dblrow_proc) (unsigned char *, unsigned char *,
unsigned char *, unsigned char *, unsigned char *, unsigned char *, int);
/* pointers and source pixel depth: */
register unsigned char *dy1, *dy2, *du, *dv, *s1, *s2;
register int src_bpp, i;
/* check arguments: */
if (
/* alignments: */
((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)
{
fail: /* fail: */
return -1;
}
/* check scale factors: */
if (dest_dx != src_dx || dest_dy != src_dy)
/* no in-place resizing !!! */
goto fail;
/* skip odd start column: */
if (dest_x & 1) { dest_x ++; dest_dx --; src_x ++; src_dx --; }
/* clip horisontal range: */
if (dest_dx & 1) { dest_dx --; src_dx --; if (dest_dx <= 0) goto fail;}
/* skip odd start row: */
if (dest_y & 1) { dest_y ++; dest_dy --; src_y ++; src_dy --; }
/* clip vertical range: */
if (dest_dy & 1) { dest_dy --; src_dy --; if (dest_dy <= 0) goto fail;}
/* select row and image converters: */
dblrow_proc = DblRowFuncs [src_format] [chroma_resampling_mode];
/* get source pixel depth: */
src_bpp = bpp [src_format];
/* check if bottop-up images: */
if (src_pitch < 0) src_ptr -= (src_height-1) * src_pitch;
if (dest_pitch <= 0) return -1; /* not supported */
/* get pointers: */
s1 = src_ptr + src_x * src_bpp + src_y * src_pitch;
s2 = s1 + src_pitch;
dy1 = dest_ptr + dest_x + dest_y * dest_pitch; /* luma offsets */
dy2 = dy1 + dest_pitch;
du = dest_ptr + dest_height * dest_pitch
+ (dest_x/2 + dest_y/2 * dest_pitch / 2); /* chroma offset */
dv = du + dest_height * dest_pitch / 4;
/* the main loop (processes 2 lines a time): */
for (i = 0; i < dest_dy/2; i ++) {
(*dblrow_proc) (dy1, dy2, du, dv, s1, s2, dest_dx);
/* switch to the next two lines: */
s1 += src_pitch * 2; s2 += src_pitch * 2;
dy1 += dest_pitch * 2; dy2 += dest_pitch * 2;
du += dest_pitch / 2; dv += dest_pitch / 2;
}
/* success: */
return 0;
}
/*
* Public format-conversion routines.
* Use:
* int XXXXtoYYYY (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.
* Note:
* Both source and destination buffers must be 4-bytes aligned,
* and their pitches (#of bytes in row) shall be multiple of 4!!!
*/
#define RGBTOYUV_FUNC(sf) \
int FN(I420,sf) (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) \
{ \
return RGBtoYUV( \
dest_ptr, dest_width, dest_height, \
dest_pitch, dest_x, dest_y, dest_dx, dest_dy, \
ID(sf), src_ptr, src_width, src_height, \
src_pitch, src_x, src_y, src_dx, src_dy); \
}
RGBTOYUV_FUNC(RGB32 )
RGBTOYUV_FUNC(RGB24 )
RGBTOYUV_FUNC(RGB565)
RGBTOYUV_FUNC(RGB555)
RGBTOYUV_FUNC(RGB8)
RGBTOYUV_FUNC(BGR_32 )
RGBTOYUV_FUNC(BGR24 )
/*********************************
* Back to the old stuff: */
/*
* Checks format conversion parameters.
* Use:
* int chk_args (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,
* int *p_scale_x, int *p_scale_y);
* 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)
* Output:
* p_scale_x, p_scale_y - scale factors for x,y axes
* (currently only 1:1, and 2:1 scale factors are allowed)
* Returns:
* 0 - if success; -1 if failure.
*/
static int
chk_args (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,
int *p_scale_x, int *p_scale_y)
{
/* 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 ||
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -