$search
00001 /* 00002 * Copyright (C) 2000-2003 Damien Douxchamps <ddouxchamps@users.sf.net> 00003 * Dan Dennedy <dan@dennedy.org> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software Foundation, 00017 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00018 */ 00019 00020 #include <string.h> 00021 #include "conversions.h" 00022 00023 #if !defined (WIN32) 00024 // This doesn't need to be extern on Windows (why does it need to be elsewhere?) 00025 extern void swab(); 00026 #endif 00027 00028 // The following #define is there for the users who experience green/purple 00029 // images in the display. This seems to be a videocard driver problem. 00030 00031 //#define YUYV // instead of the standard UYVY 00032 #define UYVY // it conforms to the yuv422 structure in the cmvision class. 00033 00034 // color conversion functions from Bart Nabbe. 00035 // corrected by Damien: bad coeficients in YUV2RGB 00036 #define YUV2RGB(y, u, v, r, g, b)\ 00037 r = y + ((v*1436) >>10);\ 00038 g = y - ((u*352 + v*731) >> 10);\ 00039 b = y + ((u*1814) >> 10);\ 00040 r = r < 0 ? 0 : r;\ 00041 g = g < 0 ? 0 : g;\ 00042 b = b < 0 ? 0 : b;\ 00043 r = r > 255 ? 255 : r;\ 00044 g = g > 255 ? 255 : g;\ 00045 b = b > 255 ? 255 : b 00046 00047 00048 #define RGB2YUV(r, g, b, y, u, v)\ 00049 y = (306*r + 601*g + 117*b) >> 10;\ 00050 u = ((-172*r - 340*g + 512*b) >> 10) + 128;\ 00051 v = ((512*r - 429*g - 83*b) >> 10) + 128;\ 00052 y = y < 0 ? 0 : y;\ 00053 u = u < 0 ? 0 : u;\ 00054 v = v < 0 ? 0 : v;\ 00055 y = y > 255 ? 255 : y;\ 00056 u = u > 255 ? 255 : u;\ 00057 v = v > 255 ? 255 : v 00058 00059 #define CLIP(in, out)\ 00060 {\ 00061 in = in < 0 ? 0 : in;\ 00062 in = in > 255 ? 255 : in;\ 00063 out=in;\ 00064 } 00065 00066 /********************************************************************** 00067 * 00068 * CONVERSION FUNCTIONS TO UYVY 00069 * 00070 **********************************************************************/ 00071 00072 void 00073 yuyv2uyvy(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels) 00074 { 00075 #ifdef YUYV 00076 swab(src, dest, NumPixels << 1); 00077 #else 00078 memcpy(dest,src, NumPixels<<1); 00079 #endif 00080 } 00081 00082 void 00083 uyvy2yuyv(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels) 00084 { 00085 #ifdef YUYV 00086 swab(src, dest, NumPixels << 1); 00087 #else 00088 memcpy(dest,src, NumPixels<<1); 00089 #endif 00090 } 00091 void 00092 uyyvyy2uyvy (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels) 00093 { 00094 register int i=NumPixels + (NumPixels >> 1)-1; 00095 register int j=(NumPixels << 1)-1; 00096 register int y0, y1, y2, y3, u, v; 00097 00098 while (i > 0) { 00099 y3 = src[i--]; 00100 y2 = src[i--]; 00101 v = src[i--]; 00102 y1 = src[i--]; 00103 y0 = src[i--]; 00104 u = src[i--]; 00105 #ifdef YUYV 00106 dest[j--] = v; 00107 dest[j--] = y3; 00108 dest[j--] = u; 00109 dest[j--] = y2; 00110 00111 dest[j--] = v; 00112 dest[j--] = y1; 00113 dest[j--] = u; 00114 dest[j--] = y0; 00115 #else // UYVY 00116 dest[j--] = y3; 00117 dest[j--] = v; 00118 dest[j--] = y2; 00119 dest[j--] = u; 00120 00121 dest[j--] = y1; 00122 dest[j--] = v; 00123 dest[j--] = y0; 00124 dest[j--] = u; 00125 #endif 00126 } 00127 } 00128 00129 void 00130 uyv2uyvy (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels) 00131 { 00132 register int i = NumPixels + (NumPixels << 1)-1; 00133 register int j = (NumPixels << 1)-1; 00134 register int y0, y1, u0, u1, v0, v1; 00135 00136 while (i > 0) { 00137 v1 = src[i--]; 00138 y1 = src[i--]; 00139 u1 = src[i--]; 00140 v0 = src[i--]; 00141 y0 = src[i--]; 00142 u0 = src[i--]; 00143 00144 #ifdef YUYV 00145 dest[j--] = (v0+v1) >> 1; 00146 dest[j--] = y1; 00147 dest[j--] = (u0+u1) >> 1; 00148 dest[j--] = y0; 00149 #else // UYVY 00150 dest[j--] = y1; 00151 dest[j--] = (v0+v1) >> 1; 00152 dest[j--] = y0; 00153 dest[j--] = (u0+u1) >> 1; 00154 #endif 00155 } 00156 } 00157 00158 00159 void 00160 y2uyvy (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels) 00161 { 00162 register int i= NumPixels-1; 00163 register int j = (NumPixels << 1)-1; 00164 register int y0, y1; 00165 00166 while (i > 0) { 00167 y1 = src[i--]; 00168 y0 = src[i--]; 00169 #ifdef YUYV 00170 dest[j--] = 128; 00171 dest[j--] = y1; 00172 dest[j--] = 128; 00173 dest[j--] = y0; 00174 #else // UYVY 00175 dest[j--] = y1; 00176 dest[j--] = 128; 00177 dest[j--] = y0; 00178 dest[j--] = 128; 00179 #endif 00180 } 00181 } 00182 00183 void 00184 y162uyvy (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels, int bits) 00185 { 00186 register int i = (NumPixels << 1)-1; 00187 register int j = (NumPixels << 1)-1; 00188 register int y0, y1; 00189 //fprintf(stderr,"Conv: Pix: %d Bpp: %d\n",NumPixels, bits); 00190 while (i > 0) { 00191 //fprintf(stderr,"%d ",i); 00192 y1 = src[i--]; 00193 y1 = (y1 + (((int)src[i--])<<8))>>(bits-8); 00194 y0 = src[i--]; 00195 y0 = (y0 + (((int)src[i--])<<8))>>(bits-8); 00196 #ifdef YUYV 00197 dest[j--] = 128; 00198 dest[j--] = y1; 00199 dest[j--] = 128; 00200 dest[j--] = y0; 00201 #else // UYVY 00202 dest[j--] = y1; 00203 dest[j--] = 128; 00204 dest[j--] = y0; 00205 dest[j--] = 128; 00206 #endif 00207 } 00208 } 00209 00210 void 00211 y162y (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels, int bits) 00212 { 00213 register int i = (NumPixels<<1)-1; 00214 register int j = NumPixels-1; 00215 register int y; 00216 00217 while (i > 0) { 00218 y = src[i--]; 00219 dest[j--] = (y + (src[i--]<<8))>>(bits-8); 00220 } 00221 } 00222 00223 void 00224 rgb2uyvy (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels) 00225 { 00226 register int i = NumPixels + ( NumPixels << 1 )-1; 00227 register int j = (NumPixels << 1)-1; 00228 register int y0, y1, u0, u1, v0, v1 ; 00229 register int r, g, b; 00230 00231 while (i > 0) { 00232 b = (unsigned char) src[i--]; 00233 g = (unsigned char) src[i--]; 00234 r = (unsigned char) src[i--]; 00235 RGB2YUV (r, g, b, y0, u0 , v0); 00236 b = (unsigned char) src[i--]; 00237 g = (unsigned char) src[i--]; 00238 r = (unsigned char) src[i--]; 00239 RGB2YUV (r, g, b, y1, u1 , v1); 00240 #ifdef YUYV 00241 dest[j--] = (v0+v1) >> 1; 00242 dest[j--] = y0; 00243 dest[j--] = (u0+u1) >> 1; 00244 dest[j--] = y1; 00245 #else // UYVY 00246 dest[j--] = y0; 00247 dest[j--] = (v0+v1) >> 1; 00248 dest[j--] = y1; 00249 dest[j--] = (u0+u1) >> 1; 00250 #endif 00251 } 00252 } 00253 00254 void 00255 rgb482uyvy (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels) 00256 { 00257 register int i = ( (NumPixels + ( NumPixels << 1 )) << 1 ) -1; 00258 register int j = (NumPixels << 1)-1; 00259 register int y0, y1, u0, u1, v0, v1 ; 00260 register int r, g, b; 00261 00262 while (i > 0) { 00263 i--; 00264 b = (unsigned char) src[i--]; 00265 i--; 00266 g = (unsigned char) src[i--]; 00267 i--; 00268 r = (unsigned char) src[i--]; 00269 i--; 00270 RGB2YUV (r, g, b, y0, u0 , v0); 00271 b = (unsigned char) src[i--]; 00272 i--; 00273 g = (unsigned char) src[i--]; 00274 i--; 00275 r = (unsigned char) src[i--]; 00276 RGB2YUV (r, g, b, y1, u1 , v1); 00277 00278 #ifdef YUYV 00279 dest[j--] = (v0+v1) >> 1; 00280 dest[j--] = y0; 00281 dest[j--] = (u0+u1) >> 1; 00282 dest[j--] = y1; 00283 #else // UYVY 00284 dest[j--] = y0; 00285 dest[j--] = (v0+v1) >> 1; 00286 dest[j--] = y1; 00287 dest[j--] = (u0+u1) >> 1; 00288 #endif 00289 } 00290 } 00291 00292 /********************************************************************** 00293 * 00294 * CONVERSION FUNCTIONS TO RGB 24bpp 00295 * 00296 **********************************************************************/ 00297 00298 void 00299 rgb482rgb (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels) 00300 { 00301 register int i = ((NumPixels + ( NumPixels << 1 )) << 1)-1; 00302 register int j = NumPixels + ( NumPixels << 1 ) -1; 00303 00304 while (i > 0) { 00305 i--; 00306 dest[j--]=src[i--]; 00307 i--; 00308 dest[j--]=src[i--]; 00309 i--; 00310 dest[j--]=src[i--]; 00311 } 00312 } 00313 00314 00315 void 00316 uyv2rgb (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels) 00317 { 00318 register int i = NumPixels + ( NumPixels << 1 ) -1; 00319 register int j = NumPixels + ( NumPixels << 1 ) -1; 00320 register int y, u, v; 00321 register int r, g, b; 00322 00323 while (i > 0) { 00324 v = (unsigned char) src[i--] - 128; 00325 y = (unsigned char) src[i--]; 00326 u = (unsigned char) src[i--] - 128; 00327 YUV2RGB (y, u, v, r, g, b); 00328 dest[j--] = b; 00329 dest[j--] = g; 00330 dest[j--] = r; 00331 } 00332 } 00333 00334 void 00335 uyvy2rgb (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels) 00336 { 00337 register int i = (NumPixels << 1)-1; 00338 register int j = NumPixels + ( NumPixels << 1 ) -1; 00339 register int y0, y1, u, v; 00340 register int r, g, b; 00341 00342 while (i > 0) { 00343 y1 = (unsigned char) src[i--]; 00344 v = (unsigned char) src[i--] - 128; 00345 y0 = (unsigned char) src[i--]; 00346 u = (unsigned char) src[i--] - 128; 00347 YUV2RGB (y1, u, v, r, g, b); 00348 dest[j--] = b; 00349 dest[j--] = g; 00350 dest[j--] = r; 00351 YUV2RGB (y0, u, v, r, g, b); 00352 dest[j--] = b; 00353 dest[j--] = g; 00354 dest[j--] = r; 00355 } 00356 } 00357 00358 00359 void 00360 uyyvyy2rgb (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels) 00361 { 00362 register int i = NumPixels + ( NumPixels >> 1 )-1; 00363 register int j = NumPixels + ( NumPixels << 1 )-1; 00364 register int y0, y1, y2, y3, u, v; 00365 register int r, g, b; 00366 00367 while (i > 0) { 00368 y3 = (unsigned char) src[i--]; 00369 y2 = (unsigned char) src[i--]; 00370 v = (unsigned char) src[i--] - 128; 00371 y1 = (unsigned char) src[i--]; 00372 y0 = (unsigned char) src[i--]; 00373 u = (unsigned char) src[i--] - 128; 00374 YUV2RGB (y3, u, v, r, g, b); 00375 dest[j--] = b; 00376 dest[j--] = g; 00377 dest[j--] = r; 00378 YUV2RGB (y2, u, v, r, g, b); 00379 dest[j--] = b; 00380 dest[j--] = g; 00381 dest[j--] = r; 00382 YUV2RGB (y1, u, v, r, g, b); 00383 dest[j--] = b; 00384 dest[j--] = g; 00385 dest[j--] = r; 00386 YUV2RGB (y0, u, v, r, g, b); 00387 dest[j--] = b; 00388 dest[j--] = g; 00389 dest[j--] = r; 00390 } 00391 } 00392 00393 void 00394 y2rgb (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels) 00395 { 00396 register int i = NumPixels-1; 00397 register int j = NumPixels + ( NumPixels << 1 )-1; 00398 register int y; 00399 00400 while (i > 0) { 00401 y = (unsigned char) src[i--]; 00402 dest[j--] = y; 00403 dest[j--] = y; 00404 dest[j--] = y; 00405 } 00406 } 00407 00408 void 00409 y162rgb (unsigned char *src, unsigned char *dest, unsigned long long int NumPixels, int bits) 00410 { 00411 register int i = (NumPixels << 1)-1; 00412 register int j = NumPixels + ( NumPixels << 1 )-1; 00413 register int y; 00414 00415 while (i > 0) { 00416 y = src[i--]; 00417 y = (y + (src[i--]<<8))>>(bits-8); 00418 dest[j--] = y; 00419 dest[j--] = y; 00420 dest[j--] = y; 00421 } 00422 } 00423 00424 /**************************************************************** 00425 * Color conversion functions for cameras that can * 00426 * output raw-Bayer pattern images, such as some Basler and * 00427 * Point Grey camera. Most of the algos presented here com from * 00428 * http://ise0.Stanford.EDU/~tingchen/main.htm and have been * 00429 * converted from Matlab to C and extended to all elementary * 00430 * patterns. * 00431 ****************************************************************/ 00432 00433 void 00434 BayerNearestNeighbor(unsigned char *src, unsigned char *dest, int sx, int sy, bayer_pattern_t type) 00435 { 00436 unsigned char *outR, *outG, *outB; 00437 register int i,j; 00438 00439 // sx and sy should be even 00440 switch (type) { 00441 case BAYER_PATTERN_GRBG: 00442 case BAYER_PATTERN_BGGR: 00443 outR=&dest[0]; 00444 outG=&dest[1]; 00445 outB=&dest[2]; 00446 break; 00447 case BAYER_PATTERN_GBRG: 00448 case BAYER_PATTERN_RGGB: 00449 outR=&dest[2]; 00450 outG=&dest[1]; 00451 outB=&dest[0]; 00452 break; 00453 default: 00454 outR=NULL;outG=NULL;outB=NULL; 00455 break; 00456 } 00457 00458 switch (type) { 00459 case BAYER_PATTERN_GRBG: //------------------------------------------- 00460 case BAYER_PATTERN_GBRG: 00461 // copy original RGB data to output images 00462 for (i=0;i<sy;i+=2) { 00463 for (j=0;j<sx;j+=2) { 00464 outG[(i*sx+j)*3]=src[i*sx+j]; 00465 outG[((i+1)*sx+(j+1))*3]=src[(i+1)*sx+(j+1)]; 00466 outR[(i*sx+j+1)*3]=src[i*sx+j+1]; 00467 outB[((i+1)*sx+j)*3]=src[(i+1)*sx+j]; 00468 } 00469 } 00470 // R channel 00471 for (i=0;i<sy;i+=2) { 00472 for (j=0;j<sx-1;j+=2) { 00473 outR[(i*sx+j)*3]=outR[(i*sx+j+1)*3]; 00474 outR[((i+1)*sx+j+1)*3]=outR[(i*sx+j+1)*3]; 00475 outR[((i+1)*sx+j)*3]=outR[(i*sx+j+1)*3]; 00476 } 00477 } 00478 // B channel 00479 for (i=0;i<sy-1;i+=2) { //every two lines 00480 for (j=0;j<sx-1;j+=2) { 00481 outB[(i*sx+j)*3]=outB[((i+1)*sx+j)*3]; 00482 outB[(i*sx+j+1)*3]=outB[((i+1)*sx+j)*3]; 00483 outB[((i+1)*sx+j+1)*3]=outB[((i+1)*sx+j)*3]; 00484 } 00485 } 00486 // using lower direction for G channel 00487 00488 // G channel 00489 for (i=0;i<sy-1;i+=2)//every two lines 00490 for (j=1;j<sx;j+=2) 00491 outG[(i*sx+j)*3]=outG[((i+1)*sx+j)*3]; 00492 00493 for (i=1;i<sy-2;i+=2)//every two lines 00494 for (j=0;j<sx-1;j+=2) 00495 outG[(i*sx+j)*3]=outG[((i+1)*sx+j)*3]; 00496 00497 // copy it for the next line 00498 for (j=0;j<sx-1;j+=2) 00499 outG[((sy-1)*sx+j)*3]=outG[((sy-2)*sx+j)*3]; 00500 00501 break; 00502 case BAYER_PATTERN_BGGR: //------------------------------------------- 00503 case BAYER_PATTERN_RGGB: 00504 // copy original data 00505 for (i=0;i<sy;i+=2) { 00506 for (j=0;j<sx;j+=2) { 00507 outB[(i*sx+j)*3]=src[i*sx+j]; 00508 outR[((i+1)*sx+(j+1))*3]=src[(i+1)*sx+(j+1)]; 00509 outG[(i*sx+j+1)*3]=src[i*sx+j+1]; 00510 outG[((i+1)*sx+j)*3]=src[(i+1)*sx+j]; 00511 } 00512 } 00513 // R channel 00514 for (i=0;i<sy;i+=2){ 00515 for (j=0;j<sx-1;j+=2) { 00516 outR[(i*sx+j)*3]=outR[((i+1)*sx+j+1)*3]; 00517 outR[(i*sx+j+1)*3]=outR[((i+1)*sx+j+1)*3]; 00518 outR[((i+1)*sx+j)*3]=outR[((i+1)*sx+j+1)*3]; 00519 } 00520 } 00521 // B channel 00522 for (i=0;i<sy-1;i+=2) { //every two lines 00523 for (j=0;j<sx-1;j+=2) { 00524 outB[((i+1)*sx+j)*3]=outB[(i*sx+j)*3]; 00525 outB[(i*sx+j+1)*3]=outB[(i*sx+j)*3]; 00526 outB[((i+1)*sx+j+1)*3]=outB[(i*sx+j)*3]; 00527 } 00528 } 00529 // using lower direction for G channel 00530 00531 // G channel 00532 for (i=0;i<sy-1;i+=2)//every two lines 00533 for (j=0;j<sx-1;j+=2) 00534 outG[(i*sx+j)*3]=outG[((i+1)*sx+j)*3]; 00535 00536 for (i=1;i<sy-2;i+=2)//every two lines 00537 for (j=0;j<sx-1;j+=2) 00538 outG[(i*sx+j+1)*3]=outG[((i+1)*sx+j+1)*3]; 00539 00540 // copy it for the next line 00541 for (j=0;j<sx-1;j+=2) 00542 outG[((sy-1)*sx+j+1)*3]=outG[((sy-2)*sx+j+1)*3]; 00543 00544 break; 00545 00546 default: //------------------------------------------- 00547 break; 00548 } 00549 } 00550 00551 00552 void 00553 BayerEdgeSense(unsigned char *src, unsigned char *dest, int sx, int sy, bayer_pattern_t type) 00554 { 00555 unsigned char *outR, *outG, *outB; 00556 register int i,j; 00557 int dh, dv; 00558 int tmp; 00559 00560 // sx and sy should be even 00561 switch (type) { 00562 case BAYER_PATTERN_GRBG: 00563 case BAYER_PATTERN_BGGR: 00564 outR=&dest[0]; 00565 outG=&dest[1]; 00566 outB=&dest[2]; 00567 break; 00568 case BAYER_PATTERN_GBRG: 00569 case BAYER_PATTERN_RGGB: 00570 outR=&dest[2]; 00571 outG=&dest[1]; 00572 outB=&dest[0]; 00573 break; 00574 default: 00575 outR=NULL;outG=NULL;outB=NULL; 00576 break; 00577 } 00578 00579 switch (type) { 00580 case BAYER_PATTERN_GRBG://--------------------------------------------------------- 00581 case BAYER_PATTERN_GBRG: 00582 // copy original RGB data to output images 00583 for (i=0;i<sy;i+=2) { 00584 for (j=0;j<sx;j+=2) { 00585 outG[(i*sx+j)*3]=src[i*sx+j]; 00586 outG[((i+1)*sx+(j+1))*3]=src[(i+1)*sx+(j+1)]; 00587 outR[(i*sx+j+1)*3]=src[i*sx+j+1]; 00588 outB[((i+1)*sx+j)*3]=src[(i+1)*sx+j]; 00589 } 00590 } 00591 // process GREEN channel 00592 for (i=3;i<sy-2;i+=2) { 00593 for (j=2;j<sx-3;j+=2) { 00594 dh=abs((outB[(i*sx+j-2)*3]+outB[(i*sx+j+2)*3])/2-outB[(i*sx+j)*3]); 00595 dv=abs((outB[((i-2)*sx+j)*3]+outB[((i+2)*sx+j)*3])/2-outB[(i*sx+j)*3]); 00596 if (dh<dv) 00597 tmp=(outG[(i*sx+j-1)*3]+outG[(i*sx+j+1)*3])/2; 00598 else { 00599 if (dh>dv) 00600 tmp=(outG[((i-1)*sx+j)*3]+outG[((i+1)*sx+j)*3])/2; 00601 else 00602 tmp=(outG[(i*sx+j-1)*3]+outG[(i*sx+j+1)*3]+outG[((i-1)*sx+j)*3]+outG[((i+1)*sx+j)*3])/4; 00603 } 00604 CLIP(tmp,outG[(i*sx+j)*3]); 00605 } 00606 } 00607 00608 for (i=2;i<sy-3;i+=2) { 00609 for (j=3;j<sx-2;j+=2) { 00610 dh=abs((outR[(i*sx+j-2)*3]+outR[(i*sx+j+2)*3])/2-outR[(i*sx+j)*3]); 00611 dv=abs((outR[((i-2)*sx+j)*3]+outR[((i+2)*sx+j)*3])/2-outR[(i*sx+j)*3]); 00612 if (dh<dv) 00613 tmp=(outG[(i*sx+j-1)*3]+outG[(i*sx+j+1)*3])/2; 00614 else { 00615 if (dh>dv) 00616 tmp=(outG[((i-1)*sx+j)*3]+outG[((i+1)*sx+j)*3])/2; 00617 else 00618 tmp=(outG[(i*sx+j-1)*3]+outG[(i*sx+j+1)*3]+outG[((i-1)*sx+j)*3]+outG[((i+1)*sx+j)*3])/4; 00619 } 00620 CLIP(tmp,outG[(i*sx+j)*3]); 00621 } 00622 } 00623 // process RED channel 00624 for (i=0;i<sy-1;i+=2) { 00625 for (j=2;j<sx-1;j+=2) { 00626 tmp=outG[(i*sx+j)*3]+(outR[(i*sx+j-1)*3]-outG[(i*sx+j-1)*3]+ 00627 outR[(i*sx+j+1)*3]-outG[(i*sx+j+1)*3])/2; 00628 CLIP(tmp,outR[(i*sx+j)*3]); 00629 } 00630 } 00631 for (i=1;i<sy-2;i+=2) { 00632 for (j=1;j<sx;j+=2) { 00633 tmp=outG[(i*sx+j)*3]+(outR[((i-1)*sx+j)*3]-outG[((i-1)*sx+j)*3]+ 00634 outR[((i+1)*sx+j)*3]-outG[((i+1)*sx+j)*3])/2; 00635 CLIP(tmp,outR[(i*sx+j)*3]); 00636 } 00637 for (j=2;j<sx-1;j+=2) { 00638 tmp=outG[(i*sx+j)*3]+(outR[((i-1)*sx+j-1)*3]-outG[((i-1)*sx+j-1)*3]+ 00639 outR[((i-1)*sx+j+1)*3]-outG[((i-1)*sx+j+1)*3]+ 00640 outR[((i+1)*sx+j-1)*3]-outG[((i+1)*sx+j-1)*3]+ 00641 outR[((i+1)*sx+j+1)*3]-outG[((i+1)*sx+j+1)*3])/4; 00642 CLIP(tmp,outR[(i*sx+j)*3]); 00643 } 00644 } 00645 00646 // process BLUE channel 00647 for (i=1;i<sy;i+=2) { 00648 for (j=1;j<sx-2;j+=2) { 00649 tmp=outG[(i*sx+j)*3]+(outB[(i*sx+j-1)*3]-outG[(i*sx+j-1)*3]+ 00650 outB[(i*sx+j+1)*3]-outG[(i*sx+j+1)*3])/2; 00651 CLIP(tmp,outB[(i*sx+j)*3]); 00652 } 00653 } 00654 for (i=2;i<sy-1;i+=2) { 00655 for (j=0;j<sx-1;j+=2) { 00656 tmp=outG[(i*sx+j)*3]+(outB[((i-1)*sx+j)*3]-outG[((i-1)*sx+j)*3]+ 00657 outB[((i+1)*sx+j)*3]-outG[((i+1)*sx+j)*3])/2; 00658 CLIP(tmp,outB[(i*sx+j)*3]); 00659 } 00660 for (j=1;j<sx-2;j+=2) { 00661 tmp=outG[(i*sx+j)*3]+(outB[((i-1)*sx+j-1)*3]-outG[((i-1)*sx+j-1)*3]+ 00662 outB[((i-1)*sx+j+1)*3]-outG[((i-1)*sx+j+1)*3]+ 00663 outB[((i+1)*sx+j-1)*3]-outG[((i+1)*sx+j-1)*3]+ 00664 outB[((i+1)*sx+j+1)*3]-outG[((i+1)*sx+j+1)*3])/4; 00665 CLIP(tmp,outB[(i*sx+j)*3]); 00666 } 00667 } 00668 break; 00669 00670 case BAYER_PATTERN_BGGR: //--------------------------------------------------------- 00671 case BAYER_PATTERN_RGGB: 00672 // copy original RGB data to output images 00673 for (i=0;i<sy;i+=2) { 00674 for (j=0;j<sx;j+=2) { 00675 outB[(i*sx+j)*3]=src[i*sx+j]; 00676 outR[((i+1)*sx+(j+1))*3]=src[(i+1)*sx+(j+1)]; 00677 outG[(i*sx+j+1)*3]=src[i*sx+j+1]; 00678 outG[((i+1)*sx+j)*3]=src[(i+1)*sx+j]; 00679 } 00680 } 00681 // process GREEN channel 00682 for (i=2;i<sy-2;i+=2) { 00683 for (j=2;j<sx-3;j+=2) { 00684 dh=abs((outB[(i*sx+j-2)*3]+outB[(i*sx+j+2)*3])/2-outB[(i*sx+j)*3]); 00685 dv=abs((outB[((i-2)*sx+j)*3]+outB[((i+2)*sx+j)*3])/2-outB[(i*sx+j)*3]); 00686 if (dh<dv) 00687 tmp=(outG[(i*sx+j-1)*3]+outG[(i*sx+j+1)*3])/2; 00688 else { 00689 if (dh>dv) 00690 tmp=(outG[((i-1)*sx+j)*3]+outG[((i+1)*sx+j)*3])/2; 00691 else 00692 tmp=(outG[(i*sx+j-1)*3]+outG[(i*sx+j+1)*3]+outG[((i-1)*sx+j)*3]+outG[((i+1)*sx+j)*3])/4; 00693 } 00694 CLIP(tmp,outG[(i*sx+j)*3]); 00695 } 00696 } 00697 for (i=3;i<sy-3;i+=2) { 00698 for (j=3;j<sx-2;j+=2) { 00699 dh=abs((outR[(i*sx+j-2)*3]+outR[(i*sx+j+2)*3])/2-outR[(i*sx+j)*3]); 00700 dv=abs((outR[((i-2)*sx+j)*3]+outR[((i+2)*sx+j)*3])/2-outR[(i*sx+j)*3]); 00701 if (dh<dv) 00702 tmp=(outG[(i*sx+j-1)*3]+outG[(i*sx+j+1)*3])/2; 00703 else { 00704 if (dh>dv) 00705 tmp=(outG[((i-1)*sx+j)*3]+outG[((i+1)*sx+j)*3])/2; 00706 else 00707 tmp=(outG[(i*sx+j-1)*3]+outG[(i*sx+j+1)*3]+outG[((i-1)*sx+j)*3]+outG[((i+1)*sx+j)*3])/4; 00708 } 00709 CLIP(tmp,outG[(i*sx+j)*3]); 00710 } 00711 } 00712 // process RED channel 00713 for (i=1;i<sy-1;i+=2) { // G-points (1/2) 00714 for (j=2;j<sx-1;j+=2) { 00715 tmp=outG[(i*sx+j)*3]+(outR[(i*sx+j-1)*3]-outG[(i*sx+j-1)*3]+ 00716 outR[(i*sx+j+1)*3]-outG[(i*sx+j+1)*3])/2; 00717 CLIP(tmp,outR[(i*sx+j)*3]); 00718 } 00719 } 00720 for (i=2;i<sy-2;i+=2) { 00721 for (j=1;j<sx;j+=2) { // G-points (2/2) 00722 tmp=outG[(i*sx+j)*3]+(outR[((i-1)*sx+j)*3]-outG[((i-1)*sx+j)*3]+ 00723 outR[((i+1)*sx+j)*3]-outG[((i+1)*sx+j)*3])/2; 00724 CLIP(tmp,outR[(i*sx+j)*3]); 00725 } 00726 for (j=2;j<sx-1;j+=2) { // B-points 00727 tmp=outG[(i*sx+j)*3]+(outR[((i-1)*sx+j-1)*3]-outG[((i-1)*sx+j-1)*3]+ 00728 outR[((i-1)*sx+j+1)*3]-outG[((i-1)*sx+j+1)*3]+ 00729 outR[((i+1)*sx+j-1)*3]-outG[((i+1)*sx+j-1)*3]+ 00730 outR[((i+1)*sx+j+1)*3]-outG[((i+1)*sx+j+1)*3])/4; 00731 CLIP(tmp,outR[(i*sx+j)*3]); 00732 } 00733 } 00734 00735 // process BLUE channel 00736 for (i=0;i<sy;i+=2) { 00737 for (j=1;j<sx-2;j+=2) { 00738 tmp=outG[(i*sx+j)*3]+(outB[(i*sx+j-1)*3]-outG[(i*sx+j-1)*3]+ 00739 outB[(i*sx+j+1)*3]-outG[(i*sx+j+1)*3])/2; 00740 CLIP(tmp,outB[(i*sx+j)*3]); 00741 } 00742 } 00743 for (i=1;i<sy-1;i+=2) { 00744 for (j=0;j<sx-1;j+=2) { 00745 tmp=outG[(i*sx+j)*3]+(outB[((i-1)*sx+j)*3]-outG[((i-1)*sx+j)*3]+ 00746 outB[((i+1)*sx+j)*3]-outG[((i+1)*sx+j)*3])/2; 00747 CLIP(tmp,outB[(i*sx+j)*3]); 00748 } 00749 for (j=1;j<sx-2;j+=2) { 00750 tmp=outG[(i*sx+j)*3]+(outB[((i-1)*sx+j-1)*3]-outG[((i-1)*sx+j-1)*3]+ 00751 outB[((i-1)*sx+j+1)*3]-outG[((i-1)*sx+j+1)*3]+ 00752 outB[((i+1)*sx+j-1)*3]-outG[((i+1)*sx+j-1)*3]+ 00753 outB[((i+1)*sx+j+1)*3]-outG[((i+1)*sx+j+1)*3])/4; 00754 CLIP(tmp,outB[(i*sx+j)*3]); 00755 } 00756 } 00757 break; 00758 default: //--------------------------------------------------------- 00759 fprintf(stderr,"Bad bayer pattern ID\n"); 00760 break; 00761 } 00762 } 00763 00764 void 00765 BayerDownsample(unsigned char *src, unsigned char *dest, int sx, int sy, bayer_pattern_t type) 00766 { 00767 unsigned char *outR, *outG, *outB; 00768 register int i,j; 00769 int tmp; 00770 00771 sx*=2; 00772 sy*=2; 00773 00774 switch (type) { 00775 case BAYER_PATTERN_GRBG: 00776 case BAYER_PATTERN_BGGR: 00777 outR=&dest[0]; 00778 outG=&dest[1]; 00779 outB=&dest[2]; 00780 break; 00781 case BAYER_PATTERN_GBRG: 00782 case BAYER_PATTERN_RGGB: 00783 outR=&dest[2]; 00784 outG=&dest[1]; 00785 outB=&dest[0]; 00786 break; 00787 default: 00788 outR=NULL;outG=NULL;outB=NULL; 00789 break; 00790 } 00791 00792 switch (type) { 00793 case BAYER_PATTERN_GRBG://--------------------------------------------------------- 00794 case BAYER_PATTERN_GBRG: 00795 for (i=0;i<sy;i+=2) { 00796 for (j=0;j<sx;j+=2) { 00797 tmp=((src[i*sx+j]+src[(i+1)*sx+(j+1)])>>1); 00798 CLIP(tmp,outG[(((i*sx)>>2)+(j>>1))*3]); 00799 tmp=src[i*sx+j+1]; 00800 CLIP(tmp,outR[(((i*sx)>>2)+(j>>1))*3]); 00801 tmp=src[(i+1)*sx+j]; 00802 CLIP(tmp,outB[(((i*sx)>>2)+(j>>1))*3]); 00803 } 00804 } 00805 break; 00806 case BAYER_PATTERN_BGGR://--------------------------------------------------------- 00807 case BAYER_PATTERN_RGGB: 00808 for (i=0;i<sy;i+=2) { 00809 for (j=0;j<sx;j+=2) { 00810 tmp=((src[(i+1)*sx+j]+src[i*sx+(j+1)])>>1); 00811 CLIP(tmp,outG[(((i*sx)>>2)+(j>>1))*3]); 00812 tmp=src[(i+1)*sx+j+1]; 00813 CLIP(tmp,outR[(((i*sx)>>2)+(j>>1))*3]); 00814 tmp=src[i*sx+j]; 00815 CLIP(tmp,outB[(((i*sx)>>2)+(j>>1))*3]); 00816 } 00817 } 00818 break; 00819 default: //--------------------------------------------------------- 00820 fprintf(stderr,"Bad bayer pattern ID\n"); 00821 break; 00822 } 00823 00824 } 00825 00826 // change a 16bit stereo image (8bit/channel) into two 8bit images on top 00827 // of each other 00828 void 00829 StereoDecode(unsigned char *src, unsigned char *dest, unsigned long long int NumPixels) 00830 { 00831 register int i = NumPixels-1; 00832 register int j = (NumPixels>>1)-1; 00833 register int k = NumPixels-1; 00834 //fprintf(stderr,"NumPixels: %d\n",NumPixels); 00835 while (i > 0) { 00836 dest[k--] = src[i--]; 00837 dest[j--] = src[i--]; 00838 } 00839 }