#include #include #include #define SEEK_SET 0 /******************* 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 */ char *malloc(); 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; 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(); char *malloc(); 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(); char *malloc(); 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); } main() { int imgno, imagecounter; char exitflag, newfile, imgloaded, hdrloaded; /* flags */ char filename[45], inpt; long position, startrecord; unsigned char accmode, hdronly; struct imgstruct *p_image, *rnato2(); FILE *fopen(), *fp; void purgeimage(), keydisplay(), hdrdisplay(); unsigned char getmode(), gethdronly(); int getimgno(), fclose(); exitflag = 0; newfile = 1; imgloaded = 0; hdrloaded = 0; p_image = (struct imgstruct *) NULL; fp = NULL; while (!exitflag) /* Outer while loop */ { /* Initialize various file marker pointers ... */ imgno = 0; imagecounter = 0; position = 0; startrecord = 0; printf("\n\n\nEnter the name of a NATO format file, or bye to abort: "); scanf("%s", filename); if ((filename[0] == 'b') && (filename[1] == 'y') && (filename[2] == 'e') && (filename[3] == '\0')) exitflag = 1; else { if ((fp = fopen(filename, "r")) == NULL) printf("\nUnable to open file %s.\n", filename); else newfile = 0; } while (!exitflag && !newfile) /* Inner while loop */ { fflush(stdin); printf("\n\n\n\n\n"); printf("Select a command: L - load an image\n"); printf(" D - display key blocks of a loaded image\n"); printf(" H - display headers\n"); printf(" F - open a new file\n"); printf(" Q - exit\n\n\n? "); while ((inpt = getchar()) == '\n') ; switch (inpt) { case 'l': case 'L': accmode = getmode(); imgno = getimgno(accmode); hdronly = gethdronly(); 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) { printf("\nCouldn't read the last image!!\n"); imgloaded = 0; hdrloaded = 0; } else { hdrloaded = 1; if (!hdronly) imgloaded = 1; } break; case 'd': case 'D': if (imgloaded) keydisplay(p_image); else printf("\nNo image is currently loaded; load an image and try again.\n"); break; case 'h': case 'H': if (hdrloaded) hdrdisplay(p_image); else printf("\nNo headers are currently loaded.\n"); break; case 'f': case 'F': newfile = 1; fclose(fp); /* ... close the old before opening the new */ if (p_image != NULL) /* Free memory assoc. with p_image if it exists */ purgeimage(p_image); break; case 'q': case 'Q': exitflag = 1; break; default: printf("Don't understand \"%c\", try again\n\n? ", inpt); } } /* Close inner while loop */ } /* Close outer while loop */ 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); printf("\nLater, dude.\n\n"); return(0); } /* End main */ /************************ FUNCTION GETMODE() ****************************/ unsigned char getmode() { unsigned char output, done; int inpt; done = 0; fflush(stdin); printf("\n\n\n"); printf("Choose an option: A - indicate an image number in the file\n"); printf(" N - load the next image in the file\n"); printf(" J - skip to the start of a record "); printf("and read an image\n\n? "); while (!done) { while ((inpt = getchar()) == '\n') ; switch (inpt) { case 'A': /* Absolute mode */ case 'a': output = 0; done = 1; break; case 'N': /* Next image; relative mode */ case 'n': output = 1; done = 1; break; case 'J': /* Jump N recordse; fast-forward mode */ case 'j': output = 2; done = 1; break; default: fflush(stdin); printf("\nHuh?? "); } } return(output); } /************************ FUNCTION GETHDRONLY() ****************************/ unsigned char gethdronly() { unsigned char output, done; int inpt; done = 0; fflush(stdin); printf("\n\n\n"); printf("Choose an option: I - load image and headers\n"); printf(" H - load headers only\n\n? "); while (!done) { while ((inpt = getchar()) == '\n') ; switch (inpt) { case 'I': case 'i': output = 0; done = 1; break; case 'H': case 'h': output = 1; done = 1; break; default: fflush(stdin); printf("\nHuh?? "); } } return(output); } /************************ FUNCTION GETIMGNO() ****************************/ int getimgno(mode) unsigned char mode; { unsigned char done; int output; done = 0; if (mode == 1) /* Next-image (relative) mode ... */ output = 1; else { while (!done) { if (mode == 2) { printf("\n"); printf("Enter the starting record number: "); } else { printf("\n"); printf("Enter the image number: "); } if (0 == scanf("%d", &output)) while (getchar() == '\n') /* fix an ugly bug */ ; else done = 1; } } return(output); } /************************ FUNCTION KEYDISPLAY() ****************************/ void keydisplay(struct_ptr) struct imgstruct *struct_ptr; { int rowmax10, rowmax2, rowmin, colmax10, colmax2, colmin; int i, j, cols, rows; rows = (int) struct_ptr->rows; cols = (int) struct_ptr->cols; /* Account for tiny arrays . . . */ rowmax10 = (10 <= rows) ? 10 : rows; rowmax2 = (2 <= rows) ? 2 : rows; colmax10 = (10 <= cols) ? 10 : cols; colmax2 = (2 <= cols) ? 2 : cols; rowmin = (2 < rows) ? rows - 2 : 0; colmin = (2 < cols) ? cols - 2 : 0; if (struct_ptr->imagetype != 4) /* If array is integer type ... */ { fprintf(stdout, "\n\nUpper left corner block of image array (10x10): \n"); for (i=0; iint_image)[i][j]); fprintf(stdout, "\n"); } fprintf(stdout, "\n\nUpper right corner block of image array (2x2): \n"); for (i=0; iint_image)[i][j]); fprintf(stdout, "\n"); } fprintf(stdout, "\n\nLower left corner block of image array (2x2): \n"); for (i=rowmin; iint_image)[i][j]); fprintf(stdout, "\n"); } fprintf(stdout, "\n\nLower right corner block of image array (2x2): \n"); for (i=rowmin; iint_image)[i][j]); fprintf(stdout, "\n"); } } else /* If array is long int type ... */ { fprintf(stdout, "\n\nUpper left corner block of image array (10x10): \n"); for (i=0; ilong_image)[i][j]); fprintf(stdout, "\n"); } fprintf(stdout, "\n\nUpper right corner block of image array (2x2): \n"); for (i=0; ilong_image)[i][j]); fprintf(stdout, "\n"); } fprintf(stdout, "\n\nLower left corner block of image array (2x2): \n"); for (i=rowmin; ilong_image)[i][j]); fprintf(stdout, "\n"); } fprintf(stdout, "\n\nLower right corner block of image array (2x2): \n"); for (i=rowmin; ilong_image)[i][j]); fprintf(stdout, "\n"); } } } /************************ FUNCTION HDRDISPLAY() ****************************/ void hdrdisplay(struct_ptr) struct imgstruct *struct_ptr; { void dispheader1(), dispirarhdr(); fprintf(stdout, "\n\n****************HEADER 1 CONTENTS******************\n\n\n"); dispheader1(struct_ptr->header1ptr, stdout); if (struct_ptr->hdr2length >= 512) { fprintf(stdout, "\n\n\n********************IRAR (FORWARD-LOOKING) HEADER"); fprintf(stdout, "******************\n\n\n"); /* Make a best guess as to location of IRAR header (may not be ok for all files) ... */ dispirarhdr(&((struct_ptr->header2ptr)[((struct_ptr->hdr2length)/512 - 1)*512]), stdout); } else fprintf(stdout, "\nNo IRAR (forward-looking) Header found.\n\n\n"); } /************************ FUNCTION DISPHEADER1() ************************/ void dispheader1 (header1, filep) unsigned char *header1; FILE *filep; { char *txtmonth, *itypestr, spec[9], *intaccstr, intseqstr[120], intdesc[65]; char tempstr[9]; int rday, rmonth, ryear, imlength, header2bytes, channels, h1cols, h1rows, imlperrec, introws, intcols, intbits, intacc, intperbundle, intday, intyear, intheader2bytes, intrnggate, intrngoff, inthorfov, intverfov, inthr, intmin, intsec, intrngquant, imtype, datypind; int i, j, temp, downlook; unsigned char errflag = 0; unsigned char firstflg = 1; long atol(); int atoi(); tempstr[8] = '\0'; downlook = 0; /* Get record date ... */ for (i=0; i<2; ++i) tempstr[i] = header1[i + 8]; tempstr[2] = '\0'; ryear = atoi(tempstr); for (i=0; i<2; ++i) tempstr[i] = header1[i + 11]; tempstr[2] = '\0'; rmonth = atoi(tempstr); for (i=0; i<2; ++i) tempstr[i] = header1[i + 14]; tempstr[2] = '\0'; rday = atoi(tempstr); switch (rmonth) { case 1: txtmonth = "Jan"; break; case 2: txtmonth = "Feb"; break; case 3: txtmonth = "Mar"; break; case 4: txtmonth = "Apr"; break; case 5: txtmonth = "May"; break; case 6: txtmonth = "Jun"; break; case 7: txtmonth = "Jul"; break; case 8: txtmonth = "Aug"; break; case 9: txtmonth = "Sep"; break; case 10: txtmonth = "Oct"; break; case 11: txtmonth = "Nov"; break; case 12: txtmonth = "Dec"; break; default: txtmonth = ""; errflag = 1; } /* Get image type ... */ for (i=0; i<8; ++i) tempstr[i] = header1[i + 16]; imtype = atoi(tempstr); switch (imtype) { case 1: itypestr = "video"; break; case 2: itypestr = "CO2 range intensity"; break; case 3: itypestr = "CO2 range"; break; case 4: itypestr = "doppler intensity"; break; case 5: itypestr = "doppler"; break; case 6: itypestr = "passive"; break; case 7: itypestr = "synthetic"; break; case 8: itypestr = "16-bit range intensity"; break; case 9: itypestr = "16-bit range"; break; case 12: itypestr = "GaAs intensity or LW passive (check logbook)"; downlook = 1; /* set flag for downlooking sensor warning */ break; case 13: itypestr = "GaAs range or LW passive (check logbook)"; downlook = 1; /* set flag for downlooking sensor warning */ break; default: itypestr = "Unrecognized image type"; } /* Get several integer parameters ... */ for (i=0; i<8; ++i) tempstr[i] = header1[i + 24]; imlength = atoi(tempstr); for (i=0; i<8; ++i) tempstr[i] = header1[i + 32]; header2bytes = atoi(tempstr); for (i=0; i<8; ++i) tempstr[i] = header1[i + 48]; channels = atoi(tempstr); for (i=0; i<8; ++i) tempstr[i] = header1[i + 80]; h1cols = atoi(tempstr); for (i=0; i<8; ++i) tempstr[i] = header1[i + 88]; h1rows = atoi(tempstr); for (i=0; i<8; ++i) tempstr[i] = header1[i + 96]; datypind = atoi(tempstr); for (i=0; i<8; ++i) spec[i] = header1[i + 104]; spec[8] = '\0'; for (i=0; i<8; ++i) tempstr[i] = header1[i + 120]; imlperrec = atoi(tempstr); /* Internal header data ... */ for (i=0; i<64; ++i) intdesc[i] = header1[i + 128]; intdesc[64] = '\0'; for (i=0; i<8; ++i) tempstr[i] = header1[i + 264]; introws= atoi(tempstr); for (i=0; i<8; ++i) tempstr[i] = header1[i + 272]; intcols = atoi(tempstr); for (i=0; i<8; ++i) tempstr[i] = header1[i + 280]; intbits = atoi(tempstr); for (i=0; i<8; ++i) tempstr[i] = header1[i + 288]; intacc = atoi(tempstr); if (intacc == 1) intaccstr = "col-by-col"; else if (intacc ==0) intaccstr = "row-by-row"; else intaccstr = "????"; for (i=0; i<8; ++i) tempstr[i] = header1[i + 296]; intperbundle = atoi(tempstr); /* Get intseqstr to read off image sequence ... */ firstflg = 1; intseqstr[0] = '\0'; for (i=0; i<8; ++i) switch (header1[i + 304]) { case '-': /* special case that only seems to appear for downlook data */ downlook = 1; /* ... set a flag to be checked in the printing section */ case ' ': break; case '1': if(!firstflg) strcat(intseqstr, ", "); strcat(intseqstr, "video"); firstflg = 0; break; case '2': if(!firstflg) strcat(intseqstr, ", "); strcat(intseqstr, "range intensity"); firstflg = 0; break; case '3': if(!firstflg) strcat(intseqstr, ", "); strcat(intseqstr, "range"); firstflg = 0; break; case '4': if(!firstflg) strcat(intseqstr, ", "); strcat(intseqstr, "doppler intensity"); firstflg = 0; break; case '5': if(!firstflg) strcat(intseqstr, ", "); strcat(intseqstr, "doppler"); firstflg = 0; break; case '6': if(!firstflg) strcat(intseqstr, ", "); strcat(intseqstr, "passive intensity"); firstflg = 0; break; case '7': if(!firstflg) strcat(intseqstr, ", "); strcat(intseqstr, "synthetic"); firstflg = 0; break; case '8': if(!firstflg) strcat(intseqstr, ", "); strcat(intseqstr, "16-bit range intensity"); firstflg = 0; break; case '9': if(!firstflg) strcat(intseqstr, ", "); strcat(intseqstr, "16-bit range"); firstflg = 0; break; default: if(!firstflg) strcat(intseqstr, ", "); strcat(intseqstr, "UNRECOGNIZED"); firstflg = 0; } for (i=0; i<8; ++i) tempstr[i] = header1[i + 320]; temp = atoi(tempstr); intday = temp / 100; intyear = temp % 100; for (i=0; i<8; ++i) tempstr[i] = header1[i + 328]; intheader2bytes = atoi(tempstr); for (i=0; i<8; ++i) tempstr[i] = header1[i + 336]; intrnggate = atoi(tempstr); for (i=0; i<8; ++i) tempstr[i] = header1[i + 344]; intrngoff = atoi(tempstr); for (i=0; i<8; ++i) tempstr[i] = header1[i + 352]; inthorfov = atoi(tempstr); for (i=0; i<8; ++i) tempstr[i] = header1[i + 360]; intverfov = atoi(tempstr); for (i=0; i<2; ++i) tempstr[i] = header1[i + 368]; tempstr[2] = '\0'; inthr = atoi(tempstr); for (i=0; i<2; ++i) tempstr[i] = header1[i + 371]; tempstr[2] = '\0'; intmin = atoi(tempstr); for (i=0; i<2; ++i) tempstr[i] = header1[i + 374]; tempstr[2] = '\0'; intsec = atoi(tempstr); for (i=0; i<8; ++i) tempstr[i] = header1[i + 376]; intrngquant = atoi(tempstr); fprintf(stdout, "Date Recorded: %02d %s %02d\n", rday, txtmonth, ryear); fprintf(stdout, "Image type: %s\n", itypestr); fprintf(stdout, "Image record length: %d records\n", imlength); fprintf(stdout, "Length of header2: %d bytes\n", header2bytes ); fprintf(stdout, "Channels per sample: %d\n", channels); fprintf(stdout, "No. of columns: %d\n", h1cols); fprintf(stdout, "No. of rows: %d\n", h1rows); fprintf(stdout, "Data type indicator: %d\n", datypind); fprintf(stdout, "Special data format: %s\n", spec); fprintf(stdout, "Image lines per record: %d\n", imlperrec); fprintf(stdout, "\nData from Internal Header (may be missing):\n\n"); fprintf(stdout, "Description of image data: %s\n", intdesc); fprintf(stdout, "No. of rows: %d\n", introws); fprintf(stdout, "No. of columns: %d\n", intcols); fprintf(stdout, "Bits per pixel: %d\n", intbits); fprintf(stdout, "Image access: %s\n", intaccstr); fprintf(stdout, "No. of images per bundle: %d\n", intperbundle); if (downlook) { fprintf(stdout, "Image sequence: "); fprintf(stdout, "Unspecified\n"); } else fprintf(stdout, "Image sequence: %s\n", intseqstr); fprintf(stdout, "Date data collected: Day %d, 19%02d\n", intday, intyear); fprintf(stdout, "Bytes in header2: %d\n", intheader2bytes); fprintf(stdout, "Range gate: %8.3f meters\n", intrnggate/1000.0); fprintf(stdout, "Range gate starting offset: %8.3f meters\n", intrngoff/1000.0); fprintf(stdout, "Horizontal F.O.V. per pixel: %d microrad\n", inthorfov); fprintf(stdout, "Vertical F. O. V. per pixel: %d microrad\n", intverfov); fprintf(stdout, "Time of day: %02d:%02d:%02d\n", inthr, intmin, intsec); fprintf(stdout, "Range quantization: %8.3f meters\n\n\n", intrngquant/1000.0); if (downlook) { fprintf(stdout, "This data appears to be from the downlooking sensor; \n"); fprintf(stdout, "interpret header information with caution, and check with \n"); fprintf(stdout, "the logbook values indicated in the DataCat file index.\n\n"); } if (errflag) { fprintf(stdout, "Some discrepancies were reported in decoding the header.\n"); fprintf(stdout, "Some of the data may be corrupted.\n\n"); } } /************************ FUNCTION DISPIRARHDR() ************************/ #define LOWBYTEMASK 255 #define BIT7 (unsigned int) 128 #define BIT6 (unsigned int) 64 #define BIT5 (unsigned int) 32 #define BIT4 (unsigned int) 16 #define BIT3 (unsigned int) 8 #define BIT2 (unsigned int) 4 #define BIT1 (unsigned int) 2 #define BIT0 (unsigned int) 1 void dispirarhdr (irarhdr, filep) unsigned char *irarhdr; FILE *filep; { unsigned char flyable, fmt, bytes, psven, aint, arng, bvid, psvd; unsigned char aavail, davail, dintd, dveld, pixsmpl, fmover, lfov, lsrt; unsigned char mode, vlock; int flength, prevrecs, sysmod, rngbits, psvbits, rnginc, rnggtoff, rnggate, hr, min, sec, day, year, airspd, baro, refp, head, pitch, roll, zoom; float az, elev; char incunits[5], target[65], location[65], weather[65], miscell[65]; char tempstr[9], *pitchstr, *rollstr; int i, temp, downlook; unsigned int field; long atol(); int atoi(); tempstr[8] = '\0'; downlook = 0; /* Get bit-flagged data ... */ /* First byte field ... */ field = ((unsigned int) irarhdr[0]) & LOWBYTEMASK; flyable = (BIT7 & field) ? 0 : 1; /* reverses the usual sense */ fmt = (BIT6 & field) ? 1 : 0; /* normal sense */ bytes = (BIT5 & field) ? 1 : 0; psven = (BIT4 & field) ? 1 : 0; aint = (BIT3 & field) ? 1 : 0; arng = (BIT2 & field) ? 1 : 0; bvid = (BIT1 & field) ? 1 : 0; psvd = (BIT0 & field) ? 1 : 0; field = ((unsigned int) irarhdr[1]) & LOWBYTEMASK; aavail = (BIT7 & field) ? 1 : 0; /* normal sense */ davail = (BIT6 & field) ? 1 : 0; dintd = (BIT5 & field) ? 1 : 0; dveld = (BIT4 & field) ? 1 : 0; pixsmpl = (BIT3 & field) ? 1 : 0; fmover = (BIT2 & field) ? 1 : 0; lfov = (BIT1 & field) ? 1 : 0; lsrt = (BIT0 & field) ? 1 : 0; field = ((unsigned int) irarhdr[2]) & LOWBYTEMASK; mode = (BIT7 & field) ? 1 : 0; /* normal sense */ vlock = (BIT6 & field) ? 1 : 0; /* Get ASCII data ... */ for (i=0; i<4; ++i) tempstr[i] = irarhdr[i + 3]; tempstr[4] = '\0'; flength = atoi(tempstr); for (i=0; i<5; ++i) tempstr[i] = irarhdr[i + 7]; tempstr[5] = '\0'; prevrecs = atoi(tempstr); for (i=0; i<2; ++i) tempstr[i] = irarhdr[i + 12]; tempstr[2] = '\0'; sysmod = atoi(tempstr); if (sysmod == 9) downlook = 1; for (i=0; i<2; ++i) tempstr[i] = irarhdr[i + 14]; tempstr[2] = '\0'; rngbits = atoi(tempstr); for (i=0; i<2; ++i) tempstr[i] = irarhdr[i + 16]; tempstr[2] = '\0'; psvbits = atoi(tempstr); for (i=0; i<3; ++i) tempstr[i] = irarhdr[i + 18]; tempstr[3] = '\0'; rnginc = atoi(tempstr); for (i=0; i<4; ++i) incunits[i] = irarhdr[i + 21]; incunits[4] = '\0'; for (i=0; i<3; ++i) tempstr[i] = irarhdr[i + 25]; tempstr[3] = '\0'; rnggtoff = atoi(tempstr); for (i=0; i<2; ++i) tempstr[i] = irarhdr[i + 28]; tempstr[2] = '\0'; rnggate = atoi(tempstr); for (i=0; i<6; ++i) tempstr[i] = irarhdr[i + 30]; tempstr[6] = '\0'; temp= atoi(tempstr); hr = temp / 10000; temp = temp % 10000; min = temp / 100; sec = temp % 100; /* ... not finished yet ... */ tempstr[0] = irarhdr[90]; /* append tenths digit to sec */ tempstr[1] = '\0'; sec = sec * 10 + atoi(tempstr); for (i=0; i<5; ++i) tempstr[i] = irarhdr[i + 36]; tempstr[5] = '\0'; temp = atoi(tempstr); day = temp / 100; year = temp % 100; for (i=0; i<5; ++i) tempstr[i] = irarhdr[i + 46]; tempstr[5] = '\0'; temp = atoi(tempstr); az = 360.0 * ((float) temp) / (1024.0 * 64.0); for (i=0; i<5; ++i) tempstr[i] = irarhdr[i + 51]; tempstr[5] = '\0'; temp = atoi(tempstr); elev = 360.0 * ((float) temp) / (1024.0 * 64.0); for (i=0; i<3; ++i) tempstr[i] = irarhdr[i + 68]; tempstr[3] = '\0'; airspd = atoi(tempstr); for (i=0; i<5; ++i) tempstr[i] = irarhdr[i + 71]; tempstr[5] = '\0'; baro = atoi(tempstr); for (i=0; i<3; ++i) tempstr[i] = irarhdr[i + 76]; tempstr[3] = '\0'; head = atoi(tempstr); for (i=0; i<5; ++i) tempstr[i] = irarhdr[i + 80]; tempstr[5] = '\0'; pitch = atoi(tempstr); if (pitch >= 0) pitchstr = "(nose up)"; else pitchstr = "(nose down)"; for (i=0; i<5; ++i) tempstr[i] = irarhdr[i + 85]; tempstr[5] = '\0'; roll = atoi(tempstr); if (roll >= 0) rollstr = "(right wing down)"; else rollstr = "(right wing up)"; for (i=0; i<2; ++i) tempstr[i] = irarhdr[i + 91]; tempstr[2] = '\0'; zoom = atoi(tempstr); for (i=0; i<4; ++i) tempstr[i] = irarhdr[i + 95]; tempstr[4] = '\0'; refp = atoi(tempstr); for (i=0; i<64; ++i) target[i] = irarhdr[i + 256]; target[64] = '\0'; for (i=0; i<64; ++i) location[i] = irarhdr[i + 320]; location[64] = '\0'; for (i=0; i<64; ++i) weather[i] = irarhdr[i + 384]; weather[64] = '\0'; for (i=0; i<64; ++i) miscell[i] = irarhdr[i + 448]; miscell[64] = '\0'; fprintf(stdout, "Bit-Flagged Header Info: \n\n"); if (!flyable) fprintf(stdout, "WARNING: No Flyable System Indicator!\n"); else fprintf(stdout, "Flyable System\n"); fprintf(stdout, "%s\n", (fmt) ? "124 x 128" : "64 x 128"); fprintf(stdout, "%s\n", (bytes) ? "2 bytes/pixel" : "1 byte/pixel"); fprintf(stdout, "Passive channel %s\n", psven ? "enabled" : "disabled"); fprintf(stdout, "Pulse intensity data %s present\n", aint ? "" : "not"); fprintf(stdout, "Pulse range data %s present\n", arng ? "" : "not"); fprintf(stdout, "Boresight video data %s present\n", bvid ? "" : "not"); fprintf(stdout, "Passive data %s present\n", psvd ? "" : "not"); fprintf(stdout, "Pulse data %s available\n", aavail ? "not" : ""); fprintf(stdout, "Doppler data %s available\n", davail ? "" : "not"); fprintf(stdout, "Doppler intensity data %s present\n", dintd ? "" : "not"); fprintf(stdout, "Doppler velocity data %s present\n", dveld ? "" : "not"); fprintf(stdout, "Linescan-mode pixel-sample interval %d microrad\n", pixsmpl ? 100 : 50); if (fmover) fprintf(stdout, "Frame mode oversampled\n"); fprintf(stdout, "Linescan field-of-view %s\n", lfov ? "20 degrees" : "10 degrees"); fprintf(stdout, "Linescan scan rate %s\n", lsrt ? "2.5 Hz" : "5 Hz"); fprintf(stdout, "%s mode\n", mode ? "Frame" : "Linescan"); if (vlock) fprintf(stdout, "V-lock on--no vertical scan\n"); fprintf(stdout, "\n\nASCII Header Info: \n\n"); fprintf(stdout, "File No.: %d\n", flength); fprintf(stdout, "Records written in previous file: %d\n", prevrecs); fprintf(stdout, "System version number: %d\n", sysmod); fprintf(stdout, "Data bits in range word: %d\n", rngbits); fprintf(stdout, "Data bits in passive word: %d\n", psvbits); fprintf(stdout, "Range quantization: %04.1f %s\n", rnginc / 10.0, incunits); fprintf(stdout, "Range gate start offset: %d feet\n", rnggtoff * 100); fprintf(stdout, "Range gate width: %d feet\n", rnggate * 100); fprintf(stdout, "Time of day: %02d:%02d:%04.1f\n", hr, min, sec/10.0); fprintf(stdout, "Date data collected: Day %d, 19%02d\n", day, year); fprintf(stdout, "Pointing azimuth: %07.3f degrees\n", az); fprintf(stdout, "Pointing elevation: %07.3f degrees\n", elev); fprintf(stdout, "Indicated airspeed: %d Knots\n", airspd); fprintf(stdout, "Barometric pressure: %6.3f inches Hg\n", baro / 1000.0); fprintf(stdout, "Reference pressure: %5.2f inches Hg\n", refp / 100.0); fprintf(stdout, "Indicated aircraft heading: %03d degrees\n", head); fprintf(stdout, "Aircraft pitch: "); fprintf(stdout, "%05.2f degrees %s\n", pitch * 360.0/65536.0, pitchstr); fprintf(stdout, "Aircraft roll: "); fprintf(stdout, "%05.2f degrees %s\n", roll * 360.0/65536.0, rollstr); fprintf(stdout, "Zoom: %d%%\n", zoom); fprintf(stdout, "Target:\n %s\n\n", target); fprintf(stdout, "Location:\n %s\n\n", location); fprintf(stdout, "Weather:\n %s\n\n", weather); fprintf(stdout, "Miscellaneous Comments:\n %s\n\n", miscell); if (downlook) { fprintf(stdout, "WARNING: The system version number corresponds to the \n"); fprintf(stdout, "downlooking system. Some header information may be incorrect; \n"); fprintf(stdout, "check logbook values indicated in the DataCat file index.\n\n"); } }