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

  1. /*
  2.  * fbm.c:
  3.  *
  4.  * adapted from code by Michael Mauldin, (mlm) at Carnegie-Mellon
  5.  * University, (fbm tools) and Kirk L. Johnson, (tuna@athena.mit.edu),
  6.  * (gif.c).
  7.  *
  8.  * fbmin.c
  9.  * Mark Majhor
  10.  * August 1990
  11.  *
  12.  * routines for reading FBM files
  13.  *
  14.  * Copyright 1990 Mark Majhor (see the included file
  15.  * "mrmcpyrght.h" for complete copyright information)
  16.  */
  17. # include <stdio.h>
  18. # include <math.h>
  19. # include <ctype.h>
  20. # include "image.h"
  21. # include "fbm.h"
  22.  
  23. /****
  24.  **
  25.  ** local variables
  26.  **
  27.  ****/
  28.  
  29. static BYTE file_open = 0;    /* status flags */
  30. static BYTE image_open = 0;
  31.  
  32. static ZFILE *ins;        /* input stream */
  33. static FBMFILEHDR phdr;        /* header structure */
  34.  
  35. /****
  36.  **
  37.  ** global variables
  38.  **
  39.  ****/
  40.  
  41. static int  fbmin_img_width;           /* image width */
  42. static int  fbmin_img_height;          /* image height */
  43. static int  fbmin_img_depth;           /* image depth */
  44. static int  fbmin_img_bits;           /* color bits */
  45. static int  fbmin_img_rowlen;           /* length of one row of data */
  46. static int  fbmin_img_plnlen;           /* length of one plane of data */
  47. static int  fbmin_img_clrlen;           /* length of the colormap */
  48. static int  fbmin_img_aspect;           /* image aspect ratio */
  49. static int  fbmin_img_physbits;           /* physical bits per pixel */
  50. static char *fbmin_img_title;        /* name of image */
  51. static char *fbmin_img_credit;        /* credit for image */
  52.  
  53. static fbmin_image_test()
  54. {
  55.   if (fbmin_img_width < 1 || fbmin_img_width > 32767) {
  56.     fprintf (stderr, "Invalid width (%d) on input\n", fbmin_img_width);
  57.     return FBMIN_ERR_BAD_SD;
  58.   }
  59.  
  60.   if (fbmin_img_height < 1 || fbmin_img_height > 32767) {
  61.     fprintf (stderr, "Invalid height (%d) on input\n", fbmin_img_height);
  62.     return (0);
  63.   }
  64.  
  65.   if (fbmin_img_depth != 1 && fbmin_img_depth != 3) {
  66.     fprintf (stderr, "Invalid number of planes (%d) on input %s\n",
  67.          fbmin_img_depth, "(must be 1 or 3)");
  68.     return FBMIN_ERR_BAD_SD;
  69.   }
  70.  
  71.   if (fbmin_img_bits < 1 || fbmin_img_bits > 8) {
  72.     fprintf (stderr, "Invalid number of bits (%d) on input %s\n",
  73.          fbmin_img_bits, "(must be [1..8])");
  74.     return FBMIN_ERR_BAD_SD;
  75.   }
  76.  
  77.   if (fbmin_img_physbits != 1 && fbmin_img_physbits != 8) {
  78.     fprintf (stderr, "Invalid number of physbits (%d) on input %s\n",
  79.          fbmin_img_physbits, "(must be 1 or 8)");
  80.     return FBMIN_ERR_BAD_SD;
  81.   }
  82.  
  83.   if (fbmin_img_rowlen < 1 || fbmin_img_rowlen > 32767) {
  84.     fprintf (stderr, "Invalid row length (%d) on input\n",
  85.          fbmin_img_rowlen);
  86.     return FBMIN_ERR_BAD_SD;
  87.   }
  88.  
  89.   if (fbmin_img_depth > 1 && fbmin_img_plnlen < 1) {
  90.     fprintf (stderr, "Invalid plane length (%d) on input\n",
  91.          fbmin_img_plnlen);
  92.     return FBMIN_ERR_BAD_SD;
  93.   }
  94.  
  95.   if (fbmin_img_aspect < 0.01 || fbmin_img_aspect > 100.0) {
  96.     fprintf (stderr, "Invalid aspect ratio %lg on input\n",
  97.          fbmin_img_aspect);
  98.     return FBMIN_ERR_BAD_SD;
  99.   }
  100.     return FBMIN_SUCCESS;
  101. }
  102.  
  103. /*
  104.  * open FBM image in the input stream; returns FBMIN_SUCCESS if
  105.  * successful. (might also return various FBMIN_ERR codes.)
  106.  */
  107. static int fbmin_open_image(s)
  108. ZFILE *s;
  109. {
  110.   char *hp;        /* header pointer */
  111.  
  112.   /* make sure there isn't already a file open */
  113.   if (file_open)
  114.     return(FBMIN_ERR_FAO);
  115.  
  116.   /* remember that we've got this file open */
  117.   file_open = 1;
  118.   ins = s;
  119.  
  120.   /* read in the fbm file header */
  121.   hp = (char *) &phdr;
  122.   if (zread(ins, (byte *)hp, sizeof(phdr)) != sizeof(phdr))
  123.     return FBMIN_ERR_EOF;
  124.  
  125.   if (strncmp(FBM_MAGIC, phdr.magic, sizeof(FBM_MAGIC)) != 0)
  126.     return FBMIN_ERR_BAD_SIG;
  127.  
  128.   /* Now extract relevant features of FBM file header */
  129.   fbmin_img_width    = atoi(phdr.cols);
  130.   fbmin_img_height   = atoi(phdr.rows);
  131.   fbmin_img_depth    = atoi(phdr.planes);
  132.   fbmin_img_bits     = atoi(phdr.bits);
  133.   fbmin_img_rowlen   = atoi(phdr.rowlen);
  134.   fbmin_img_plnlen   = atoi(phdr.plnlen);
  135.   fbmin_img_clrlen   = atoi(phdr.clrlen);
  136.   fbmin_img_aspect   = atoi(phdr.aspect);
  137.   fbmin_img_physbits = atoi(phdr.physbits);
  138.   fbmin_img_title    = phdr.title;
  139.   fbmin_img_credit   = phdr.credits;
  140.  
  141.   if (fbmin_image_test() != FBMIN_SUCCESS)
  142.     return FBMIN_ERR_BAD_SD;
  143.  
  144.   return FBMIN_SUCCESS;
  145. }
  146.  
  147. /*
  148.  * close an open FBM file
  149.  */
  150.  
  151. static int fbmin_close_file()
  152. {
  153.   /* make sure there's a file open */
  154.   if (!file_open)
  155.     return FBMIN_ERR_NFO;
  156.  
  157.   /* mark file (and image) as closed */
  158.   file_open  = 0;
  159.   image_open = 0;
  160.  
  161.   /* done! */
  162.   return FBMIN_SUCCESS;
  163. }
  164.     
  165. #if 0
  166. /*
  167.  * semi-graceful fatal error mechanism
  168.  */
  169.  
  170. static fbmin_fatal(msg)
  171.      char *msg;
  172. {
  173.   printf("Error reading FBM file: %s\n", msg);
  174.   exit(0);
  175. }
  176. #endif
  177.  
  178. /*
  179.  * these are the routines added for interfacing to xloadimage
  180.  */
  181.  
  182. /*
  183.  * tell someone what the image we're loading is.  this could be a little more
  184.  * descriptive but I don't care
  185.  */
  186.  
  187. static void tellAboutImage(name)
  188.      char *name;
  189. {
  190.   if (fbmin_img_clrlen > 0) 
  191.     printf("%s is a %dx%d FBM image with %d colors\n", name,
  192.       fbmin_img_width, fbmin_img_height, fbmin_img_clrlen / 3);
  193.   else
  194.     printf("%s is a %dx%d FBM image with %d greyscale planes\n",
  195.       name, fbmin_img_width, fbmin_img_height, fbmin_img_bits);
  196. }
  197.  
  198. Image *fbmLoad(fullname, name, verbose)
  199.      char         *fullname, *name;
  200.      unsigned int  verbose;
  201.   ZFILE *zf;
  202.   Image *image;
  203.   register int    x, y, j, k, rowlen, plnlen;
  204.   unsigned char *pixptr, *cm;
  205.   unsigned int map_size;
  206.   extern int Scrn;
  207.   unsigned char *r, *g, *b;
  208.  
  209.   if (! (zf= zopen(fullname)))
  210.     return(NULL);
  211.   if (fbmin_open_image(zf) != FBMIN_SUCCESS) {  /* read image header */
  212.     fbmin_close_file();
  213.     zclose(zf);
  214.     return(NULL);
  215.   }
  216.   if (verbose)
  217.     tellAboutImage(name);
  218.   znocache(zf);
  219.  
  220.   image = newRGBImage(fbmin_img_width, fbmin_img_height, fbmin_img_bits);
  221.  
  222.   /* if image has a local colormap, override global colormap
  223.    */
  224.   if (fbmin_img_clrlen > 0) {
  225.     cm = (unsigned char *) lmalloc(fbmin_img_clrlen);
  226.  
  227.     if (zread(ins, cm, fbmin_img_clrlen) != fbmin_img_clrlen) {
  228.       fprintf (stderr, "can't read colormap (%d bytes)\n", fbmin_img_clrlen);
  229.       return(NULL);
  230.     }
  231.     /*
  232.      * fbm color map is organized as
  233.      * buf[3][16]
  234.      */
  235.     y = fbmin_img_clrlen / 3;
  236.     r = &cm[0], g = &cm[y], b = &cm[2 * y];
  237.     for (x = 0; x < y; x++, r++, g++, b++) {
  238.       image->rgb.red[x]   = *r << 8;
  239.       image->rgb.green[x] = *g << 8;
  240.       image->rgb.blue[x]  = *b << 8;
  241.     }
  242.     image->rgb.used = y;
  243.  
  244.   } else if (fbmin_img_bits > 0) {
  245.     map_size = 3 * (int) pow(2.0, (double) fbmin_img_bits);
  246.     cm = (unsigned char *) lmalloc(map_size);
  247.  
  248.     y = map_size / 3;
  249.     for (x = 0; x < y; x++) {
  250.       cm[x] = cm[y+x] = cm[2*y+x] = x;
  251.     }
  252.  
  253.     r = &cm[0], g = &cm[y], b = &cm[2 * y];
  254.     for (x = 0; x < y; x++, r++, g++, b++) {
  255.       image->rgb.red[x]   = *r << 8;
  256.       image->rgb.green[x] = *g << 8;
  257.       image->rgb.blue[x]  = *b << 8;
  258.     }
  259.     image->rgb.used = y;
  260.   } else 
  261.     cm = NULL;
  262.  
  263.   rowlen = fbmin_img_rowlen;
  264.   plnlen = fbmin_img_plnlen;
  265.  
  266.   for (k = 0; k < fbmin_img_depth; k++) {
  267.     pixptr = &(image->data[k * plnlen]);
  268.  
  269.     for (j = 0; j < fbmin_img_height; j++, pixptr += rowlen) {
  270.       if (zread(ins, pixptr, rowlen) != rowlen) {
  271.     printf("%s: Short read within image data\n", fullname);
  272.         exit(1);
  273.       }
  274.     }
  275.   }
  276.  
  277.   if (cm != NULL)
  278.     lfree(cm);
  279.  
  280.   fbmin_close_file();
  281.   zclose(zf);
  282.  
  283.   if (strlen(fbmin_img_title) != 0)
  284.     image->title= dupString(fbmin_img_title);
  285.   else
  286.     image->title= dupString(name);
  287.  
  288.   return(image);
  289. }
  290.  
  291. int fbmIdent(fullname, name)
  292. char *fullname, *name;
  293. {
  294.   ZFILE        *zf;
  295.   unsigned int  ret;
  296.  
  297.   if (! (zf= zopen(fullname)))
  298.     return(0);
  299.   if (fbmin_open_image(zf) == FBMIN_SUCCESS) {
  300.     tellAboutImage(name);
  301.     ret = 1;
  302.   } else
  303.     ret = 0;
  304.   fbmin_close_file();
  305.   zclose(zf);
  306.   return(ret);
  307. }
  308.