Fawkes API Fawkes Development Version
|
00001 00002 /**************************************************************************** 00003 * rgbyuv.h - RGB to YUV conversion - specific methods, macros and constants 00004 * 00005 * Created: Sat Aug 12 15:21:39 2006 00006 * based on colorspaces.h from Tue Feb 23 13:49:38 2005 00007 * Copyright 2005-2006 Tim Niemueller [www.niemueller.de] 00008 * 00009 ****************************************************************************/ 00010 00011 /* This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. A runtime exception applies to 00015 * this software (see LICENSE.GPL_WRE file mentioned below for details). 00016 * 00017 * This program is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 * GNU Library General Public License for more details. 00021 * 00022 * Read the full text in the LICENSE.GPL_WRE file in the doc directory. 00023 */ 00024 00025 #include <fvutils/color/rgbyuv.h> 00026 #include <fvutils/color/yuv.h> 00027 #include <fvutils/color/rgb.h> 00028 #include <fvutils/color/colorspaces.h> 00029 00030 #include <cstring> 00031 00032 namespace firevision { 00033 #if 0 /* just to make Emacs auto-indent happy */ 00034 } 00035 #endif 00036 00037 void 00038 rgb_to_yuy2(const unsigned char *RGB, unsigned char *YUV, unsigned int width, unsigned int height) 00039 { 00040 unsigned int i, j; 00041 register int y0, y1, u0, u1, v0, v1 ; 00042 register int r, g, b; 00043 00044 for (i = 0, j = 0; i < 3 * width * height; i += 6, j += 4) { 00045 r = RGB[i + 0]; 00046 g = RGB[i + 1]; 00047 b = RGB[i + 2]; 00048 RGB2YUV(r, g, b, y0, u0 , v0); 00049 r = RGB[i + 3]; 00050 g = RGB[i + 4]; 00051 b = RGB[i + 5]; 00052 RGB2YUV(r, g, b, y1, u1 , v1); 00053 YUV[j + 0] = y0; 00054 YUV[j + 1] = (u0+u1)/2; 00055 YUV[j + 2] = y1; 00056 YUV[j + 3] = (v0+v1)/2; 00057 } 00058 } 00059 00060 00061 /** RGB to YUV Conversion 00062 * 00063 * Y = (0.257 * R) + (0.504 * G) + (0.098 * B) + 16 00064 * Cr = V = (0.439 * R) - (0.368 * G) - (0.071 * B) + 128 00065 * Cb = U = -(0.148 * R) - (0.291 * G) + (0.439 * B) + 128 00066 * 00067 * Values have to be clamped to keep them in the [0-255] range. 00068 * Rumour has it that the valid range is actually a subset of [0-255] (fourcc.org mentions an RGB range 00069 * of [16-235]) but clamping the values into [0-255] seems to produce acceptable results. 00070 * @param RGB unsigned char array that contains the pixels, pixel after pixel, 3 bytes per pixel 00071 * (thus this is a 24bit RGB with one byte per color) line by line. 00072 * @param YUV where the YUV output will be written to, will have 4 pixels in 6 byte macro pixel, line after 00073 * line 00074 * @param width Width of the image contained in the RGB buffer 00075 * @param height Height of the image contained in the RGB buffer 00076 */ 00077 void 00078 rgb_to_yuv411packed_plainc(const unsigned char *RGB, unsigned char *YUV, 00079 unsigned int width, unsigned int height) 00080 { 00081 register unsigned int i = 0, j = 0; 00082 register int y[4] = {0, 0, 0, 0}, u, v; 00083 register RGB_t *r; 00084 register unsigned int su = 0; 00085 register unsigned int sv = 0; 00086 00087 while (i < (width * height)) { 00088 r = (RGB_t *)RGB; 00089 for (register unsigned int k = 0; j <= 4; ++j) { 00090 RGB2YUV(r->R, r->G, r->B, y[k], u, v); 00091 su += u; 00092 sv += v; 00093 RGB += 3; 00094 } 00095 YUV[j++] = su/4; 00096 YUV[j++] = y[0]; 00097 YUV[j++] = y[1]; 00098 YUV[j++] = sv/4; 00099 YUV[j++] = y[2]; 00100 YUV[j++] = y[3]; 00101 } 00102 } 00103 00104 00105 /** Convert a line of a RGB buffer to a line in a planar YUV422 buffer. 00106 * See above for general notes about color space conversion from RGB to YUV. 00107 * @param RGB unsigned char array that contains the pixels, pixel after pixel, 3 bytes per pixel 00108 * (thus this is a 24bit RGB with one byte per color) line by line. 00109 * @param YUV where the YUV output will be written to, will have 4 pixels in 6 byte macro pixel, line after 00110 * line 00111 * @param width Width of the image contained in the RGB buffer 00112 * @param height Height of the image contained in the RGB buffer 00113 * @param rgb_line the index of the line to be converted 00114 * @param yuv_line the index of the line to convert to in the YUV buffer 00115 */ 00116 void 00117 convert_line_rgb_to_yuv422planar(const unsigned char *RGB, unsigned char *YUV, 00118 unsigned int width, unsigned int height, 00119 unsigned int rgb_line, unsigned int yuv_line) 00120 { 00121 register unsigned int i = 0; 00122 register int y1, y2, u1, u2, v1, v2; 00123 register RGB_t *r1, *r2; 00124 register unsigned char *yp, *up, *vp; 00125 00126 yp = YUV + (width * yuv_line); 00127 up = YUV422_PLANAR_U_PLANE(YUV, width, height) + (width * yuv_line / 2); 00128 vp = YUV422_PLANAR_V_PLANE(YUV, width, height) + (width * yuv_line / 2); 00129 00130 RGB += 3 * width * rgb_line; 00131 00132 while (i < width) { 00133 r1 = (RGB_t *)RGB; 00134 RGB += 3; 00135 r2 = (RGB_t *)RGB; 00136 RGB += 3; 00137 00138 RGB2YUV(r1->R, r1->G, r1->B, y1, u1, v1); 00139 RGB2YUV(r2->R, r2->G, r2->B, y2, u2, v2); 00140 00141 *yp++ = y1; 00142 *yp++ = y2; 00143 *up++ = (u1 + u2) / 2; 00144 *vp++ = (v1 + v2) / 2; 00145 00146 i += 2; 00147 } 00148 } 00149 00150 00151 /** Convert an RGB buffer to a planar YUV422 buffer. 00152 * See above for general notes about color space conversion from RGB to YUV. 00153 * @param RGB unsigned char array that contains the pixels, pixel after pixel, 3 bytes per pixel 00154 * (thus this is a 24bit RGB with one byte per color) line by line. 00155 * @param YUV where the YUV output will be written to, will have 4 pixels in 6 byte macro pixel, line after 00156 * line 00157 * @param width Width of the image contained in the RGB buffer 00158 * @param height Height of the image contained in the RGB buffer 00159 */ 00160 void 00161 rgb_to_yuv422planar_plainc(const unsigned char *RGB, unsigned char *YUV, 00162 unsigned int width, unsigned int height) 00163 { 00164 register unsigned int i = 0; 00165 register int y1, y2, u1, u2, v1, v2; 00166 register RGB_t *r1, *r2; 00167 register unsigned char *yp, *up, *vp; 00168 00169 yp = YUV; 00170 up = YUV422_PLANAR_U_PLANE(YUV, width, height); 00171 vp = YUV422_PLANAR_V_PLANE(YUV, width, height); 00172 00173 while (i < (width * height)) { 00174 r1 = (RGB_t *)RGB; 00175 RGB += 3; 00176 r2 = (RGB_t *)RGB; 00177 RGB += 3; 00178 00179 RGB2YUV(r1->R, r1->G, r1->B, y1, u1, v1); 00180 RGB2YUV(r2->R, r2->G, r2->B, y2, u2, v2); 00181 00182 *yp++ = y1; 00183 *yp++ = y2; 00184 *up++ = (u1 + u2) / 2; 00185 *vp++ = (v1 + v2) / 2; 00186 00187 i += 2; 00188 } 00189 } 00190 00191 /* Convert a line of a RGB buffer to a line in a packed YUV422 buffer, see above for general 00192 * notes about color space conversion from RGB to YUV 00193 * @param RGB unsigned char array that contains the pixels, pixel after pixel, 3 bytes per pixel 00194 * (thus this is a 24bit RGB with one byte per color) line by line. 00195 * @param YUV where the YUV output will be written to, will have 4 pixels in 6 byte macro pixel, line after 00196 * line 00197 * @param width Width of the image contained in the RGB buffer 00198 * @param height Height of the image contained in the RGB buffer 00199 * @param rgb_line the index of the line to be converted 00200 * @param yuv_line the index of the line to convert to in the YUV buffer 00201 */ 00202 void 00203 convert_line_rgb_to_yuv422packed(const unsigned char *RGB, unsigned char *YUV, 00204 unsigned int width, unsigned int height, 00205 unsigned int rgb_line, unsigned int yuv_line) 00206 { 00207 register unsigned int i = 0; 00208 register int y1, y2, u1, u2, v1, v2; 00209 register RGB_t *r1, *r2; 00210 register unsigned char *p; 00211 00212 p = YUV + (width * yuv_line) * 2; 00213 00214 RGB += 3 * width * rgb_line; 00215 00216 while (i < width) { 00217 r1 = (RGB_t *)RGB; 00218 RGB += 3; 00219 r2 = (RGB_t *)RGB; 00220 RGB += 3; 00221 00222 RGB2YUV(r1->R, r1->G, r1->B, y1, u1, v1); 00223 RGB2YUV(r2->R, r2->G, r2->B, y2, u2, v2); 00224 00225 *p++ = (u1 + u2) / 2; 00226 *p++ = y1; 00227 *p++ = (v1 + v2) / 2; 00228 *p++ = y2; 00229 00230 i += 2; 00231 } 00232 } 00233 00234 /* Convert an RGB buffer to a packed YUV422 buffer, see above for general notes about color space 00235 * conversion from RGB to YUV 00236 * @param RGB unsigned char array that contains the pixels, pixel after pixel, 3 bytes per pixel 00237 * (thus this is a 24bit RGB with one byte per color) line by line. 00238 * @param YUV where the YUV output will be written to, will have 4 pixels in 6 byte macro pixel, line after 00239 * line 00240 * @param width Width of the image contained in the RGB buffer 00241 * @param height Height of the image contained in the RGB buffer 00242 */ 00243 void 00244 rgb_to_yuv422packed_plainc(const unsigned char *RGB, unsigned char *YUV, 00245 unsigned int width, unsigned int height) 00246 { 00247 register unsigned int i = 0; 00248 register int y1, y2, u1, u2, v1, v2; 00249 register RGB_t *r1, *r2; 00250 register unsigned char *p; 00251 00252 p = YUV; 00253 00254 while (i < (width * height)) { 00255 r1 = (RGB_t *)RGB; 00256 RGB += 3; 00257 r2 = (RGB_t *)RGB; 00258 RGB += 3; 00259 00260 RGB2YUV(r1->R, r1->G, r1->B, y1, u1, v1); 00261 RGB2YUV(r2->R, r2->G, r2->B, y2, u2, v2); 00262 00263 *p++ = (u1 + u2) / 2; 00264 *p++ = y1; 00265 *p++ = (v1 + v2) / 2; 00266 *p++ = y2; 00267 00268 i += 2; 00269 } 00270 } 00271 00272 /** Convert an BGR buffer to a planar YUV422 buffer. 00273 * See above for general notes about color space conversion from RGB to YUV. 00274 * @param RGB unsigned char array that contains the pixels, pixel after pixel, 3 bytes per pixel 00275 * (thus this is a 24bit RGB with one byte per color) line by line. 00276 * @param YUV where the YUV output will be written to, will have 4 pixels in 6 byte macro pixel, line after 00277 * line 00278 * @param width Width of the image contained in the RGB buffer 00279 * @param height Height of the image contained in the RGB buffer 00280 */ 00281 void 00282 bgr_to_yuv422planar_plainc(const unsigned char *BGR, unsigned char *YUV, 00283 unsigned int width, unsigned int height) 00284 { 00285 register unsigned int i = 0; 00286 register int y1, y2, u1, u2, v1, v2; 00287 register BGR_t *r1, *r2; 00288 register unsigned char *yp, *up, *vp; 00289 00290 yp = YUV; 00291 up = YUV422_PLANAR_U_PLANE(YUV, width, height); 00292 vp = YUV422_PLANAR_V_PLANE(YUV, width, height); 00293 00294 while (i < (width * height)) { 00295 r1 = (BGR_t *)BGR; 00296 BGR += 3; 00297 r2 = (BGR_t *)BGR; 00298 BGR += 3; 00299 00300 RGB2YUV(r1->R, r1->G, r1->B, y1, u1, v1); 00301 RGB2YUV(r2->R, r2->G, r2->B, y2, u2, v2); 00302 00303 *yp++ = y1; 00304 *yp++ = y2; 00305 *up++ = (u1 + u2) / 2; 00306 *vp++ = (v1 + v2) / 2; 00307 00308 i += 2; 00309 } 00310 } 00311 00312 } // end namespace firevision