/*============================================================ dumpnato.c USAGE: dumpnato This is hacked version of readnato.c from MIT Lincoln Labs This will dump each image contained in to disk in raw form. Output filename is: .sensor_type.nbytes.NXxNY.raw The NATO file format sometimes stores strips of data: sensor_type1 rows 0-31 sensor_type2 rows 0-31 ... sensor_typeN rows 0-31 sensor_type1 rows 32-63 sensor_type2 rows 32-63 ... sensor_typeN rows 32-63 ... ... The correct ordering of each image is: rows (31 ... 0) (63 ... 32) etc. Thus the funky loops in SaveRaw() ==============================================================*/ #include #include #include #include #include #include static void CloseAllFiles(); static char outprefix[1024]; /******************* DEFINE STRUCTURE IMGSTRUCT ********************/ struct imgstruct { unsigned char *header1ptr; long hdr2length; unsigned char *header2ptr; long imagetype; long rows; long cols; unsigned int **int_image; unsigned long **long_image; }; /************************ FUNCTION RNATO2() ************************/ struct imgstruct * rnato2(filep, posptr, imgcntptr, startrecptr, mode, imageno, nodata, order, quiet) /* Extract image and header info from a NATO-format file */ FILE *filep; /* pointer to opened NATO file */ long int *posptr; /* pointer to position marker in file */ long int *startrecptr;/* pointer to record imgcnt is measured from */ int *imgcntptr; /* pointer to image counter, w/r/t startrec */ int imageno; /* sequence number of image sought (see mode) */ unsigned char order; /* order flag for setting array order */ /* 0 -> matches plot coords, */ /* 1 -> image raster format */ unsigned char quiet; /* quiet flag: 1 suppresses reporting */ unsigned char nodata; /* nodata flag: 1 means return headers only unsigned char mode; /* mode flag: 0 -> normal--imageno refers to */ /* absolute position of image to */ /* be retrieved in file; */ /* 1 -> relative--imageno refers to */ /* position of image to be retrieved */ /* relative to current pos. marker; */ /* 2-> fastforward--imageno refers */ /* to number of starting record in */ /* file to begin image read from */ { unsigned char *header1, *header2; long parameters[16], header2bytes, header2size, rows, cols; long nbytes, bytes, datarecs; char s[9], *orderstr; int i, j, imagenum; struct imgstruct *imgptr; unsigned int **image2; /* array implemented as pointers to pointers */ unsigned long **image4; /* array implemented as pointers to pointers */ unsigned long **allocandloadlong(); unsigned int **allocandloadint(); long atol(); int atoi(); /************************************************************************/ /************************ Housekeeping chores ***************************/ s[8] = '\0'; orderstr = order ? "raster" : "plot"; /* set print tag */ /* allocate header1 buffer ... *****/ if (NULL == (header1 = (unsigned char *) malloc(512))) goto allocerr; /************************************************************************/ /******************* Get to start of requested image ********************/ if (mode == 2) /* Record-fastforward mode */ { if (imageno <= 0) /* Check for bad */ goto error1; /* imageno arg */ *posptr = (imageno - 1) * 512L; /* Set position marker */ *imgcntptr = 0; /* and counters ... */ *startrecptr = (long int) imageno; imagenum = 1; if (fseek(filep, *posptr, SEEK_SET)) /* Move into position */ if (feof(filep)) goto endofilerr; else goto error; /* otherwise report unknown error */ /* ... and skip to image read */ } else { /* For the other image-by-image modes ... */ if (mode == 0) /* Absolute retrieve mode */ { if (imageno <= 0) /* Check for bad */ goto error2; /* imageno arg */ *startrecptr = 0; /* Flag an absolute-mode access; */ *posptr = 0; /* Setup location markers to do a */ *imgcntptr = 0; /* relative access from file start */ imagenum = imageno; /* set internal absolute image specifier */ if (fseek(filep, *posptr, SEEK_SET)) /* Move into position */ if (feof(filep)) goto endofilerr; else goto error; /* otherwise report unknown error */ } else /* Relative retrieve mode */ { if (imageno <= 0) /* Check for bad */ goto error2; /* imageno arg */ /* This seek is necessary for recovery from a read error ... */ if (fseek(filep, *posptr, SEEK_SET)) if (feof(filep)) goto endofilerr; else goto error; /* set internal absolute image specifier */ imagenum = imageno - 1 + *imgcntptr + 1; } /**** Skip over intervening images for absolute or relative retrieve *****/ while ((*imgcntptr + 1) < imagenum) { /* Increment internal image counter ... */ ++(*imgcntptr); /* read header of next image to determine how far to advance ... */ if (!fread(header1, sizeof(*header1), 512, filep)) goto endofilerr; *posptr += 512L; /* perform crude test for NATO format ... */ if (!((header1[0] == ((unsigned char) 'U')) && (header1[1] == ((unsigned char) 'S')) && (header1[2] == ((unsigned char) 'A')) && (header1[3] == ((unsigned char) ' ')) ) ) goto error3; /* construct parameter array ... */ for (j=0; j<16; ++j) { for (i=0; i<8; ++i) s[i] = (header1 + 256 + j * 8)[i]; parameters[j] = atol(s); } /* get size of second header if present ... */ for (i=0; i<8; ++i) s[i] = (header1 + 32)[i]; header2bytes = atol(s); if (header2bytes < 0) goto correrr; header2size = ((header2bytes + 511) / 512) * 512; /* move position marker through header2 ... */ *posptr += header2size; /* get image size, rows by columns ... */ for (i=0; i<8; ++i) s[i] = (header1 + 80)[i]; cols = atol(s); for (i=0; i<8; ++i) s[i] = (header1 + 88)[i]; rows = atol(s); /* determine the byte format of the data ... */ switch (parameters[3]) { /* if available check in internal */ /* values for data length ... */ case 8: nbytes = 1L; break; case 16: nbytes = 2L; break; case 32: nbytes = 4L; break; default: { /* if internal header missing or */ /* corrupted, look in standard header: */ for (i=0; i<8; ++i) s[i] = (header1 + 96)[i]; bytes = atol(s); switch (bytes) { case 5: nbytes = 1L; break; case 0: nbytes = 2L; break; case 4: nbytes = 4L; break; default: goto error4; } } } /* Update posptr ... */ datarecs = (rows * cols * nbytes + 511) / 512; *posptr += 512L * datarecs; /* ... and advance to new postion marker ... */ if (fseek(filep, *posptr, SEEK_SET)) if (feof(filep)) goto endofilerr; else goto error; } } /************************************************************************/ /*********************** Read the current image *************************/ /* Increment internal image counter ... */ ++(*imgcntptr); /* read first header */ if (!fread(header1, sizeof(*header1), 512, filep)) goto endofilerr; *posptr += 512L; /* perform crude test for NATO format ... */ if (!((header1[0] == ((unsigned char) 'U')) && (header1[1] == ((unsigned char) 'S')) && (header1[2] == ((unsigned char) 'A')) && (header1[3] == ((unsigned char) ' ')) ) ) goto error3; /* construct parameter array ... */ for (j=0; j<16; ++j) { for (i=0; i<8; ++i) s[i] = (header1 + 256 + j * 8)[i]; parameters[j] = atol(s); } /* get size of second header and read if present ... */ for (i=0; i<8; ++i) s[i] = (header1 + 32)[i]; /* Allocate storage and read header2 if present ... */ if (header2bytes = atol(s)) { if (header2bytes < 0) goto correrr; if (NULL == (header2 = (unsigned char *) malloc((unsigned int) header2bytes))) goto allocerr; header2size = ((header2bytes + 511) / 512) * 512; if (!fread(header2, sizeof(*header2), (int) header2bytes, filep)) goto endofilerr; /* ... and move to end of header2 ... */ *posptr += header2size; if (fseek(filep, *posptr, SEEK_SET)) { if (feof(filep)) goto endofilerr; else goto error; } } /* Or signal no header2 present ... */ else header2 = NULL; /* get image size, rows by columns ... */ for (i=0; i<8; ++i) s[i] = (header1 + 80)[i]; cols = atol(s); for (i=0; i<8; ++i) s[i] = (header1 + 88)[i]; rows = atol(s); /* determine the byte format of the data ... */ switch (parameters[3]) { /* if available check in internal */ /* values for data length ... */ case 8: nbytes = 1L; break; case 16: nbytes = 2L; break; case 32: nbytes = 4L; break; default: { /* if internal header missing or */ /* corrupted, look in standard header */ for (i=0; i<8; ++i) s[i] = (header1 + 96)[i]; bytes = atol(s); switch (bytes) { case 5: nbytes = 1L; break; case 0: nbytes = 2L; break; case 4: nbytes = 4L; break; default: goto error4; } } } /**** Allocate 2-D array as array of pointers to linear arrays ****************/ /*********************************** of chars and read file into structure ****/ if (!nodata) { /* In standard mode, get image data ... */ if (nbytes==4) { image4 = allocandloadlong (filep, rows, cols, nbytes, (int) parameters[4], order); if (NULL == image4) /* In case allocandload had a read error, punt */ goto error; image2 = (unsigned int **) NULL; } else { image2 = allocandloadint (filep, rows, cols, nbytes, (int) parameters[4], order); if (NULL == image2) /* In case allocandload had a read error, punt */ goto error; image4 = (unsigned long **) NULL; } } else { /* In nodata mode, punt image data ... */ image2 = (unsigned int **) NULL; image4 = (unsigned long **) NULL; } /* Update posptr ... */ datarecs = (rows * cols * nbytes + 511) / 512; *posptr += 512L * datarecs; /* ... and advance to new position marker ... */ if (fseek(filep, *posptr, SEEK_SET)) if (feof(filep)) goto endofilerr; else goto error; /* Construct return structure */ /* Allocate storage ... */ imgptr = (struct imgstruct *) malloc(sizeof(struct imgstruct)); /* Assign members ... */ imgptr->header1ptr = header1; imgptr->hdr2length = header2bytes; imgptr->header2ptr = header2; imgptr->imagetype = nbytes; imgptr->rows = rows; imgptr->cols = cols; imgptr->int_image = image2; imgptr->long_image = image4; quiet=1; if (!quiet) /* Report results ... */ { printf("\nImage no. %d successfully read in %s format.\n", imagenum, orderstr); printf(" imageno in file = %d\n", *imgcntptr); printf(" rows X columns = %d X %d\n", rows, cols); printf(" bytes per pixel = %d\n\n", nbytes); } return (imgptr); error: fprintf(stderr, "rnato2: Sorry, an unspecified read error occurred.\n"); fprintf(stderr, " startrec = %d\n", *startrecptr); fprintf(stderr, " imageno = %d\n", (*imgcntptr + 1)); fprintf(stderr, " mode = %d\n\n", mode); *startrecptr = 0; /* Reset all location markers */ *imgcntptr = 0; *posptr = 0L; clearerr(filep); return(NULL); error1: fprintf(stderr, "rnato2: Bogus starting record number %d, dude!\n", imageno); *startrecptr = 0; /* Reset all location markers */ *imgcntptr = 0; *posptr = 0L; return(NULL); error2: fprintf(stderr, "rnato2: Invalid image number %d; try something more positive.\n", imageno); return(NULL); error3: if (mode == 2) { fprintf(stderr, "rnato2: Record %d doesn't correspond to the start", *startrecptr); fprintf(stderr, " of an image,\n or image is not in NATO format\n\n"); } else { fprintf(stderr, "rnato2: Image number %d after starting ", (*imgcntptr)); fprintf(stderr, "record %d \n doesn't appear to be in NATO format.\n\n", *startrecptr); } *startrecptr = 0; /* Reset all location markers */ *imgcntptr = 0; *posptr = 0L; return(NULL); error4: fprintf(stderr, "rnato2: Bad data size indicated in header: %d \n\n", bytes); *startrecptr = 0; /* Reset all location markers */ *imgcntptr = 0; *posptr = 0L; return(NULL); allocerr: fprintf(stderr, "rnato2: Bummer, dude! Unable to allocate memory for array.\n\n"); return(NULL); correrr: fprintf(stderr, "rnato2: Bad header2 size indicated in header: %d \n\n", header2bytes); *startrecptr = 0; /* Reset all location markers */ *imgcntptr = 0; *posptr = 0L; return(NULL); endofilerr: /* Reached end of file */ fprintf(stderr, "rnato2: Encountered End of File.\n"); fprintf(stderr, "File contains %d images", *imgcntptr - 1); if (*startrecptr > 1) fprintf(stderr, " after starting record %d.\n\n", *startrecptr); else fprintf(stderr, ".\n\n"); clearerr(filep); *startrecptr = 0; /* Reset all location markers */ *imgcntptr = 0; *posptr = 0L; return(NULL); } /************************ FUNCTION PURGEIMAGE() ************************/ void purgeimage(imgstr_p) struct imgstruct *imgstr_p; { long rows; int i; rows = imgstr_p->rows; if (NULL != imgstr_p->header1ptr) free(imgstr_p->header1ptr); /* free 1st header array */ if (NULL != imgstr_p->header2ptr) free(imgstr_p->header2ptr); /* free 2nd header array */ if (NULL != imgstr_p->int_image) { for (i=0; iint_image)[i]); /* freeing each col array */ free(imgstr_p->int_image); /* free array of row ptrs */ } if (NULL != imgstr_p->long_image) { /* repeat process for long */ for (i=0; ilong_image)[i]); free(imgstr_p->long_image); } free(imgstr_p); /* Lastly, free structure itself */ } /************************ FUNCTION ALLOCANDLOADLONG() *******************/ unsigned long ** allocandloadlong (fp, rowcount, colcount, elsize, accessmode, order) FILE *fp; int accessmode; long elsize, rowcount, colcount; unsigned char order; { unsigned long **image; int j, i, bufptr; unsigned char readbuf[512]; int atoi(); long atol(); bufptr = 512; if (elsize != 4) goto elsizerr; /* Allocate storage ... */ if (NULL == (image = (unsigned long **) malloc((unsigned int) (rowcount * sizeof(unsigned long *))))) goto allocerr; for (i=0; i < rowcount; ++i) if (NULL == (image[i] = (unsigned long *) malloc((unsigned int) (colcount * sizeof(unsigned long))))) goto allocerr; /* Read file data into "array" ... */ switch (2 * order + accessmode) { /* There are 4 possible loading sequences required: */ case 1: /* plot format, col-by-col access */ for (j=0; j < colcount; j++) { for (i = rowcount - 1; i >= 0; --i) { if (bufptr >= 512) /* refill read buffer when depleted */ { if (!fread(readbuf, sizeof(*readbuf), 512, fp)) goto endofilerr; bufptr = 0; } image[i][j] = ((unsigned long) readbuf[bufptr]) + (((unsigned long) readbuf[bufptr + 1]) << 8) + (((unsigned long) readbuf[bufptr + 2]) << 16) + (((unsigned long) readbuf[bufptr + 3]) << 24); bufptr += 4; } } break; case 3: /* raster format, col-by-col access */ for (j=0; j < colcount; j++) { for (i=0; i < rowcount; i++) { if (bufptr >= 512) /* refill read buffer when depleted */ { if (!fread(readbuf, sizeof(*readbuf), 512, fp)) goto endofilerr; bufptr = 0; } image[i][j] = ((unsigned long) readbuf[bufptr]) + (((unsigned long) readbuf[bufptr + 1]) << 8) + (((unsigned long) readbuf[bufptr + 2]) << 16) + (((unsigned long) readbuf[bufptr + 3]) << 24); bufptr += 4; } } break; case 0: /* plot format, row-by-row access */ for (i = rowcount - 1; i >= 0; --i) { for (j=0; j < colcount; j++) { if (bufptr >= 512) /* refill read buffer when depleted */ { if (!fread(readbuf, sizeof(*readbuf), 512, fp)) goto endofilerr; bufptr = 0; } image[i][j] = ((unsigned long) readbuf[bufptr]) + (((unsigned long) readbuf[bufptr + 1]) << 8) + (((unsigned long) readbuf[bufptr + 2]) << 16) + (((unsigned long) readbuf[bufptr + 3]) << 24); bufptr += 4; } } break; default: /* raster format, row-by-row access */ for (i=0; i < rowcount; i++) { for (j=0; j < colcount; j++) { if (bufptr >= 512) /* refill read buffer when depleted */ { if (!fread(readbuf, sizeof(*readbuf), 512, fp)) goto endofilerr; bufptr = 0; } image[i][j] = ((unsigned long) readbuf[bufptr]) + (((unsigned long) readbuf[bufptr + 1]) << 8) + (((unsigned long) readbuf[bufptr + 2]) << 16) + (((unsigned long) readbuf[bufptr + 3]) << 24); bufptr += 4; } } } return(image); allocerr: fprintf(stderr, "allocandloadlong: Bummer, dude! Unable to allocate memory for array.\n\n"); return(NULL); elsizerr: fprintf(stderr, "allocandloadlong: Unsupported data size indicated: %d bytes per pixel.\n\n", elsize); return(NULL); endofilerr: /* Reached end of file */ fprintf(stderr, "allocandloadlong: Encountered End of File.\n\n"); return(NULL); } /************************ FUNCTION ALLOCANDLOADINT() *******************/ unsigned int ** allocandloadint (fp, rowcount, colcount, elsize, accessmode, order) FILE *fp; int accessmode; long elsize, rowcount, colcount; unsigned char order; { unsigned int **image; int j, i, bufptr; unsigned char readbuf[512]; int atoi(); long atol(); bufptr = 512; /* Allocate storage ... */ if (NULL == (image = (unsigned int **) malloc((unsigned int)(rowcount * sizeof(int *))))) goto allocerr; for (i=0; i < rowcount; ++i) if (NULL == (image[i] = (unsigned int *) malloc((unsigned int) (colcount * sizeof(int))))) goto allocerr; /* Read file data into "array" ... */ switch (2 * order + accessmode) { /* There are 4 possible loading sequences required: */ case 1: /* plot format, col-by-col access */ for (j=0; j < colcount; j++) /* plot formats are untested; should */ { /* flip image top-to-bottom */ for (i = rowcount - 1; i >= 0; --i) { if (bufptr >= 512) /* refill read buffer when depleted */ { if (!fread(readbuf, sizeof(*readbuf), 512, fp)) goto endofilerr; bufptr = 0; } if (elsize == 1) { image[i][j] = (unsigned int) readbuf[bufptr]; bufptr++; } else if (elsize == 2) { image[i][j] = (unsigned int) readbuf[bufptr] + (((unsigned int) readbuf[bufptr + 1]) << 8); bufptr += 2; } else goto elsizerr; } } break; case 3: /* raster format, col-by-col access */ for (j=0; j < colcount; j++) { for (i=0; i < rowcount; i++) { if (bufptr >= 512) /* refill read buffer when depleted */ { if (!fread(readbuf, sizeof(*readbuf), 512, fp)) goto endofilerr; bufptr = 0; } if (elsize == 1) { image[i][j] = (unsigned int) readbuf[bufptr]; bufptr++; } else if (elsize == 2) { image[i][j] = (unsigned int) readbuf[bufptr] + (((unsigned int) readbuf[bufptr + 1]) << 8); bufptr += 2; } else goto elsizerr; } } break; case 0: /* plot format, row-by-row access */ for (i = rowcount - 1; i >= 0; --i) { /* plot formats are untested; should */ for (j=0; j < colcount; j++) /* flip image top-to-bottom */ { if (bufptr >= 512) /* refill read buffer when depleted */ { if (!fread(readbuf, sizeof(*readbuf), 512, fp)) goto endofilerr; bufptr = 0; } if (elsize == 1) { image[i][j] = (unsigned int) readbuf[bufptr]; bufptr++; } else if (elsize == 2) { image[i][j] = (unsigned int) readbuf[bufptr] + (((unsigned int) readbuf[bufptr + 1]) << 8); bufptr += 2; } else goto elsizerr; } } break; default: /* raster format, row-by-row access */ for (i=0; i < rowcount; i++) { for (j=0; j < colcount; j++) { if (bufptr >= 512) /* refill read buffer when depleted */ { if (!fread(readbuf, sizeof(*readbuf), 512, fp)) goto endofilerr; bufptr = 0; } if (elsize == 1) { image[i][j] = (unsigned int) readbuf[bufptr]; bufptr++; } else if (elsize == 2) { image[i][j] = (unsigned int) readbuf[bufptr] + (((unsigned int) readbuf[bufptr + 1]) << 8); bufptr += 2; } else goto elsizerr; } } } return(image); allocerr: fprintf(stderr, "allocandloadint: Bummer, dude! Unable to allocate memory for array.\n\n"); return(NULL); elsizerr: fprintf(stderr, "allocandloadint: Unsupported data size indicated: %d bytes per pixel.\n\n", elsize); return(NULL); endofilerr: /* Reached end of file */ fprintf(stderr, "allocandloadint: Encountered End of File.\n\n"); return(NULL); } void FinishImages(); main(int argc, char **argv) { int imgno, ii,imagecounter; char exitflag, newfile, imgloaded, hdrloaded; /* flags */ char filename[45], inpt; long position, startrecord; unsigned char accmode, hdronly; FILE *fp; char infile[MAXPATHLEN]; struct imgstruct *p_image, *rnato2(); int l; void keysave(); void purgeimage(); int getimgno(); if(argc != 2) { fprintf(stderr,"USAGE: %s \n",argv[0]); fprintf(stderr," (the input file should end in '.nat')\n"); exit(1); } sprintf(outprefix,"%s",argv[1]); l=strlen(outprefix); if(outprefix[l-4] == '.') outprefix[l-4] = 0; exitflag = 0; newfile = 1; imgloaded = 0; hdrloaded = 0; p_image = (struct imgstruct *) NULL; fp = NULL; /* Initialize various file marker pointers ... */ imgno = 0; imagecounter = 0; position = 0; startrecord = 0; sprintf(infile,"%s.nat",outprefix); if ((fp = fopen(infile, "r")) == NULL) { sprintf(infile,"%s.NAT",outprefix); if ((fp = fopen(infile, "r")) == NULL) { fprintf(stderr,"\nERROR: Unable to open file %s.\n", infile); exit(1); } } ii = 0; while(1) { accmode = 1; /* next image */ hdronly = 0; imgno = 1; if (p_image != NULL) /* Free memory assoc. with p_image if it exists */ purgeimage(p_image); p_image = rnato2(fp, &position, &imagecounter, &startrecord, accmode, imgno, hdronly, 1, 0); if (p_image != NULL) keysave(p_image,ii++); else break; } if (fp != NULL) fclose(fp); /* ... close any open files */ if (p_image != NULL) /* Free memory assoc. with p_image if it exists */ purgeimage(p_image); CloseAllFiles(); printf("\nLater, dude.\n\n"); return(0); } /* End main */ #ifdef NOTDEF void ShowMaxMin(struct imgstruct *img) { int x,y,nx,ny; short smin,smax; if(img->imagetype != 1) return; nx = img->cols; ny = img->rows; smin = smax = img->int_image[0][0]; for(y=0;yint_image[y][x] < smin) smin = img->int_image[y][x]; if(img->int_image[y][x] > smax) smax = img->int_image[y][x]; } printf("MIN: %ld MAX: %ld\n",(long)smin,(long)smax); } #endif int convert1byte(struct imgstruct *img,char *fname) { int rval = 0; if(img->imagetype != 1) { printf("WARNING: %s :: Converting from %d bytes/pixel to 1 byte/pixel\n", fname,img->imagetype); rval = 1; } switch(img->imagetype){ case 1: break; case 2: { int i,j,nx,ny; int ival,imax,imin; float frange; nx = img->cols; ny = img->rows; imax = imin = (int)img->int_image[0][0]; for(j=0;jint_image[j][i]; if(ival < imin) imin = ival; if(ival > imax) imax = ival; } frange = (float)(imax - imin); if(frange == 0.0) frange = 1.0; for(j=0;jint_image[j][i]; img->int_image[j][i] = (unsigned int)( (float)(ival-imin)/frange * 255.0); } } break; case 4: { int i,j,nx,ny; unsigned long lval,lmax,lmin; unsigned int **image; float frange; if((image=(unsigned int**)malloc(sizeof(int*)*ny))==(unsigned int**)NULL) { fprintf(stderr,"ERROR: out of memory\n"); exit(1); } for(j=0;jint_image = image; nx = img->cols; ny = img->rows; lmax = lmin = img->long_image[0][0]; for(j=0;jlong_image[j][i]; if(lval < lmin) lmin = lval; if(lval > lmax) lmax = lval; } frange = (float)(lmax - lmin); if(frange == 0.0) frange = 1.0; for(j=0;jlong_image[j][i]; img->int_image[j][i] = (unsigned int)( (float)(lval-lmin)/frange * 255.0); } } break; default: fprintf(stderr,"ERROR: file nbytes/pixel != (1,2,4) !!\n"); exit(1); } return(rval); } static char *image_type_strings[14] = { "UNKNOWN","video","CO2_range_intensity","CO2_range","doppler_intensity", "doppler","passive","synthetic","16bit_range_intensity", "16bit_range","16bit_doppler_intensity","16bit_doppler", "GaAs_intensity_or_LW_passive","GaAs_range_or_LW_passive" }; static char sstring[MAXPATHLEN*2]; static char *filenames[14]; static FILE *fps[14]; static int totnx[14],totny[14]; static char new_name[MAXPATHLEN]; static int unknown_count = 0; void CloseAllFiles() { int i; for(i=0;i<14;i++) if(fps[i] != NULL) { fclose(fps[i]); /* rename each file to indicate dimensions */ sprintf(new_name,"%s.%dx%d.raw",filenames[i],totnx[i],totny[i]); sprintf(sstring,"mv -f %s %s",filenames[i],new_name); system(sstring); } } /* Save each raw data in reverse order so that strips concatenated together will produce correct image. The data should not be flipped in the case of a single portion of data (as opposed to strips), but am only handling 'video' here since it never appears to be in strips If the header type field is UNKNOWN (0), then save each raw file separately */ void SaveRaw(struct imgstruct *img, char *fname,int tpe) { int nx,ny,nb,x,y; FILE *fp; if((fp=fps[tpe])==(FILE*)NULL) { if((fps[tpe] = fp = fopen(fname,"wb"))==(FILE*)NULL) { fprintf(stderr,"ERROR: Cant open '%s' for write\n",fname); exit(1); } sprintf(filenames[tpe],"%s",fname); } nx = img->cols; ny = img->rows; totnx[tpe] = nx; totny[tpe] += ny; switch(img->imagetype) { case 1: { unsigned char c; if(tpe == 1) {/* video, dont reverse raw */ for(y=0;yint_image[y][x]; fwrite((void*)&c,1,1,fp); } } else { for(y=ny-1;y>=0;y--) for(x=0;xint_image[y][x]; fwrite((void*)&c,1,1,fp); } } } break; case 2: { unsigned short c; if(tpe == 1) { for(y=ny-1;y>=0;y--) for(x=0;xint_image[y][x]; fwrite((void*)&c,2,1,fp); } } else { for(y=ny-1;y>=0;y--) for(x=0;xint_image[y][x]; fwrite((void*)&c,2,1,fp); } } } break; case 4: { unsigned long c; if(tpe == 1) { for(y=0;ylong_image[y][x]; fwrite((void*)&c,4,1,fp); } } else { for(y=ny-1;y>=0;y--) for(x=0;xlong_image[y][x]; fwrite((void*)&c,4,1,fp); } } } break; default: break; } if(tpe == 0) { /* UNKNOWN -- save each separately */ fclose(fp); fps[tpe] = (FILE*)NULL; sprintf(new_name,"%s.%dx%d.%03d.raw",filenames[tpe],totnx[tpe],totny[tpe],unknown_count++); sprintf(sstring,"mv -f %s %s",filenames[tpe],new_name); system(sstring); totnx[tpe] = totny[tpe] = 0; } } static int firstsave=1; #define BuffCopy(start,len) { \ for(i=0;iheader1ptr[i+start]; \ tbuff[len] = 0;} void keysave(struct imgstruct *struct_ptr, int rno) { int nx,ny,nchan,itype,i; int month,day,year,hour,min,sec; char fname[1024]; char *type_string,tbuff[128]; ny = struct_ptr->rows; nx = struct_ptr->cols; if(firstsave) { firstsave=0; for(i=0;i<14;i++) { fps[i] = (FILE*)NULL; totnx[i] = totny[i] = 0; filenames[i] = (char*)calloc(sizeof(char),MAXPATHLEN); } } BuffCopy(48,8); nchan = atoi(tbuff); if(nchan != 1) printf("WARNING: %d channels per sample\n",nchan); BuffCopy(16,8); itype = atoi(tbuff); if(itype < 0) itype = 0; else if(itype > 13) itype = 0; BuffCopy(368,2); hour = atoi(tbuff); BuffCopy(371,2); min = atoi(tbuff); BuffCopy(374,2); sec = atoi(tbuff); BuffCopy(8,2); year = atoi(tbuff); BuffCopy(11,2); month = atoi(tbuff); BuffCopy(14,2); day = atoi(tbuff); sprintf(fname,"%s.%s.%dbytes",outprefix,image_type_strings[itype],struct_ptr->imagetype); SaveRaw(struct_ptr,fname,itype); }