home *** CD-ROM | disk | FTP | other *** search
/ Photo CD Demo 1 / Demo.bin / fbm / src / flrle.c < prev    next >
C/C++ Source or Header  |  1990-06-24  |  9KB  |  343 lines

  1. /*****************************************************************
  2.  * flrle.c: FBM Release 1.0 25-Feb-90 Michael Mauldin
  3.  *
  4.  * flrle.c: Library routines for reading and Writing Utah RLE
  5.  *        raster toolkit format.
  6.  *
  7.  * CONTENTS
  8.  *    read_rle (image, rfile, mstr, mlen)
  9.  *    write_rle (image, wfile)
  10.  *
  11.  * EDITLOG
  12.  *    LastEditDate = Mon Jun 25 00:05:13 1990 - Michael Mauldin
  13.  *    LastFileName = /usr2/mlm/src/misc/fbm/flrle.c
  14.  *
  15.  * HISTORY
  16.  * 25-Jun-90  Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
  17.  *    Package for Release 1.0
  18.  *
  19.  * 13-Aug-89  Paul Milazzo (milazzo@diamond.bbn.com) BBN
  20.  *    Created.
  21.  *****************************************************************/
  22.  
  23. #include    <stdio.h>
  24. #include    "fbm.h"
  25.  
  26. #ifndef lint
  27. static char *fbmid =
  28. "$FBM flrle.c <1.0> 25-Jun-90  by Paul Milazzo, source code available \
  29. free from MLM@CS.CMU.EDU and from UUNET archives$";
  30. #endif
  31.  
  32. #ifdef RLE
  33.  
  34. #include    "svfb_global.h"
  35.  
  36. #define        CMAP_COLORS        3
  37.  
  38. #define        TITLE_COMMENT        "TITLE"
  39. #define        CREDITS_COMMENT        "CREDITS"
  40. #define        ASPECT_COMMENT        "aspect_ratio"
  41. #define        CMAP_COMMENT        "color_map_length"
  42. #define        MAX_COMMENTS        4
  43. #define        MAX_LABEL_LENGTH    (sizeof (CMAP_COMMENT))
  44.  
  45. #define        TRUE            1
  46. #define        FALSE            0
  47.  
  48. static char    *CommentBuf (bpp)
  49. char        **bpp;
  50. {
  51.     char    *bp;
  52.  
  53.     if ((bp = (char *)malloc (FBM_MAX_TITLE + MAX_LABEL_LENGTH)) ==
  54.     (char *)NULL)
  55.     {
  56.     perror ("Can't allocate space for RLE comment");
  57.     exit (1);
  58.     }
  59.  
  60.     *bpp = bp;
  61.  
  62.     return bp;
  63. }
  64.  
  65. /****************************************************************
  66.  * write_rle (image, wfile)
  67.  ****************************************************************/
  68.  
  69. write_rle    (image, wfile)
  70. FBM        *image;
  71. FILE        *wfile;
  72. {
  73.     rle_pixel    **rowvec;
  74.     char    *comments[MAX_COMMENTS + 1];
  75.     char    **cp = comments;
  76.     rle_map    *colorMap = (rle_map *)NULL;
  77.     int        channel;
  78.     int        i;
  79.     int        j;
  80.     int        rows;
  81.     int        cols;
  82.     int        planes;
  83.     int        rowlen;
  84.     int        plnlen;
  85.  
  86.     if (image->hdr.physbits != 8) {
  87.     fputs ("write_rle:  error:  can only handle 8 physical bits per pixel\n",
  88.         stderr);
  89.     return (0);
  90.     }
  91.  
  92.     rows = image->hdr.rows;
  93.     cols = image->hdr.cols;
  94.     planes = image->hdr.planes;
  95.     rowlen = image->hdr.rowlen;
  96.     plnlen = image->hdr.plnlen;
  97.  
  98.     sv_globals.sv_ncolors    = planes;
  99.     sv_globals.sv_alpha        = 0;  /* no alpha channel */
  100.     sv_globals.sv_background    = 2;  /* clear background to sv_bg_color */
  101.     sv_globals.sv_xmin        = 0;
  102.     sv_globals.sv_xmax        = cols - 1;
  103.     sv_globals.sv_ymin        = 0;
  104.     sv_globals.sv_ymax        = rows - 1;
  105.     sv_globals.sv_cmaplen    = 0;  /* log2(color_map_length) */
  106.     if (image->hdr.clrlen > 0) {
  107.     sv_globals.sv_ncmap = CMAP_COLORS;
  108.  
  109.     for (i = 1; i < image->hdr.clrlen / CMAP_COLORS; i <<= 1)
  110.         sv_globals.sv_cmaplen++;
  111.  
  112.     if ((colorMap = (rle_map *)malloc(image->hdr.clrlen*sizeof(rle_map))) ==
  113.         (rle_map *)NULL)
  114.     {
  115.         perror ("write_rle:  can't allocate RLE color map");
  116.         return 0;
  117.     }
  118.     for (i = 0; i < image->hdr.clrlen; i++)
  119.         colorMap[i] = (rle_map)image->cm[i] << 8;
  120.     sv_globals.sv_cmap    = colorMap;
  121.     }
  122.     else {
  123.     sv_globals.sv_ncmap    = 0;
  124.     sv_globals.sv_cmap    = (rle_map *)NULL;
  125.     }
  126.  
  127.     for (channel = 0; channel < planes; channel++)
  128.     SV_SET_BIT (sv_globals, channel);
  129.  
  130.     if (*image->hdr.title != '\0')
  131.     sprintf (CommentBuf (cp++), "%s=%s",
  132.              TITLE_COMMENT, image->hdr.title);
  133.  
  134.     if (*image->hdr.credits != '\0')
  135.     sprintf (CommentBuf (cp++), "%s=%s",
  136.              CREDITS_COMMENT, image->hdr.credits);
  137.  
  138.     if (image->hdr.aspect != 1.0)
  139.     sprintf (CommentBuf (cp++), "%s=%g",
  140.              ASPECT_COMMENT, image->hdr.aspect);
  141.  
  142.     /*
  143.      *  If the color map length is not a power of two, put the actual length
  144.      *  in a comment.
  145.      */
  146.     if (image->hdr.clrlen > 0 &&
  147.     (1 << sv_globals.sv_cmaplen) != image->hdr.clrlen / CMAP_COLORS)
  148.     {
  149.     sprintf (CommentBuf (cp++), "%s=%d",
  150.              CMAP_COMMENT, image->hdr.clrlen / CMAP_COLORS);
  151.     }
  152.  
  153.     *cp = (char *)NULL;
  154.  
  155.     sv_globals.sv_comments = cp > comments ? comments : (char **)NULL;
  156.  
  157.     sv_globals.svfb_fd        = wfile;
  158.   
  159.     sv_setup (RUN_DISPATCH, &sv_globals);
  160.  
  161.     if ((rowvec = (unsigned char **)malloc (planes*sizeof(unsigned char *))) ==
  162.     (unsigned char **)NULL)
  163.     {
  164.     perror ("write_rle:  can't allocate row indirection vectors");
  165.     return 0;
  166.     }
  167.  
  168.     for (j = rows - 1; j >= 0; --j) {
  169.     for (channel = 0; channel < planes; channel ++)
  170.         rowvec[channel] = image->bm + j * rowlen + channel * plnlen;
  171.     sv_putrow (rowvec, cols, &sv_globals);
  172.     }
  173.     sv_puteof (&sv_globals);
  174.  
  175.     free (rowvec);
  176.     while (cp > comments)
  177.     free (*--cp);
  178.     if (colorMap != (rle_map *)NULL)
  179.     free (colorMap);
  180.  
  181.     return 1;
  182. }
  183.  
  184. /****************************************************************
  185.  * read_rle (image, rfile)
  186.  ****************************************************************/
  187.  
  188. read_rle (image, rfile, mstr, mlen)
  189. FBM    *image;
  190. FILE    *rfile;
  191. char    *mstr;
  192. int    mlen;
  193. {
  194.     rle_pixel        **colorMap;
  195.     rle_pixel        **rowvec;
  196.     unsigned char    *cp;
  197.     char        *comment;
  198.     int            j;
  199.     int            channel;
  200.     int            rows;
  201.     int            planes;
  202.     int            rowlen;
  203.     int            plnlen;
  204.     int            mapEntries;
  205.     int            clearRow;
  206.  
  207.     /* must put the magic number back so the setup code can read it */
  208.     while (mlen--)
  209.     (void)ungetc (*mstr++, rfile);
  210.  
  211.     sv_globals.svfb_fd = rfile;
  212.     switch (rle_get_setup (&sv_globals)) {
  213.     case 0:
  214.         break;    /* success */
  215.     case -1:
  216.         fputs ("read_rle:  input is not a Utah RLE file.\n", stderr);
  217.         /* fall through... */
  218.     case -2:
  219.         return 0;    /* sv_get_setup already printed an error message */
  220.     case -3:
  221.         fputs ("read_rle:  input file is empty.\n", stderr);
  222.         return 0;
  223.     case -4:
  224.         fputs ("read_rle:  end-of-file encountered while reading RLE header.\n",
  225.            stderr);
  226.         return 0;
  227.     default:
  228.         fputs ("read_rle:  rle_get_setup returned something strange!\n",
  229.            stderr);
  230.     }
  231.  
  232.     if (sv_globals.sv_alpha) {
  233.     fputs ("read_rle:  discarding alpha channel.\n", stderr);
  234.     SV_CLR_BIT (sv_globals, SV_ALPHA);
  235.     }
  236.  
  237.     image->hdr.cols    = sv_globals.sv_xmax - sv_globals.sv_xmin + 1;
  238.     image->hdr.rows    = rows = sv_globals.sv_ymax - sv_globals.sv_ymin + 1;
  239.     image->hdr.planes    = planes = sv_globals.sv_ncolors;
  240.     image->hdr.bits    = sv_globals.sv_cmaplen ? sv_globals.sv_cmaplen : 8;
  241.     image->hdr.physbits    = 8;
  242.     image->hdr.rowlen    = rowlen = image->hdr.cols;
  243.     image->hdr.plnlen    = plnlen = image->hdr.rows * image->hdr.rowlen;
  244.  
  245.     image->hdr.clrlen    = 1 << sv_globals.sv_cmaplen;
  246.     if ((comment = rle_getcom (CMAP_COMMENT, &sv_globals)) != (char *)NULL)
  247.     image->hdr.clrlen = atoi (comment);
  248.     image->hdr.clrlen    *= sv_globals.sv_ncmap;
  249.  
  250.     if ((comment = rle_getcom (ASPECT_COMMENT, &sv_globals)) != (char *)NULL)
  251.     image->hdr.aspect = atof (comment);
  252.     else
  253.     image->hdr.aspect = 1.0;
  254.  
  255.     if ((comment = rle_getcom (TITLE_COMMENT, &sv_globals)) != (char *)NULL)
  256.     (void)strcpy (image->hdr.title, comment);
  257.     else
  258.     image->hdr.title[0] = '\0';
  259.     if ((comment = rle_getcom (CREDITS_COMMENT, &sv_globals)) != (char *)NULL)
  260.     (void)strcpy (image->hdr.credits, comment);
  261.     else
  262.     image->hdr.credits[0] = '\0';
  263.  
  264.     image->cm = (unsigned char *)NULL;
  265.     image->bm = (unsigned char *)NULL;
  266.     alloc_fbm (image);
  267.  
  268.     if (image->hdr.clrlen > 0) {
  269.     mapEntries = (image->hdr.clrlen / sv_globals.sv_ncmap);
  270.     cp = image->cm;
  271.     colorMap = buildmap (&sv_globals, CMAP_COLORS, 1.0);
  272.     for (channel = 0; channel < CMAP_COLORS; channel++) {
  273.         for (j = 0; j < mapEntries; j++)
  274.         *cp++ = colorMap[channel][j];
  275.         free (colorMap[channel]);
  276.     }
  277.     free (colorMap);
  278.     image->hdr.clrlen = mapEntries * CMAP_COLORS; /* renormalize clrlen */
  279.     }
  280.  
  281.     switch (sv_globals.sv_background) {
  282.     case 0:        /* no background color was saved */
  283.         clearRow = TRUE;    /* manually clear rows to 0 */
  284.         break;
  285.     case 1:        /* don't clear to the background color */
  286.         sv_globals.sv_background = 2;  /* force automatic clearing */
  287.         /* fall through... */
  288.     case 2:        /* clear to the background color */
  289.         clearRow = FALSE;
  290.         break;
  291.     default:
  292.         fprintf (stderr, "read_rle:  unknown background flag '%d'.\n",
  293.              sv_globals.sv_background);
  294.     }
  295.  
  296.     /* move image to origin */
  297.     sv_globals.sv_xmin    = 0;
  298.     sv_globals.sv_xmax    = image->hdr.cols - 1;
  299.     sv_globals.sv_ymin    = 0;
  300.     sv_globals.sv_ymax    = image->hdr.rows - 1;
  301.  
  302.     if ((rowvec = (unsigned char **)malloc (planes*sizeof(unsigned char *))) ==
  303.     (unsigned char **)NULL)
  304.     {
  305.     perror ("write_rle:  can't allocate row indirection vectors");
  306.     return 0;
  307.     }
  308.  
  309.     for (j = rows - 1; j >= 0; --j) {
  310.     for (channel = 0; channel < planes; channel ++) {
  311.         rowvec[channel] = image->bm + j * rowlen + channel * plnlen;
  312.         if (clearRow)
  313.         bzero ((char *)rowvec[channel], rowlen);
  314.     }
  315.     rle_getrow (&sv_globals, rowvec);
  316.     }
  317.     free (rowvec);
  318.  
  319.     return 1;
  320. }
  321.  
  322. #else /* ! RLE */
  323.  
  324. /*ARGSUSED*/
  325. write_rle    (image, wfile)
  326. FBM        *image;
  327. FILE        *wfile;
  328. {
  329.     fputs ("RLE support was omitted at compile time.\n", stderr);
  330. }
  331.  
  332. /*ARGSUSED*/
  333. read_rle (image, rfile, mstr, mlen)
  334. FBM    *image;
  335. FILE    *rfile;
  336. char    *mstr;
  337. int    mlen;
  338. {
  339.     write_rle (image, rfile);
  340. }
  341.  
  342. #endif /* RLE */
  343.