yuvrgb.h

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