home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume19 / fbm / part05 / flsun.c < prev    next >
C/C++ Source or Header  |  1989-06-08  |  9KB  |  340 lines

  1. /*****************************************************************
  2.  * flsun.c: FBM Library 0.94 (Beta test) 20-May-89  Michael Mauldin
  3.  *
  4.  * Copyright (C) 1989 by Michael Mauldin.  Permission is granted to
  5.  * use this file in whole or in part provided that you do not sell it
  6.  * for profit and that this copyright notice is retained unchanged.
  7.  *
  8.  * flsun.c: 
  9.  *
  10.  * CONTENTS
  11.  *    read_sun (image, rfile, mstr, mlen)
  12.  *    write_sun (image, wfile)
  13.  *
  14.  * EDITLOG
  15.  *    LastEditDate = Sat May 20 19:08:32 1989 - Michael Mauldin
  16.  *    LastFileName = /usr2/mlm/src/misc/fbm/flsun.c
  17.  *
  18.  * HISTORY
  19.  * 20-May-89  Michael Mauldin (mlm) at Carnegie Mellon University
  20.  *    Fixed problem with odd length rows on reading
  21.  *
  22.  * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
  23.  *    Beta release (version 0.9) mlm@cs.cmu.edu
  24.  *
  25.  * 12-Nov-88  Michael Mauldin (mlm) at Carnegie-Mellon University
  26.  *    Created.
  27.  *****************************************************************/
  28.  
  29. # include <stdio.h>
  30. # include <math.h>
  31. # include <ctype.h>
  32. # include "fbm.h"
  33.  
  34. typedef struct rasterfile {
  35.     long ras_magic;
  36.     long ras_width;
  37.     long ras_height;
  38.     long ras_depth;
  39.     long ras_length;
  40.     long ras_type;
  41.     long ras_maptype;
  42.     long ras_maplength;
  43. } RASHDR;
  44.  
  45. # define RT_STANDARD    1
  46. # define RMT_NONE    0
  47. # define RMT_EQUAL_RGB    1
  48. # define RMT_RAW    2
  49.  
  50. # define RED 0
  51. # define GRN 1
  52. # define BLU 2
  53.  
  54. /****************************************************************
  55.  * write_sun (image, wfile)
  56.  ****************************************************************/
  57.  
  58. #ifndef lint
  59. static char *fbmid =
  60.     "$FBM flsun.c <0.9> 07-Mar-89  (C) 1989 by Michael Mauldin$";
  61. #endif
  62.  
  63. write_sun (image, wfile)
  64. FBM *image;
  65. FILE *wfile;
  66. { RASHDR rhdr;
  67.   register int i, j, byte;
  68.   register unsigned char *bmp, *rp, *gp, *bp;
  69.   int width, height, plnlen, clrlen, rowlen, depth, bits;
  70.  
  71.   if (image->hdr.planes != 1 && image->hdr.planes != 3)
  72.   { fprintf (stderr,
  73.          "Error, write_sun can only handle images with depth 1 or 3\n");
  74.     return (0);
  75.   }
  76.  
  77.   if (image->hdr.physbits != 8)
  78.   { fprintf (stderr,
  79.          "Error, write_sun can only handle 8 physical bits per pixel\n");
  80.     return (0);
  81.   }
  82.  
  83.   if (image->hdr.physbits == 1 && (image->hdr.rowlen % 16) != 0)
  84.   { fprintf (stderr,
  85.     "Error, 1 bit deep files must have rowlen (%d) divisible by 16");
  86.     return (0);
  87.   }
  88.  
  89.   if (image->hdr.physbits == 8 && image->hdr.bits == 1)
  90.     bits = 1;
  91.   else
  92.     bits = image->hdr.physbits > 1 ? 8 : 1;
  93.  
  94. # ifdef DEBUG
  95.   fprintf (stderr, "write_sun: [%dx%d] rowlen %d, planes %d, bits %d, physbits %d, using %d\n",
  96.        image->hdr.cols,
  97.        image->hdr.rows,
  98.        image->hdr.rowlen,
  99.        image->hdr.planes,
  100.        image->hdr.bits,
  101.        image->hdr.physbits,
  102.            bits);
  103. # endif
  104.  
  105.   width = image->hdr.cols;
  106.   height = image->hdr.rows;
  107.   rowlen = image->hdr.rowlen;
  108.   plnlen = image->hdr.plnlen;
  109.   clrlen = image->hdr.clrlen;
  110.   depth = bits * image->hdr.planes;
  111.  
  112.   /* Initialize Sun raster header */
  113.   rhdr.ras_magic = SUN_MAGIC;
  114.   rhdr.ras_width = width;
  115.   rhdr.ras_height = height;
  116.   rhdr.ras_depth = depth;
  117.   rhdr.ras_length = plnlen * bits / 8;
  118.   rhdr.ras_type = RT_STANDARD;
  119.   rhdr.ras_maptype = depth > 8 ? RMT_RAW : clrlen ? RMT_EQUAL_RGB : RMT_NONE;
  120.   rhdr.ras_maplength = clrlen;
  121.  
  122.   /* Write rasterfile header - note: use Sun byte order */
  123.   put_long (rhdr.ras_magic, wfile, BIG);
  124.   put_long (rhdr.ras_width, wfile, BIG);
  125.   put_long (rhdr.ras_height, wfile, BIG);
  126.   put_long (rhdr.ras_depth, wfile, BIG);
  127.   put_long (rhdr.ras_length, wfile, BIG);
  128.   put_long (rhdr.ras_type, wfile, BIG);
  129.   put_long (rhdr.ras_maptype, wfile, BIG);
  130.   put_long (rhdr.ras_maplength, wfile, BIG);
  131.   
  132.   /* Dump colormap if need be */
  133.   if (clrlen > 0)
  134.   { fwrite (image->cm, 1, clrlen, wfile); }
  135.   
  136.   /* Write bytes */
  137.   switch (depth)
  138.   { case 24:    rp = &image->bm[0];
  139.         gp = rp + plnlen;
  140.         bp = gp + plnlen;
  141.  
  142.         for (i=0; i<plnlen; i++)
  143.         { fputc (*rp++, wfile);
  144.           fputc (*gp++, wfile);
  145.           fputc (*bp++, wfile);
  146.         }
  147.         break;
  148.  
  149.     case 8:    fwrite (image->bm, 1, plnlen, wfile);
  150.         break;
  151.  
  152.     case 1:    
  153. # ifdef DEBUG
  154.         fprintf (stderr, "Writing Sun 1bit file [%dx%d] rowlen %d\n",
  155.              width, height, rowlen);
  156. # endif
  157.         for (j=0; j<height; j++)
  158.         { bmp = &(image->bm[j*rowlen]);
  159.           byte = 0;
  160.  
  161.           for (i=0; i<rowlen; i++)
  162.           { byte = (byte << 1) | (*bmp++ ? 0 : 1);
  163.  
  164.             if ((i & 7) == 7)
  165.             { fputc (byte, wfile); byte = 0; }
  166.           }
  167.         }
  168.         break;
  169.  
  170.     default:    fprintf  (stderr,
  171.                   "Error, write_sun given invalid depth %d bits\n",
  172.               depth);
  173.         return (0);
  174.   }
  175.   return (1);
  176. }
  177.  
  178. /****************************************************************
  179.  * read_sun (image, rfile)
  180.  ****************************************************************/
  181.  
  182. read_sun (image, rfile, mstr, mlen)
  183. FBM *image;
  184. FILE *rfile;
  185. char *mstr;
  186. int mlen;
  187. { RASHDR rhdr;
  188.   int width, height, plnlen, rowlen, clrlen, res, depth;
  189.   register int i, j, byte;
  190.   register unsigned char *bmp, *rp, *gp, *bp;
  191.   int m1, m2, m3, m4;
  192.  
  193.   m1 = NEXTMCH(rfile,mstr,mlen) & 0xff;
  194.   m2 = NEXTMCH(rfile,mstr,mlen) & 0xff;
  195.   m3 = NEXTMCH(rfile,mstr,mlen) & 0xff;
  196.   m4 = NEXTMCH(rfile,mstr,mlen) & 0xff;
  197.  
  198.   rhdr.ras_magic = (m1 << 24) | (m2 << 16) | (m3 << 8)| (m4);
  199.  
  200.   /* Write rasterfile header - note: use Sun byte order */
  201.   if (rhdr.ras_magic != SUN_MAGIC)
  202.   { fprintf (stderr, "Error, not a Sun raster file (bad magic %08x)\n",
  203.          rhdr.ras_magic);
  204.     return (0);
  205.   }
  206.  
  207.   rhdr.ras_width = get_long (rfile, BIG);
  208.   rhdr.ras_height = get_long (rfile, BIG);
  209.   rhdr.ras_depth = get_long (rfile, BIG);
  210.   rhdr.ras_length = get_long (rfile, BIG);
  211.   rhdr.ras_type = get_long (rfile, BIG);
  212.   rhdr.ras_maptype = get_long (rfile, BIG);
  213.   rhdr.ras_maplength = get_long (rfile, BIG);
  214.  
  215.   /* Check for nonstandard rasterfile formats */
  216.   if (rhdr.ras_type != RT_STANDARD)
  217.   { fprintf (stderr, "Error: rasterfile is not a Sun RT_STANDARD file\n");
  218.     return (0);
  219.   }
  220.  
  221.   if (rhdr.ras_maplength > 0 && rhdr.ras_maptype != RMT_EQUAL_RGB)
  222.   { fprintf (stderr, "Error: color rasterfile is not RMT_EQUAL_RGB\n");
  223.     return (0);
  224.   }
  225.   
  226.   if (rhdr.ras_maplength == 0 &&
  227.       rhdr.ras_maptype != RMT_NONE &&
  228.       rhdr.ras_maptype != RMT_RAW)
  229.   { fprintf (stderr, "Error: black and white rasterfile is not RMT_NONE\n");
  230.     return (0);
  231.   }
  232.  
  233.   if (rhdr.ras_depth != 24 && rhdr.ras_depth != 8 && rhdr.ras_depth != 1)
  234.   { fprintf (stderr, "Error, bits per pixel (%d) must be 1, 8 or 24\n", 
  235.          rhdr.ras_depth);
  236.     return (0);
  237.   }
  238.  
  239.   /* Initialize and allocate input image */  
  240.   width = rhdr.ras_width;
  241.   height = rhdr.ras_height;
  242.   depth = rhdr.ras_depth;
  243.   clrlen = rhdr.ras_maplength;
  244.  
  245.   if (depth == 1)
  246.   { rowlen = 16 * ((width + 15) / 16);
  247.     plnlen = rowlen * height;
  248.   }
  249.   else
  250.   { rowlen = width;
  251.     if (rowlen & 1) rowlen++;
  252.     
  253.     plnlen = width * height;
  254.   }
  255.   
  256.   /* Check for consitency between colormap and depth */
  257.   if (depth > 8 && clrlen > 0)
  258.   { fprintf (stderr,
  259.     "Error, input has colormap of length %d, but %d bits per pixel\n",
  260.     clrlen, depth);
  261.     return (0);
  262.   }
  263.  
  264.   /* Initialize image header */
  265.   image->hdr.cols = width;
  266.   image->hdr.rows = height;
  267.   image->hdr.planes = (depth == 24) ? 3 : 1;
  268.   image->hdr.bits = (depth == 24) ? 8 : depth;
  269.   image->hdr.physbits = 8;
  270.   image->hdr.rowlen = rowlen;
  271.   image->hdr.plnlen = plnlen;
  272.   image->hdr.clrlen = clrlen;
  273.   image->hdr.aspect = 1.0;
  274.   image->hdr.title[0] = '\0';
  275.   image->hdr.credits[0] = '\0';
  276.  
  277.   /* Allocate space */
  278.   alloc_fbm (image);
  279.  
  280.   /* Read colormap if need be */
  281.   if (clrlen > 0 && (res = fread (image->cm, 1, clrlen, rfile)) != clrlen) 
  282.   { fprintf (stderr, "Error: couldn't read colormap, read %d of %d bytes\n",
  283.          res, clrlen);
  284.     return (0);
  285.   }
  286.  
  287.   /* Read bytes */
  288.   switch (depth)
  289.   { case 24:    rp = &image->bm[0];
  290.         gp = rp + plnlen;
  291.         bp = gp + plnlen;
  292.  
  293.         for (i=0; i<plnlen && !feof (rfile); i++)
  294.         { *rp++ = fgetc (rfile);
  295.           *gp++ = fgetc (rfile);
  296.           *bp++ = fgetc (rfile);
  297.         }
  298.         
  299.         if (i<plnlen)
  300.         { fprintf (stderr, "Error: %s %d of %d pixels (%d bytes)\n",
  301.                "EOF on bitmap after",
  302.                i, plnlen, plnlen * image->hdr.planes);
  303.           return (0);
  304.         }
  305.         
  306.         break;
  307.  
  308.     case 8:    if ((res = fread (image->bm, 1, plnlen, rfile)) != plnlen)
  309.         { fprintf (stderr,
  310.                "Error: EOF on bitmap after %d of %d bytes\n",
  311.                res, plnlen);
  312.           return (0);
  313.         }
  314.         break;
  315.  
  316.     case 1:    for (j=0; j<height; j++)
  317.         { bmp = &(image->bm[j * rowlen]);
  318.     
  319.           for (i=0; i<rowlen; i++)
  320.           { if ((i&7) == 0)
  321.             { if ((byte = fgetc (rfile)) == EOF)
  322.               { fprintf (stderr,
  323.                  "Error: EOF on bitmap after %d of %d bytes\n",
  324.                  j*rowlen + i, height*rowlen);
  325.             return (0);
  326.               }
  327.             }
  328.         
  329.             *bmp++ = (byte & 0x80) ? BLACK : WHITE;
  330.             byte <<= 1;
  331.           }
  332.         }
  333.         break;
  334.     default:    fprintf (stderr, "Invalid depth %d bits\n", depth);
  335.         return (0);
  336.   }
  337.  
  338.   return (1);
  339. }
  340.