RealYUV420toRGB24Converter.cpp

Go to the documentation of this file.
00001 
00036 #ifdef _WINDOWS
00037 #define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
00038 #include <windows.h>
00039 #else
00040 #include <stdio.h>
00041 #endif
00042 
00043 #include <math.h>
00044 #include <string.h>
00045 #include <stdlib.h>
00046 
00047 #include "RealYUV420toRGB24Converter.h"
00048 
00049 /*
00050 ===========================================================================
00051         Macros.
00052 ===========================================================================
00053 */
00054 #define RYUVRGB24C_RANGECHECK_0TO255(x) ( (((x) <= 255)&&((x) >= 0))?((x)):( ((x) > 255)?(255):(0) ) )
00055 
00056 #define RYUVRGB24C_U0            2.032
00057 #define RYUVRGB24C_U1           -0.394
00058 #define RYUVRGB24C_V1           -0.581
00059 #define RYUVRGB24C_V0            1.140
00060 
00061 /*
00062 ===========================================================================
00063         Private Methods.
00064 ===========================================================================
00065 */
00066 void RealYUV420toRGB24Converter::NonRotateConvert(void* pY, void* pU, void* pV, void* pRgb)
00067 {
00068         unsigned char*  optr    =       (unsigned char *)pRgb;
00069         yuvType*                                py              = (yuvType *)pY;
00070         yuvType*                                pu              = (yuvType *)pU;
00071         yuvType*                                pv              = (yuvType *)pV;
00072         int             lumX    = _width;
00073         int             lumY    = _height;
00074         int             uvX             = _width >> 1;
00075 
00076         int x,y;
00077         int lumposy;
00078         int rgbposy;
00079         int uvposy;
00080   int r,b,g;
00081 
00082         int tworows  = lumX << 1;
00083         int rgb1row  = (_width * 3);
00084         int rgb2rows = (_width * 3) << 1;
00085 
00086         for(y = 0,lumposy = 0,uvposy = 0,rgbposy = 0;   y < lumY;       y += 2,lumposy += tworows,uvposy += uvX,rgbposy += rgb2rows)
00087         {
00088                 int lumpos0 = lumposy;                                  // Reset to start of rows.
00089                 int lumpos1 = lumposy + lumX;
00090                 int uvpos        = uvposy;
00091 
00092                 int rgbpos0 = rgbposy;
00093                 int rgbpos1 = rgbposy + rgb1row;
00094 
00095                 for(x = 0; x < lumX; x += 2)
00096                 {
00097                         double lum00 = (double)((int)(py[lumpos0++]));
00098                         double u                 = (double)(((int)(pu[uvpos])) - 128);
00099                         double v                 = (double)(((int)(pv[uvpos++])) - 128);
00100 
00101                         // Lum00, u and v.
00102 
00103                 // Fast calculation intermediate variables. 
00104                         double cc = (RYUVRGB24C_U0 * u) + 0.5;
00105                         double cb = (RYUVRGB24C_U1 * u) + (RYUVRGB24C_V1 * v) + 0.5;
00106                         double ca = (RYUVRGB24C_V0 * v) + 0.5;
00107 
00108                         b = (int)(lum00 + cc);
00109                         g = (int)(lum00 + cb);
00110                         r = (int)(lum00 + ca);
00111   
00112                         // R, G & B have range 0..255.
00113                         optr[rgbpos0++] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(b));
00114                         optr[rgbpos0++] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(g));
00115                         optr[rgbpos0++] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(r));
00116 
00117                         // Lum01.
00118                         double lum01 = (double)((int)(py[lumpos0++]));
00119 
00120                         b = (int)(lum01 + cc);
00121                         g = (int)(lum01 + cb);
00122                         r = (int)(lum01 + ca);
00123   
00124                         optr[rgbpos0++] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(b));
00125                         optr[rgbpos0++] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(g));
00126                         optr[rgbpos0++] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(r));
00127 
00128                         // Lum10.
00129                         double lum10 = (double)((int)(py[lumpos1++]));
00130 
00131                         b = (int)(lum10 + cc);
00132                         g = (int)(lum10 + cb);
00133                         r = (int)(lum10 + ca);
00134   
00135                         optr[rgbpos1++] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(b));
00136                         optr[rgbpos1++] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(g));
00137                         optr[rgbpos1++] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(r));
00138 
00139                         // Lum11.
00140                         double lum11 = (double)((int)(py[lumpos1++]));
00141 
00142                         b = (int)(lum11 + cc);
00143                         g = (int)(lum11 + cb);
00144                         r = (int)(lum11 + ca);
00145   
00146                         optr[rgbpos1++] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(b));
00147                         optr[rgbpos1++] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(g));
00148                         optr[rgbpos1++] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(r));
00149 
00150                 }//end for x...
00151                 
00152         }//end for y...
00153 
00154 }//end NonRotateConvert.
00155 
00156 void RealYUV420toRGB24Converter::RotateConvert(void* pY, void* pU, void* pV, void* pRgb)
00157 {
00158         unsigned char*  optr    =       (unsigned char *)pRgb;
00159         yuvType*                                py              = (yuvType *)pY;
00160         yuvType*                                pu              = (yuvType *)pU;
00161         yuvType*                                pv              = (yuvType *)pV;
00162         int             lumX    = _width;
00163         int             lumY    = _height;
00164         int             uvX             = _width >> 1;
00165 
00166         int x,y;
00167         int lumposy;
00168         int rgbposx;
00169         int uvposy;
00170   int r,b,g;
00171 
00172         int tworows  = lumX << 1;
00173         //int rgb1row  = (_width * 3);
00174         int rgb1row  = (_height * 3);
00175 
00176         for(y = 0,lumposy = 0,uvposy = 0,rgbposx = 0;   y < lumY;       y += 2,lumposy += tworows,uvposy += uvX,rgbposx += 6)
00177         {
00178                 int lumpos0 = lumposy;                                  // Reset to start of rows.
00179                 int lumpos1 = lumposy + lumX;
00180                 int uvpos        = uvposy;
00181 
00182                 int rgbpos0 = rgbposx;
00183                 int rgbpos1 = rgbposx + 3;
00184 
00185                 for(x = 0; x < lumX; x += 2)
00186                 {
00187                         double lum00 = (double)((int)(py[lumpos0++]));
00188                         double u                 = (double)(((int)(pu[uvpos])) - 128);
00189                         double v                 = (double)(((int)(pv[uvpos++])) - 128);
00190 
00191                         // Lum00, u and v.
00192 
00193                 // Fast calculation intermediate variables. 
00194                         double cc = (RYUVRGB24C_U0 * u) + 0.5;
00195                         double cb = (RYUVRGB24C_U1 * u) + (RYUVRGB24C_V1 * v) + 0.5;
00196                         double ca = (RYUVRGB24C_V0 * v) + 0.5;
00197 
00198                         b = (int)(lum00 + cc);
00199                         g = (int)(lum00 + cb);
00200                         r = (int)(lum00 + ca);
00201   
00202                         // R, G & B have range 0..255.
00203                         optr[rgbpos0]           = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(b));
00204                         optr[rgbpos0+1] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(g));
00205                         optr[rgbpos0+2] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(r));
00206                         rgbpos0 += rgb1row;
00207 
00208                         // Lum01.
00209                         double lum01 = (double)((int)(py[lumpos0++]));
00210 
00211                         b = (int)(lum01 + cc);
00212                         g = (int)(lum01 + cb);
00213                         r = (int)(lum01 + ca);
00214   
00215                         optr[rgbpos0]           = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(b));
00216                         optr[rgbpos0+1] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(g));
00217                         optr[rgbpos0+2] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(r));
00218                         rgbpos0 += rgb1row;
00219 
00220                         // Lum10.
00221                         double lum10 = (double)((int)(py[lumpos1++]));
00222 
00223                         b = (int)(lum10 + cc);
00224                         g = (int)(lum10 + cb);
00225                         r = (int)(lum10 + ca);
00226   
00227                         optr[rgbpos1]           = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(b));
00228                         optr[rgbpos1+1] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(g));
00229                         optr[rgbpos1+2] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(r));
00230                         rgbpos1 += rgb1row;
00231 
00232                         // Lum11.
00233                         double lum11 = (double)((int)(py[lumpos1++]));
00234 
00235                         b = (int)(lum11 + cc);
00236                         g = (int)(lum11 + cb);
00237                         r = (int)(lum11 + ca);
00238   
00239                         optr[rgbpos1]           = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(b));
00240                         optr[rgbpos1+1] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(g));
00241                         optr[rgbpos1+2] = (unsigned char)(RYUVRGB24C_RANGECHECK_0TO255(r));
00242                         rgbpos1 += rgb1row;
00243 
00244                 }//end for x...
00245                 
00246         }//end for y...
00247 
00248 }//end NonNonRotateConvert.
00249 
00250 
00251 
00252 

Generated on Fri Mar 13 14:12:38 2009 for RTVC by  doxygen 1.5.3