00001
00002 #include <stdio.h>
00003 #include <stdlib.h>
00004 #include <math.h>
00005 #include <string.h>
00006 #include <sys/types.h>
00007 #include <sys/time.h>
00008 #define ALN2I 1.442695022
00009 #define TINY 1.0e-5
00010 #define ABS(x) ((x)>=0?(x):-(x))
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 int aia_despike(
00021 int *array, unsigned char *mask, int nx, int ny, float frac, int level, int niter,
00022 int *badblobs, int sizeofbads,
00023 int *nspikes, int **oldvalues, int **spikelocs, int **newvalues);
00024 int mask_erode(unsigned char *pbase, unsigned char *qbase, int n, int m);
00025
00026 int aia_despike(
00027 int *array, unsigned char *mask, int nx, int ny, float frac, int level, int niter,
00028 int *badblobs, int sizeofbads,
00029 int *nspikes, int **oldvalues, int **spikelocs, int **newvalues)
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 {
00059 int iq, result_sym, n, m, sum, nc;
00060 int lognb2, jj, jc;
00061 float absmin = 4.0;
00062 int nxc, nyc, offset, *lastiterendaddr;
00063 int save_niter, ntotal, npix, nslocal, ndups, itercount;
00064 float fsum, cfrac, tq, fdif;
00065 int *p, *ptr, *p1, *p2, *p3, *spikeold, *oldptr;
00066 unsigned char *mptr, *mp, mskv, *mskbase, *eroded, *eroded2;
00067 int *spikebufadd, *sptradd;
00068 int *spikenew, *newptr, *base;
00069 int arr[16], *pps, *ss, *spikestarts[20], *spikeends[20];
00070
00071
00072 lognb2 = (log((double) 16)*ALN2I+TINY);
00073
00074
00075 if (nx < 5 || ny < 5 ) {
00076 printf("dimensions must be 5 or greater, nx, ny = %d %d\n", nx,ny);
00077 return -1; }
00078
00079 if (sizeofbads > 0 && badblobs != 0 ) {
00080
00081
00082 int countdown = sizeofbads;
00083 int *pblob, nperim, npix, xq, offset;
00084 float acc;
00085 pblob = badblobs;
00086 while (1) {
00087 acc = 0.0;
00088 nperim = *pblob++;
00089 if (nperim <= 0 || nperim > countdown) break;
00090 n = nperim;
00091
00092 while (n--) { offset = *pblob++; acc += *(array + offset); }
00093 xq = rintf(acc/(float) nperim);
00094 npix = *pblob++;
00095 if (npix <= 0 || npix > countdown) break;
00096 n = npix;
00097 while (n--) { offset = *pblob++; *(array + offset) = xq; }
00098 countdown = countdown - nperim - npix - 2;
00099 if (countdown <= 0) break;
00100 }
00101 }
00102
00103
00104 {
00105 int i, *toprow, *botrow, *tmprow;
00106 botrow = array;
00107 toprow = botrow + 4095*4096;
00108 tmprow = (int *) malloc(sizeof(int)*4096);
00109 for (i = 0; i < 2048; i++) {
00110 memcpy(tmprow, toprow, 16384);
00111 memcpy(toprow, botrow, 16384);
00112 memcpy(botrow, tmprow, 16384);
00113 botrow += 4096;
00114 toprow -= 4096;
00115 }
00116 free(tmprow);
00117 }
00118
00119 eroded = malloc(nx*ny*sizeof(unsigned char));
00120 if (!eroded) { printf("malloc error in local mask copy\n"); return 1; }
00121 mp = eroded;
00122
00123
00124
00125 p = array;
00126
00127 if (mask == 0) {
00128 int nq = nx * ny;
00129 while (nq--) {
00130
00131
00132
00133 if (*p == 0x80000000) { *mp++ = 0; } else { *mp++ = 1; }
00134 p++;
00135 }
00136
00137 } else {
00138
00139 int nq = nx * ny;
00140 mp = mask;
00141 while (nq--) {
00142
00143
00144
00145 if (*p == 0x80000000) { *mp++ = 0; }
00146 p++;
00147 }
00148 eroded2 = malloc(nx*ny*sizeof(unsigned char));
00149 if (!eroded2) { printf("malloc error in local mask copy\n"); return 1; }
00150 mask_erode(mask, eroded2, nx, ny);
00151 mask_erode(eroded2, eroded, nx, ny);
00152
00153 free(eroded2);
00154 }
00155 mask = mp = eroded;
00156 ptr = base = array;
00157
00158 mptr = mskbase = mask;
00159 cfrac = 1.0/(1.0 + frac);
00160 nc = ntotal = nslocal = 0;
00161 niter = ABS(niter);
00162
00163 if (niter > 20 || niter < 0) { printf("DESPIKE - error, excessive # of iterations = %d\n",
00164 niter); return 1; }
00165
00166
00167 save_niter = niter;
00168 spikeold = oldptr = malloc(nx*ny*sizeof(int));
00169 spikenew = newptr = malloc(nx*ny*sizeof(int));
00170 spikebufadd = sptradd = malloc(nx*ny*sizeof(int));
00171 lastiterendaddr = spikebufadd;
00172 ndups = 0;
00173
00174 npix = 0;
00175 itercount = 0;
00176 spikestarts[itercount] = spikebufadd;
00177
00178 while (niter--) {
00179 ptr = array + 2*nx;
00180
00181 mptr = mask + 2*nx;
00182
00183 m = ny-4;
00184 while (m--) {
00185
00186 p = ptr;
00187 p += 2;
00188
00189 mp = mptr + 2;
00190 n = nx-4;
00191 p2 = p - 1;
00192 p1 = p2 - nx;
00193 p3 = p2 + nx;
00194 while (n--) {
00195 npix++;
00196
00197
00198
00199 if ( (*p > 0) && *mp ) {
00200
00201 tq = (cfrac * (float) *p);
00202 sum = *p1 + *(p1+1) + *(p1+2) + *p2 + *(p2+2) + *p3 + *(p3+1) + *(p3+2);
00203
00204
00205
00206 fsum = (float) sum * 0.125;
00207
00208 if ( (fsum < tq) && ((tq-fsum) > absmin) ) {
00209 nc++;
00210
00211 ss = arr; pps = p - 2*nx -2;
00212 *ss++ = *pps++; *ss++ = *pps++; *ss++ = *pps++; *ss++ = *pps++; *ss++ = *pps++;
00213 *ss++ = *(p - nx -2); *ss++ = *(p - nx +2);
00214 *ss++ = *(p -2); *ss++ = *(p +2);
00215 *ss++ = *(p + nx -2); *ss++ = *(p + nx +2);
00216 pps = p + 2 *nx - 2;
00217 *ss++ = *pps++; *ss++ = *pps++; *ss++ = *pps++; *ss++ = *pps++; *ss++ = *pps++;
00218
00219
00220
00221
00222 { int nn,m,j,i,n=16;
00223 int t;
00224 m=n;
00225 for (nn=1;nn<=lognb2;nn++) {
00226 m >>= 1;
00227 for (j=m;j<n;j++) {
00228 i=j-m;
00229 t=arr[j];
00230 while (i >= 0 && arr[i] > t) {
00231 arr[i+m]=arr[i];
00232 i -= m;
00233 }
00234 arr[i+m]=t;
00235 }
00236 }
00237 }
00238
00239 *oldptr++ = *p; offset = p - base;
00240
00241 *sptradd++ = offset;
00242 nslocal++;
00243
00244 *newptr++ = arr[level];
00245 }
00246 }
00247 p++; mp++; p1++; p2++; p3++;
00248
00249 }
00250
00251
00252 ptr = ptr + nx;
00253
00254
00255 mptr = mptr + nx;
00256 }
00257
00258
00259
00260
00261
00262 ntotal += nc; nc = 0;
00263 npix = 0;
00264 if (niter < (save_niter - 1)) {
00265 int *ip, *jp, *iplast = spikebufadd;
00266 int ioff, joff, delta1, delta2, previter;
00267
00268
00269
00270
00271 int *jprevstart[20];
00272 spikestarts[itercount] = spikeends[itercount-1] + 1;
00273 for (previter=0; previter<itercount; previter++) { jprevstart[previter] = spikestarts[previter]; }
00274 for (ip=spikestarts[itercount]; ip<sptradd; ip++) {
00275 ioff = *ip;
00276
00277 for (previter=0; previter<itercount; previter++) {
00278
00279 for (jp=jprevstart[previter]; jp<=spikeends[previter]; jp++) {
00280 joff = *jp;
00281 if (joff == ioff) {
00282
00283
00284 delta2 = jp - spikebufadd;
00285 delta1 = ip - spikebufadd;
00286 *(spikeold + delta1) = *(spikeold + delta2);
00287
00288 *jp = -1;
00289 ndups++;
00290 break;
00291 }
00292 if (joff > ioff) {
00293
00294
00295 break;
00296 }
00297 }
00298
00299 jprevstart[previter] = jp;
00300 }
00301 }
00302
00303 }
00304 spikeends[itercount] = sptradd - 1;
00305
00306
00307
00308 {
00309 int *ip, ioff, *snew, nq;
00310 ip=spikestarts[itercount];
00311 snew = spikenew + (ip - spikebufadd);
00312 while ( ip<sptradd ) {
00313 ioff = *ip++;
00314 array[ioff] = *snew++;
00315 }
00316 }
00317 itercount++;
00318 }
00319
00320 *nspikes = nslocal;
00321
00322 *nspikes = nslocal - ndups;
00323
00324 n = (nslocal - ndups)*sizeof(int);
00325
00326 if (n > 0) {
00327 int i;
00328 int *p1, *p2, *p3, *q1, *q2, *q3;
00329 *oldvalues = p1 = malloc(n);
00330 q1 = spikeold;
00331 *newvalues = p2 = malloc(n);
00332 q2 = spikenew;
00333 *spikelocs = p3 = malloc(n);
00334 q3 = spikebufadd;
00335 for (i=0;i<nslocal;i++) {
00336 if (*q3 > 0) { *p1++ = *q1; *p2++ = *q2; *p3++ = *q3; }
00337 q1++; q2++; q3++;
00338 }
00339 } else {
00340 *oldvalues = 0; *spikelocs = 0; *newvalues = 0;
00341 }
00342
00343 free(spikebufadd); free(spikenew); free(spikeold); free(eroded);
00344
00345
00346
00347
00348
00349 return 0;
00350 }
00351
00352
00353
00354
00355 int mask_erode(unsigned char *pbase, unsigned char *qbase, int n, int m)
00356 {
00357 unsigned char *p, *q, *p_endline, *qabove, *qbelow;
00358 int iq, mq, type;
00359 double t1, t2, t3, t4;
00360
00361 if ( n < 3 || m < 3 ) {
00362 printf("ERODE: array too small, nx, ny = %d %d\n", n, m);
00363 return -1; }
00364
00365 bcopy(pbase, qbase, n*m);
00366 p = pbase;
00367 q = qbase;
00368
00369
00370
00371 if (*p == 0) {
00372 *q++; *q = 0; q = qbase + n; *q++ = 0; *q = 0;}
00373
00374 p_endline = pbase + n - 2;
00375 p++;
00376
00377 while (1) {
00378 if (*p == 0) {
00379
00380 q = (qbase - pbase - 1) + p;
00381 qabove = q + n;
00382 *q++ = 0; q++; *q++ = 0;
00383 *qabove++ = 0; *qabove++ = 0; *qabove++ = 0;
00384 if (p >= p_endline) break;
00385 p++;
00386
00387 while (*p == 0) {
00388 if (p >= p_endline) break;
00389 *q++ = 0; *qabove++ = 0;
00390 p++; }
00391 }
00392 if (p >= p_endline) break;
00393 p++;
00394 }
00395 p++;
00396
00397
00398 if (*p == 0) {
00399 q = (qbase - pbase - 1) + p;
00400 qabove = q + n;
00401 *q = 0;
00402 *qabove++ = 0; *qabove = 0;
00403 }
00404 p++;
00405
00406
00407
00408
00409 mq = m - 2;
00410 while (mq-- > 0) {
00411
00412
00413 if (*p == 0) {
00414 q = (qbase - pbase - 1) + 1 + p;
00415 qabove = q + n; qbelow = q - n;
00416 *q++; *q = 0;
00417 *qabove++ = 0; *qabove = 0;
00418 *qbelow++ = 0; *qbelow = 0;
00419 }
00420 p_endline = p + n - 2;
00421 p++;
00422
00423
00424
00425 while (1) {
00426 if (*p == 0) {
00427
00428 q = (qbase - pbase - 1) + p;
00429 qabove = q + n; qbelow = q - n;
00430 *q++ = 0; q++; *q++ = 0;
00431 *qabove++ = 0; *qabove++ = 0; *qabove++ = 0;
00432 *qbelow++ = 0; *qbelow++ = 0; *qbelow++ = 0;
00433 if (p >= p_endline) break;
00434 p++;
00435
00436 while (*p == 0) {
00437 if (p >= p_endline) break;
00438 *q++ = 0; *qabove++ = 0; *qbelow++ = 0;
00439 p++; }
00440 }
00441 if (p >= p_endline) break;
00442 p++;
00443 }
00444 p++;
00445
00446
00447
00448 if (*p == 0) {
00449 q = (qbase - pbase - 1) + p;
00450 qabove = q + n; qbelow = q - n;
00451 *q = 0;
00452 *qabove++ = 0; *qabove++ = 0;
00453 *qbelow++ = 0; *qbelow++ = 0;
00454 }
00455 p++;
00456
00457 }
00458
00459
00460
00461 if (*p == 0) {
00462 q = (qbase - pbase - 1) + 1 + p;
00463 qbelow = q - n;
00464 q++; *q = 0;
00465 *qbelow++ = 0; *qbelow = 0;
00466 }
00467 p_endline = p + n - 2;
00468 p++;
00469
00470
00471
00472 while (1) {
00473 if (*p == 0) {
00474
00475 q = (qbase - pbase - 1) + p;
00476 qbelow = q - n;
00477 *q++ = 0; q++; *q++ = 0;
00478 *qbelow++ = 0; *qbelow++ = 0; *qbelow++ = 0;
00479 if (p >= p_endline) break;
00480 p++;
00481
00482 while (*p == 0) {
00483 if (p >= p_endline) break;
00484 *q++ = 0; *qbelow++ = 0; p++; }
00485 }
00486 if (p >= p_endline) break;
00487 p++;
00488 }
00489 p++;
00490
00491
00492
00493 if (*p == 0) {
00494 q = (qbase - pbase - 1) + p;
00495 qbelow = q - n;
00496 *q = 0;
00497 *qbelow++ = 0; *qbelow = 0;
00498 }
00499
00500
00501
00502 return 0;
00503 }