apps/ccam/imageaccess.c

Go to the documentation of this file.
00001 /*
00002  * modified for model 313
00003  * imageaccess.c
00004  *
00005  */
00006 #include <fcntl.h>  /*open*/
00007 #include <unistd.h> /* close */
00008 #include <string.h>
00009 
00010 
00011 #include <stdio.h>
00012 #include <stdlib.h>
00013 #include <sys/mman.h>           /* mmap */
00014 
00015 #include "imageaccess.h"
00016 #define D(x)
00017 
00018 
00019 //   MD(fprintf(stderr,"width- %d, height %d, quality - %d, contrast - %d, color - %d, orient - %d, depth - %d\r\n", ImageWidth,ImageHeight, Quality, Contrast, Color, bayerOrient, Depth));
00020 
00021 /*
00022 struct pixel_buffers {
00023   int                     data_fd;      // frame read pseudo-file file descriptor
00024   unsigned char   rgb[MAX_IMAGE_WIDTH*3];       // r-g-b-r-g-b... bayer-decoded data
00025   int                     imageWidth;
00026   int                     imageHeight;
00027   unsigned char * this; // pointer to current line of 8-bit data (to decoded data or DMA line (if 8-bit)
00028   unsigned char * prev; // pointer to previous line
00029   unsigned char * next;
00030   int                     depth;        //  only 8/not 8 (16) bits/pixel
00031   int                     shft;         //      0-5 - software "gain"
00032   int                     color;        // 0 -mono, 1 - rgb, 2 - pseudo color
00033   unsigned long   BayerRows[3][( MAX_IMAGE_WIDTH >> 2) +4];      // not used in 8-bit, 0-shift mode
00034   int                     BayerOrient; // pixel at 0/0: 0 - R, 1 G(R), 2 - G(B), 3 - B
00035   int                     bufferedRows[3]; // row numbers currently available in BayerRows[0], [1] and [2]
00036   unsigned long   palette[256]; // lsb -b, next - g, next - r
00037 };
00038 
00039 */
00040 //local functions declarations
00041 
00042 
00043 unsigned char* convert8to8 ( int data_fd,   // image data file descriptor
00044                       unsigned long * row8Bit,
00045                       int rowNumber,
00046                                           int ImageWidth,
00047                       int Contrast);
00048 
00049 unsigned char* convert16to8 ( int data_fd,   // image data file descriptor
00050                       unsigned long * row8Bit,
00051                       int rowNumber,
00052                                           int ImageWidth,
00053                       int Contrast);
00054 int initPalette     (struct pixel_buffers * pbp,
00055                                          const char * pseudo
00056                                          );
00057 
00058 int initPalette     (struct pixel_buffers * pbp,
00059                                          const char * pseudo
00060                                          ) {
00061   int i,l;
00062   int c, c0, p,p0,p1,k,d;
00063   int  r,g,b;
00064   char pseudo_dflt[]="0W";
00065   const char * cp= pseudo;
00066   c0=0;p0=0; // just to make compiler happy ;-)
00067   if ((!cp) || (strlen(cp)==0)) return 0;
00068   pbp->color=2; // overwrite
00069   if (strlen(cp) < 2) {
00070     pseudo_dflt[1]=cp[0];
00071         cp=(const char *) pseudo_dflt; 
00072   }
00073   l=strlen(cp); // length of pseudo color string
00074   for (i=0; i<l;i++) {
00075     p1=(i*255)/(l-1);
00076     switch (cp[i] ) {
00077       case '0': case 'k': case 'K':  {c=0;break;}
00078       case '1': case 'r': case 'R':  {c=1;break;}
00079       case '2': case 'g': case 'G':  {c=2;break;}
00080       case '3': case 'y': case 'Y':  {c=3;break;}
00081       case '4': case 'b': case 'B':  {c=4;break;}
00082       case '5': case 'm': case 'M':  {c=5;break;}
00083       case '6': case 'c': case 'C':  {c=6;break;}
00084       case '7': case 'w': case 'W':  {c=7;break;}
00085       default:                 {c=1;break;}
00086     }
00087         if (i>0) {
00088          k=0xff0000/(p1-p0);
00089 D(fprintf(stderr,"p0=%x p1=%x k=%x\r\n",p0,p1,k));
00090          for (p=0;p<=(p1-p0);p++) { // will set each break point twice
00091            d=(p*k)>>16;
00092            if ((c^c0) & 1) {
00093              r= (c&1)?d:255-d;
00094            } else {     // if ((c^c0) & 1)
00095              r= (c&1)?255:0;
00096            } // if ((c^c0) & 1)
00097 
00098            if ((c^c0) & 2) {
00099              g= (c&2)?d:255-d;
00100            } else {     // if ((c^c0) & 1)
00101              g= (c&2)?255:0;
00102            } // if ((c^c0) & 1)
00103 
00104            if ((c^c0) & 4) {
00105              b= (c&4)?d:255-d;
00106            } else {     // if ((c^c0) & 1)
00107              b= (c&4)?255:0;
00108            } // if ((c^c0) & 1)
00109 D(fprintf(stderr,"c=%x r=%x g=%x b=%x\r\n",c,r,g,b));
00110 //         pbp->palette[p+p0]=r | (g<<8) | (b<<16);
00111            pbp->palette[p+p0]=b | (g<<8) | (r<<16);
00112          }
00113         } // if (i>0) {
00114 
00115         c0=c;
00116         p0=p1;
00117   }
00118 D(for (i=0;i<256;i++) fprintf(stderr,"%03x: %08x\r\n",i,pbp->palette[i]));
00119   return 1;
00120 }
00121 unsigned long * getPalette (struct pixel_buffers * pbp) {return ((pbp->color)==2)?pbp->palette:NULL; } 
00122 
00123 /*
00124   int                     color;        // 0 -mono, 1 - rgb, 2 - pseudo color
00125   unsigned long   palette[256]; // lsb -b, next - g, next - r
00126 
00127 */
00128 
00129 int initPixelBuffers(struct pixel_buffers * pbp,
00130                                         const char * dmaFileName,
00131                                         int     width, // should be obtained from imageParamsR[P_ACTUAL_WIDTH]
00132                                         int height, // should be obtained from imageParamsR[P_ACTUAL_HEIGHT]
00133                                         int contrast,
00134                                         int colorMode,  // 0- b/w, 1 - color
00135                                         int bayer,      // 0..3 color under 0:0
00136                                         int     pixelDepth,             // 10,8,4
00137                                         const char * pseudo
00138                                         ) {
00139     int i; //, ppl;
00140    MD(fprintf(stderr,"dmaFileName- %s,width - %d, height %d, contrast - %d, colorMode - %d, bayer - %d, pixelDepth - %d\r\n",dmaFileName,width,height,contrast,colorMode,bayer,pixelDepth));
00141 
00142 //
00143         pbp->data_fd=-1; // not initialized 
00144         switch (pixelDepth) {
00145          case 10:
00146          case 8:
00147          case 4: {pbp->depth=pixelDepth; break;}
00148          default: return -1; // bad depth
00149         }
00150  MD(fprintf(stderr,"\r\n"));
00151 
00152         if ((contrast >=0) && (contrast <6)) pbp->shft=contrast;
00153         else return -1;     // bad contrast
00154  MD(fprintf(stderr,"\r\n"));
00155         pbp->color=(colorMode>0);
00156         pbp->BayerOrient=bayer & 3;
00157         for (i=0;i<3;i++) pbp->bufferedRows[i] =-1;     // none cached
00158         if ((width >0)  && (width  <= MAX_IMAGE_WIDTH))  pbp->imageWidth=width;
00159         else return -1;
00160  MD(fprintf(stderr,"\r\n"));
00161         if ((height >0) && (height <= MAX_IMAGE_HEIGHT)) pbp->imageHeight=height;
00162         else return -1;
00163  MD(fprintf(stderr,"\r\n"));
00164 
00165 //try open dmaFileName
00166         if ((pbp->data_fd = open(dmaFileName, O_RDONLY))==-1) return -2; // file open error
00167  MD(fprintf(stderr,"\r\n"));
00168     initPalette ( pbp, pseudo);
00169     return 0; // all OK
00170 }
00171 
00172 void closePixelBuffers(struct pixel_buffers * pbp) {// just close data_fd;
00173   if (pbp->data_fd>=0) {
00174                 close(pbp->data_fd);
00175                 pbp->data_fd=-1;
00176   }
00177 }
00178 
00179 
00180 /*
00181 struct pixel_buffers {
00182   int                     data_fd;      // frame read pseudo-file file descriptor
00183   unsigned char   rgb[MAX_IMAGE_WIDTH*3];       // r-g-b-r-g-b... bayer-decoded data
00184   int                     imageWidth;
00185   int                     imageHeight;
00186   unsigned char * this; // pointer to current line of 8-bit data (to decoded data or DMA line (if 8-bit)
00187   unsigned char * prev; // pointer to previous line
00188   unsigned char * next;
00189   int                     depth;        //  only 8/not 8 (16) bits/pixel
00190   int                     shft;         //      0-5 - software "gain"
00191   int                     color;        // 0 -mono, 1 - rgb, 2 - pseudo color
00192   unsigned long   BayerRows[3][( MAX_IMAGE_WIDTH >> 2) +4];      // not used in 8-bit, 0-shift mode
00193   int                     BayerOrient; // pixel at 0/0: 0 - R, 1 G(R), 2 - G(B), 3 - B
00194   int                     bufferedRows[3]; // row numbers currently available in BayerRows[0], [1] and [2]
00195   unsigned long   palette[256]; // lsb -b, next - g, next - r
00196 };
00197 */
00198 // in color mode will not return rows 0 and last, will start at second pixel in each row 
00199 unsigned char * getPixelRow(struct pixel_buffers * pbp, int row) {      //returns pointer to row data (mono or color depending on mode)
00200   int i,j;
00201   int curFilter;
00202   unsigned char * pr;
00203   unsigned long * pp;
00204   unsigned long d;
00205         if (pbp->data_fd <0) return NULL;
00206 
00207         if ((pbp->color)==1) {
00208           if ((row < 1) || (row >= (pbp->imageHeight-1))) return NULL;
00209 // make this,prev,next
00210           if      ((row-1) == pbp->bufferedRows[0]) pbp->prev= (unsigned char *) pbp->BayerRows[0];
00211           else if ((row-1) == pbp->bufferedRows[1]) pbp->prev= (unsigned char *) pbp->BayerRows[1];
00212           else if ((row-1) == pbp->bufferedRows[2]) pbp->prev= (unsigned char *) pbp->BayerRows[2];
00213           else { // not in cache
00214             i=   (pbp->bufferedRows[0] > pbp->bufferedRows[1])? \
00215                       ((pbp->bufferedRows[2] > pbp->bufferedRows[1])? 1 : 2 ): \
00216                       ((pbp->bufferedRows[0] > pbp->bufferedRows[2])? 2 : 0 );
00217                   pbp->prev= getMonoRow(pbp, row-1, i);
00218                           pbp->bufferedRows[i]=row-1;
00219           }
00220           if      ((row  ) == pbp->bufferedRows[0]) pbp->this= (unsigned char *) pbp->BayerRows[0];
00221           else if ((row  ) == pbp->bufferedRows[1]) pbp->this= (unsigned char *) pbp->BayerRows[1];
00222           else if ((row  ) == pbp->bufferedRows[2]) pbp->this= (unsigned char *) pbp->BayerRows[2];
00223           else { // not in cache
00224             i=   (pbp->bufferedRows[0] > pbp->bufferedRows[1])? \
00225                       ((pbp->bufferedRows[2] > pbp->bufferedRows[1])? 1 : 2 ): \
00226                       ((pbp->bufferedRows[0] > pbp->bufferedRows[2])? 2 : 0 );
00227                   pbp->this= getMonoRow(pbp, row  , i);
00228                           pbp->bufferedRows[i]=row  ;
00229           }
00230           if      ((row+1) == pbp->bufferedRows[0]) pbp->next= (unsigned char *) pbp->BayerRows[0];
00231           else if ((row+1) == pbp->bufferedRows[1]) pbp->next= (unsigned char *) pbp->BayerRows[1];
00232           else if ((row+1) == pbp->bufferedRows[2]) pbp->next= (unsigned char *) pbp->BayerRows[2];
00233           else { // not in cache
00234             i=   (pbp->bufferedRows[0] > pbp->bufferedRows[1])? \
00235                       ((pbp->bufferedRows[2] > pbp->bufferedRows[1])? 1 : 2 ): \
00236                       ((pbp->bufferedRows[0] > pbp->bufferedRows[2])? 2 : 0 );
00237                   pbp->next= getMonoRow(pbp, row+1, i);
00238                           pbp->bufferedRows[i]=row+1;
00239           }
00240 //  MD(fprintf(stderr,"row=%d bufferedRows[0..2] %d %d %d\r\n",row, pbp->bufferedRows[0],pbp->bufferedRows[1],pbp->bufferedRows[2]));
00241 //  MD(fprintf(stderr,"prev,this,next %x %x %x\r\n",(int) pbp->prev, (int) pbp->this, (int) pbp->next));
00242           if ((!pbp->prev) || (!pbp->this) || (!pbp->next)) return NULL;
00243 
00244 // calculate rgb using this, prev and next bayer rows
00245       curFilter=((pbp->BayerOrient ^ 1) ^ (row << 1)) & 3;       // filter number over the first pixel in a row
00246           j=0;
00247           for (i=1;i<(pbp->imageWidth-1);i++){ 
00248             switch (curFilter) {
00249              case 0: { // r
00250                pbp->rgb[j++]=       pbp->this[i];                                                          // R component
00251                pbp->rgb[j++]=((int) pbp->this[i+1]+pbp->this[i-1]+pbp->prev[i  ]+pbp->next[i  ]) >> 2; // G component
00252                pbp->rgb[j++]=((int) pbp->prev[i+1]+pbp->prev[i-1]+pbp->next[i+1]+pbp->next[i-1]) >> 2; // B component
00253            break;
00254              }
00255              case 1: { // g on r
00256                pbp->rgb[j++]=((int) pbp->this[i+1]+pbp->this[i-1]) >> 1;                          // R component
00257                pbp->rgb[j++]=       pbp->this[i  ];                                               // G component
00258                pbp->rgb[j++]=((int) pbp->prev[i  ]+pbp->next[i  ]) >> 1;                          // B component
00259                break;
00260              }
00261              case 2: { // g on b
00262                pbp->rgb[j++]=((int) pbp->prev[i  ]+pbp->next[i  ]) >> 1;                          // R component
00263                pbp->rgb[j++]=       pbp->this[i  ];                                               // G component
00264                pbp->rgb[j++]=((int) pbp->this[i+1]+pbp->this[i-1]) >> 1;                          // B component
00265                break;
00266              }
00267              case 3: { // b
00268                pbp->rgb[j++]=((int) pbp->prev[i+1]+pbp->prev[i-1]+pbp->next[i+1]+pbp->next[i-1]) >> 2; // R component
00269                pbp->rgb[j++]=((int) pbp->this[i+1]+pbp->this[i-1]+pbp->prev[i  ]+pbp->next[i  ]) >> 2; // G component
00270                pbp->rgb[j++]=       pbp->this[i];                                                // B component
00271                break;
00272              }
00273             }
00274           curFilter ^=1; // r-g-r-g... or g-b-g-b...
00275 
00276           }
00277 //      MD(fprintf(stderr,"color calculated\r\n"));
00278 
00279       return (unsigned char*) pbp->rgb;
00280         } else if ((pbp->color)==2) {
00281 // build pbp->rgb
00282 //  unsigned char * pr;
00283 //  unsigned long * pp;
00284        pr=getMonoRow(pbp, row, 0);
00285            pp=getPalette(pbp);
00286            j=0;
00287            for (i=0;i<(pbp->imageWidth);i++){
00288              d=pp[pr[i]];
00289 //               pbp->rgb[j++]= (d         & 0xff);
00290 //               pbp->rgb[j++]= ((d >>  8) & 0xff);
00291 //               pbp->rgb[j++]= ((d >> 16) & 0xff);
00292 // sequence changed to match bmp files (b-g-r)
00293                  pbp->rgb[j++]= ((d >> 16) & 0xff);
00294                  pbp->rgb[j++]= ((d >>  8) & 0xff);
00295                  pbp->rgb[j++]= (d         & 0xff);
00296            } 
00297        return (unsigned char*) pbp->rgb;
00298         } else return getMonoRow(pbp, row, 0); //if ((pbp->color)==1)
00299 }
00300 
00301 unsigned char * getMonoRow(struct pixel_buffers * pbp, int row, int bufn) {
00302 //  MD(fprintf(stderr,"bufn= %d, row=%d\r\n",bufn,row));
00303 
00304   if (pbp->data_fd < 0) return NULL;
00305   if ((bufn < 0) || (bufn >  2)) return NULL;
00306   if ((row  < 0) || (row  >= pbp->imageHeight)) return NULL;
00307   switch(pbp->depth){
00308     case  8: return convert8to8  (pbp->data_fd,pbp->BayerRows[bufn],row,pbp->imageWidth,pbp->shft);
00309     default: return convert16to8 (pbp->data_fd,pbp->BayerRows[bufn],row,pbp->imageWidth,pbp->shft);
00310   }
00311 }
00312 
00313 
00314 
00315 /*
00316  * Apply contrast to convert DMA 8-bit data to rows of 8-bit data
00317  */
00318 
00319 unsigned char* convert8to8 ( int data_fd,   // image data file descriptor
00320                       unsigned long * row8Bit,
00321                       int rowNumber,
00322                                           int ImageWidth,
00323                       int Contrast) {
00324   int i,DMALongsPerRow;
00325   unsigned long dmask;
00326 
00327 // read line from file
00328   lseek(data_fd,ImageWidth*rowNumber,0);
00329   read (data_fd,row8Bit,ImageWidth);
00330   if (Contrast>0) {
00331     DMALongsPerRow=(ImageWidth>>2)+ ((ImageWidth & 3)? 1:0);
00332     dmask=(0xff<<Contrast) & 0xff;
00333     dmask |= ((dmask)<<8) | ((dmask)<<16) | ((dmask)<<24);
00334     MD(fprintf(stderr,"row= %d, Contrast=%d, dmask=%lx\r\n",rowNumber,Contrast,dmask));
00335     for (i=0;i<DMALongsPerRow;i++)  row8Bit[i]=(row8Bit[i]<<Contrast) & dmask;
00336   }
00337   return (unsigned char*) row8Bit;
00338  }
00339 
00340 unsigned char* convert16to8 ( int data_fd,   // image data file descriptor
00341                       unsigned long * row8Bit,
00342                       int rowNumber,
00343                                           int ImageWidth,
00344                       int Contrast) {
00345   int i,sr,sl;
00346   unsigned long lrow16[(MAX_IMAGE_WIDTH >>1 ) + 4] ; //+4??
00347   short *       row16= (short *) lrow16;
00348   unsigned char * brow8= (unsigned char *) row8Bit;
00349 // read line from file
00350   lseek(data_fd,(ImageWidth*rowNumber)<<1,0);
00351   read (data_fd,row16,ImageWidth<<1);
00352   sr=2-Contrast;
00353   sl=Contrast-2;
00354   if (Contrast <= 2) for (i=0;i<ImageWidth;i++) brow8[i]= (row16[i]>>sr) & 0xff;
00355   else               for (i=0;i<ImageWidth;i++) brow8[i]= (row16[i]<<sl) & 0xff;
00356   return (unsigned char*) row8Bit;
00357  }
00358 
00359 
00360 

Generated on Thu Aug 7 16:18:59 2008 for elphel by  doxygen 1.5.1