home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / saoimage / sao1_07.tar / imgcheck.c < prev    next >
C/C++ Source or Header  |  1990-05-02  |  6KB  |  210 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    imgcheck.c (Image Check)
  6.  * Purpose:    Check parameters for consistency and check image file size
  7.  * Subroutine:    check_image()            returns: int
  8.  * Xlib calls:    none
  9.  * Unix calls:    stat()
  10.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  11.  *        You may do anything you like with this file except remove
  12.  *        this copyright.  The Smithsonian Astrophysical Observatory
  13.  *        makes no representations about the suitability of this
  14.  *        software for any purpose.  It is provided "as is" without
  15.  *        express or implied warranty.
  16.  * Modified:    {0} Eric Mandel, M VanHilst initial version    9 January 1989
  17.  *        {n} <who> -- <does what> -- <when>
  18.  */
  19.  
  20. #include <stdio.h>            /* stderr, NULL, etc. */
  21. #include <math.h>            /* define sqrt */
  22. #include <sys/types.h>
  23. #include <sys/stat.h>            /* define stat */
  24. #include "hfiles/constant.h"        /* define codes */
  25. #include "hfiles/image.h"
  26. #include "hfiles/cmdparse.h"        /* define parse status bits */
  27.  
  28. /*
  29.  * Subroutine:    check_image
  30.  * Purpose:    Do some consistency checks on image type and size
  31.  * Returns:    0 if no errors found, else -1
  32.  */
  33. int check_image ( img, got_status )
  34.      struct imageRec *img;
  35.      int got_status;
  36. {
  37.   int len;
  38.   static int check_array();
  39.  
  40.   /* if no image type given, check name suffix or assume an array */
  41.   if( (got_status & CMD_FTYPE) == 0 ) {
  42.     if( img->filename != NULL ) {
  43.       len = strlen(img->filename);
  44.       if( strcmp(&img->filename[len - 5], ".fits") == 0 ) {
  45.     img->file_type = SOP_FITS;
  46. #ifdef OIF
  47.       } else if( strcmp(&img->filename[len - 4], ".imh") == 0 ) {
  48.     img->file_type = SOP_IRAF;
  49. #endif
  50.       } else
  51.     img->file_type = SOP_Array;
  52.     } else
  53.       /* if no name, default */
  54.       img->file_type = SOP_Logo;
  55.   }
  56.   /* check for file existence and validity early on */
  57.   if( (img->file_type != SOP_Imtool) &&
  58.       (img->file_type != SOP_PROS) &&
  59.       (img->file_type != SOP_Logo) &&
  60.       (img->filename != NULL) ) {
  61.     struct stat statbuf;
  62.     if( stat(img->filename, &statbuf) <0 ) {
  63.       (void)fprintf(stderr,
  64.             "Error: cannot access image: %s\n", img->filename);
  65.       perror(img->filename);
  66.       return( -1 );
  67.     }
  68.   }
  69.   /* for arrays, we can make some checks and some calculations */
  70.   if( img->file_type == SOP_Array ) {
  71.     if( check_array(img) <0 ) {
  72.       return( -1 );
  73.     }
  74.   }
  75.   /* conflicting zoom factors? */
  76.   if( img->fdblock == 0 ) {
  77.     img->fdblock = img->fiblock;
  78.   } else if( (img->fdblock < img->fiblock) &&
  79.          ((img->fdblock % img->fiblock) != 0) ) {
  80.     (void)fprintf(stderr, "Error: incompatible display and buffer zooms\n");
  81.     return( -1 );
  82.   }
  83.   /* if we are dealing with fits files on a little endian (vax), swap bytes */
  84. #ifdef LSB
  85.   /* Standard FITS images are fixed order (not in native order to VAX) */
  86.   if( img->file_type == SOP_FITS )
  87.     img->byte_swap = !img->byte_swap;
  88. #endif
  89.   return( 0 );
  90. }
  91.  
  92. /*
  93.  * Subroutine:    check_array
  94.  * Purpose:    Check array size vs file size etc
  95.  * Returns:    0 if size determined and/or OK, else -1
  96.  */
  97. static int check_array ( img )
  98.      struct imageRec *img;
  99. {
  100.   long fsize;
  101.   long arrsize;
  102.   float posdim;        /* possible dimension */
  103.   int headersize;    /* size in bytes of header */
  104.   int rawsize;
  105.   static long size_imagefile();
  106.  
  107.   /* get header size */
  108.   headersize = img->headersize;
  109.   /* get file size */
  110.   fsize = size_imagefile(img, headersize, &rawsize);
  111.   /* we might be able to figure out the dimensions for a square */
  112.   if( (img->filerows == 0) || (img->filecols == 0) ) {
  113.     /* if there is an image data type specified, try it */
  114.     if( img->storage_type != ARR_None ){
  115.       posdim = (int)sqrt((double)fsize);
  116.       if( fsize == (posdim * posdim) ){
  117.     img->filecols = (int)posdim;
  118.     img->filerows = (int)posdim;
  119.       } else {
  120.     (void)fprintf(stderr, "File size neither given nor square: %d (%d)\n",
  121.               rawsize, fsize);
  122.     return( -1 );
  123.       }
  124.     } else {
  125.       /* check 2, 4 byte data size */
  126.       /* check for I2 default */
  127.       fsize /= 2;
  128.       posdim = (int)sqrt((double)fsize);
  129.       if( fsize == (posdim * posdim) ){
  130.     img->storage_type = ARR_I2;
  131.       } else {
  132.     /* check for R4 default */
  133.     fsize /=  2;
  134.     posdim = (int)sqrt((double)fsize);
  135.     if( fsize == (posdim * posdim) ){
  136.       img->storage_type = ARR_R4;
  137.     } else {
  138.       (void)fprintf(stderr, "File size not square I2 or R4: %d (%d)\n",
  139.             rawsize, rawsize - headersize);
  140.       return( -1 );
  141.     }
  142.       }
  143.       img->filecols = posdim;
  144.       img->filerows = posdim;
  145.     }
  146.   } else if( img->storage_type == ARR_None ) {
  147.     /* get product of array dimensions in bytes */
  148.     arrsize = img->filecols * img->filerows;
  149.     /* we might find pixel size for a default, if only rows&cols given */
  150.     if( fsize == arrsize ) {
  151.       img->storage_type = ARR_U1;
  152.     } else if( fsize == (arrsize*2) ) {
  153.       img->storage_type = ARR_I2;
  154.     } else if( fsize == (arrsize*4) ) {
  155.       img->storage_type = ARR_R4;
  156.     } else if( fsize == (arrsize*8) ) {
  157.       img->storage_type = ARR_R8;
  158.     } else {
  159.       (void)fprintf(stderr, "File size does not scale to any type: %d (%d)\n",
  160.             rawsize, rawsize - headersize);
  161.       return( -1 );
  162.     }
  163.   } else {
  164.     /* in any case, image must not exceed file */
  165.     arrsize = img->filecols * img->filerows;
  166.     if( arrsize > fsize ) {
  167.       (void)fprintf(stderr, "Request (%d) exceeds file size: %d (%d)\n",
  168.             arrsize, rawsize, fsize);
  169.       return( -1 );
  170.     }
  171.   }
  172.   return( 0 );
  173. }
  174.  
  175. /*
  176.  * Subroutine:    size_imagefile
  177.  * Purpose:    return size of file adjusted for header and storage type
  178.  */
  179. static long size_imagefile ( img, headersize, rawsize )
  180.      struct imageRec *img;
  181.      int headersize;        /* given size of file header area */
  182.      int *rawsize;        /* raw file size in bytes */
  183. {
  184.   struct stat buf;
  185.   int fsize;
  186.  
  187.   /* get the file length in bytes */
  188.   (void)stat(img->filename, &buf);
  189.   *rawsize = buf.st_size;
  190.   /* computed the equivalent array size */
  191.   switch( img->storage_type ) {
  192.   case ARR_R8:
  193.     fsize = (*rawsize - headersize) / sizeof(double);
  194.     break;
  195.   case ARR_I4:
  196.   case ARR_R4:
  197.     fsize = (*rawsize - headersize) / sizeof(float);
  198.     break;
  199.   case ARR_U2:
  200.   case ARR_I2:
  201.     fsize = (*rawsize - headersize) / sizeof(short);
  202.     break;
  203.   case ARR_U1:
  204.   default:
  205.     fsize = *rawsize - headersize;
  206.     break;
  207.   }
  208.   return( fsize );
  209. }
  210.