/****************************************************************************** * * 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 * ---- ---- ----------- * outfile *FILE Opened output data file pointer * hdr std_hdr Filled std_hdr header info structure * structA *std_data Pointer to scanline A struct of array data * structAhi *std_data Pointer to scanline A hi-res array * structBhi *std_data Pointer to scanline B hi-res array * * 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 #include "common_structures" /** Function prototypes **/ float ewbounds ( float ) ; int write_scan ( FILE *outfile, struct std_hdr hdr, struct std_data *structA, struct std_data *structAhi, struct std_data *structBhi ) { short chan ; /* Channel counter */ float epsilon ; /* Fudge factor for rounding floats */ int error_flag ; /* Error flag */ short loc ; /* Array location */ short lat ; /* Latitude of pixel * scale factor */ short lon ; /* Longitude of pixel * scale factor */ float llscale=100.0 ; /* Scale factor for lat/lon values */ 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 = (hdr.fields + hdr.hifields) * sizeof(short); temparray = ( short * ) malloc ( maxbytes ) ; if ( temparray == NULL ) { error_flag = -1 ; goto outta_here ; } /** CASE 1: process for single resolution data **/ if ( hdr.hifields == 0 ) { /** Loop thru pixel number of samples **/ for ( pix=0; pix < hdr.pixperscan ; pix++ ) { /** Loop through channels to fill array of values **/ for ( chan = 0 ; chan < hdr.fields ; chan++ ) { if ( structA->fielddata[chan][pix] < (float)hdr.missing_val+epsilon && structA->fielddata[chan][pix] > (float)hdr.missing_val-epsilon) temparray[chan] = hdr.missing_val ; else temparray[chan] = ( short ) ( ( structA->fielddata[chan][pix] + hdr.offset[chan] ) * hdr.scale[chan] + epsilon ) ; } fwrite ( &structA->itime[pix], 4, 1, outfile ) ; lat = ( short ) nint ( structA->lat[pix] * llscale ) ; lon = ( short ) nint ( ewbounds ( structA->lng[pix] ) * llscale ) ; fwrite ( &lat, 2, 1, outfile ) ; fwrite ( &lon, 2, 1, outfile ) ; fwrite ( &temparray[0], sizeof ( short ), hdr.fields, outfile ) ; } } /** CASE 2: process for low- and high-resolution data **/ else { /** Loop thru pixel number of samples **/ for ( pix=0; pix < hdr.hipixperscan ; pix++ ) { /** Even-numbered pixels **/ if ( pix % 2 == 0 ) { loc = 0 ; for ( chan=0; chan < hdr.fields ; chan++ ) { if ( structA->fielddata[chan][pix/2] < (float)hdr.missing_val+epsilon && structA->fielddata[chan][pix/2] > (float)hdr.missing_val-epsilon ) temparray[loc] = hdr.missing_val ; else temparray[chan] = ( short ) ( ( structA->fielddata[chan][pix/2] + hdr.offset[chan] ) * hdr.scale[chan] + epsilon ) ; loc ++ ; } for ( chan=0; chan < hdr.hifields ; chan++ ) { if ( structAhi->fielddata[chan][pix] < (float)hdr.missing_val+epsilon && structAhi->fielddata[chan][pix] > (float)hdr.missing_val - epsilon ) temparray[loc] = hdr.missing_val ; else temparray[loc] = ( short ) ( ( structAhi->fielddata[chan][pix] + hdr.offset[hdr.fields + chan] ) * hdr.scale[hdr.fields + chan] + epsilon ) ; loc ++ ; } fwrite ( &structAhi->itime[pix], 4, 1, outfile ) ; lat = ( short ) nint ( structAhi->lat[pix] * llscale ) ; lon = ( short ) nint ( ewbounds ( structAhi->lng[pix] ) * llscale ) ; fwrite ( &lat, 2, 1, outfile ) ; fwrite ( &lon, 2, 1, outfile ) ; fwrite ( &temparray[0], sizeof ( short ), hdr.fields + hdr.hifields, outfile ) ; } /** Odd-numbered pixels **/ else { loc = 0 ; for ( chan=0; chan < hdr.hifields ; chan++ ) { if ( structAhi->fielddata[chan][pix] < (float)hdr.missing_val+epsilon && structAhi->fielddata[chan][pix] > (float)hdr.missing_val - epsilon ) temparray[loc] = hdr.missing_val ; else temparray[loc] = ( short ) ( ( structAhi->fielddata[chan][pix] + hdr.offset[hdr.fields + chan] ) * hdr.scale[hdr.fields + chan] + epsilon ) ; loc ++ ; } fwrite ( &structAhi->itime[pix], 4, 1, outfile ) ; lat = ( short ) nint ( structAhi->lat[pix] * llscale ) ; lon = ( short ) nint ( ewbounds ( structAhi->lng[pix] ) * llscale ) ; fwrite ( &lat, 2, 1, outfile ) ; fwrite ( &lon, 2, 1, outfile ) ; fwrite ( &temparray[0], sizeof ( short ), hdr.hifields, outfile ) ; } } for ( pix=0; pix < hdr.hipixperscan ; pix++ ) { /** All pixels **/ loc = 0 ; for ( chan=0; chan < hdr.hifields ; chan++ ) { if ( structBhi->fielddata[chan][pix] < (float)hdr.missing_val + epsilon && structBhi->fielddata[chan][pix] > (float)hdr.missing_val - epsilon ) temparray[loc] = hdr.missing_val ; else temparray[loc] = ( short ) ( ( structBhi->fielddata[chan][pix] + hdr.offset[hdr.fields + chan] ) * hdr.scale[hdr.fields + chan] + epsilon ) ; loc ++ ; } fwrite ( &structBhi->itime[pix], 4, 1, outfile ) ; lat = ( short ) nint ( structBhi->lat[pix] * llscale ) ; lon = ( short ) nint ( ewbounds ( structBhi->lng[pix] ) * llscale ) ; fwrite ( &lat, 2, 1, outfile ) ; fwrite ( &lon, 2, 1, outfile ) ; fwrite ( &temparray[0], sizeof ( short ), hdr.hifields, 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 ) ; }