rgb2yuv


Thanks to Adam Li.





/**************************************************************************
 *                                                                        *
 * This code is developed by Adam Li.  This software is an                *
 * implementation of a part of one or more MPEG-4 Video tools as          *
 * specified in ISO/IEC 14496-2 standard.  Those intending to use this    *
 * software module in hardware or software products are advised that its  *
 * use may infringe existing patents or copyrights, and any such use      *
 * would be at such party's own risk.  The original developer of this     *
 * software module and his/her company, and subsequent editors and their  *
 * companies (including Project Mayo), will have no liability for use of  *
 * this software or modifications or derivatives thereof.                 *
 *                                                                        *
 * Project Mayo gives users of the Codec a license to this software       *
 * module or modifications thereof for use in hardware or software        *
 * products claiming conformance to the MPEG-4 Video Standard as          *
 * described in the Open DivX license.                                    *
 *                                                                        *
 * The complete Open DivX license can be found at                         *
 * http://www.projectmayo.com/opendivx/license.php .                      *
 *                                                                        *
 **************************************************************************/

/**************************************************************************
 *
 *  rgb2yuv.c, 24-bit RGB bitmap to YUV converter
 *
 *  Copyright (C) 2001  Project Mayo
 *
 *  Adam Li
 *
 *  DivX Advance Research Center 
 *
 **************************************************************************/

/* This file contains RGB to YUV transformation functions.                */

#include "stdlib.h"
#include "rgb2yuv.h"

static float RGBYUV02990[256], RGBYUV05870[256], RGBYUV01140[256];
static float RGBYUV01684[256], RGBYUV03316[256];
static float RGBYUV04187[256], RGBYUV00813[256];

void InitLookupTable();

/************************************************************************
 *
 *  int RGB2YUV (int x_dim, int y_dim, void *bmp, YUV *yuv)
 *
 * Purpose : It takes a 24-bit RGB bitmap and convert it into
 *    YUV (4:2:0) format
 *
 *  Input :  x_dim the x dimension of the bitmap
 *    y_dim the y dimension of the bitmap
 *    bmp  pointer to the buffer of the bitmap
 *    yuv  pointer to the YUV structure
 *
 *  Output : 0  OK
 *    1  wrong dimension
 *    2  memory allocation error
 *
 * Side Effect :
 *    None
 *
 * Date :  09/28/2000
 *
 *  Contacts:
 *
 *  Adam Li
 *
 *  DivX Advance Research Center 
 *
 ************************************************************************/

int RGB2YUV (int x_dim, int y_dim, void *bmp, void *y_out, void *u_out, void *v_out, int flip)
{
 static int init_done = 0;

 long i, j, size;
 unsigned char *r, *g, *b;
 unsigned char *y, *u, *v;
 unsigned char *pu1, *pu2, *pv1, *pv2, *psu, *psv;
 unsigned char *y_buffer, *u_buffer, *v_buffer;
 unsigned char *sub_u_buf, *sub_v_buf;

 if (init_done == 0)
 {
  InitLookupTable();
  init_done = 1;
 }

 // check to see if x_dim and y_dim are divisible by 2
 if ((x_dim % 2) || (y_dim % 2)) return 1;
 size = x_dim * y_dim;

 // allocate memory
 y_buffer = (unsigned char *)y_out;
 sub_u_buf = (unsigned char *)u_out;
 sub_v_buf = (unsigned char *)v_out;
 u_buffer = (unsigned char *)malloc(size * sizeof(unsigned char));
 v_buffer = (unsigned char *)malloc(size * sizeof(unsigned char));
 if (!(u_buffer && v_buffer))
 {
  if (u_buffer) free(u_buffer);
  if (v_buffer) free(v_buffer);
  return 2;
 }

 b = (unsigned char *)bmp;
 y = y_buffer;
 u = u_buffer;
 v = v_buffer;

 // convert RGB to YUV
 if (!flip) {
  for (j = 0; j < y_dim; j ++)
  {
   y = y_buffer + (y_dim - j - 1) * x_dim;
   u = u_buffer + (y_dim - j - 1) * x_dim;
   v = v_buffer + (y_dim - j - 1) * x_dim;

   for (i = 0; i < x_dim; i ++) {
    g = b + 1;
    r = b + 2;
    *y = (unsigned char)(  RGBYUV02990[*r] + RGBYUV05870[*g] + RGBYUV01140[*b]);
    *u = (unsigned char)(- RGBYUV01684[*r] - RGBYUV03316[*g] + (*b)/2          + 128);
    *v = (unsigned char)(  (*r)/2          - RGBYUV04187[*g] - RGBYUV00813[*b] + 128);
    b += 3;
    y ++;
    u ++;
    v ++;
   }
  }
 } else {
  for (i = 0; i < size; i++)
  {
   g = b + 1;
   r = b + 2;
   *y = (unsigned char)(  RGBYUV02990[*r] + RGBYUV05870[*g] + RGBYUV01140[*b]);
   *u = (unsigned char)(- RGBYUV01684[*r] - RGBYUV03316[*g] + (*b)/2          + 128);
   *v = (unsigned char)(  (*r)/2          - RGBYUV04187[*g] - RGBYUV00813[*b] + 128);
   b += 3;
   y ++;
   u ++;
   v ++;
  }
 }

 // subsample UV
 for (j = 0; j < y_dim/2; j ++)
 {
  psu = sub_u_buf + j * x_dim / 2;
  psv = sub_v_buf + j * x_dim / 2;
  pu1 = u_buffer + 2 * j * x_dim;
  pu2 = u_buffer + (2 * j + 1) * x_dim;
  pv1 = v_buffer + 2 * j * x_dim;
  pv2 = v_buffer + (2 * j + 1) * x_dim;
  for (i = 0; i < x_dim/2; i ++)
  {
   *psu = (*pu1 + *(pu1+1) + *pu2 + *(pu2+1)) / 4;
   *psv = (*pv1 + *(pv1+1) + *pv2 + *(pv2+1)) / 4;
   psu ++;
   psv ++;
   pu1 += 2;
   pu2 += 2;
   pv1 += 2;
   pv2 += 2;
  }
 }

 free(u_buffer);
 free(v_buffer);

 return 0;
}


void InitLookupTable()
{
 int i;

 for (i = 0; i < 256; i++) RGBYUV02990[i] = (float)0.2990 * i;
 for (i = 0; i < 256; i++) RGBYUV05870[i] = (float)0.5870 * i;
 for (i = 0; i < 256; i++) RGBYUV01140[i] = (float)0.1140 * i;
 for (i = 0; i < 256; i++) RGBYUV01684[i] = (float)0.1684 * i;
 for (i = 0; i < 256; i++) RGBYUV03316[i] = (float)0.3316 * i;
 for (i = 0; i < 256; i++) RGBYUV04187[i] = (float)0.4187 * i;
 for (i = 0; i < 256; i++) RGBYUV00813[i] = (float)0.0813 * i;
}


이 블로그의 인기 게시물

둘 중 누군가 그녀를 죽였다, 범인 해설

[MAC OS X] mds_stores 100% CPU usage

tips more on unity ...