⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rgb2yuv.c

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 C
📖 第 1 页 / 共 3 页
字号:

/*
 * 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 + -