home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 11 Util / 11-Util.zip / xloadimg.zip / xloadimage.4.1 / vff.c < prev    next >
C/C++ Source or Header  |  1993-10-27  |  10KB  |  400 lines

  1. /* vff.c
  2.  * Sun Visualization File Format images
  3.  *
  4.  * -ksp  8 June 91
  5.  */
  6.  
  7. /*
  8.  * Copyright (c) 1991 Southwest Research Institute
  9.  * All rights reserved.
  10.  *
  11.  * Permission to use, copy, modify, distribute, and sell this software
  12.  * and its documentation for any purpose is hereby granted without fee,
  13.  * provided that the above copyright notice appears in all copies and
  14.  * that both that copyright notice and this permission notice appear
  15.  * in supporting documentation.  The name of Southwest Research
  16.  * Institute may not be used to endorse or promote products derived
  17.  * from this software without specific prior written permission.  The
  18.  * author makes no representations about the suitability of this
  19.  * software for any purpose.  It is provided "as is" without express
  20.  * or implied warranty.
  21.  *
  22.  * THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  23.  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
  24.  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  25.  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
  26.  * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  27.  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
  28.  * USE OR PERFORMANCE OF THIS SOFTWARE.
  29.  */
  30.  
  31.  
  32. #include "image.h"
  33.  
  34. #define HEAD_BUF_SIZE    2048
  35. #define MAX_HEAD_LINES    100
  36.  
  37. static char *header[MAX_HEAD_LINES];
  38. static int width, height, bands, cmsize;
  39. static unsigned char rm[256], gm[256], bm[256];
  40.  
  41. static int readHeader();
  42. static int parseHeader();
  43. static int readImage();
  44. static void freeheader();
  45.  
  46.  
  47. Image *
  48. vffLoad(fullname, name, verbose)
  49. char *fullname, *name;
  50. unsigned int verbose;
  51. {
  52.  
  53.      ZFILE *zf;
  54.      char buf[4];
  55.      Image *image = NULL;
  56.  
  57.      if (!(zf = zopen(fullname)))
  58.       return(NULL);
  59.  
  60.      if (zread(zf, (unsigned char *)buf, 4) != 4) {
  61.       zclose(zf);
  62.       return(NULL);
  63.      }
  64.  
  65.      if (strncmp(buf, "ncaa", 4) != 0) {
  66.       zclose(zf);
  67.       return(NULL);
  68.      }
  69.  
  70.      if (readHeader(zf)) {
  71.       zclose(zf);
  72.       return(NULL);
  73.      }
  74.  
  75.      if (parseHeader()) {
  76.       zclose(zf);
  77.       return(NULL);
  78.      }
  79.  
  80.      if (bands == 1) {
  81.       image = newRGBImage(width, height, 8);
  82.      } else if (bands == 2) {
  83.       printf("Only Sun VFF files with one or three+ bands are supported.\n");
  84.       zclose(zf);
  85.       return(NULL);
  86.      } else if (bands >= 3) {
  87.       image = newTrueImage(width, height);
  88.      }
  89.  
  90.      image->title = dupString(name);
  91.      
  92.      if (verbose) {
  93.       if (bands == 1) {
  94.            printf("%s is a %dx%d Sun VFF image with 1 band\n", name, width, height);
  95.       } else {
  96.            printf("%s is a %dx%d Sun VFF image with %d bands\n", name, width, height, bands);
  97.       }
  98.      }
  99.  
  100.      if (readImage(zf, image)) {
  101.       freeImage(image);
  102.       zclose(zf);
  103.       return(NULL);
  104.      }
  105.      zclose(zf);
  106.      
  107.      return(image);
  108. }
  109.  
  110. static int
  111. readImage(zf, image)
  112. ZFILE *zf;
  113. Image *image;
  114. {
  115.      byte *buf;
  116.      byte *op, *ip;
  117.      int x, y, skip, linewidth, i;
  118.      void memoryExhausted();
  119.  
  120.      if (bands == 1) {
  121.       if (cmsize == 0) {
  122.            /* build a grey ramp */
  123.            for (i = 0; i < 256; i++) {
  124.             *(image->rgb.red + i) = i * 256;
  125.             *(image->rgb.green + i) = i * 256;
  126.             *(image->rgb.blue + i) = i * 256;
  127.            }
  128.            image->rgb.used = 256;
  129.       } else {
  130.            if (cmsize > 256) {
  131.             cmsize = 256;
  132.            }
  133.            for (i = 0; i < cmsize; i++) {
  134.             *(image->rgb.red + i) = rm[i] * 256;
  135.             *(image->rgb.green + i) = gm[i] * 256;
  136.             *(image->rgb.blue + i) = bm[i] * 256;
  137.            }
  138.            image->rgb.used = cmsize;
  139.       }
  140.       op = image->data;
  141.       for (y = 0; y < height; y++) {
  142.            if (zread(zf, op, width) != width) {
  143.             printf("%s: short read line %d\n", image->title, y);
  144.             return(0); /* show what we got */
  145.            }
  146.            op += width;
  147.       }
  148.      } else {
  149.       op = image->data;
  150.       skip = bands - 3;
  151.       linewidth = bands * width;
  152.       buf = (unsigned char *)malloc((unsigned)linewidth);
  153.       if (buf == NULL) {
  154.            memoryExhausted();    
  155.       }
  156.       for (y = 0; y < height; y++) {
  157.            ip = buf;
  158.            if (zread(zf, buf, linewidth) != linewidth) {
  159.             printf("%s: short read line %d\n", image->title, y);
  160.             return(0); /* show what we got */
  161.            }
  162.            for (x = 0; x < width; x++) {
  163.             ip += skip;
  164.             *(op++) = *(ip+2);
  165.             *(op++) = *(ip+1);
  166.             *(op++) = *(ip);
  167.             ip += 3;
  168.            }
  169.       }
  170.       free(buf);
  171.      }
  172.      
  173.      return(0);
  174. }
  175.  
  176. static int
  177. parseHeader()
  178. {
  179.      int bits;
  180.      int line;
  181.  
  182.      /* KISS ? */
  183.  
  184.      for (line = 0; ((line < MAX_HEAD_LINES) && (header[line] != NULL)); line++) {
  185.       if (strncmp(header[line], "type", 4) == 0) {
  186.            if (strncmp(header[line], "type raster", 11) != 0) {
  187.             printf("Only Sun VFF files of type `raster' are supported.\n");
  188.             freeheader();
  189.             return(1);
  190.            }
  191.       }
  192.       if (strncmp(header[line], "bands", 5) == 0) {
  193.            sscanf(header[line], "bands %d", &bands);
  194.       }
  195.       if (strncmp(header[line], "bits", 4) == 0) {
  196.            sscanf(header[line], "bits %d", &bits); /* only check one band */
  197.            if (bits != 8) {
  198.             printf("Only Sun VFF files with 8-bit bands are supported.\n");
  199.             freeheader();
  200.             return(1);    
  201.            }
  202.       }
  203.       if (strncmp(header[line],"components", 10) == 0) {
  204.            printf("Only Sun VFF files of type `raster' are supported.\n");
  205.            freeheader();
  206.            return(1);
  207.       }
  208.       if ((strncmp(header[line], "colormap", 8) == 0) &&
  209.           (strncmp(header[line], "colormapsize", 12) != 0)) {
  210.           {
  211.            char *cp;
  212.            int i, r, g, b;
  213.  
  214.            /* ship colormap */
  215.            cp = header[line]+8;
  216.            /* find the first entry */
  217.            while (*cp && !isxdigit(*cp)) {
  218.             cp++;
  219.            }
  220.            for (i = 0; i < 256; i++) {
  221.             if (sscanf(cp, "%02x%02x%02x", &b, &g, &r) != 3)
  222.                  break;
  223.             bm[i] = b;
  224.             gm[i] = g;
  225.             rm[i] = r;
  226.             cp += 6;
  227.             while (*cp && !isxdigit(*cp)) {
  228.                  cp++;
  229.             }
  230.            }
  231.            cmsize = i;
  232.           }
  233.  
  234.       }
  235.       if (strncmp(header[line], "size", 4) == 0) {
  236.            sscanf(header[line], "size %d %d", &width, &height);
  237.       }
  238.      }
  239.      freeheader();
  240.      return(0);
  241. }
  242.  
  243. static void
  244. freeheader()
  245. {
  246.      int line;
  247.  
  248.      for (line = 0; ((line < MAX_HEAD_LINES) && (header[line] != NULL)); line++) {
  249.       free(header[line]);
  250.     }
  251. }
  252.  
  253. static int
  254. readHeader(zf)
  255. ZFILE *zf;
  256. {
  257.      char buf[HEAD_BUF_SIZE];
  258.      int count, c, lines;
  259.      char *cp;
  260.      
  261.      cp = buf;
  262.      count = 0;
  263.      lines = 0;
  264.  
  265.      while (lines < MAX_HEAD_LINES) {
  266.       while ((((c = zgetc(zf)) != '\f')) && (c != EOF) && (c != '=')) {
  267.            switch(c) {
  268.            case '\n':
  269.            case ' ':
  270.            case '\t':
  271.            case '\r':
  272.             continue;
  273.            
  274.            case ';':
  275.             printf("Malformed Sun VFF header line: a `;' was found before a `='.\n" );
  276.             return(1);
  277.             default:
  278.             if (count < HEAD_BUF_SIZE) {
  279.              *cp = (char)c;
  280.              cp++;
  281.              count++;
  282.             } else {
  283.              printf("Malformed Sun VFF header line: a line longer then %d bytes was found.\n", HEAD_BUF_SIZE);
  284.              return(0); /* go ahead and try to parse what we got (geometry file?) */
  285.             }
  286.             break;     
  287.            }
  288.       }
  289.  
  290.  
  291.       if (c == '=') {
  292.            if (count < HEAD_BUF_SIZE) {
  293.             *cp = ' ';
  294.             cp++;
  295.             count++;
  296.            } else {
  297.             printf("Malformed Sun VFF header line: a line longer then %d bytes was found.\n", HEAD_BUF_SIZE);
  298.             return(0);
  299.            
  300.            }
  301.     
  302.            while ((c = zgetc(zf)) != ';') {
  303.             switch(c) {
  304.             case EOF:
  305.              printf("Malformed Sun VFF header line: a `EOF' was found before a `;'.\n" );
  306.              return(1);
  307.             case '\f':
  308.              printf("Malformed Sun VFF header line: a `\f' was found before a `;'.\n" );
  309.              return(1);
  310.             case '\n':
  311.              printf("Malformed Sun VFF header line: a `\\n' was found before a `;'.\n" );
  312.              return(1);
  313.             case '\\':
  314.              if ((c = zgetc(zf)) == EOF) {
  315.                   printf("Malformed Sun VFF header line: a `EOF' was found after a `\\'.\n" );
  316.                   return(1);
  317.              }
  318.              default:
  319.              if (count < HEAD_BUF_SIZE) {
  320.                   *cp = (char)c;
  321.                   cp++;
  322.                   count++;
  323.              } else {
  324.                   printf("Malformed Sun VFF header line: a line longer then %d bytes was found.\n", HEAD_BUF_SIZE);
  325.                   return(0);
  326.              }
  327.  
  328.             }
  329.            }
  330.            if (count < HEAD_BUF_SIZE) {
  331.             *cp = '\0';
  332.             cp++;
  333.             count++;
  334.            } else {
  335.             printf("Malformed Sun VFF header line: a line longer then %d bytes was found.\n", HEAD_BUF_SIZE-1);
  336.             return(0);
  337.            }
  338.  
  339.            if ((header[lines] = (char *)malloc((unsigned)count+1)) == NULL) {
  340.             memoryExhausted();    
  341.            }
  342.            bcopy(buf, header[lines], count);
  343.            count = 0;
  344.            cp = buf;
  345.            lines++;
  346.       } else if (c == EOF) {
  347.            printf("Malformed Sun VFF header line: EOF found before the end of the header.\n");
  348.            return(1);  
  349.       } else if (c == '\f') {
  350.            /* read the \n after the \f */
  351.            c = zgetc(zf);
  352.            if (c == EOF) {
  353.             printf("Malformed Sun VFF header line: EOF found before the end of the header.\n");
  354.             return(1);
  355.            }
  356.            return(0);
  357.       }
  358.      }
  359.      printf("Malformed Sun VFF header: more then %d lines found.\n", MAX_HEAD_LINES);
  360.      return(0); /* so that we try and see what was wrong */
  361. }
  362.  
  363. vffIdent(fullname, name)
  364. char *fullname, *name;
  365. {
  366.  
  367.      ZFILE *zf;
  368.      char buf[4];
  369.  
  370.      if (!(zf = zopen(fullname)))
  371.       return(0);
  372.  
  373.      if (zread(zf, (unsigned char *)buf, 4) != 4) {
  374.       zclose(zf);
  375.       return(0);
  376.      }
  377.  
  378.      if (strncmp(buf, "ncaa", 4) != 0) {
  379.       zclose(zf);
  380.       return(0);
  381.      }
  382.  
  383.      if (readHeader(zf)) {
  384.       zclose(zf);
  385.       return(0);
  386.      }
  387.  
  388.      if (parseHeader()) {
  389.       zclose(zf);
  390.       return(0);
  391.      }
  392.  
  393.      if (bands == 1) {
  394.       printf("%s is a %dx%d Sun VFF image with 1 band\n", name, width, height);
  395.      } else {
  396.       printf("%s is a %dx%d Sun VFF image with %d bands\n", name, width, height, bands);
  397.      }
  398.      return(1);
  399. }
  400.