00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifdef HAVE_CONFIG_H
00031 #include <config.h>
00032 #endif
00033
00034 #include <cpl.h>
00035 #include <math.h>
00036 #include <string.h>
00037
00038 #include "vircam_utils.h"
00039 #include "vircam_filt.h"
00040
00041 static void docols(float *data, unsigned char *bpm, int nx, int ny,
00042 int filter, int stat);
00043 static void dorows(float *data, unsigned char *bpm, int nx, int ny,
00044 int filter, int stat);
00045 static void wraparound(float *data, unsigned char *bpm, int npts, int nfilt,
00046 int whichstat, float **ybuf, unsigned char **ybbuf,
00047 int *nbuf);
00048 static void medavg(float *array, unsigned char *bpm, int *ipoint, int npix,
00049 int whichstat, int newl, float *outval,
00050 unsigned char *outbp);
00051 static void quickie(float *array, unsigned char *iarray, int *iarray2,
00052 int lll, int narray);
00053 static void sortm(float *a1, unsigned char *a2, int *a3, int n);
00054 static void plugholes(float *data, unsigned char *bpm, int nx);
00055
00056
00057
00058 static float sum;
00059 static float sumw;
00060 static int naver;
00061 static float nextw;
00062 static float lastw;
00063 static float nextval;
00064 static float lastval;
00065 static short int nextc;
00066 static short int lastc;
00067
00082
00120
00121
00122 extern void vircam_bfilt(float *data, unsigned char *bpm, int nx, int ny,
00123 int filt, int stat, int axis) {
00124
00125
00126
00127
00128 if (axis == 1) {
00129 dorows(data,bpm,nx,ny,filt,stat);
00130 docols(data,bpm,nx,ny,filt,stat);
00131 } else {
00132 docols(data,bpm,nx,ny,filt,stat);
00133 dorows(data,bpm,nx,ny,filt,stat);
00134 }
00135
00136 }
00137
00138
00168
00169
00170 static void docols(float *data, unsigned char *bpm, int nx, int ny,
00171 int filter, int stat) {
00172 int j,k,indx,nbuf;
00173 unsigned char *goodval,*bbuf;
00174 float *dbuf;
00175
00176
00177
00178 if (filter <= 0)
00179 return;
00180
00181
00182
00183 nbuf = max(nx,ny);
00184 dbuf = cpl_malloc(nbuf*sizeof(*dbuf));
00185 bbuf = cpl_malloc(nbuf*sizeof(*bbuf));
00186 goodval = cpl_malloc(ny*sizeof(*goodval));
00187
00188
00189
00190 for (k = 0; k < nx; k++) {
00191 memset((char *)goodval,0,ny);
00192 for (j = 0; j < ny; j++) {
00193 indx = j*nx + k;
00194 dbuf[j] = data[indx];
00195 bbuf[j] = bpm[indx];
00196 }
00197
00198
00199
00200 vircam_dostat(dbuf,bbuf,goodval,ny,filter,stat);
00201 plugholes(dbuf,goodval,ny);
00202
00203
00204
00205 for (j = 0; j < ny; j++) {
00206 indx = j*nx + k;
00207 data[indx] = dbuf[j];
00208 }
00209 }
00210
00211
00212
00213 freespace(dbuf);
00214 freespace(bbuf);
00215 freespace(goodval);
00216 }
00217
00218
00248
00249
00250 static void dorows(float *data, unsigned char *bpm, int nx, int ny,
00251 int filter, int stat) {
00252 int j,k,indx,nbuf;
00253 unsigned char *goodval,*bbuf;
00254 float *dbuf;
00255
00256
00257
00258 if (filter <= 0)
00259 return;
00260
00261
00262
00263 nbuf = max(nx,ny);
00264 dbuf = cpl_malloc(nbuf*sizeof(*dbuf));
00265 bbuf = cpl_malloc(nbuf*sizeof(*bbuf));
00266 goodval = cpl_malloc(nx*sizeof(*goodval));
00267
00268
00269
00270 for (k = 0; k < ny; k++) {
00271 memset((char *)goodval,0,nx);
00272 for (j = 0; j < nx; j++) {
00273 indx = k*nx + j;
00274 dbuf[j] = data[indx];
00275 bbuf[j] = bpm[indx];
00276 }
00277
00278
00279
00280 vircam_dostat(dbuf,bbuf,goodval,nx,filter,stat);
00281 plugholes(dbuf,goodval,nx);
00282
00283
00284
00285 for (j = 0; j < nx; j++) {
00286 indx = k*nx + j;
00287 data[indx] = dbuf[j];
00288 }
00289 }
00290
00291
00292
00293 freespace(dbuf);
00294 freespace(bbuf);
00295 freespace(goodval);
00296 }
00297
00298
00328
00329
00330 extern void vircam_dostat(float *data, unsigned char *bpm,
00331 unsigned char *goodval, int npts, int nfilt,
00332 int whichstat) {
00333 int nbuf,jl,jh,j,*ipoint,ifree,i;
00334 unsigned char *ybbuf,*barray,bval;
00335 float *ybuf,*darray,val;
00336
00337
00338
00339 if ((nfilt/2)*2 == nfilt)
00340 nfilt++;
00341
00342
00343
00344 wraparound(data,bpm,npts,nfilt,whichstat,&ybuf,&ybbuf,&nbuf);
00345
00346
00347
00348 darray = cpl_malloc(nfilt*sizeof(*darray));
00349 barray = cpl_malloc(nfilt*sizeof(*barray));
00350 ipoint = cpl_malloc(nfilt*sizeof(*ipoint));
00351 memmove((char *)darray,(char *)ybuf,nfilt*sizeof(*ybuf));
00352 memmove((char *)barray,(char *)ybbuf,nfilt*sizeof(*ybbuf));
00353 for (j = 0; j < nfilt; j++)
00354 ipoint[j] = j;
00355
00356
00357
00358 ifree = 0;
00359 medavg(darray,barray,ipoint,nfilt,whichstat,-1,&val,&bval);
00360 if (! bval)
00361 data[0] = val;
00362 goodval[0] = bval;
00363
00364
00365
00366
00367 jl = nfilt;
00368 jh = nfilt + npts - 2;
00369 for (j = jl; j <= jh; j++) {
00370 for (i = 0; i < nfilt; i++) {
00371 if (ipoint[i] == 0) {
00372 ifree = i;
00373 ipoint[i] = nfilt - 1;
00374 lastval = darray[ifree];
00375 lastw = 0.0;
00376 lastc = 0;
00377 if (barray[ifree] == 0) {
00378 lastw = 1.0;
00379 lastc = 1;
00380 }
00381 darray[ifree] = ybuf[j];
00382 barray[ifree] = ybbuf[j];
00383 nextval = darray[ifree];
00384 nextw = 0.0;
00385 nextc = 0;
00386 if (barray[ifree] == 0) {
00387 nextw = 1.0;
00388 nextc = 1;
00389 }
00390 } else
00391 ipoint[i]--;
00392 }
00393 medavg(darray,barray,ipoint,nfilt,whichstat,ifree,&val,&bval);
00394 if (! bval)
00395 data[j-jl+1] = val;
00396 goodval[j-jl+1] = bval;
00397 }
00398
00399
00400
00401 freespace(darray);
00402 freespace(barray);
00403 freespace(ipoint);
00404 freespace(ybuf);
00405 freespace(ybbuf);
00406 }
00407
00408
00443
00444
00445 static void wraparound(float *data, unsigned char *bpm, int npts, int nfilt,
00446 int whichstat, float **ybuf, unsigned char **ybbuf, int *nbuf) {
00447
00448 float *darray,xmns,xmnf;
00449 int i1,ilow,i,*ipoint;
00450 unsigned char *barray,bxmns,bxmnf;
00451
00452
00453
00454 i1 = nfilt/2;
00455 ilow = max(3,nfilt/4);
00456 ilow = (ilow/2)*2 + 1;
00457
00458
00459
00460 darray = cpl_malloc(nfilt*sizeof(*darray));
00461 barray = cpl_malloc(nfilt*sizeof(*barray));
00462 ipoint = cpl_calloc(nfilt,sizeof(*ipoint));
00463 *nbuf = npts + 2*i1;
00464 *ybuf = cpl_malloc(*nbuf*sizeof(float));
00465 *ybbuf = cpl_malloc(*nbuf*sizeof(unsigned char));
00466
00467
00468
00469 memmove((char *)darray,(char *)data,ilow*sizeof(*data));
00470 memmove((char *)barray,(char *)bpm,ilow*sizeof(*bpm));
00471 medavg(darray,barray,ipoint,ilow,whichstat,-1,&xmns,&bxmns);
00472 memmove((char *)darray,(char *)(data+npts-ilow),ilow*sizeof(*data));
00473 memmove((char *)barray,(char *)(bpm+npts-ilow),ilow*sizeof(*bpm));
00474 medavg(darray,barray,ipoint,ilow,whichstat,-1,&xmnf,&bxmnf);
00475 for (i = 0; i < i1; i++) {
00476 if (! bxmns) {
00477 (*ybuf)[i] = 2.0*xmns - data[i1+ilow-i-1];
00478 (*ybbuf)[i] = bpm[i1+ilow-i-1];
00479 } else {
00480 (*ybuf)[i] = data[i1+ilow-i-1];
00481 (*ybbuf)[i] = 1;
00482 }
00483 if (! bxmnf) {
00484 (*ybuf)[npts+i1+i] = 2.0*xmnf - data[npts-i-ilow-1];
00485 (*ybbuf)[npts+i1+i] = bpm[npts-i-ilow-1];
00486 } else {
00487 (*ybuf)[npts+i1+i] = data[npts-i-ilow-1];
00488 (*ybbuf)[npts+i1+i] = 1;
00489 }
00490 }
00491
00492
00493
00494 memmove((char *)(*ybuf+i1),data,npts*sizeof(*data));
00495 memmove((char *)(*ybbuf+i1),bpm,npts*sizeof(*bpm));
00496
00497
00498
00499 freespace(darray);
00500 freespace(barray);
00501 freespace(ipoint);
00502 }
00503
00504
00541
00542
00543 static void medavg(float *array, unsigned char *bpm, int *ipoint, int npix,
00544 int whichstat, int newl, float *outval,
00545 unsigned char *outbp) {
00546
00547 float *buf = NULL;
00548 int m,i;
00549
00550
00551
00552
00553
00554 m = 0;
00555 if (whichstat == MEDIANCALC) {
00556 if (newl == -1)
00557 sortm(array,bpm,ipoint,npix);
00558 else
00559 quickie(array,bpm,ipoint,newl,npix);
00560
00561
00562
00563 buf = cpl_malloc(npix*sizeof(*buf));
00564
00565
00566
00567 m = 0;
00568 for (i = 0; i < npix; i++) {
00569 if (bpm[i] == 0) {
00570 buf[m] = array[i];
00571 m++;
00572 }
00573 }
00574
00575
00576
00577
00578
00579
00580 } else if (whichstat == MEANCALC) {
00581 if (newl == -1) {
00582 sum = 0.0;
00583 sumw = 0.0;
00584 naver = 0;
00585 for (i = 0; i < npix; i++) {
00586 if (bpm[i] == 0) {
00587 sum += array[i];
00588 sumw += 1.0;
00589 naver += 1;
00590 }
00591 }
00592 m = naver;
00593 } else {
00594 sum += (nextw*nextval - lastw*lastval);
00595 sumw += (nextw - lastw);
00596 naver += (nextc - lastc);
00597 m = naver;
00598 }
00599 }
00600
00601
00602
00603 if (m == 0) {
00604 *outval = 0.0;
00605 *outbp = 1;
00606 if (whichstat == MEDIANCALC)
00607 freespace(buf);
00608
00609
00610
00611 } else {
00612 if (whichstat == MEDIANCALC) {
00613 if (!(m & 1))
00614 *outval = 0.5*(buf[(m/2)-1] + buf[m/2]);
00615 else
00616 *outval = buf[m/2];
00617 freespace(buf);
00618 } else if (whichstat == MEANCALC)
00619 *outval = sum/sumw;
00620 *outbp = 0;
00621 }
00622 }
00623
00624
00648
00649
00650 static void quickie(float *array, unsigned char *iarray, int *iarray2,
00651 int testloc, int narray) {
00652
00653 float test;
00654 int i,j,npt,it2;
00655 unsigned char it;
00656
00657 test = array[testloc];
00658 it = iarray[testloc];
00659 it2 = iarray2[testloc];
00660 j = -1;
00661 for (i = 0; i < narray; i++) {
00662 if (i != testloc && test <= array[i]) {
00663 j = i;
00664 break;
00665 }
00666 }
00667 if (j == -1)
00668 j = narray;
00669 if (j - 1 == testloc)
00670 return;
00671
00672 if (j - testloc < 0) {
00673 npt = testloc - j;
00674 for (i = 0; i < npt; i++) {
00675 array[testloc-i] = array[testloc-i-1];
00676 iarray[testloc-i] = iarray[testloc-i-1];
00677 iarray2[testloc-i] = iarray2[testloc-i-1];
00678 }
00679 array[j] = test;
00680 iarray[j] = it;
00681 iarray2[j] = it2;
00682 } else {
00683 j--;
00684 npt = j - testloc;
00685 if (npt != 0) {
00686 for (i = 0; i < npt; i++) {
00687 array[testloc+i] = array[testloc+i+1];
00688 iarray[testloc+i] = iarray[testloc+i+1];
00689 iarray2[testloc+i] = iarray2[testloc+i+1];
00690 }
00691 }
00692 array[j] = test;
00693 iarray[j] = it;
00694 iarray2[j] = it2;
00695 }
00696 }
00697
00698
00720
00721
00722 static void sortm(float *a1, unsigned char *a2, int *a3, int n) {
00723 int iii,ii,i,ifin,j,b3;
00724 unsigned char b2;
00725 float b1;
00726
00727 iii = 4;
00728 while (iii < n)
00729 iii *= 2;
00730 iii = min(n,(3*iii)/4 - 1);
00731
00732 while (iii > 1) {
00733 iii /= 2;
00734 ifin = n - iii;
00735 for (ii = 0; ii < ifin; ii++) {
00736 i = ii;
00737 j = i + iii;
00738 if (a1[i] > a1[j]) {
00739 b1 = a1[j];
00740 b2 = a2[j];
00741 b3 = a3[j];
00742 while (1) {
00743 a1[j] = a1[i];
00744 a2[j] = a2[i];
00745 a3[j] = a3[i];
00746 j = i;
00747 i = i - iii;
00748 if (i < 0 || a1[i] <= b1)
00749 break;
00750 }
00751 a1[j] = b1;
00752 a2[j] = b2;
00753 a3[j] = b3;
00754 }
00755 }
00756 }
00757 }
00758
00759
00779
00780
00781 static void plugholes(float *data, unsigned char *bpm, int nx) {
00782 int i,ifirst,ilast,i1,i2,j;
00783 float nc,d1,d2,t1,t2,slope;
00784
00785
00786
00787 i = 0;
00788 while (i < nx && bpm[i] != 0)
00789 i++;
00790 ifirst = i;
00791
00792
00793
00794 if (ifirst == nx)
00795 return;
00796
00797
00798
00799 i = nx - 1;
00800 while (i >= 0 && bpm[i] != 0)
00801 i--;
00802 ilast = i;
00803
00804
00805
00806
00807 i = ifirst;
00808 while (i <= ilast) {
00809 if (bpm[i] == 0) {
00810 i++;
00811 continue;
00812 }
00813 i1 = i - 1;
00814 while (bpm[i] != 0)
00815 i++;
00816 i2 = i;
00817 nc = (float)(i2 - i1 + 1);
00818 d1 = data[i1];
00819 d2 = data[i2];
00820 for (j = i1+1; j <= i2-1; j++) {
00821 t1 = 1.0 - (float)(j - i1)/nc;
00822 t2 = 1.0 - t1;
00823 data[j] = t1*d1 + t2*d2;
00824 }
00825 }
00826
00827
00828
00829 if (ifirst > 0) {
00830 slope = data[ifirst+1] - data[ifirst];
00831 for (j = 0; j < ifirst; j++)
00832 data[j] = slope*(j - ifirst) + data[ifirst];
00833 }
00834
00835
00836
00837 if (ilast < nx - 1) {
00838 slope = data[ilast] - data[ilast-1];
00839 for (j = ilast; j < nx; j++)
00840 data[j] = slope*(j - ilast) + data[ilast];
00841 }
00842 }
00843
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863