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
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
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;
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
00102
00103
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
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
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
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
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 }
00151
00152 }
00153
00154 }
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
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;
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
00192
00193
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
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
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
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
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 }
00245
00246 }
00247
00248 }
00249
00250
00251
00252