conversions.c
Go to the documentation of this file.
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 }


image_algos
Author(s): Dejan Pangercic
autogenerated on Mon Oct 6 2014 09:35:23