video_util_rgb.cpp
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:6k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /**************************************************************************
  2.  *                                                                        *
  3.  * This code is developed by Adam Li.  This software is an                *
  4.  * implementation of a part of one or more MPEG-4 Video tools as          *
  5.  * specified in ISO/IEC 14496-2 standard.  Those intending to use this    *
  6.  * software module in hardware or software products are advised that its  *
  7.  * use may infringe existing patents or copyrights, and any such use      *
  8.  * would be at such party's own risk.  The original developer of this     *
  9.  * software module and his/her company, and subsequent editors and their  *
  10.  * companies (including Project Mayo), will have no liability for use of  *
  11.  * this software or modifications or derivatives thereof.                 *
  12.  *                                                                        *
  13.  * Project Mayo gives users of the Codec a license to this software       *
  14.  * module or modifications thereof for use in hardware or software        *
  15.  * products claiming conformance to the MPEG-4 Video Standard as          *
  16.  * described in the Open DivX license.                                    *
  17.  *                                                                        *
  18.  * The complete Open DivX license can be found at                         *
  19.  * http://www.projectmayo.com/opendivx/license.php .                      *
  20.  *                                                                        *
  21.  **************************************************************************/
  22. /**************************************************************************
  23.  *
  24.  *  rgb2yuv.c, 24-bit RGB bitmap to YUV converter
  25.  *
  26.  *  Copyright (C) 2001  Project Mayo
  27.  *
  28.  *  Adam Li
  29.  *
  30.  *  DivX Advance Research Center <darc@projectmayo.com>
  31.  *
  32.  **************************************************************************/
  33. /* This file contains RGB to YUV transformation functions.                */
  34. #include "stdlib.h"
  35. #include "video_util_rgb.h"
  36. static float RGBYUV02990[256], RGBYUV05870[256], RGBYUV01140[256];
  37. static float RGBYUV01684[256], RGBYUV03316[256];
  38. static float RGBYUV04187[256], RGBYUV00813[256];
  39. void InitLookupTable();
  40. /************************************************************************
  41.  *
  42.  *  int RGB2YUV (int x_dim, int y_dim, void *bmp, YUV *yuv)
  43.  *
  44.  * Purpose : It takes a 24-bit RGB bitmap and convert it into
  45.  * YUV (4:2:0) format
  46.  *
  47.  *  Input : x_dim the x dimension of the bitmap
  48.  * y_dim the y dimension of the bitmap
  49.  * bmp pointer to the buffer of the bitmap
  50.  * yuv pointer to the YUV structure
  51.  *
  52.  *  Output : 0 OK
  53.  * 1 wrong dimension
  54.  * 2 memory allocation error
  55.  *
  56.  * Side Effect :
  57.  * None
  58.  *
  59.  * Date : 09/28/2000
  60.  *
  61.  *  Contacts:
  62.  *
  63.  *  Adam Li
  64.  *
  65.  *  DivX Advance Research Center <darc@projectmayo.com>
  66.  *
  67.  ************************************************************************/
  68. int RGB2YUV (int x_dim, int y_dim, void *bmp, void *y_out, void *u_out, void *v_out, int flip)
  69. {
  70. static int init_done = 0;
  71. long i, j, size;
  72. unsigned char *r, *g, *b;
  73. unsigned char *y, *u, *v;
  74. unsigned char *pu1, *pu2, *pv1, *pv2, *psu, *psv;
  75. unsigned char *y_buffer, *u_buffer, *v_buffer;
  76. unsigned char *sub_u_buf, *sub_v_buf;
  77. if (init_done == 0)
  78. {
  79. InitLookupTable();
  80. init_done = 1;
  81. }
  82. // check to see if x_dim and y_dim are divisible by 2
  83. if ((x_dim % 2) || (y_dim % 2)) return 1;
  84. size = x_dim * y_dim;
  85. // allocate memory
  86. y_buffer = (unsigned char *)y_out;
  87. sub_u_buf = (unsigned char *)u_out;
  88. sub_v_buf = (unsigned char *)v_out;
  89. u_buffer = (unsigned char *)malloc(size * sizeof(unsigned char));
  90. v_buffer = (unsigned char *)malloc(size * sizeof(unsigned char));
  91. if (!(u_buffer && v_buffer))
  92. {
  93. if (u_buffer) free(u_buffer);
  94. if (v_buffer) free(v_buffer);
  95. return 2;
  96. }
  97. b = (unsigned char *)bmp;
  98. y = y_buffer;
  99. u = u_buffer;
  100. v = v_buffer;
  101. // convert RGB to YUV
  102. if (!flip) {
  103. for (j = 0; j < y_dim; j ++)
  104. {
  105. y = y_buffer + (y_dim - j - 1) * x_dim;
  106. u = u_buffer + (y_dim - j - 1) * x_dim;
  107. v = v_buffer + (y_dim - j - 1) * x_dim;
  108. for (i = 0; i < x_dim; i ++) {
  109. g = b + 1;
  110. r = b + 2;
  111. *y = (unsigned char)(  RGBYUV02990[*r] + RGBYUV05870[*g] + RGBYUV01140[*b]);
  112. *u = (unsigned char)(- RGBYUV01684[*r] - RGBYUV03316[*g] + (*b)/2          + 128);
  113. *v = (unsigned char)(  (*r)/2          - RGBYUV04187[*g] - RGBYUV00813[*b] + 128);
  114. b += 3;
  115. y ++;
  116. u ++;
  117. v ++;
  118. }
  119. }
  120. } else {
  121. for (i = 0; i < size; i++)
  122. {
  123. g = b + 1;
  124. r = b + 2;
  125. *y = (unsigned char)(  RGBYUV02990[*r] + RGBYUV05870[*g] + RGBYUV01140[*b]);
  126. *u = (unsigned char)(- RGBYUV01684[*r] - RGBYUV03316[*g] + (*b)/2          + 128);
  127. *v = (unsigned char)(  (*r)/2          - RGBYUV04187[*g] - RGBYUV00813[*b] + 128);
  128. b += 3;
  129. y ++;
  130. u ++;
  131. v ++;
  132. }
  133. }
  134. // subsample UV
  135. for (j = 0; j < y_dim/2; j ++)
  136. {
  137. psu = sub_u_buf + j * x_dim / 2;
  138. psv = sub_v_buf + j * x_dim / 2;
  139. pu1 = u_buffer + 2 * j * x_dim;
  140. pu2 = u_buffer + (2 * j + 1) * x_dim;
  141. pv1 = v_buffer + 2 * j * x_dim;
  142. pv2 = v_buffer + (2 * j + 1) * x_dim;
  143. for (i = 0; i < x_dim/2; i ++)
  144. {
  145. *psu = (*pu1 + *(pu1+1) + *pu2 + *(pu2+1)) / 4;
  146. *psv = (*pv1 + *(pv1+1) + *pv2 + *(pv2+1)) / 4;
  147. psu ++;
  148. psv ++;
  149. pu1 += 2;
  150. pu2 += 2;
  151. pv1 += 2;
  152. pv2 += 2;
  153. }
  154. }
  155. free(u_buffer);
  156. free(v_buffer);
  157. return 0;
  158. }
  159. void InitLookupTable()
  160. {
  161. int i;
  162. for (i = 0; i < 256; i++) RGBYUV02990[i] = (float)0.2990 * i;
  163. for (i = 0; i < 256; i++) RGBYUV05870[i] = (float)0.5870 * i;
  164. for (i = 0; i < 256; i++) RGBYUV01140[i] = (float)0.1140 * i;
  165. for (i = 0; i < 256; i++) RGBYUV01684[i] = (float)0.1684 * i;
  166. for (i = 0; i < 256; i++) RGBYUV03316[i] = (float)0.3316 * i;
  167. for (i = 0; i < 256; i++) RGBYUV04187[i] = (float)0.4187 * i;
  168. for (i = 0; i < 256; i++) RGBYUV00813[i] = (float)0.0813 * i;
  169. }