/****************************************************************************** * * write_scan * * Writes one scanline of data from the specified array(s) to the * specified output file. * * LAST UPDATE: 4 December 1997 * * ARGUMENTS: * * Name Type Description * ---- ---- ----------- * option int 0=write as single-res data; * 1=write as lo+hi res data * outfile *FILE Opened output data file pointer * ldata **float (Low-resolution) data (dim: [lochans][samples]) ? * hadata **float High-res scan A data (dim: [hichans][samples]) ? * hbdata **float High-res scan B data (dim: [hichans][samples]) ? * itime long Scanline time, seconds since 1-1-70 * lochans short Number of (low-resolution) channels * hichans short Number of high-resolution channels * lopix short Number of pixels per (low-resolution) scanline * hipix short Number of pixels per high-resolution scanline * llscale float Scaling factor for latitude and longitude values * alat[] float Array of (A-scan) pixel latitudes * alon[] float Array of (A-scan) pixel longitudes * blat[] float Array of B-scan pixel latitudes * blon[] float Array of B-scan pixel longitudes * loscale float Array of scaling factors for (low-res) channels * hiscale float Array of scaling factors for (low-res) channels * amin float Array of minimum data values (reals) * amax float Array of minimum data values (reals) * bmin short Array of minimum output data values (integer*2) * bmax short Array of minimum output data values (integer*2) * * ORIGINAL AUTHORS: * Don Anderson, CIRES/CDC, November 1997 * * RETURNS: 0 If successful * -1 If error allocating temporary array * -2 If error writing outfile * * NOTES: * (1) The passed file descriptor ("outfile") must be for a file that * has already been opened * (2) Adequate memory must already be allocated for the arrays in the * passed data structures (or, structAhi and structBhi may be NULL) * (3) This only handles case where hires is 2X resolution of lo-res. Other * multiples of nested resolution cannot be handled by this code. * * MODIFICATIONS: * Don Anderson 12/4/97 Proper handling of missing values & offsets * Don Anderson 12/4/97 Added nint handling of lat/long values * Don Anderson 12/4/97 Added ewbounds function to bound lon values * ***************************************************************************/ #include #include /** Function prototypes **/ float ewbounds ( float ) ; int write_scan ( int option, FILE *outfile, float **ldata, float **hadata, float **hbdata, long itime, int lochans, int hichans, short lopix, short hipix, float alat[], float alon[], float blat[], float blon[], float *loscale, float *hiscale, float *offsets, double llscale, short misval, float *amin, float *amax, short *bmin, short *bmax ) { short chan ; /* Channel counter */ float epsilon ; /* Fudge factor for rounding floats */ int error_flag ; /* Error flag */ short lat ; /* Latitude of pixel * scale factor */ short loc ; /* Array location */ short lon ; /* Longitude of pixel * scale factor */ long maxbytes ; /* Length of A-scan data to read */ int pix ; /* Pixel counter */ int pixels ; /* Pixels per scanline */ int scan ; /* Generic counter */ short *temparray ; /* Array for holding one pixel's data */ epsilon = 0.1 ; error_flag = 0 ; /** Allocate temporary array space **/ maxbytes = ( lochans + hichans ) * sizeof ( short ) ; temparray = ( short * ) malloc ( maxbytes ) ; if ( temparray == NULL ) { error_flag = -1 ; goto outta_here ; } /** CASE 1: process for single resolution data **/ if ( option == 0 ) { /** Loop thru pixel number of samples **/ for ( pix=0; pix < lopix ; pix++ ) { /** Loop through channels to fill array of values **/ for ( chan = 0 ; chan < lochans ; chan++ ) { if ( ldata[pix][chan] < misval + epsilon && ldata[pix][chan] > misval - epsilon ) temparray[chan] = ( short ) misval ; else if (ldata[pix][chan] < 0 ) temparray[chan] = ( short ) ( (ldata[pix][chan] + offsets[chan]) * loscale[chan] - epsilon ); else { temparray[chan] = ( short ) (( ldata[pix][chan] + offsets[chan]) * loscale[chan] + epsilon ) ; if ( ldata[pix][chan] < amin[chan] ) amin[chan] = ldata[pix][chan] ; if ( ldata[pix][chan] > amax[chan] ) amax[chan] = ldata[pix][chan] ; if ( temparray[chan] < bmin[chan] ) bmin[chan] = temparray[chan] ; if ( temparray[chan] > bmax[chan] ) bmax[chan] = temparray[chan] ; } } /*NOTE: insert function to calc itime from 1970!*/ fwrite ( &itime, 4, 1, outfile ) ; lat = ( short ) ( alat[pix] * llscale + 0.5 ) ; lon = ( short ) ( ewbounds ( alon[pix] ) * llscale + 0.5 ) ; fwrite ( &lat, 2, 1, outfile ) ; fwrite ( &lon, 2, 1, outfile ) ; fwrite ( &temparray[0], chan * sizeof ( short ), 1, outfile ) ; } } /** CASE 2: process for low- and high-resolution data **/ else if ( option == 1 ) { /** Loop thru pixel number of samples **/ for ( pix=0; pix < hipix ; pix++ ) { /** Even-numbered pixels **/ if ( pix % 2 == 0 ) { loc = 0 ; for ( chan=0; chan < lochans ; chan++ ) { if ( ldata[pix/2][chan] < misval + epsilon && ldata[pix/2][chan] > misval - epsilon ) temparray[loc] = ( short ) misval ; else if (ldata[pix/2][chan] < 0 ) temparray[loc] = ( short ) ( (ldata[pix/2][chan] + offsets[chan]) * loscale[chan] - epsilon ); else { temparray[loc] = ( short ) ( (ldata[pix/2][chan] + offsets[chan]) * loscale[chan] - epsilon ); if ( ldata[pix/2][chan] < amin[chan] ) amin[chan] = ldata[pix/2][chan] ; if ( ldata[pix/2][chan] > amax[chan] ) amax[chan] = ldata[pix/2][chan] ; if ( temparray[loc] < bmin[chan] ) bmin[chan] = temparray[loc] ; if ( temparray[loc] > bmax[chan] ) bmax[chan] = temparray[loc] ; } loc ++ ; } for ( chan=0; chan < hichans ; chan++ ) { if ( hadata[pix][chan] < misval + epsilon && hadata[pix][chan] > misval - epsilon ) temparray[loc] = ( short ) misval ; else if (hadata[pix][chan] < 0 ) temparray[loc] = ( short ) ( (hadata[pix][chan] + offsets[chan]) * hiscale[chan] - epsilon ); else { temparray[loc] = ( short ) ( (hadata[pix][chan] + offsets[chan + lochans] ) * hiscale[chan] + epsilon ); if ( hadata[pix][chan] < amin[chan + lochans] ) amin[chan + lochans] = hadata[pix][chan] ; if ( hadata[pix][chan] > amax[chan + lochans] ) amax[chan + lochans] = hadata[pix][chan] ; if ( temparray[loc] < bmin[chan + lochans] ) bmin[chan + lochans] = temparray[loc] ; if ( temparray[loc] > bmax[chan + lochans] ) bmax[chan + lochans] = temparray[loc] ; } loc ++ ; } fwrite ( &itime, 4, 1, outfile ) ; lat = ( short ) ( alat[pix] * llscale + 0.5 ) ; lon = ( short ) ( ewbounds ( alon[pix] ) * llscale + 0.5 ) ; fwrite ( &lat, 2, 1, outfile ) ; fwrite ( &lon, 2, 1, outfile ) ; fwrite ( &temparray[0], loc * sizeof ( short ), 1, outfile ) ; } /** Odd-numbered pixels **/ else { loc = 0 ; for ( chan=0; chan < hichans ; chan++ ) { if ( hadata[pix][chan] < misval + epsilon && hadata[pix][chan] > misval - epsilon ) temparray[loc] = ( short ) misval ; else if ( hadata[pix][chan] < 0.0 ) temparray[loc] = ( short ) (( hadata[pix][chan] + offsets[chan + lochans] ) * hiscale[chan] - epsilon ) ; else { temparray[loc] = ( short ) (( hadata[pix][chan] + offsets[chan + lochans] ) * hiscale[chan] + epsilon ) ; if ( hadata[pix][chan] < amin[chan + lochans] ) amin[chan + lochans] = hadata[pix][chan] ; if ( hadata[pix][chan] > amax[chan + lochans] ) amax[chan + lochans] = hadata[pix][chan] ; if ( temparray[loc] < bmin[chan + lochans] ) bmin[chan + lochans] = temparray[loc] ; if ( temparray[loc] > bmax[chan + lochans] ) bmax[chan + lochans] = temparray[loc] ; } loc ++ ; } fwrite ( &itime, 4, 1, outfile ) ; lat = ( short ) ( alat[pix] * llscale + 0.5 ) ; lon = ( short ) ( ewbounds ( alon[pix] ) * llscale + 0.5 ) ; fwrite ( &lat, 2, 1, outfile ) ; fwrite ( &lon, 2, 1, outfile ) ; fwrite ( &temparray[0], loc * sizeof ( short ), 1, outfile ) ; } } for ( pix=0; pix < hipix ; pix++ ) { /** All pixels **/ loc = 0 ; for ( chan=0; chan < hichans ; chan++ ) { if ( hbdata[pix][chan] < misval + epsilon && hbdata[pix][chan] > misval - epsilon ) temparray[loc] = ( short ) misval ; else if ( hbdata[pix][chan] < 0.0 ) temparray[loc] = ( short ) (( hbdata[pix][chan] + offsets[chan + lochans] ) * hiscale[chan] - epsilon ) ; else { temparray[loc] = ( short ) (( hbdata[pix][chan] + offsets[chan + lochans] ) * hiscale[chan] + epsilon ) ; if ( hbdata[pix][chan] < amin[chan + lochans] ) amin[chan + lochans] = hbdata[pix][chan] ; if ( hbdata[pix][chan] > amax[chan + lochans] ) amax[chan + lochans] = hbdata[pix][chan] ; if ( temparray[loc] < bmin[chan + lochans] ) bmin[chan + lochans] = temparray[loc] ; if ( temparray[loc] > bmax[chan + lochans] ) bmax[chan + lochans] = temparray[loc] ; } loc ++ ; } fwrite ( &itime, 4, 1, outfile ) ; lat = ( short ) ( blat[pix] * llscale + 0.5 ) ; lon = ( short ) ( ewbounds ( blon[pix] ) * llscale + 0.5 ) ; fwrite ( &lat, 2, 1, outfile ) ; fwrite ( &lon, 2, 1, outfile ) ; fwrite ( &temparray[0], loc * sizeof ( short ), 1, outfile ) ; } } outta_here : free ( temparray ) ; return ( error_flag ) ; } /*************************************************************************** * * ewbounds * * Returns the passed longitude value as a -180 to +180 range value. * ****************************************************************************/ float ewbounds ( float alon ) { float tmpln; tmpln = alon; if ( tmpln > 180.0 ) tmpln = tmpln - 360.0; if ( tmpln < -180.0 ) tmpln = tmpln + 360.0; if ( tmpln > 180.0 ) tmpln = -999.0; if ( tmpln < -180.0 ) tmpln = -999.0; return ( tmpln ) ; }