/* imdisplay.c Generic image resize, rescale, etc. routines */ /* Modifications: 31-Mar-1992 GCE Created 25-Aug-1992 GCE Better error handling; more flexible functions 18-Mar-1994 GCE Added flexibility to handle OSL CCD images 24-Mar-1995 JRV Modified for Macintosh */ #include #include #include "imdisplay.h" int getpixel (void *array, int pixnum, int bitpix) { switch (bitpix) { case 16: return *((short *) array + pixnum); case 8: return *((unsigned char *) array + pixnum); } } void setpixel (void *array, int pixnum, int value, int bitpix) { switch (bitpix) { case 16: *((short *) array + pixnum) = value; break; case 8: *((unsigned char *) array + pixnum) = value; break; } } /* Find max, min, and average value of image for display scaling */ /* Uses optional algorithm to get rid of anomalous pixels */ /* Return average value */ double maxmin (void *pic, int naxes[2], int bitpix, int *max, int *min, int edge, int algorithm) { int x, y, pixel, pixval, i, nbrval; double avg; avg = 0; *max = INT_MIN; *min = INT_MAX; if (algorithm && !edge) edge = 1; /* Edge must be at least 1 */ /* Run over whole picture EXCEPT edges */ for (x = edge; x < naxes[0] - edge; x++) { for (y = edge; y < naxes[1] - edge; y++) { pixel = y * naxes[0] + x; /* Get pixel value */ pixval = getpixel (pic, pixel, bitpix); /* Check max and min */ if (pixval > *max || pixval < *min) switch (algorithm) { case MAXMIN_SMOOTH: /* Smooth over a 3x3 box */ for (nbrval = i = 0; i < 9; i++) { nbrval += getpixel (pic, pixel + (i / 3 - 1) * naxes[0] + (i % 3 - 1), bitpix); } nbrval /= 9; /* Set max and min */ if (nbrval > *max) *max = nbrval; if (nbrval < *min) *min = nbrval; break; case MAXMIN_NEIGHBOR: /* Search over a 3x3 box */ for (i = 0; i < 9; i++) { nbrval = getpixel (pic, pixel + (i / 3 - 1) * naxes[0] + (i % 3 - 1), bitpix); /* If a higher/lower neighbor, set max/min */ if ((nbrval > pixval) && (pixval > *max)) *max = pixval; if ((nbrval < pixval) && (pixval < *min)) *min = pixval; } break; default: /* Check max and min */ if (pixval > *max) *max = pixval; if (pixval < *min) *min = pixval; break; } /* Add pixval to average */ avg += pixval; } } avg /= (naxes[0] - 2 * edge) * (naxes[1] - 2 * edge); return avg; } /* Find max value of 16-bit image for exposure checking */ /* Uses neighbor algorithm to get rid of anomalous pixels */ int fastmax (unsigned short *pic, const int naxes[2], const int edge) { static int nbr[8][2] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 }; int max, x, y, pixel, pixval, i, nbrval; max = INT_MIN; /* Run over whole picture EXCEPT edges */ for (x = edge; x < naxes[0] - edge; x++) { for (y = edge; y < naxes[1] - edge; y++) { pixel = y * naxes[0] + x; pixval = pic [pixel]; /* If pixval greater than max, search over 3x3 neighborhood */ if (pixval > max) for (i = 0; i < 8; i++) { nbrval = pic [pixel + nbr[i][0] * naxes[0] + nbr[i][1]]; /* If a higher neighbor, set max */ if (nbrval >= pixval) max = pixval; } } } return max; } /* Uses neighbor algorithm to get rid of anomalous pixels */ int fastmaxmin (unsigned short *pic, const int naxes[2], const int edge, int *minval) { static int nbr[8][2] = { -1,-1, -1,0, -1,1, 0,-1, 0,1, 1,-1, 1,0, 1,1 }; int max, min, x, y, pixel, pixval, i, nbrval; max = INT_MIN; min = INT_MAX; /* Run over whole picture EXCEPT edges */ for (x = edge; x < naxes[0] - edge; x++) { for (y = edge; y < naxes[1] - edge; y++) { pixel = y * naxes[0] + x; pixval = pic [pixel]; if (pixval > max || pixval < min) for (i = 0; i < 8; i++) { /* Search over 3x3 neighborhood */ nbrval = pic [pixel + nbr[i][0] * naxes[0] + nbr[i][1]]; if ((nbrval >= pixval) && (pixval > max)) max = pixval; if ((nbrval <= pixval) && (pixval < min)) min = pixval; } } } if (minval) *minval = min; return max; }