home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Photo CD Demo 1
/
Demo.bin
/
fbm
/
src
/
flrle.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-06-24
|
9KB
|
343 lines
/*****************************************************************
* flrle.c: FBM Release 1.0 25-Feb-90 Michael Mauldin
*
* flrle.c: Library routines for reading and Writing Utah RLE
* raster toolkit format.
*
* CONTENTS
* read_rle (image, rfile, mstr, mlen)
* write_rle (image, wfile)
*
* EDITLOG
* LastEditDate = Mon Jun 25 00:05:13 1990 - Michael Mauldin
* LastFileName = /usr2/mlm/src/misc/fbm/flrle.c
*
* HISTORY
* 25-Jun-90 Michael Mauldin (mlm@cs.cmu.edu) Carnegie Mellon
* Package for Release 1.0
*
* 13-Aug-89 Paul Milazzo (milazzo@diamond.bbn.com) BBN
* Created.
*****************************************************************/
#include <stdio.h>
#include "fbm.h"
#ifndef lint
static char *fbmid =
"$FBM flrle.c <1.0> 25-Jun-90 by Paul Milazzo, source code available \
free from MLM@CS.CMU.EDU and from UUNET archives$";
#endif
#ifdef RLE
#include "svfb_global.h"
#define CMAP_COLORS 3
#define TITLE_COMMENT "TITLE"
#define CREDITS_COMMENT "CREDITS"
#define ASPECT_COMMENT "aspect_ratio"
#define CMAP_COMMENT "color_map_length"
#define MAX_COMMENTS 4
#define MAX_LABEL_LENGTH (sizeof (CMAP_COMMENT))
#define TRUE 1
#define FALSE 0
static char *CommentBuf (bpp)
char **bpp;
{
char *bp;
if ((bp = (char *)malloc (FBM_MAX_TITLE + MAX_LABEL_LENGTH)) ==
(char *)NULL)
{
perror ("Can't allocate space for RLE comment");
exit (1);
}
*bpp = bp;
return bp;
}
/****************************************************************
* write_rle (image, wfile)
****************************************************************/
write_rle (image, wfile)
FBM *image;
FILE *wfile;
{
rle_pixel **rowvec;
char *comments[MAX_COMMENTS + 1];
char **cp = comments;
rle_map *colorMap = (rle_map *)NULL;
int channel;
int i;
int j;
int rows;
int cols;
int planes;
int rowlen;
int plnlen;
if (image->hdr.physbits != 8) {
fputs ("write_rle: error: can only handle 8 physical bits per pixel\n",
stderr);
return (0);
}
rows = image->hdr.rows;
cols = image->hdr.cols;
planes = image->hdr.planes;
rowlen = image->hdr.rowlen;
plnlen = image->hdr.plnlen;
sv_globals.sv_ncolors = planes;
sv_globals.sv_alpha = 0; /* no alpha channel */
sv_globals.sv_background = 2; /* clear background to sv_bg_color */
sv_globals.sv_xmin = 0;
sv_globals.sv_xmax = cols - 1;
sv_globals.sv_ymin = 0;
sv_globals.sv_ymax = rows - 1;
sv_globals.sv_cmaplen = 0; /* log2(color_map_length) */
if (image->hdr.clrlen > 0) {
sv_globals.sv_ncmap = CMAP_COLORS;
for (i = 1; i < image->hdr.clrlen / CMAP_COLORS; i <<= 1)
sv_globals.sv_cmaplen++;
if ((colorMap = (rle_map *)malloc(image->hdr.clrlen*sizeof(rle_map))) ==
(rle_map *)NULL)
{
perror ("write_rle: can't allocate RLE color map");
return 0;
}
for (i = 0; i < image->hdr.clrlen; i++)
colorMap[i] = (rle_map)image->cm[i] << 8;
sv_globals.sv_cmap = colorMap;
}
else {
sv_globals.sv_ncmap = 0;
sv_globals.sv_cmap = (rle_map *)NULL;
}
for (channel = 0; channel < planes; channel++)
SV_SET_BIT (sv_globals, channel);
if (*image->hdr.title != '\0')
sprintf (CommentBuf (cp++), "%s=%s",
TITLE_COMMENT, image->hdr.title);
if (*image->hdr.credits != '\0')
sprintf (CommentBuf (cp++), "%s=%s",
CREDITS_COMMENT, image->hdr.credits);
if (image->hdr.aspect != 1.0)
sprintf (CommentBuf (cp++), "%s=%g",
ASPECT_COMMENT, image->hdr.aspect);
/*
* If the color map length is not a power of two, put the actual length
* in a comment.
*/
if (image->hdr.clrlen > 0 &&
(1 << sv_globals.sv_cmaplen) != image->hdr.clrlen / CMAP_COLORS)
{
sprintf (CommentBuf (cp++), "%s=%d",
CMAP_COMMENT, image->hdr.clrlen / CMAP_COLORS);
}
*cp = (char *)NULL;
sv_globals.sv_comments = cp > comments ? comments : (char **)NULL;
sv_globals.svfb_fd = wfile;
sv_setup (RUN_DISPATCH, &sv_globals);
if ((rowvec = (unsigned char **)malloc (planes*sizeof(unsigned char *))) ==
(unsigned char **)NULL)
{
perror ("write_rle: can't allocate row indirection vectors");
return 0;
}
for (j = rows - 1; j >= 0; --j) {
for (channel = 0; channel < planes; channel ++)
rowvec[channel] = image->bm + j * rowlen + channel * plnlen;
sv_putrow (rowvec, cols, &sv_globals);
}
sv_puteof (&sv_globals);
free (rowvec);
while (cp > comments)
free (*--cp);
if (colorMap != (rle_map *)NULL)
free (colorMap);
return 1;
}
/****************************************************************
* read_rle (image, rfile)
****************************************************************/
read_rle (image, rfile, mstr, mlen)
FBM *image;
FILE *rfile;
char *mstr;
int mlen;
{
rle_pixel **colorMap;
rle_pixel **rowvec;
unsigned char *cp;
char *comment;
int j;
int channel;
int rows;
int planes;
int rowlen;
int plnlen;
int mapEntries;
int clearRow;
/* must put the magic number back so the setup code can read it */
while (mlen--)
(void)ungetc (*mstr++, rfile);
sv_globals.svfb_fd = rfile;
switch (rle_get_setup (&sv_globals)) {
case 0:
break; /* success */
case -1:
fputs ("read_rle: input is not a Utah RLE file.\n", stderr);
/* fall through... */
case -2:
return 0; /* sv_get_setup already printed an error message */
case -3:
fputs ("read_rle: input file is empty.\n", stderr);
return 0;
case -4:
fputs ("read_rle: end-of-file encountered while reading RLE header.\n",
stderr);
return 0;
default:
fputs ("read_rle: rle_get_setup returned something strange!\n",
stderr);
}
if (sv_globals.sv_alpha) {
fputs ("read_rle: discarding alpha channel.\n", stderr);
SV_CLR_BIT (sv_globals, SV_ALPHA);
}
image->hdr.cols = sv_globals.sv_xmax - sv_globals.sv_xmin + 1;
image->hdr.rows = rows = sv_globals.sv_ymax - sv_globals.sv_ymin + 1;
image->hdr.planes = planes = sv_globals.sv_ncolors;
image->hdr.bits = sv_globals.sv_cmaplen ? sv_globals.sv_cmaplen : 8;
image->hdr.physbits = 8;
image->hdr.rowlen = rowlen = image->hdr.cols;
image->hdr.plnlen = plnlen = image->hdr.rows * image->hdr.rowlen;
image->hdr.clrlen = 1 << sv_globals.sv_cmaplen;
if ((comment = rle_getcom (CMAP_COMMENT, &sv_globals)) != (char *)NULL)
image->hdr.clrlen = atoi (comment);
image->hdr.clrlen *= sv_globals.sv_ncmap;
if ((comment = rle_getcom (ASPECT_COMMENT, &sv_globals)) != (char *)NULL)
image->hdr.aspect = atof (comment);
else
image->hdr.aspect = 1.0;
if ((comment = rle_getcom (TITLE_COMMENT, &sv_globals)) != (char *)NULL)
(void)strcpy (image->hdr.title, comment);
else
image->hdr.title[0] = '\0';
if ((comment = rle_getcom (CREDITS_COMMENT, &sv_globals)) != (char *)NULL)
(void)strcpy (image->hdr.credits, comment);
else
image->hdr.credits[0] = '\0';
image->cm = (unsigned char *)NULL;
image->bm = (unsigned char *)NULL;
alloc_fbm (image);
if (image->hdr.clrlen > 0) {
mapEntries = (image->hdr.clrlen / sv_globals.sv_ncmap);
cp = image->cm;
colorMap = buildmap (&sv_globals, CMAP_COLORS, 1.0);
for (channel = 0; channel < CMAP_COLORS; channel++) {
for (j = 0; j < mapEntries; j++)
*cp++ = colorMap[channel][j];
free (colorMap[channel]);
}
free (colorMap);
image->hdr.clrlen = mapEntries * CMAP_COLORS; /* renormalize clrlen */
}
switch (sv_globals.sv_background) {
case 0: /* no background color was saved */
clearRow = TRUE; /* manually clear rows to 0 */
break;
case 1: /* don't clear to the background color */
sv_globals.sv_background = 2; /* force automatic clearing */
/* fall through... */
case 2: /* clear to the background color */
clearRow = FALSE;
break;
default:
fprintf (stderr, "read_rle: unknown background flag '%d'.\n",
sv_globals.sv_background);
}
/* move image to origin */
sv_globals.sv_xmin = 0;
sv_globals.sv_xmax = image->hdr.cols - 1;
sv_globals.sv_ymin = 0;
sv_globals.sv_ymax = image->hdr.rows - 1;
if ((rowvec = (unsigned char **)malloc (planes*sizeof(unsigned char *))) ==
(unsigned char **)NULL)
{
perror ("write_rle: can't allocate row indirection vectors");
return 0;
}
for (j = rows - 1; j >= 0; --j) {
for (channel = 0; channel < planes; channel ++) {
rowvec[channel] = image->bm + j * rowlen + channel * plnlen;
if (clearRow)
bzero ((char *)rowvec[channel], rowlen);
}
rle_getrow (&sv_globals, rowvec);
}
free (rowvec);
return 1;
}
#else /* ! RLE */
/*ARGSUSED*/
write_rle (image, wfile)
FBM *image;
FILE *wfile;
{
fputs ("RLE support was omitted at compile time.\n", stderr);
}
/*ARGSUSED*/
read_rle (image, rfile, mstr, mlen)
FBM *image;
FILE *rfile;
char *mstr;
int mlen;
{
write_rle (image, rfile);
}
#endif /* RLE */