Fawkes API
Fawkes Development Version
|
00001 00002 /**************************************************************************** 00003 * yuvrgb.h - YUV to RGB conversion - specific methods, macros and constants 00004 * 00005 * Created: Sat Aug 12 15:01:36 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 #ifndef __FIREVISION_UTILS_COLOR_YUVRGB_H 00026 #define __FIREVISION_UTILS_COLOR_YUVRGB_H 00027 00028 #include <fvutils/color/yuv.h> 00029 #include <fvutils/color/rgb.h> 00030 00031 namespace firevision { 00032 #if 0 /* just to make Emacs auto-indent happy */ 00033 } 00034 #endif 00035 00036 00037 #define YUV2RGB(y, u, v, r, g, b) {\ 00038 r = y + ((v*1436) >> 10); \ 00039 g = y - ((u*352 + v*731) >> 10); \ 00040 b = y + ((u*1814) >> 10); \ 00041 r = r < 0 ? 0 : r; \ 00042 g = g < 0 ? 0 : g; \ 00043 b = b < 0 ? 0 : b; \ 00044 r = r > 255 ? 255 : r; \ 00045 g = g > 255 ? 255 : g; \ 00046 b = b > 255 ? 255 : b; } 00047 00048 00049 #define clip(x) (unsigned char)( (x) < 0 ? 0 : ( (x) > 255 ? 255 : (x) ) ) 00050 00051 00052 #define yuv411packed_to_rgb(YUV, RGB, width, height) yuv411packed_to_rgb_plainc(YUV, RGB, width, height) 00053 00054 00055 00056 /** YUV to RGB Conversion 00057 * B = 1.164(Y - 16) + 2.018(U - 128) 00058 * G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) 00059 * R = 1.164(Y - 16) + 1.596(V - 128) 00060 * 00061 * Values have to be clamped to keep them in the [0-255] range. 00062 * Rumour has it that the valid range is actually a subset of [0-255] (fourcc.org mentions an RGB range 00063 * of [16-235] mentioned) but clamping the values into [0-255] seems to produce acceptable results. 00064 * @param YUV unsigned char array that contains the pixels, 4 pixels in 6 byte macro pixel, line after 00065 * line 00066 * @param RGB where the RGB output will be written to, will have pixel after pixel, 3 bytes per pixel 00067 * (thus this is a 24bit RGB with one byte per color) line by line. 00068 * @param width Width of the image contained in the YUV buffer 00069 * @param height Height of the image contained in the YUV buffer 00070 */ 00071 void yuv411packed_to_rgb_plainc(const unsigned char *YUV, unsigned char *RGB, 00072 unsigned int width, unsigned int height); 00073 00074 00075 /** YUV to RGB Conversion 00076 * B = 1.164(Y - 16) + 2.018(U - 128) 00077 * G = 1.164(Y - 16) - 0.813(V - 128) - 0.391(U - 128) 00078 * R = 1.164(Y - 16) + 1.596(V - 128) 00079 * 00080 * Values have to be clamped to keep them in the [0-255] range. 00081 * Rumour has it that the valid range is actually a subset of [0-255] (fourcc.org mentions an RGB range 00082 * of [16-235] mentioned) but clamping the values into [0-255] seems to produce acceptable results. 00083 * @param YUV unsigned char array that contains the pixels, 4 pixels in 6 byte macro pixel, line after 00084 * line 00085 * @param RGB where the RGB output will be written to, will have pixel after pixel, 3 bytes per pixel 00086 * (thus this is a 24bit RGB with one byte per color) line by line. 00087 * @param width Width of the image contained in the YUV buffer 00088 * @param height Height of the image contained in the YUV buffer 00089 */ 00090 void yuv422planar_to_rgb_plainc(const unsigned char *planar, unsigned char *RGB, 00091 unsigned int width, unsigned int height); 00092 00093 void yuv422packed_to_rgb_plainc(const unsigned char *planar, unsigned char *RGB, 00094 unsigned int width, unsigned int height); 00095 00096 void yuv422planar_to_bgr_plainc(const unsigned char *planar, unsigned char *BGR, 00097 unsigned int width, unsigned int height); 00098 00099 00100 void yuv422planar_to_rgb_with_alpha_plainc(const unsigned char *planar, unsigned char *RGB, 00101 unsigned int width, unsigned int height); 00102 00103 void yuv422planar_to_bgr_with_alpha_plainc(const unsigned char *planar, unsigned char *BGR, 00104 unsigned int width, unsigned int height); 00105 00106 void yuv422packed_to_bgr_with_alpha_plainc(const unsigned char *YUV, unsigned char *BGR, 00107 unsigned int width, unsigned int height); 00108 00109 00110 #if (defined __i386__ || \ 00111 defined __386__ || \ 00112 defined __X86__ || \ 00113 defined _M_IX86 || \ 00114 defined i386 ) 00115 void yuv411planar_to_rgb_mmx (const unsigned char *yuv, unsigned char *rgb, 00116 unsigned int w, unsigned int h); 00117 #endif 00118 00119 00120 00121 inline void 00122 pixel_yuv_to_rgb(const unsigned char y, unsigned u, unsigned char v, 00123 unsigned char *r, unsigned char *g, unsigned char *b) 00124 { 00125 int yt, ut, vt; 00126 00127 yt = y - 16; 00128 ut = u - 128; 00129 vt = v - 128; 00130 00131 *r = clip( (76284 * yt + 104595 * vt ) >> 16 ); 00132 *g = clip( (76284 * yt - 25625 * ut - 53281 * vt ) >> 16 ); 00133 *b = clip( (76284 * yt + 132252 * ut ) >> 16 ); 00134 00135 } 00136 00137 00138 /* Convert a line of a RGB buffer to a line in a planar YUV422 buffer, see above for general 00139 * notes about color space conversion from RGB to YUV 00140 * @param RGB where the RGB output will be written to, will have pixel after pixel, 3 bytes per pixel 00141 * (thus this is a 24bit RGB with one byte per color) line by line. 00142 * @param YUV unsigned char array that contains the pixels, 4 pixels in 6 byte macro pixel, line after 00143 * line 00144 * @param width Width of the image contained in the YUV buffer 00145 * @param height Height of the image contained in the YUV buffer 00146 * @param rgb_line the index of the line to be converted 00147 * @param yuv_line the index of the line to convert to in the YUV buffer 00148 */ 00149 inline void 00150 convert_line_yuv422planar_to_rgb(const unsigned char *YUV, unsigned char *RGB, 00151 unsigned int width, unsigned int height, 00152 unsigned int yuv_line, unsigned int rgb_line) 00153 { 00154 register unsigned int i = 0; 00155 register RGB_t *r1, *r2; 00156 register const unsigned char *yp, *up, *vp; 00157 00158 yp = YUV + (width * yuv_line); 00159 up = YUV422_PLANAR_U_PLANE(YUV, width, height) + (width * yuv_line / 2); 00160 vp = YUV422_PLANAR_V_PLANE(YUV, width, height) + (width * yuv_line / 2); 00161 00162 RGB += 3 * width * rgb_line; 00163 00164 while (i < width) { 00165 r1 = (RGB_t *)RGB; 00166 RGB += 3; 00167 r2 = (RGB_t *)RGB; 00168 RGB += 3; 00169 00170 pixel_yuv_to_rgb(*yp++, *up, *vp, &(r1->R), &(r1->G), &(r1->B)); 00171 pixel_yuv_to_rgb(*yp++, *up++, *vp++, &(r2->R), &(r2->G), &(r2->B)); 00172 00173 i += 2; 00174 } 00175 } 00176 00177 } // end namespace firevision 00178 00179 #endif