00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 #include <openvideo/ConverterYV12.h>
00052 #include <memory.h>
00053
00054
00055 namespace openvideo {
00056
00057
00058 #define RGB888_to_RGB32(r, g, b) ( (unsigned int)( (((r&0xff))<<16) | (((g&0xff))<<8) | (((b&0xff))<<0) ) )
00059
00060
00061 void
00062 ConverterYV12::init()
00063 {
00064 int i;
00065
00066
00067
00068
00069 lutCap0 = new unsigned char[LUTCAP_MAX-LUTCAP_MIN+1];
00070 lutCap = lutCap0 - LUTCAP_MIN;
00071
00072 for(i=LUTCAP_MIN; i<=LUTCAP_MAX; i++)
00073 lutCap[i] = i>0 ? (i<256 ? i : 255) : 0;
00074
00075
00076
00077 lutV_for_Red = new short[CHANNEL_RANGE];
00078 for(i=0; i<CHANNEL_RANGE; i++)
00079 lutV_for_Red[i] = static_cast<short>(1.596f*(i-128));
00080
00081 lutU_for_Blue = new short[CHANNEL_RANGE];
00082 for(i=0; i<CHANNEL_RANGE; i++)
00083 lutU_for_Blue[i] = static_cast<short>(2.018f*(i-128));
00084
00085 lutV_for_Green = new short[CHANNEL_RANGE];
00086 for(i=0; i<CHANNEL_RANGE; i++)
00087 lutV_for_Green[i] = static_cast<short>(-0.813f*(i-128));
00088
00089 lutU_for_Green = new short[CHANNEL_RANGE];
00090 for(i=0; i<CHANNEL_RANGE; i++)
00091 lutU_for_Green[i] = static_cast<short>(-0.391f*(i-128));
00092
00093 lutY = new short[CHANNEL_RANGE];
00094 for(i=0; i<CHANNEL_RANGE; i++)
00095 lutY[i] = static_cast<short>(1.164f*(i-16));
00096 }
00097
00098
00099 void
00100 ConverterYV12::deinit()
00101 {
00102 delete lutCap0;
00103 delete lutV_for_Red;
00104 delete lutU_for_Blue;
00105 delete lutV_for_Green;
00106 delete lutU_for_Green;
00107 delete lutY;
00108 }
00109
00110
00111 void
00112 ConverterYV12::convertToRGB32(const unsigned char* nSrcYUV, int nWidth, int nHeight, unsigned int* nDstRGB32, bool nSwizzle34, int nCropX, int nCropY)
00113 {
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 const int V_OFFS = nWidth*nHeight;
00141 const int U_OFFS = V_OFFS*5/4;
00142 const int croppedWidth = nWidth-2*nCropX;
00143 const int croppedHeight = nHeight-2*nCropY;
00144 const int extendedWidth = nWidth+2*nCropX;
00145 const int cropOffsY = nCropX + (nCropY/2)*nWidth;
00146 const int cropOffsUV = nCropX/2 + (nCropY/4)*nWidth/2;
00147
00148 const unsigned char* srcU = nSrcYUV + U_OFFS + cropOffsUV;
00149 const unsigned char* srcV = nSrcYUV + V_OFFS + cropOffsUV;
00150 const unsigned char* srcY0 = nSrcYUV + cropOffsY;
00151 const unsigned char* srcY1 = nSrcYUV + cropOffsY + nWidth;
00152
00153 unsigned int* dst0 = nDstRGB32;
00154 unsigned int* dst1 = nDstRGB32+croppedWidth;
00155
00156 if(nSwizzle34)
00157 {
00158 int yl = croppedHeight/2 + 1;
00159 while(--yl)
00160 {
00161 int xl=croppedWidth/4 + 1;
00162 while(--xl)
00163 {
00164
00165
00166
00167 int R,G,B, R0,G0,B0;
00168 int U,V,Y, Y0;
00169
00170
00171
00172 U = *srcU++;
00173 V = *srcV++;
00174
00175 R0 = getV_for_Red(V);
00176 B0 = getU_for_Blue(U);
00177 G0 = getV_for_Green(V) + getU_for_Green(U);
00178
00179
00180 Y = srcY0[0];
00181 Y0 = getY(Y);
00182
00183 R = cap(Y0 + R0);
00184 G = cap(Y0 + G0);
00185 B = cap(Y0 + B0);
00186
00187 dst0[0] = RGB888_to_RGB32(R,G,B);
00188
00189
00190 Y = srcY0[1];
00191 Y0 = getY(Y);
00192
00193 R = cap(Y0 + R0);
00194 G = cap(Y0 + G0);
00195 B = cap(Y0 + B0);
00196
00197 dst0[1] = RGB888_to_RGB32(R,G,B);
00198
00199
00200 Y = srcY1[0];
00201 Y0 = getY(Y);
00202
00203 R = cap(Y0 + R0);
00204 G = cap(Y0 + G0);
00205 B = cap(Y0 + B0);
00206
00207 dst1[0] = RGB888_to_RGB32(R,G,B);
00208
00209
00210 Y = srcY1[1];
00211 Y0 = getY(Y);
00212
00213 R = cap(Y0 + R0);
00214 G = cap(Y0 + G0);
00215 B = cap(Y0 + B0);
00216
00217 dst1[1] = RGB888_to_RGB32(R,G,B);
00218
00219
00220
00221
00222 U = *srcU++;
00223 V = *srcV++;
00224
00225 R0 = getV_for_Red(V);
00226 B0 = getU_for_Blue(U);
00227 G0 = getV_for_Green(V) + getU_for_Green(U);
00228
00229
00230 Y = srcY0[3];
00231 Y0 = getY(Y);
00232
00233 R = cap(Y0 + R0);
00234 G = cap(Y0 + G0);
00235 B = cap(Y0 + B0);
00236
00237 dst0[2] = RGB888_to_RGB32(R,G,B);
00238
00239
00240 Y = srcY0[2];
00241 Y0 = getY(Y);
00242
00243 R = cap(Y0 + R0);
00244 G = cap(Y0 + G0);
00245 B = cap(Y0 + B0);
00246
00247 dst0[3] = RGB888_to_RGB32(R,G,B);
00248
00249
00250 Y = srcY1[3];
00251 Y0 = getY(Y);
00252
00253 R = cap(Y0 + R0);
00254 G = cap(Y0 + G0);
00255 B = cap(Y0 + B0);
00256
00257 dst1[2] = RGB888_to_RGB32(R,G,B);
00258
00259
00260 Y = srcY1[2];
00261 Y0 = getY(Y);
00262
00263 R = cap(Y0 + R0);
00264 G = cap(Y0 + G0);
00265 B = cap(Y0 + B0);
00266
00267 dst1[3] = RGB888_to_RGB32(R,G,B);
00268
00269
00270 dst0 += 4;
00271 dst1 += 4;
00272 srcY0 += 4;
00273 srcY1 += 4;
00274 }
00275
00276 dst0 += croppedWidth;
00277 dst1 += croppedWidth;
00278 srcU += nCropX;
00279 srcV += nCropX;
00280 srcY0 += extendedWidth;
00281 srcY1 += extendedWidth;
00282 }
00283 }
00284 else
00285 {
00286 int yl = croppedHeight/2 + 1;
00287 while(--yl)
00288 {
00289 int xl=croppedWidth/4 + 1;
00290 while(--xl)
00291 {
00292
00293
00294
00295 int R,G,B, R0,G0,B0;
00296 int U,V,Y, Y0;
00297
00298
00299
00300 U = *srcU++;
00301 V = *srcV++;
00302
00303 R0 = getV_for_Red(V);
00304 B0 = getU_for_Blue(U);
00305 G0 = getV_for_Green(V) + getU_for_Green(U);
00306
00307
00308 Y = srcY0[0];
00309 Y0 = getY(Y);
00310
00311 R = cap(Y0 + R0);
00312 G = cap(Y0 + G0);
00313 B = cap(Y0 + B0);
00314
00315 dst0[0] = RGB888_to_RGB32(R,G,B);
00316
00317
00318 Y = srcY0[1];
00319 Y0 = getY(Y);
00320
00321 R = cap(Y0 + R0);
00322 G = cap(Y0 + G0);
00323 B = cap(Y0 + B0);
00324
00325 dst0[1] = RGB888_to_RGB32(R,G,B);
00326
00327
00328 Y = srcY1[0];
00329 Y0 = getY(Y);
00330
00331 R = cap(Y0 + R0);
00332 G = cap(Y0 + G0);
00333 B = cap(Y0 + B0);
00334
00335 dst1[0] = RGB888_to_RGB32(R,G,B);
00336
00337
00338 Y = srcY1[1];
00339 Y0 = getY(Y);
00340
00341 R = cap(Y0 + R0);
00342 G = cap(Y0 + G0);
00343 B = cap(Y0 + B0);
00344
00345 dst1[1] = RGB888_to_RGB32(R,G,B);
00346
00347
00348
00349
00350 U = *srcU++;
00351 V = *srcV++;
00352
00353 R0 = getV_for_Red(V);
00354 B0 = getU_for_Blue(U);
00355 G0 = getV_for_Green(V) + getU_for_Green(U);
00356
00357
00358 Y = srcY0[2];
00359 Y0 = getY(Y);
00360
00361 R = cap(Y0 + R0);
00362 G = cap(Y0 + G0);
00363 B = cap(Y0 + B0);
00364
00365 dst0[2] = RGB888_to_RGB32(R,G,B);
00366
00367
00368 Y = srcY0[3];
00369 Y0 = getY(Y);
00370
00371 R = cap(Y0 + R0);
00372 G = cap(Y0 + G0);
00373 B = cap(Y0 + B0);
00374
00375 dst0[3] = RGB888_to_RGB32(R,G,B);
00376
00377
00378 Y = srcY1[2];
00379 Y0 = getY(Y);
00380
00381 R = cap(Y0 + R0);
00382 G = cap(Y0 + G0);
00383 B = cap(Y0 + B0);
00384
00385 dst1[2] = RGB888_to_RGB32(R,G,B);
00386
00387
00388 Y = srcY1[3];
00389 Y0 = getY(Y);
00390
00391 R = cap(Y0 + R0);
00392 G = cap(Y0 + G0);
00393 B = cap(Y0 + B0);
00394
00395 dst1[3] = RGB888_to_RGB32(R,G,B);
00396
00397
00398 dst0 += 4;
00399 dst1 += 4;
00400 srcY0 += 4;
00401 srcY1 += 4;
00402 }
00403
00404 dst0 += croppedWidth;
00405 dst1 += croppedWidth;
00406 srcU += nCropX;
00407 srcV += nCropX;
00408 srcY0 += extendedWidth;
00409 srcY1 += extendedWidth;
00410 }
00411 }
00412 }
00413
00414
00415 void
00416 ConverterYV12::convertToLum(const unsigned char* nSrcYUV, int nWidth, int nHeight, unsigned char* nDstLum, bool nSwizzle34, int nCropX, int nCropY)
00417 {
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 const unsigned int* src = reinterpret_cast<const unsigned int*>(nSrcYUV+nCropX+(nCropY/2)*nWidth);
00428 unsigned int* dst = reinterpret_cast<unsigned int*>(nDstLum);
00429 const int numRuns = (nWidth-2*nCropX)/16 + 1;
00430
00431 int y = nHeight-2*nCropY+1;
00432 while(--y)
00433 {
00434
00435
00436
00437 int x = numRuns;
00438 int v0,v1,v2,v3;
00439
00440 if(nSwizzle34)
00441 {
00442 while(--x)
00443 {
00444
00445
00446 v0 = *src++;
00447 v1 = *src++;
00448 v2 = *src++;
00449 v3 = *src++;
00450
00451
00452
00453 *dst++ = (v0&0x0000ffff) | ((v0>>8)&0x00ff0000) | ((v0<<8)&0xff000000);
00454 *dst++ = (v1&0x0000ffff) | ((v1>>8)&0x00ff0000) | ((v1<<8)&0xff000000);
00455 *dst++ = (v2&0x0000ffff) | ((v2>>8)&0x00ff0000) | ((v2<<8)&0xff000000);
00456 *dst++ = (v3&0x0000ffff) | ((v3>>8)&0x00ff0000) | ((v3<<8)&0xff000000);
00457 }
00458 }
00459 else
00460 {
00461 x--;
00462 memcpy(dst,src, x*16);
00463 src += x*4;
00464 dst += x*4;
00465 }
00466
00467 src += nCropX/2;
00468 }
00469 }
00470
00471
00472 }
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485