#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} <who> -- <does what> -- <when>
*/
#include <stdio.h>
#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;
}
syntax highlighted by Code2HTML, v. 0.9.1