apps/autoexposure/aexp_utils.c

Go to the documentation of this file.
00001 /*!***************************************************************************
00002 *! FILE NAME  : aexp_utils.c
00003 *! DESCRIPTION: Daemon to adjust camera exposure and white balance
00004 *! Copyright (C) 2008 Elphel, Inc.
00005 *! -----------------------------------------------------------------------------**
00006 *!  This program is free software: you can redistribute it and/or modify
00007 *!  it under the terms of the GNU General Public License as published by
00008 *!  the Free Software Foundation, either version 3 of the License, or
00009 *!  (at your option) any later version.
00010 *!
00011 *!  This program is distributed in the hope that it will be useful,
00012 *!  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 *!  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 *!  GNU General Public License for more details.
00015 *!
00016 *!  You should have received a copy of the GNU General Public License
00017 *!  along with this program.  If not, see <http://www.gnu.org/licenses/>.
00018 *! -----------------------------------------------------------------------------**
00019 *!
00020 *!  $Log: aexp_utils.c,v $
00021 *!  Revision 1.1.1.1  2008/11/27 20:04:01  elphel
00022 *!
00023 *!
00024 *!  Revision 1.2  2008/11/18 19:30:16  elphel
00025 *!  Added initialization of the "next" frame - otherwise it wait _very_ long if the camera frame number is reset
00026 *!
00027 *!  Revision 1.1  2008/11/15 23:08:24  elphel
00028 *!  8.0.alpha17 - split autoexposure source file
00029 *!
00030 *!
00031 */ 
00032 
00033 #include "autoexposure.h"
00034 
00035 int poorLog(int x) {
00045   if (x<0) return 0;
00046   int y=5;
00047   if ((x & ~0x1ff) ==0  ) { 
00048     while (((x & 0x100) ==0) && (y>1)) {
00049       y--;
00050       x <<=1;
00051     }
00052     if (y>1) x+=(y<<8);
00053     return x; // 0..511
00054   }
00055   while (x & ~0x1ff) { 
00056     x >>= 1;
00057     y++;
00058   }
00059   return x+(y<<8);
00060 }
00061 
00062 int poorExp(int x) {
00063   int  y=x & 0xff;
00064   x >>= 8;
00065   if      (x <  1) return y >> 4;
00066   else if (x <= 5) return y >> (5-x);
00067   else             return y << (x-5);
00068 }
00069 
00070 int   waitRequstPrevHist(unsigned long next_frame) {
00071   unsigned long write_data[4]; 
00072   this_frame=GLOBALPARS(G_THIS_FRAME);
00073   MDF2(fprintf(stderr,"next_frame=0x%08lx, this_frame=0x%08lx\n",next_frame,this_frame)); 
00074 
00075   if (next_frame <= this_frame) return 0; 
00076   else if (next_frame > (this_frame+5) ) { 
00077     lseek(fd_fparmsall, next_frame-5+LSEEK_FRAME_WAIT_ABS, SEEK_END);
00078     this_frame=GLOBALPARS(G_THIS_FRAME);
00079   }
00081   write_data[0]= FRAMEPARS_SETFRAME;
00082   write_data[1]= next_frame-1;
00083   write_data[2]= P_HISTRQ_YC; 
00084   write_data[3]= 3; 
00085   int rslt=write(fd_fparmsall, write_data, sizeof(write_data));
00086   if (rslt < sizeof(write_data)) return -errno;
00088   if (next_frame > this_frame ) {
00089     lseek(fd_fparmsall, next_frame+LSEEK_FRAME_WAIT_ABS, SEEK_END);
00090     this_frame=GLOBALPARS(G_THIS_FRAME);
00091     return 1;
00092   }
00093   return 0;
00094 }
00095 
00106 long getPercentile(unsigned long frame,int color, unsigned long fraction, int request_colors) {
00107    unsigned long hash32;
00108    unsigned long  write_data[2];
00109    int rslt;
00110    unsigned long * hist_cumul;      
00111    unsigned char * hist_percentile; 
00112    int total_pixels;
00113    int perc;
00114    int perc_frac=0;
00115    int frac_pixels; 
00116    int delta;
00117    MDF2(fprintf(stderr,"percentile for frame=0x%lx, color=%x, fraction=0x%lx, request_colors=0x%x\n",frame, color, fraction, request_colors));
00119    if (request_colors) { 
00120      if (request_colors & ~ (1<<COLOR_Y_NUMBER)) lseek(fd_histogram_cache, LSEEK_HIST_WAIT_C, SEEK_END); 
00121      else                                        lseek(fd_histogram_cache, LSEEK_HIST_WAIT_Y, SEEK_END); 
00122     MDF2(fprintf(stderr,"this_frame: 0x%lx,  NOW: 0x%lx\n",this_frame, GLOBALPARS(G_THIS_FRAME)));
00123      lseek(fd_histogram_cache, LSEEK_HIST_NEEDED + (request_colors << 8), SEEK_END);      
00124      hist_index=lseek(fd_histogram_cache, frame, SEEK_SET);                             
00125     MDF2(fprintf(stderr,"got histogram for frame: 0x%lx,  NOW: 0x%lx\n",histogram_cache[hist_index].frame, GLOBALPARS(G_THIS_FRAME)));
00127      if(hist_index <0) {
00128        ELP_FERR(fprintf(stderr, "Requested histograms for frame %ld (0x%lx) are not available. this_frame=0x%lx, now=0x%lx\n",frame,frame,this_frame,GLOBALPARS(G_THIS_FRAME) ));
00129        return -1;
00130      }
00131    }
00132    hist_cumul=     &(histogram_cache[hist_index].cumul_hist[color<<8]);
00133    hist_percentile=&(histogram_cache[hist_index].percentile[color<<8]);
00134    if (fraction > (PERCENTILE_1-1)) fraction = PERCENTILE_1-1;
00135    total_pixels=   hist_cumul[255];
00136    frac_pixels=(((long long) total_pixels) * fraction) >> PERCENTILE_SHIFT;
00137    perc=hist_percentile[fraction >> (PERCENTILE_SHIFT-8)]; 
00138    MDF2(fprintf(stderr,"total_pixels=0x%x, frac_pixels=0x%x, perc=0x%x\n",total_pixels, frac_pixels, perc));
00139 
00140    if (perc>0) perc--;                                              
00141    while ((perc>0) &&  (hist_cumul[perc] > frac_pixels)) perc--;    
00142    perc++;
00143    while ((perc<255) &&  (hist_cumul[perc] <= frac_pixels)) perc++; 
00144    perc--;
00145    delta=hist_cumul[perc+1] - hist_cumul[perc];
00146    if (delta) {
00147      perc_frac=((frac_pixels-hist_cumul[perc]) << (PERCENTILE_SHIFT-8))/delta;
00148    }
00149    perc_frac += perc << (PERCENTILE_SHIFT-8);
00150    MDF2(fprintf(stderr,"hist_cumul[0x%x]=0x%lx hist_cumul[0x%x]=0x%lx, delta=0x%x, perc_frac=0x%x\n",perc,hist_cumul[perc],perc+1,hist_cumul[perc+1],delta,perc_frac));
00151 
00154    hash32=histogram_cache[hist_index].gtab[color];
00155    MDF2(fprintf(stderr,"frame=0x%lx hist.frame=0x%lx  hist_index=%d hash32=0x%lx\n",frame, histogram_cache[hist_index].frame, hist_index, hash32));
00156    MDF7(fprintf(stderr,"frame=0x%lx hist.frame=0x%lx  hist_index=%d hash32=0x%lx\n",frame, histogram_cache[hist_index].frame, hist_index, hash32));
00157    write_data[0]=hash32;
00158    write_data[1]=GAMMA_MODE_NEED_REVERSE;
00159    rslt=write(fd_gamma_cache, write_data, 6);
00160    if (rslt<= 0) {
00161        ELP_FERR(fprintf(stderr,"Request for gamma returned %d, hash32=0x%lx (gamma=%f, black=%d, scale=%f)\n",rslt,hash32, 0.01*((hash32>>16) & 0xff),(int)(hash32>>24), (hash32 & 0xffff)/1024.0));
00162        return -1;
00163    }
00164    gamma_index=lseek(fd_gamma_cache, 0, SEEK_CUR);
00165    MDF2(fprintf(stderr,"gamma_index=0x%x, rslt=0x%x\n",gamma_index,rslt));
00166   if (gamma_index <= 0) {
00167        ELP_FERR(fprintf(stderr,"request for gamma table (frame=%ld(0x%lx), color=%d, fraction=0x%lx) failed\n",frame,frame,color, fraction));
00168        return -1;
00169    }
00171    MDF2(fprintf(stderr,"gamma_index=0x%x\n",gamma_index));
00172    return gammaReverse (perc_frac);
00173 }
00174 
00180 unsigned long gammaDirect (unsigned long x) {
00181    if (x>0xffff) x=0xffff;
00182    unsigned long y= gamma_cache[gamma_index].direct[x >> 8]; 
00183    y+= ((gamma_cache[gamma_index].direct[(x >> 8)+1]-y)*(x & 0xff))>>8;
00184    if (y > 0xffff) y=0xffff;
00185    return y;
00186 }
00187 
00193 unsigned long gammaReverse (unsigned long x) {
00194    unsigned short * gamma_direct= gamma_cache[gamma_index].direct;  
00195    unsigned char *  gamma_reverse=gamma_cache[gamma_index].reverse; 
00196    if (x>0xffff) x=0xffff;
00197    int y_frac=0;
00198    int y=gamma_reverse[x >> 8]; 
00199    if (y>0) y--;                                   
00200    while ((y > 0) &&  (gamma_direct[y] >  x)) y--; 
00201    y++;
00202    while ((y<255) &&  (gamma_direct[y] <= x)) y++; 
00203    y--;
00204    int delta=gamma_direct[y+1] - gamma_direct[y];
00205    if (delta)  y_frac=((x - gamma_direct[y]) << 8)/delta;
00206 
00207    MDF2(fprintf(stderr,"y_frac=0x%x\n",y_frac));
00208    y_frac += y << 8;
00209    MDF2(fprintf(stderr,"gamma_direct[0x%x]=0x%x gamma_direct[0x%x]=0x%x, delta=0x%x, y_frac=0x%x\n",y, (int) gamma_direct[y],y+1,(int) gamma_direct[y+1],delta,y_frac));
00211    if      (y_frac <      0) y_frac=0;
00212    else if (y_frac > 0xffff) y_frac=0xffff;
00213    return y_frac;
00214 }
00215 
00216 
00217 
00224 unsigned long get_imageParamsThat     (int indx, unsigned long frame) {
00225    int frame_index=  frame & PARS_FRAMES_MASK;
00226    int past_index=   frame & PASTPARS_SAVE_ENTRIES_MASK;
00227    unsigned long value;
00229    if (framePars[frame_index].pars[P_FRAME] != frame) {
00231      if ((indx < PARS_SAVE_FROM) || (indx >= (PARS_SAVE_FROM+PARS_SAVE_NUM))) return 0xffffffff ; 
00232      value=pastPars[past_index].past_pars[indx - PARS_SAVE_FROM]; 
00233      if (pastPars[past_index].past_pars[P_FRAME-PARS_SAVE_FROM] != frame) { 
00234        ELP_FERR(fprintf (stderr,"Can not find frame 0x%x data neither in framePars[0x%x].pars[0x%x]=0x%x, nor in pastPars[0x%x].past_pars[0x%x]=0x%x\n",\
00235                      (int) frame, frame_index, (int) P_FRAME, (int) framePars[frame_index].pars[P_FRAME],\
00236                                   past_index,  (int) (P_FRAME-PARS_SAVE_FROM), (int) pastPars[past_index].past_pars[P_FRAME-PARS_SAVE_FROM]));
00237        return 0xffffffff;
00238      }
00239    } else {
00240      value=framePars[frame_index].pars[indx];
00241    }
00242    return value;
00243 }
00244 
00251 int           get_imageParamsThatValid(int indx, unsigned long frame) {
00252    int frame_index=  frame & PARS_FRAMES_MASK;
00253    int past_index=   frame & PASTPARS_SAVE_ENTRIES_MASK;
00254    int value;
00256    if (framePars[frame_index].pars[P_FRAME] != frame) {
00258      if ((indx < PARS_SAVE_FROM) || (indx >= (PARS_SAVE_FROM+PARS_SAVE_NUM))) return -2 ; 
00259      value=pastPars[past_index].past_pars[indx - PARS_SAVE_FROM] & 0x7fffffff;
00260      if (pastPars[past_index].past_pars[P_FRAME-PARS_SAVE_FROM] != frame) { 
00261        ELP_FERR(fprintf (stderr,"Can not find frame 0x%x data neither in framePars[0x%x].pars[0x%x]=0x%x, nor in pastPars[0x%x].past_pars[0x%x]=0x%x\n",\
00262                      (int) frame, frame_index, (int) P_FRAME, (int) framePars[frame_index].pars[P_FRAME],\
00263                                   past_index,  (int) (P_FRAME-PARS_SAVE_FROM), (int) pastPars[past_index].past_pars[P_FRAME-PARS_SAVE_FROM]));
00264        return -1;
00265      }
00266    } else {
00267      value=framePars[frame_index].pars[indx] & 0x7fffffff;
00268    }
00269    return value ;
00270 }
00271 
00277 int recalibrateDim(void) {
00278   unsigned long vexpos_was, fraction, dims;
00279   unsigned long write_data[4];
00280   int rslt;
00281   this_frame=GLOBALPARS(G_THIS_FRAME);
00282   MDF1(fprintf(stderr,"this_frame: 0x%lx\n",this_frame));
00283   unsigned long target_frame=this_frame+RECALIBRATE_AHEAD;
00284   vexpos_was= framePars[target_frame & PARS_FRAMES_MASK].pars[P_VEXPOS];
00285   fraction=   framePars[target_frame & PARS_FRAMES_MASK].pars[P_AEXP_FRACPIX];
00286   MDF1(fprintf(stderr,"this_frame: 0x%lx target_frame: 0x%lx\n",this_frame,target_frame));
00287   write_data[0]=FRAMEPARS_SETFRAME;
00288   write_data[1]= target_frame;
00289   write_data[2]= P_VEXPOS; // | FRAMEPAIR_FORCE_NEWPROC ?
00290   write_data[3]= 1;
00291   rslt=write(fd_fparmsall, write_data, sizeof(write_data));
00292   if (rslt < sizeof(write_data)) return -errno;
00293   write_data[1]= target_frame+RECALIBRATE_AFTER; 
00294   write_data[3]= vexpos_was;
00295   rslt=write(fd_fparmsall, write_data, sizeof(write_data));
00296   if (rslt < sizeof(write_data)) return -errno;
00298   dims= getPercentile(target_frame,0, fraction, 0xf) & 0xffff; 
00299   dims|=getPercentile(target_frame,1, fraction, 0xf) << 16; 
00300   GLOBALPARS(G_HIST_DIM_01)=dims;
00301   dims= getPercentile(target_frame,2, fraction, 0xf) & 0xffff; 
00302   dims|=getPercentile(target_frame,3, fraction, 0xf) << 16; 
00303   GLOBALPARS(G_HIST_DIM_23)=dims;
00304   MDF1(fprintf(stderr,"dims: 0x%lx NOW: 0x%lx\n",dims, GLOBALPARS(G_THIS_FRAME)));
00305   lseek(fd_histogram_cache, target_frame+RECALIBRATE_AFTER, SEEK_SET); 
00306   return 0;
00307 }
00308 
00309 
00310 

Generated on Fri Nov 28 00:06:21 2008 for elphel by  doxygen 1.5.1