#ifndef lint static char SccsId[] = "%W% %G%"; #endif /* Module: readreal.c (Read Real) * Purpose: Scale real image data to fit in a short (int*2) buffer * Subroutine: scale_data_r4() returns: void * Subroutine: scale_data_r8() returns: void * Xlib calls: none * Copyright: 1998 Smithsonian Astrophysical Observatory * You may do anything you like with this file except remove * this copyright. The Smithsonian Astrophysical Observatory * makes no representations about the suitability of this * software for any purpose. It is provided "as is" without * express or implied warranty. * Modified: {0} Michael VanHilst initial version 31 October 1988 * {1} Doug Mink added byte swapping May 2, 1994 * {2} Robert Wilson Put in code for NaN July 7, 1995 * {3} Doug Mink separate min and max Oct 2, 1996 * {4} Paul Sydney include stdio.h July 9 1998 * {5} Doug Mink declare bswap8() and bswap4() July 9 1998 * {n} -- -- */ #include #include "hfiles/image.h" /* image struct */ #include "hfiles/scale.h" /* define SCALEWIDTH, etc. */ /* * Subroutine: scale_data_r4 * Purpose: scale 32 bit real data into the (short) img array */ void scale_data_r4 ( image, imgbuf, databuf, vals, verbose ) struct imageRec *image; short *imgbuf; float *databuf; int vals; int verbose; /* whether to print explanatory messages */ { register float *fbuf, *fbufend; float fmin, fmax; int swap = image->byte_swap, started = 0; void bswap4(); /* set buf start and end pointers for a pass through databuf. * This pass will do the byte swapping if needed and find fmin and fmax */ fbuf = databuf; fbufend = fbuf + vals; for(; fbuf < fbufend; fbuf++) { if(swap) bswap4 ((char *)fbuf); if(! started) { if(*fbuf == *fbuf) { /* A NaN doesn't equal anything, not even itself */ fmin = fmax = *fbuf; started = 7; } } else if(*fbuf == *fbuf) { if( *fbuf < fmin ) fmin = *fbuf; else if( *fbuf > fmax ) fmax = *fbuf; } } if(!started) { printf("No valid pixels in this image\n"); fmin = fmax = 0.0; } /* make announcement if requested */ if( verbose ) (void)printf("Data min and max as read: %g, %g\n", fmin, fmax); /* apply preset limits if given */ if (image->fsmin) { fmin = image->fimin; if (verbose) (void)printf("Using preset min: %g\n", fmin); } if (image->fsmax ) { fmax = image->fimax; if (verbose) (void)printf("Using preset max: %g\n", fmax); } { float scale, bias; float ftemp; register short *sbuf; /* set bias to offset values to zero center the range */ bias = -((fmin + fmax) / (float)2.0); /* get the scale factor */ if( (fmax - fmin) > 0.0 ) { scale = (float)SCALEWIDTH / (fmax - fmin); } else { scale = 1.0; } /* reset buf for another pass through fbuf */ /* while loop changed to current form from: * buf = databuf; * while( buf < bufend ) * *sbuf RND((*buf++ + bias) * scale; * because Sun compiler was inc'ing buf by 8 bytes */ fbuf = databuf; sbuf = imgbuf; /* use min and max to mark out limits */ fmin = (float)SCALEMIN; fmax = (float)SCALEMAX; /* scale the picture */ do { if(*fbuf == *fbuf) { /* Pixel is not NaN */ ftemp = (*fbuf + bias) * scale; if( ftemp < 0.0 ) { ftemp -= 0.5; if( ftemp < fmin ) *sbuf++ = fmin; else *sbuf++ = (short)ftemp; } else { ftemp += 0.5; if( ftemp > fmax ) *sbuf++ = fmax; else *sbuf++ = (short)ftemp; } } else { /* Pixel is NaN */ *sbuf++ = -SCALEOFF; } } while( ++fbuf < fbufend ); image->fiscaled = 1; image->fibias = (double)(-bias); image->fiscale = 1.0 / (double)scale; } } /* * Subroutine: scale_data_r8 * Purpose: Scale 64 bit real data into the (short) img array */ void scale_data_r8 ( image, imgbuf, databuf, vals, verbose ) struct imageRec *image; short *imgbuf; double *databuf; int vals; int verbose; /* whether to print explanatory messages */ { register double *dbuf, *dbufend; double dmin, dmax; int swap = image->byte_swap, started = 0; void bswap8(); /* set buf start and end pointers for a pass through databuf. * This pass will do the byte swapping if needed and find fmin and fmax */ dbuf = databuf; dbufend = dbuf + vals; for(; dbuf < dbufend; dbuf++) { if(swap) bswap8 ((char *)dbuf); if(! started) { if(*dbuf == *dbuf) { /* A NaN doesn't equal anything, not even itself */ dmin = dmax = *dbuf; started = 7; } } else if(*dbuf == *dbuf) { if( *dbuf < dmin ) dmin = *dbuf; else if( *dbuf > dmax ) dmax = *dbuf; } } if(!started) { printf("No valid pixels in this image\n"); dmin = dmax = 0.0; } /* make announcement if requested */ if (verbose) (void)printf("Data min and max as read: %g, %g\n", dmin, dmax); /* apply preset limits if given */ if (image->fsmin) dmin = image->fimin; if (image->fsmax ) dmax = image->fimax; if (verbose && (image->fsmin || image->fsmax )) (void)printf("Using given limits: %g, %g\n", dmin, dmax); { double scale, bias; double dtemp; register short *sbuf; /* set bias to offset values to zero center the range */ bias = -((dmin + dmax) / (double)2.0); /* get the scale factor */ if( (dmax - dmin) > 0.0 ) { scale = (double)SCALEWIDTH / (dmax - dmin); } else { scale = 1.0; } /* reset buf for another pass through dbuf */ dbuf = databuf; sbuf = imgbuf; /* use min and max to mark out limits */ dmin = (double)SCALEMIN; dmax = (double)SCALEMAX; /* scale the picture */ do { if(*dbuf == *dbuf) { /* Pixel is not NaN */ dtemp = (*dbuf + bias) * scale; if( dtemp < 0.0 ) { dtemp -= 0.5; if( dtemp < dmin ) *sbuf++ = dmin; else *sbuf++ = (short)dtemp; } else { dtemp += 0.5; if( dtemp > dmax ) *sbuf++ = dmax; else *sbuf++ = (short)dtemp; } } else { /* Pixel is NaN */ *sbuf++ = -SCALEOFF; } } while( ++dbuf < dbufend ); image->fiscaled = 1; image->fibias = -bias; image->fiscale = 1.0 / scale; } } void bswap4 (string) /* Reverse bytes of 4-byte variable * * string Address of 4-byte variable */ char *string; { char temp0, temp1, temp2, temp3; temp3 = string[0]; temp2 = string[1]; temp1 = string[2]; temp0 = string[3]; string[0] = temp0; string[1] = temp1; string[2] = temp2; string[3] = temp3; return; } void bswap8 (string) /* Reverse bytes of 8-byte number * * string Address of 8-byte number */ char *string; { char temp[8]; temp[7] = string[0]; temp[6] = string[1]; temp[5] = string[2]; temp[4] = string[3]; temp[3] = string[4]; temp[2] = string[5]; temp[1] = string[6]; temp[0] = string[7]; string[0] = temp[0]; string[1] = temp[1]; string[2] = temp[2]; string[3] = temp[3]; string[4] = temp[4]; string[5] = temp[5]; string[6] = temp[6]; string[7] = temp[7]; return; }