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


ar_recog
Author(s): Graylin Trevor Jay and Christopher Crick
autogenerated on Fri Jan 25 2013 12:15:00