/****************************************************************************** * * read_scan * * Fills the passed structures with data read from the next scanline * (low res scan A and, if it exists, hi res scan A and B) of the specified * file. Memory must already be allocated for the passed structures * (use allocdata function). * * LAST UPDATE: 5 December 1997 * * ARGUMENTS: * * Name Type Description * ---- ---- ----------- * infile *FILE Opened input data file pointer * hdr std_hdr Filled std_hdr header info structure * structA *std_data Pointer to scanline A stuct 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 read of scanline * 999 If end-of-file scanline read * -1 If error allocating temporary array * -2 If error reading infile for low resolution data * -3 If error reading infile for high-resolution scanline A * -4 If error reading infile for high-resolution scanline B * -5 If the passed structA is null * * NOTES: * (1) The passed file descriptor ("infile") must be for a file that * has already been opened * (2) The passed std_hdr structure holding header information about the * opened file must already be populated with valid data (use read_hdr) * (3) Adequate memory must already be allocated for the arrays in the * passed data structures (use allocdata). Alternatively, structAhi * and structBhi may be declared NULL. * (4) This code handles either single-resolution data, or low-and-high * resolution data where hi-res is 2X resolution of lo-res (e.g., SSM/I). * Other multiples of nested resolution cannot be handled by this code. * (5) This code expects that the EOF file record has an itime value equal * to hdr.missing_val, whereupon this function returns the value 999. * (6) Assumes that lat and long values in data file scaled by 100. * * MODIFICATIONS: * Wes Berg 12/5/97 Add reclen increments to read past EOF * Don Anderson 12/5/97 Return data values as scaled & offset floats * ***************************************************************************/ #include #include #include #include "common_structures" #define LATSCALE 100.0 #define LONSCALE 100.0 int read_scan ( FILE *infile, struct std_hdr hdr, struct std_data *structA, struct std_data *structAhi, struct std_data *structBhi ) { int Abytes ; /* Length of A-scan data to read */ int Bbytes ; /* Length of B-scan data to read */ int Bflag ; /* Flag to expect B-scan data */ int error_flag ; /* Error flag */ short field ; /* Array field counter */ short fields ; /* Number of lo-res fields */ short hifields ; /* Number of hi-res fields */ int loc ; /* Array byte location */ int pix ; /* Pixel counter */ int reclen ; /* Total record length */ short *temparray ; /* Array for holding one scanline data */ short tlat ; /* Temporary latitude value holder */ short tlon ; /* Temporary longitude value holder */ long ttime ; /* Temporary itime value holder */ char buf[5000] ; /* Temporary buffer to read to EOR */ error_flag = 0 ; Bflag = 0 ; if ( ! structA ) { error_flag = -5 ; goto outta_here ; } if ( hdr.hifields > 0 && structAhi != NULL && structBhi != NULL ) Bflag = 1 ; /** Determine length of data records per pixel **/ Abytes = hdr.fields * sizeof ( short ) ; if ( ! Bflag ) Bbytes = 0 ; else { Abytes = ( hdr.fields + hdr.hifields ) * sizeof ( short ) ; Bbytes = hdr.hifields * sizeof ( short ) ; } reclen = ( Abytes + 8 ) * hdr.pixperscan + ( Bbytes + 8 ) * ( hdr.hipixperscan / 2 ) + ( Bbytes + 8 ) * hdr.hipixperscan ; temparray = ( short * ) malloc ( Abytes ) ; if ( temparray == NULL ) { error_flag = -1 ; goto outta_here ; } /** Case 1: single-resolution data only **/ if ( ! Bflag ) { for ( pix = 0 ; pix < hdr.pixperscan ; pix++ ) { fread ( &ttime, 4, 1, infile ) ; fread ( &tlat, 2, 1, infile ) ; fread ( &tlon, 2, 1, infile ) ; if ( ttime == hdr.missing_val ) { error_flag = 999 ; fread ( &buf, reclen - 8, 1, infile ) ; goto outta_here ; } structA->itime[pix] = ttime ; structA->lat[pix] = tlat / LATSCALE ; structA->lng[pix] = tlon / LONSCALE ; loc = 0 ; if ( ! fread ( temparray, Abytes, 1, infile ) ) { error_flag = -2 ; goto outta_here ; } field = 0 ; while ( field < hdr.fields ) { if ( temparray[loc] == hdr.missing_val ) structA->fielddata[field][pix] = (float) hdr.missing_val ; else structA->fielddata[field][pix] = ( (float) temparray[loc] / hdr.scale[field] ) - hdr.offset[field] ; loc ++ ; field++ ; } } } /** Case 2: low- and high-resolution data together **/ if ( Bflag ) { /** Read scanline A **/ for ( pix = 0 ; pix < hdr.hipixperscan ; pix++ ) { fread ( &ttime, 4, 1, infile ) ; fread ( &tlat, 2, 1, infile ) ; fread ( &tlon, 2, 1, infile ) ; if ( ttime == hdr.missing_val ) { error_flag = 999 ; fread ( &buf, reclen - 8, 1, infile ) ; goto outta_here ; } /** Even scanline A locations **/ if ( pix % 2 == 0 ) { structA->itime[pix/2] = ttime ; structAhi->itime[pix] = ttime ; structA->lat[pix/2] = tlat / LATSCALE ; structAhi->lat[pix] = tlat / LATSCALE ; structA->lng[pix/2] = tlon / LONSCALE ; structAhi->lng[pix] = tlon / LONSCALE ; loc = 0 ; if ( ! fread ( temparray, Abytes, 1, infile ) ) { error_flag = -3 ; goto outta_here ; } /** Load lo-res data **/ field = 0 ; while ( field < hdr.fields ) { if ( temparray[loc] == hdr.missing_val ) structA->fielddata[field][pix/2] = (float) hdr.missing_val ; else structA->fielddata[field][pix/2] = ( (float) temparray[loc] / hdr.scale[field] ) - hdr.offset[field] ; loc ++ ; field++ ; } /** Load hi-res data **/ if ( hdr.hifields > 0 ) { field = 0 ; while ( field < hdr.hifields ) { if ( temparray[loc] == hdr.missing_val ) structAhi->fielddata[field][pix] = (float) hdr.missing_val ; else structAhi->fielddata[field][pix] = ( (float) temparray[loc] / hdr.scale[hdr.fields+field] ) - hdr.offset[hdr.fields+field] ; loc ++ ; field++ ; } } } /** Odd scanline A locations **/ else { structAhi->itime[pix] = ttime ; structAhi->lat[pix] = tlat / LATSCALE ; structAhi->lng[pix] = tlon / LONSCALE ; if ( ! fread ( temparray, Bbytes, 1, infile ) ) { error_flag = -3 ; goto outta_here ; } /** Load hi-res data **/ loc = 0 ; if ( hdr.hifields > 0 ) { field = 0 ; while ( field < hdr.hifields ) { if ( temparray[loc] == hdr.missing_val ) structAhi->fielddata[field][pix] = (float) hdr.missing_val ; else structAhi->fielddata[field][pix] = ( (float) temparray[loc] / hdr.scale[hdr.fields+field] ) - hdr.offset[hdr.fields+field] ; loc ++ ; field++ ; } } } } /** End scan A read **/ /** Read scanline B **/ loc = 0 ; for ( pix = 0 ; pix < hdr.hipixperscan ; pix++ ) { fread ( &ttime, 4, 1, infile ) ; fread ( &tlat, 2, 1, infile ) ; fread ( &tlon, 2, 1, infile ) ; if ( ! fread ( temparray, Bbytes, 1, infile ) ) { error_flag = -4 ; goto outta_here ; } structBhi->itime[pix] = ttime ; structBhi->lat[pix] = tlat / LATSCALE ; structBhi->lng[pix] = tlon / LATSCALE ; loc = 0 ; if ( hdr.hifields > 0 ) { field = 0 ; while ( field < hdr.hifields ) { if ( temparray[loc] == hdr.missing_val ) structBhi->fielddata[field][pix] = (float) hdr.missing_val ; else structBhi->fielddata[field][pix] = ( (float) temparray[loc] / hdr.scale[hdr.fields+field] ) - hdr.offset[hdr.fields+field] ; loc ++ ; field ++ ; } } } /** End scan B read **/ } /** End hi-resolution case **/ outta_here : return ( error_flag ) ; }