v19i051: FBM, image manipulation library, Part05/08
Rich Salz
rsalz at uunet.uu.net
Fri Jun 9 22:49:35 AEST 1989
Submitted-by: Michael.Mauldin at NL.CS.CMU.EDU
Posting-number: Volume 19, Issue 51
Archive-name: fbm/part05
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 5 (of 8)."
# Contents: fbext.c fbps.c flclr.c fledge.c flklnr.c flsun.c pbm2ps.c
# Wrapped by rsalz at fig.bbn.com on Fri Jun 9 08:38:26 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'fbext.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'fbext.c'\"
else
echo shar: Extracting \"'fbext.c'\" \(6337 characters\)
sed "s/^X//" >'fbext.c' <<'END_OF_FILE'
X/*****************************************************************
X * fbext.c: FBM Library 0.94 (Beta test) 20-May-89 Michael Mauldin
X *
X * Copyright (C) 1989 by Michael Mauldin. Permission is granted to
X * use this file in whole or in part provided that you do not sell it
X * for profit and that this copyright notice is retained unchanged.
X *
X * fbext.c:
X *
X * USAGE
X * % fbext [ -w<width> -h<height> -W<maxwidth> -H<maxheight>
X * -a<aspect> -t'title' -c'credits' ]
X * [ x y width height ] < foo.fbm > bar.fbm
X *
X * EDITLOG
X * LastEditDate = Sat May 20 19:03:55 1989 - Michael Mauldin
X * LastFileName = /usr2/mlm/src/misc/fbm/fbext.c
X *
X * HISTORY
X * 20-May-89 Michael Mauldin (mlm) at Carnegie Mellon University
X * Bug fix from Dave Cohrs <dave at cs.wisc.edu>
X *
X * 20-Apr-89 Michael Mauldin (mlm) at Carnegie Mellon University
X * Beta release (version 0.91) mlm at cs.cmu.edu
X *
X * 22-Aug-88 Michael Mauldin (mlm) at Carnegie-Mellon University
X * Created.
X *****************************************************************/
X
X# include <stdio.h>
X# include <math.h>
X# include "fbm.h"
X
Xint allowrot = 0;
X
X# define USAGE \
X"Usage: fbext [ -w<width> -h<height> ] [ -R ]\n\
X [ -W<maxwdith> -H<maxheight> -s<size> ]\n\
X [ -a<aspect> -t'title' -c'credits' ] [ -<type> ]\n\
X [ x y [ width height ] ] < image > image"
X
X#ifndef lint
Xstatic char *fbmid =
X "$FBM fbext.c <0.94> 20-May-89 (C) 1989 by Michael Mauldin$";
X#endif
X
Xmain (argc, argv)
Xchar *argv[];
X{ int xo = -1, yo = -1, w = -1, h = -1, ow = -1, oh = -1, size = -1;
X int mh = -1, mw = -1;
X double aspect = -1.0;
X char title[FBM_MAX_TITLE], credits[FBM_MAX_TITLE];
X FBM input, rotated, output, *image = &input;
X int outtype = FMT_FBM;
X
X /* Clear the memory pointers so alloc_fbm won't be confused */
X input.cm = input.bm = (unsigned char *) NULL;
X rotated.cm = rotated.bm = (unsigned char *) NULL;
X output.cm = output.bm = (unsigned char *) NULL;
X
X title[0] = '\0';
X credits[0] = '\0';
X
X /* Get the options */
X while (--argc > 0 && (*++argv)[0] == '-')
X { while (*++(*argv))
X { switch (**argv)
X { case 't': strcpy (title, *argv+1); CLRARG; break;
X case 'c': strcpy (credits, *argv+1); CLRARG; break;
X case 'a': aspect = atof (*argv+1); SKIPARG; break;
X case 'w': ow = atoi (*argv+1); SKIPARG; break;
X case 'h': oh = atoi (*argv+1); SKIPARG; break;
X case 'W': mw = atoi (*argv+1); SKIPARG; break;
X case 'H': mh = atoi (*argv+1); SKIPARG; break;
X case 'R': allowrot++; break;
X case 's': size = atoi (*argv+1); SKIPARG; break;
X case 'A': outtype = FMT_ATK; break;
X case 'B': outtype = FMT_FACE; break;
X case 'F': outtype = FMT_FBM; break;
X case 'G': outtype = FMT_GIF; break;
X case 'I': outtype = FMT_IFF; break;
X case 'L': outtype = FMT_LEAF; break;
X case 'M': outtype = FMT_MCP; break;
X case 'P': outtype = FMT_PBM; break;
X case 'S': outtype = FMT_SUN; break;
X case 'T': outtype = FMT_TIFF; break;
X case 'X': outtype = FMT_X11; break;
X case 'Z': outtype = FMT_PCX; break;
X default: fprintf (stderr, "%s\n", USAGE);
X exit (1);
X }
X }
X }
X
X
X if (read_bitmap (&input, (char *) NULL))
X {
X if (image->hdr.physbits != 8)
X { fprintf (stderr,
X "Can't handle images with %d bits and %d physbits per pixel\n",
X image->hdr.bits, image->hdr.physbits);
X exit (1);
X }
X
X /* Get arguments */
X if (argc > 0) xo = atoi (argv[0]);
X if (xo < 0) xo = 0;
X
X if (argc > 1) yo = atoi (argv[1]);
X if (yo < 0) yo = 0;
X
X if (argc > 2) w = atoi (argv[2]);
X if (w < 0) w = image->hdr.cols - xo;
X
X if (argc > 3) h = atoi (argv[3]);
X if (h < 0) h = image->hdr.rows - yo;
X
X if (argc > 4) ow = atoi (argv[4]);
X
X if (argc > 5) aspect = atof (argv[5]);
X
X /* If 'allowrot' is on, rotate image if its fits better */
X if (allowrot && mh > 0 && mw > 0)
X { int inhoriz=0, outhoriz=0;
X
X if (aspect < 0.0) aspect = 1.0;
X
X if (image->hdr.cols >= (image->hdr.aspect * image->hdr.rows)) inhoriz++;
X if (mw >= (aspect * mh)) outhoriz++;
X
X if (inhoriz != outhoriz)
X { if (rotate_fbm (image, &rotated, 90))
X { free (image);
X image = &rotated;
X
X fprintf (stderr, "Rotating [%dx%d] image for better fit [%dx%d]\n",
X image->hdr.rows, image->hdr.cols, mw, mh);
X }
X }
X else
X { exit (1); }
X }
X
X /* If max number of pixels specified, calculate width and height */
X if (size > 0)
X { if (ow > 0 || oh > 0)
X { fprintf (stderr,
X "fbext: error, can only specify one of size and width,height\n");
X exit (1);
X }
X
X aspect = 1.0;
X
X ow = sqrt ((double) size * w / (h * image->hdr.aspect));
X ow &= ~7; /* Make width multiple of 8 */
X oh = ow * image->hdr.aspect * h / w;
X }
X
X /* If given width and height, must determine output aspect */
X if (aspect <= 0.0)
X { if (ow > 0 && oh > 0)
X { aspect = image->hdr.aspect * ow * h / (oh * w); }
X else
X { aspect = image->hdr.aspect; }
X }
X
X /* If given only maximum sizes, assume largest width */
X if (ow <= 0 && oh <= 0)
X { if (mw > 0) ow = mw;
X else if (mh > 0) oh = mh;
X }
X
X /*
X * If given one of width or height, calculate the other.
X * If given only aspect ratio, inflate the smaller dimension
X */
X
X if (ow > 0 && oh > 0)
X { /* Nothing to pick */ }
X else if (ow <= 0 && oh > 0)
X { ow = ((double) oh + 0.5) * (aspect / image->hdr.aspect) * w / h; }
X else if (ow > 0 && oh <= 0)
X { oh = ((double) ow + 0.5) * (image->hdr.aspect / aspect) * h / w; }
X else if (aspect != image->hdr.aspect)
X { if (aspect > image->hdr.aspect)
X { oh = h;
X ow = ((double) oh + 0.5) * (aspect / image->hdr.aspect) * w / h;
X }
X else
X { ow = w;
X oh = ((double) ow + 0.5) * (input.hdr.aspect / aspect) * h / w;
X }
X }
X else
X { ow = w; oh = h; }
X
X /* If either dimension exceeds given maximums, shrink the image to fit */
X if (mh > 0 && oh > mh)
X { ow = ow * mh / oh; oh = mh; }
X
X /* Now extract the specified rectangle and write it out */
X if (mw > 0 && ow > mw)
X { oh = oh * mw / ow; ow = mw; }
X
X if (extract_fbm (&input, &output, xo, yo, w, h, ow, oh,
X title[0] ? title : NULL,
X credits[0] ? credits : NULL))
X { if (write_bitmap (&output, stdout, outtype)) exit (0); }
X }
X
X exit (1);
X}
END_OF_FILE
if test 6337 -ne `wc -c <'fbext.c'`; then
echo shar: \"'fbext.c'\" unpacked with wrong size!
fi
# end of 'fbext.c'
fi
if test -f 'fbps.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'fbps.c'\"
else
echo shar: Extracting \"'fbps.c'\" \(7399 characters\)
sed "s/^X//" >'fbps.c' <<'END_OF_FILE'
X/****************************************************************
X * fbps.c: FBM Library 0.92 (Beta test) 27-Apr-89 Michael Mauldin
X *
X * Copyright (C) 1989 by Michael Mauldin. Permission is granted to
X * use this file in whole or in part provided that you do not sell it
X * for profit and that this copyright notice is retained unchanged.
X *
X * fbps: Convert a grayscale image to a PostScript file
X *
X * USAGE
X * % fbps < image > postscript
X *
X * EDITLOG
X * LastEditDate = Thu Apr 27 10:06:15 1989 - Michael Mauldin
X * LastFileName = /usr2/mlm/src/misc/fbm/fbps.c
X *
X * HISTORY
X * 27-Apr-89 Michael Mauldin (mlm) at Carnegie Mellon University
X * Beta release (version 0.92) mlm at cs.cmu.edu
X *
X * 25-Apr-89 Paul Milazzo (milazzo) at BBN
X * Added color postscript support
X *
X * 27-Aug-88 Michael Mauldin (mlm) at Carnegie-Mellon University
X * Created.
X *****************************************************************/
X
X# include <stdio.h>
X# include <math.h>
X# include "fbm.h"
X
X# define MAXWIDTH 7.0 /* inches */
X# define MAXHEIGHT 9.5 /* inches */
X
Xchar *ps_chars();
X
X# define USAGE \
X"Usage: fbps [-tT] [-pP] [ -s ] [ -w<width> ] < foo.fbm > foo.PS"
X
X#ifndef lint
Xstatic char *fbmid =
X "$FBM fbps.c <0.92> 27-Apr-89 (C) 1989 by Michael Mauldin$";
X#endif
X
Xmain (argc, argv)
Xchar *argv[];
X{ register int i, j;
X int rows, cols, rowlen;
X double width = -1, height, llx, lly;
X int bytcnt=0;
X int dotitle=1, dosize=1, scribe=0;
X char buf[BUFSIZ], *title=NULL, *creator=NULL;
X long clock = time ((long *) NULL);
X char *ctime ();
X FBM image;
X
X /* Clear the memory pointer so alloc_fbm won't be confused */
X image.cm = image.bm = (unsigned char *) NULL;
X
X /* Get the options */
X while (--argc > 0 && (*++argv)[0] == '-')
X { while (*++(*argv))
X { switch (**argv)
X { case 't': dotitle = 1; break;
X case 'T': dotitle = 0; break;
X case 'p': dosize = 1; break;
X case 'P': dosize = 0; break;
X case 's': scribe++; break;
X case 'w': width = atof (*argv+1); SKIPARG; break;
X default: fprintf (stderr, "%s\n", USAGE);
X exit (1);
X }
X }
X }
X
X if (!read_bitmap (&image, (char *) NULL))
X { exit (1); }
X
X if ((image.hdr.planes != 1 && image.hdr.planes != 3) || image.hdr.clrlen > 0)
X { fprintf (stderr,
X "Error:\tfbps only handles grayscale or unmapped color files\n");
X fprintf (stderr, "\tUse the clr2gray filter to create grayscale first\n");
X exit (1);
X }
X
X if (image.hdr.bits == 1)
X { fprintf (stderr, "Error:\tfbps cannot handle 1 bit deep bitmaps\n");
X fprintf (stderr, "\tUse 'fbcat -P | pbm2ps' to convert %s\n",
X "1bit files to Postscript");
X exit (1);
X }
X
X /* Get title */
X if (image.hdr.title && image.hdr.title[0])
X { title = image.hdr.title; }
X
X /* Get width and height */
X rows = image.hdr.rows;
X cols = image.hdr.cols;
X rowlen = image.hdr.rowlen;
X
X /* Pick output size */
X if (width < 0.0 || width > MAXWIDTH)
X { width = MAXWIDTH; }
X
X height = width * image.hdr.aspect * (double) rows / cols;
X
X if (height > MAXHEIGHT)
X { width = width * MAXHEIGHT / height; height = MAXHEIGHT; }
X
X /* Pick lower left corner */
X if (scribe)
X { llx = lly = 0.0; }
X else
X { llx = (8.0 - width) / 2.0 + 0.5;
X lly = (11.0 - height) / 2.0;
X }
X
X fprintf (stderr,
X "FBM to PS \"%s\" width %1.3lf inches, height %1.3lf inches\n",
X title ? title : "(untitled)", width, height);
X
X /* Write out PostScript Header */
X if (scribe)
X { printf ("%%! Scribe @graphic style PostScript\n");
X if (title) { printf ("%%%%Title: %s\n", ps_chars (title)); }
X if (creator) { printf ("%%%%Creator: %s\n", ps_chars (creator)); }
X printf ("%%%%CreationDate: %s", ctime (&clock));
X
X printf ("/inch { 72 mul } def\n");
X printf ("/picstr %d string def\n\n", BYTESPERLINE);
X }
X else
X { printf ("%%!\n");
X if (title) { printf ("%%%%Title: %s\n", ps_chars (title)); }
X if (creator) { printf ("%%%%Creator: %s\n", ps_chars (creator)); }
X printf ("%%%%CreationDate: %s", ctime (&clock));
X printf ("%%%%Pages: 1\n");
X printf ("%%%%DocumentFonts:%s%s\n",
X dotitle ? " Times-Bold" : "",
X dosize ? " Times-Roman" : "");
X printf ("%%%%EndComments\n");
X printf ("%%%%EndProlog\n");
X printf ("%%%%Page: 1 1\n\n");
X
X printf ("/inch { 72 mul } def\n");
X printf ("/picstr %d string def\n\n", BYTESPERLINE);
X
X if (dotitle && title)
X { printf ("/Times-Bold findfont 14 scalefont setfont\n");
X printf ("%lg inch %lg inch moveto\n",
X llx + width/2.0, lly + 0.125 + height);
X printf ("(%s)\n", ps_chars (title));
X printf ("dup stringwidth pop 2 div 0 exch sub 0 rmoveto show\n\n");
X }
X
X if (dosize)
X { printf ("/Times-Roman findfont 8 scalefont setfont\n");
X printf ("%lg inch %lg inch moveto\n", llx + width, lly - 0.25);
X sprintf (buf, "[ %d by %d pixels, %1.3lf %s, %1.2lf by %1.2lf inches ]",
X image.hdr.cols, image.hdr.rows, image.hdr.aspect,
X "aspect ratio", width, height);
X printf ("(%s)\n", ps_chars (buf));
X printf ("dup stringwidth pop 0 exch sub 0 rmoveto show\n\n");
X }
X
X }
X
X printf ("gsave\n");
X
X if (llx != 0.0 || lly != 0.0)
X { printf ("%lg inch %lg inch translate ", llx, lly); }
X
X printf ("%lg inch %lg inch scale\n", width, height);
X
X if (image.hdr.planes == 3) {
X int plane;
X int plnlen = image.hdr.plnlen;
X int bits = image.hdr.bits;
X
X /* use QMS colorimage operator */
X
X printf ("/redScanLine %d string def\n", cols * 8 / bits);
X printf ("/greenScanLine %d string def\n", cols * 8 / bits);
X printf ("/blueScanLine %d string def\n", cols * 8 / bits);
X
X printf ("%d %d %d [%d 0 0 %d 0 %d]\n",
X cols, rows, bits, cols, -rows, rows);
X puts ("{currentfile redScanLine readhexstring pop}");
X puts ("{currentfile greenScanLine readhexstring pop}");
X puts ("{currentfile blueScanLine readhexstring pop}");
X puts ("true 3 colorimage");
X
X for (j = 0; j < rows; j++) {
X for (plane = 0; plane < 3; plane++) {
X for (i = 0; i < cols; i++) {
X printf ("%02x", image.bm[plane * plnlen + j * rowlen + i]);
X if (++bytcnt % BYTESPERLINE == 0)
X putchar ('\n');
X }
X bytcnt = 0;
X putchar ('\n');
X }
X }
X }
X else {
X printf ("%d %d 8 [%d 0 0 -%d 0 %d] ", cols, rows, cols, rows, rows);
X printf ("{ currentfile picstr readhexstring pop }\n");
X printf ("image\n");
X
X /* Write out bitmap */
X for (j=0; j < rows; j++)
X { for (i=0; i < cols; i++)
X { printf ("%02x", image.bm[j * rowlen + i]);
X
X if (++bytcnt % BYTESPERLINE == 0) putchar ('\n');
X }
X }
X
X }
X
X /* Pad so there are exactly BYTESPERLINE bytes in each line */
X if (bytcnt % BYTESPERLINE)
X { while (bytcnt++ % BYTESPERLINE) printf ("00");
X printf ("\n");
X }
X
X printf ("grestore\n");
X
X if (!scribe)
X { printf ("\nshowpage\n\n");
X printf ("%%%%Trailer\n");
X }
X
X exit (0);
X}
X
X/****************************************************************
X * ps_chars: Put in proper escapes so an arbitrary string works
X * according to the PostScript definition of a literal
X ****************************************************************/
X
Xchar *ps_chars (txt)
Xchar *txt;
X{ static char buf[512];
X register char *s = buf;
X char *index ();
X
X for (; *txt; txt++)
X { if (index ("()\\", *txt))
X { *s++ = '\\'; *s++ = *txt; }
X else if (*txt < ' ' || *txt > '~')
X { sprintf (s, "\\%03o", *txt & 0377); s += 4; }
X else
X { *s++ = *txt; }
X }
X *s = '\0';
X s = buf;
X return (s);
X}
END_OF_FILE
if test 7399 -ne `wc -c <'fbps.c'`; then
echo shar: \"'fbps.c'\" unpacked with wrong size!
fi
# end of 'fbps.c'
fi
if test -f 'flclr.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'flclr.c'\"
else
echo shar: Extracting \"'flclr.c'\" \(7570 characters\)
sed "s/^X//" >'flclr.c' <<'END_OF_FILE'
X/*****************************************************************
X * flclr.c: FBM Library 0.9 (Beta test) 07-Mar-89 Michael Mauldin
X *
X * Copyright (C) 1989 by Michael Mauldin. Permission is granted to
X * use this file in whole or in part provided that you do not sell it
X * for profit and that this copyright notice is retained unchanged.
X *
X * flclr.c: Color <--> BW, (Mapped Color | BW) --> unmapped color
X *
X * CONTENTS
X * clr2gray (input, output, rw, gw, bw)
X * gray2clr (input, output, sun)
X *
X * EDITLOG
X * LastEditDate = Thu Apr 20 16:55:23 1989 - Michael Mauldin
X * LastFileName = /usr2/mlm/src/misc/fbm/flclr.c
X *
X * HISTORY
X * 07-Mar-89 Michael Mauldin (mlm) at Carnegie Mellon University
X * Beta release (version 0.9) mlm at cs.cmu.edu
X *
X * 28-Nov-88 Michael Mauldin (mlm) at Carnegie-Mellon University
X * Created.
X *****************************************************************/
X
X# include <stdio.h>
X# include "fbm.h"
X
X/****************************************************************
X * clr2gray: Apply a triplet of weights to each color in and RGB
X * or mapped image and produce an 8bit grayscale image
X ****************************************************************/
X
X#ifndef lint
Xstatic char *fbmid =
X "$FBM flclr.c <0.9> 07-Mar-89 (C) 1989 by Michael Mauldin$";
X#endif
X
Xclr2gray (input, output, rw, gw, bw)
XFBM *input, *output;
Xint rw, gw, bw;
X{ int rw1, gw1, bw1, width, height, clrlen, rowlen, colors;
X register int i, j;
X register unsigned char *bmp, *obm;
X
X /* Already monochrome? */
X if (input->hdr.planes == 1 && input->hdr.clrlen == 0)
X { *output = *input; return (1); }
X
X /* Invalid raster type */
X if (input->hdr.planes != 3 && input->hdr.clrlen == 0)
X { fprintf (stderr,
X "clr2gray was passed invalid raster type, clrlen %d, planes %d\n",
X input->hdr.clrlen, input->hdr.planes);
X return (0);
X }
X
X /* Adjust weights for fast division via shift */
X rw1 = rw * 256 / (rw + gw + bw);
X gw1 = gw * 256 / (rw + gw + bw);
X bw1 = 256 - (rw1+gw1);
X
X fprintf (stderr, "Using weights [%2d %2d %2d] ==> <%3d, %3d, %3d>\n",
X rw, gw, bw, rw1, gw1, bw1);
X
X /* Allocate output bitmap */
X output->hdr = input->hdr;
X output->hdr.clrlen = 0;
X output->hdr.planes = 1;
X output->hdr.bits = output->hdr.physbits = 8;
X alloc_fbm (output);
X
X /* Set commonly used vars */
X width = input->hdr.cols;
X height = input->hdr.rows;
X rowlen = input->hdr.rowlen;
X clrlen = input->hdr.clrlen;
X colors = clrlen / 3;
X
X /* Mapped color to gray scale */
X if (input->hdr.clrlen > 0)
X { register int *gray;
X
X gray = (int *) malloc ((unsigned) input->hdr.clrlen * sizeof (int));
X
X for (i=0; i<colors; i++)
X { gray[i] = (rw1 * input->cm[i] +
X gw1 * input->cm[i+colors] +
X bw1 * input->cm[i+(colors<<1)]) >> 8;
X
X# ifdef DEBUG
X fprintf (stderr, "color %3d: [%3d %3d %3d] => %3d\n",
X i,
X input->cm[i],
X input->cm[i+colors],
X input->cm[i+colors*2],
X gray[i]);
X# endif
X
X }
X
X for (j=0; j<height; j++)
X { bmp = &(input->bm[j*rowlen]);
X obm = &(output->bm[j*rowlen]);
X
X for (i=0; i<width; i++)
X { *obm++ = gray[*bmp++]; }
X }
X }
X
X
X /* RGB color to gray scale */
X else if (input->hdr.planes == 3 && input->hdr.physbits == 8)
X { register unsigned char *rp, *gp, *bp;
X
X for (j=0; j<height; j++)
X { rp = &(input->bm[j*rowlen]);
X gp = rp + input->hdr.plnlen;
X bp = gp + input->hdr.plnlen;
X obm = (&output->bm[j*rowlen]);
X
X for (i=0; i<width; i++)
X { *obm++ = (rw1 * *rp++ +
X gw1 * *gp++ +
X bw1 * *bp++) >> 8;
X }
X }
X }
X
X return (1);
X}
X
X/****************************************************************
X * gray2clr: Add a colormap (shades of gray) to a grayscale file
X ****************************************************************/
X
Xgray2clr (input, output, sun_map)
XFBM *input, *output;
Xint sun_map;
X{ register unsigned char *rmap, *gmap, *bmap, *bmp, *obm;
X register int i, maplen, plnlen;
X
X /* Invalid raster type */
X if (input->hdr.planes == 3)
X { fprintf (stderr, "Input already is in RGB format\n");
X *output = *input; return (1);
X }
X
X /* Invalid raster type */
X if (input->hdr.clrlen > 0 )
X { fprintf (stderr, "Input already has color map with %d colors\n",
X input->hdr.clrlen / 3);
X *output = *input; return (1);
X }
X
X /* Invalid raster type */
X if (input->hdr.planes != 1 || input->hdr.clrlen != 0)
X { fprintf (stderr,
X "gray2clr was passed invalid raster type, clrlen %d, planes %d\n",
X input->hdr.clrlen, input->hdr.planes);
X return (0);
X }
X
X plnlen = input->hdr.plnlen;
X
X /* Make colormap length power of two */
X maplen = 1 << input->hdr.bits;
X
X /* Allocate output bitmap */
X output->hdr = input->hdr;
X output->hdr.clrlen = maplen * 3;
X alloc_fbm (output);
X
X rmap = &(output->cm[0]);
X gmap = &(output->cm[maplen]);
X bmap = &(output->cm[2*maplen]);
X
X for (i=0; i<maplen; i++)
X { *rmap++ = *gmap++ = *bmap++ = i; }
X
X /* For sun_map, swap colors 0 and 255 */
X if (sun_map && (maplen == 256))
X { rmap = &(output->cm[0]);
X gmap = &(output->cm[maplen]);
X bmap = &(output->cm[2*maplen]);
X
X rmap[0] = gmap[0] = bmap[0] = 255;
X rmap[255] = gmap[255] = bmap[255] = 0;
X
X /* Copy bits */
X for (bmp = input->bm, obm = output-> bm, i=0; i<plnlen; i++, bmp++)
X { if (*bmp == 0) *obm++ = 255;
X else if (*bmp == 255) *obm++ = 0;
X else *obm++ = *bmp;
X }
X }
X
X else
X {
X /* Copy bits */
X for (bmp = input->bm, obm = output-> bm, i=0; i<plnlen; i++)
X { *obm++ = *bmp++; }
X }
X
X return (1);
X}
X
X/****************************************************************
X * clr_unmap: Convert a mapped color image into RGB
X ****************************************************************/
X
Xclr_unmap (input, output)
XFBM *input, *output;
X{ register unsigned char *red, *grn, *blu, *bmp, *obm, *tail;
X register int plnlen, k;
X
X if (input->hdr.planes == 3)
X { *output = *input; return (1); }
X
X if (input->hdr.planes != 1)
X { fprintf (stderr, "clr_unmap cannot handle images with %d planes\n",
X input->hdr.planes);
X return (0);
X }
X
X if (input->hdr.physbits != 8)
X { fprintf (stderr, "clr_unmap cannot handle images with %d physbits\n",
X input->hdr.physbits);
X return (0);
X }
X
X output->hdr = input->hdr;
X output->hdr.planes = 3;
X output->hdr.clrlen = 0;
X output->hdr.bits = output->hdr.physbits;
X
X alloc_fbm (output);
X
X /* Real mapped color image */
X if (input->hdr.clrlen > 0)
X { red = &(input->cm[0]);
X grn = red + input->hdr.clrlen / 3;
X blu = grn + input->hdr.clrlen / 3;
X plnlen = input->hdr.plnlen;
X
X bmp = input->bm;
X obm = output->bm;
X tail = bmp + plnlen;
X
X while (bmp < tail)
X { k = *bmp++;
X
X obm[0] = red[k];
X obm[plnlen] = grn[k];
X obm[plnlen+plnlen] = blu[k];
X obm++;
X }
X
X }
X
X /* Grayscale image (just duplicate planes) */
X else
X { plnlen = input->hdr.plnlen;
X
X bmp = input->bm;
X tail = bmp + plnlen;
X
X red = output->bm;
X grn = red + plnlen;
X blu = grn + plnlen;
X
X while (bmp < tail)
X { *red++ = *grn++ = *blu++ = *bmp++; }
X }
X
X return (1);
X}
X
X/****************************************************************
X * copy_clr: Copy colormap from input to output
X ****************************************************************/
X
Xcopy_clr (input, output)
XFBM *input, *output;
X{ register int i, clrlen;
X register unsigned char *ic, *oc;
X
X output->hdr.clrlen = clrlen = input->hdr.clrlen;
X
X ic = input->cm;
X oc = output->cm;
X
X for (i=0; i < clrlen; i++)
X { *oc++ = *ic++; }
X}
END_OF_FILE
if test 7570 -ne `wc -c <'flclr.c'`; then
echo shar: \"'flclr.c'\" unpacked with wrong size!
fi
# end of 'flclr.c'
fi
if test -f 'fledge.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'fledge.c'\"
else
echo shar: Extracting \"'fledge.c'\" \(8359 characters\)
sed "s/^X//" >'fledge.c' <<'END_OF_FILE'
X/*****************************************************************
X * fledge.c: FBM Library 0.9 (Beta test) 07-Mar-89 Michael Mauldin
X *
X * Copyright (C) 1989 by Gary Sherwin & Michael Mauldin.
X * Permission is granted to use this file in whole or in part provided
X * that you do not sell it for profit and that this copyright notice
X * is retained unchanged.
X *
X * fledge.c:
X *
X * CONTENTS
X * findedge_fbm (&image, beta)
X *
X * EDITLOG
X * LastEditDate = Tue Mar 7 19:56:54 1989 - Michael Mauldin
X * LastFileName = /usr2/mlm/src/misc/fbm/fledge.c
X *
X * HISTORY
X * 07-Mar-89 Michael Mauldin (mlm) at Carnegie Mellon University
X * Beta release (version 0.9) mlm at cs.cmu.edu
X *
X * 21-Aug-88 Michael Mauldin (mlm) at Carnegie-Mellon University
X * Created.
X *****************************************************************/
X
X# include <stdio.h>
X# include <math.h>
X# include <ctype.h>
X# include "fbm.h"
X
X/****************************************************************
X * findedge_fbm: determine whether image is in color, and call the
X * appropriate edge detection routine.
X ****************************************************************/
X
X#ifndef lint
Xstatic char *fbmid =
X "$FBM fledge.c <0.9> 07-Mar-89 (C) 1989 by Michael Mauldin$";
X#endif
X
Xfindedge_fbm (input, output, beta)
XFBM *input, *output;
Xint beta;
X{
X if (input->hdr.planes == 1)
X { return (findedge_bw (input, output, beta)); }
X else
X { return (findedge_bw (input, output, beta)); }
X}
X
X/****************************************************************
X * findedge_bw: use a digital Laplacian filter to edge detect a BW image
X ****************************************************************/
X
Xfindedge_bw (input, output, beta)
XFBM *input, *output;
Xint beta;
X{ register unsigned char *bmp, *obm;
X register int i, j, rowlen, w, h;
X int new, sum;
X int bf, wf, tf; /* white and black pixel counters */
X
X/* Filter Chip
X*
X*
X* UL, UC, UR
X* CL, CC, CR
X* BL, BC, BR
X*
X*/
X
X if (input->hdr.planes != 1)
X { fprintf (stderr, "findedge_bw: can't process color images\n");
X return (0);
X }
X
X fprintf (stderr, "Edge detect BW, beta %d\n", beta);
X
X /* Allocate output */
X output->hdr = input->hdr;
X alloc_fbm (output);
X
X w = input->hdr.cols;
X h = input->hdr.rows;
X rowlen = input->hdr.rowlen;
X
X /* Set pixel counters for image statistics */
X bf = wf = tf = 0;
X
X /* Compute outer border of pixels */
X /* Compute Top Line U of Pixels */
X /* Compute ULPixel */
X
X j=0;
X { bmp = &(input->bm[j*rowlen]);
X obm = &(output->bm[j*rowlen]);
X
X i=0;
X { sum = 0;
X sum = sum + (bmp[i]*(-3) + bmp[i+1] );
X sum = sum + (bmp[i+rowlen] + bmp[i+rowlen+1]);
X sum = (sum * 8) / 3;
X
X if (sum > beta) { new = BLACK; bf++; }
X else { new = WHITE; wf++; }
X
X tf++;
X
X obm[i] = new;
X
X }
X
X /* Compute URPixel */
X
X i=w;
X { sum = 0;
X sum = sum + (bmp[i-1]*(-3) + bmp[i] ) ;
X sum = sum + (bmp[i+rowlen-1] + bmp[i+rowlen] ) ;
X sum = (sum * 8) / 3;
X
X if (sum > beta) { new = BLACK; bf++; }
X else { new = WHITE; wf++; }
X
X tf++;
X
X obm[i] = new;
X
X }
X
X /* Compute Rest of U1 Line */
X
X for (i=1; i < w-1; i++)
X { sum = 0;
X sum = sum + (bmp[i-1]*(-5) + bmp[i] + bmp[i+1] ) ;
X sum = sum + (bmp[i+rowlen-1] + bmp[i+rowlen] + bmp[i+rowlen+1]) ;
X sum = (sum * 8) / 5;
X
X if (sum > beta) { new = BLACK; bf++; }
X else { new = WHITE; wf++; }
X
X tf++;
X
X obm[i] = new;
X
X }
X }
X
X /* Compute Left and Right borders */
X
X for (j=1; j < h-1; j++)
X { bmp = &(input->bm[j*rowlen]);
X obm = &(output->bm[j*rowlen]);
X
X /* Compute L Pixel */
X i=0;
X { sum = 0;
X sum = sum + (bmp[i-rowlen] + bmp[i-rowlen+1]) ;
X sum = sum + (bmp[i]*(-5) + bmp[i+1] ) ;
X sum = sum + (bmp[i+rowlen] + bmp[i+rowlen+1]) ;
X sum = (sum * 8) / 5;
X
X if (sum > beta) { new = BLACK; bf++; }
X else { new = WHITE; wf++; }
X
X tf++;
X
X obm[i] = new;
X
X }
X
X
X /* Compute R1Pixel */
X i=w;
X { sum = 0;
X sum = sum + (bmp[i-rowlen-1] + bmp[i-rowlen] ) ;
X sum = sum + (bmp[i-1] + bmp[i]*(-5) ) ;
X sum = sum + (bmp[i+rowlen-1] + bmp[i+rowlen] ) ;
X sum = (sum * 8) / 5;
X
X if (sum > beta) { new = BLACK; bf++; }
X else { new = WHITE; wf++; }
X
X tf++;
X
X obm[i] = new;
X
X }
X }
X
X /* Compute Bottom Line B of Pixels */
X /* Compute BL Pixel */
X j=h;
X { bmp = &(input->bm[j*rowlen]);
X obm = &(output->bm[j*rowlen]);
X
X i=0;
X { sum = 0;
X sum = sum + (bmp[i-rowlen] + bmp[i-rowlen+1]) ;
X sum = sum + (bmp[i]*(-3) + bmp[i+1] ) ;
X sum = (sum * 8) / 3;
X
X if (sum > beta) { new = BLACK; bf++; }
X else { new = WHITE; wf++; }
X
X tf++;
X
X obm[i] = new;
X
X }
X
X /* Compute BR Pixel */
X
X i=w;
X { sum = 0;
X sum = sum + (bmp[i-rowlen-1] + bmp[i-rowlen] ) ;
X sum = sum + (bmp[i-1] + bmp[i]*(-3) ) ;
X sum = (sum * 8) / 3;
X
X if (sum > beta) { new = BLACK; bf++; }
X else { new = WHITE; wf++; }
X
X tf++;
X
X obm[i] = new;
X
X }
X
X /* Compute Rest of B1 Line */
X
X for (i=1; i < w-1; i++)
X { sum = 0;
X sum = sum + (bmp[i-rowlen-1] + bmp[i-rowlen] + bmp[i-rowlen+1]) ;
X sum = sum + (bmp[i-1] + bmp[i]*(-5) + bmp[i+1] ) ;
X sum = (sum * 8) / 5;
X
X if (sum > beta) { new = BLACK; bf++; }
X else { new = WHITE; wf++; }
X
X tf++;
X
X obm[i] = new;
X
X }
X }
X
X /* Compute Main Image Body */
X
X for (j=1; j < h-1; j++)
X { bmp = &(input->bm[j*rowlen]);
X obm = &(output->bm[j*rowlen]);
X
X for (i=1; i < w-1; i++)
X { sum = 0;
X sum = sum + (bmp[i-rowlen-1] + bmp[i-rowlen] + bmp[i-rowlen+1]) ;
X sum = sum + (bmp[i-1] + bmp[i]*(-8) + bmp[i+1] ) ;
X sum = sum + (bmp[i+rowlen-1] + bmp[i+rowlen] + bmp[i+rowlen+1]) ;
X
X if (sum > beta) { new = BLACK; bf++; }
X else { new = WHITE; wf++; }
X
X tf++;
X
X obm[i] = new;
X
X }
X }
X
X fprintf (stderr, "Edge detection complete for slope of %2d for %d pixels.\n", beta, tf);
X fprintf (stderr, "Detected %d white pixels and %d black pixels.\n", bf, wf);
X
X return (1);
X}
X
X/****************************************************************
X * findedge_clr: use a digital Laplacian filter to edge detect a CLR image
X ****************************************************************/
X
Xfindedge_clr (input, output, beta)
XFBM *input, *output;
Xdouble beta;
X{ register unsigned char *bmp, *obm, *avg;
X register int i, j, k, rowlen, plnlen, w, h, p, sum;
X int new, delta, beta100 = beta * 100;
X unsigned char *gray;
X
X fprintf (stderr, "Sharpen color, beta %lg\n", beta);
X
X /* Allocate output */
X output->hdr = input->hdr;
X alloc_fbm (output);
X
X w = input->hdr.cols;
X h = input->hdr.rows;
X p = input->hdr.planes;
X rowlen = input->hdr.rowlen;
X plnlen = input->hdr.plnlen;
X
X /* Calculate the intensity plane */
X gray = (unsigned char *) malloc (plnlen);
X
X for (j=0; j<h; j++)
X { bmp = &(input->bm[j*rowlen]);
X avg = &(gray[j*rowlen]);
X
X for (i=0; i<w; i++)
X { sum = 0;
X for (k=0; k<p; k++)
X { sum += bmp[i+k*plnlen]; }
X avg[i] = sum/p;
X }
X }
X
X /* Copy edges directly */
X for (k=0; k<p; k++)
X { for (j=0; j<h; j++)
X { output->bm[k*plnlen + j*rowlen] =
X input->bm[k*plnlen + j*rowlen];
X output->bm[k*plnlen + j*rowlen + w-1] =
X input->bm[k*plnlen + j*rowlen + w-1];
X }
X
X for (i=0; i<w; i++)
X { output->bm[k*plnlen + i] =
X input->bm[k*plnlen + i];
X output->bm[k*plnlen + (h-1)*rowlen + i] =
X input->bm[k*plnlen + (h-1)*rowlen + i];
X }
X }
X
X for (j=1; j < h-1; j++)
X { avg = &(gray[j*rowlen]);
X
X for (i=1; i < w-1; i++)
X { sum = avg[i-rowlen-1] + avg[i-rowlen] + avg[i-rowlen+1] +
X avg[i-1] - 8 * avg[i] + avg[i+1] +
X avg[i+rowlen-1] + avg[i+rowlen] + avg[i+rowlen+1];
X
X for (k=0; k<p; k++)
X { bmp = &(input->bm[k*plnlen + j*rowlen + i]);
X obm = &(output->bm[k*plnlen + j*rowlen + i]);
X
X if (sum < 0)
X { delta = - (beta100 * *bmp * -sum / (8*100)); }
X else
X { delta = beta100 * *bmp * sum / (8*100); }
X
X new = *bmp - delta;
X
X if (new < BLACK) new = BLACK;
X else if (new > WHITE) new = WHITE;
X
X *obm = new;
X }
X }
X }
X}
END_OF_FILE
if test 8359 -ne `wc -c <'fledge.c'`; then
echo shar: \"'fledge.c'\" unpacked with wrong size!
fi
# end of 'fledge.c'
fi
if test -f 'flklnr.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'flklnr.c'\"
else
echo shar: Extracting \"'flklnr.c'\" \(6703 characters\)
sed "s/^X//" >'flklnr.c' <<'END_OF_FILE'
X/*****************************************************************
X * flklnr.c: FBM Library 0.9 (Beta test) 07-Mar-89 Michael Mauldin
X *
X * Copyright (C) 1989 by Michael Mauldin. Permission is granted to
X * use this file in whole or in part provided that you do not sell it
X * for profit and that this copyright notice is retained unchanged.
X *
X * fbm.c:
X *
X * USAGE
X * clean_fbm (input, output, beta, gamma, nbr)
X *
X * EDITLOG
X * LastEditDate = Tue Mar 7 19:57:19 1989 - Michael Mauldin
X * LastFileName = /usr2/mlm/src/misc/fbm/flklnr.c
X *
X * HISTORY
X * 07-Mar-89 Michael Mauldin (mlm) at Carnegie Mellon University
X * Beta release (version 0.9) mlm at cs.cmu.edu
X *
X * 21-Aug-88 Michael Mauldin (mlm) at Carnegie-Mellon University
X * Created.
X *****************************************************************/
X
X# include <stdio.h>
X# include <math.h>
X# include <ctype.h>
X# include "fbm.h"
X
X/****************************************************************
X * clean_fbm: determine whether image is in color, and call the
X * appropriate cleaning routine.
X ****************************************************************/
X
X#ifndef lint
Xstatic char *fbmid =
X "$FBM flklnr.c <0.9> 07-Mar-89 (C) 1989 by Michael Mauldin$";
X#endif
X
Xclean_fbm (input, output, beta, gamma, nbr)
XFBM *input, *output;
Xint beta, gamma, nbr;
X{
X if (input->hdr.planes == 1)
X { return (clean_bw (input, output, beta, gamma, nbr)); }
X else
X { return (clean_bw (input, output, beta, gamma, nbr)); }
X}
X
X/****************************************************************
X * clean_bw: use a digital Laplacian filter to clean a BW image
X ****************************************************************/
X
Xclean_bw (input, output, beta, gamma, nbr)
XFBM *input, *output;
Xint beta, gamma, nbr;
X{ register unsigned char *obm, *bmp;
X register int dx, dy, left, right, top, bot, i, j;
X int rowlen, w, h, off, cnt;
X int new, sum, sumw, sumb, Whites;
X int bf, wf, ubf, uwf; /* white and black pixel counters */
X
X double pc;
X
X if (input->hdr.planes != 1)
X { fprintf (stderr, "clean_bw: can't process color images\n");
X return (0);
X }
X
X fprintf (stderr, "Clean BW, beta %d, gamma %d, nbr %d\n",
X beta, gamma, nbr);
X
X /* Allocate output */
X output->hdr = input->hdr;
X alloc_fbm (output);
X
X w = input->hdr.cols;
X h = input->hdr.rows;
X rowlen = input->hdr.rowlen;
X Whites = 252;
X
X /* If not edge detect do black white trip point */
X if (gamma > 0)
X {
X fprintf (stderr, "Thresholding image, gamma %d...\n", gamma);
X bf = wf = 0;
X for (j=0; j < h; j++)
X { bmp = &(input->bm[j*rowlen]);
X
X for (i=0; i < w; i++)
X {
X if (bmp[i] >= gamma) { bmp[i] = WHITE; wf++; }
X else { bmp[i] = BLACK; bf++; }
X }
X }
X
X pc = (((double)bf) * 100.00) / ((double)(bf + wf));
X fprintf (stderr, "Converted to %1.2f %% Black, %1.2f %% White image.\n",
X pc, (100.00 - pc));
X }
X
X /* Set pixel counters for image statistics */
X bf = wf = ubf = uwf = 0;
X off = nbr/2;
X
X /* Compute outer border of 2 pixels */
X /* Compute Top Line U1 of Pixels */
X /* Compute U1L1Pixel */
X
X /* Compute Main Image Body */
X for (j=0; j<h; j++)
X { obm = &(output->bm[j*rowlen]);
X
X /* Set limits of neighborhood */
X top = j-off; if (top < 0) top = 0;
X bot = top+nbr; if (bot > h) bot = h;
X
X for (i=0; i<w; i++)
X { sum = 0;
X cnt = 0;
X
X /* Set limits of neighborhood */
X left = i-off; if (left < 0) left = 0;
X right = left+nbr; if (right > w) right = w;
X
X /* Sample neighborhood */
X bmp = &(input->bm[top*rowlen]);
X
X for (dy = top; dy < bot; dy++, bmp += rowlen)
X { for (dx = left; dx < right; dx++)
X { sum += bmp[dx]; cnt ++; }
X }
X
X if (cnt == 0)
X { fprintf (stderr, "Panic, no pixels in neighborhood!\n");
X abort ();
X }
X
X sumw = sum * 100 / (WHITE * cnt);
X sumb = 100 - sumw;
X
X if (input->bm[i + j*rowlen] > Whites)
X {
X if (sumw < beta) { new = BLACK; bf++; }
X else { new = WHITE; uwf++; }
X }
X else
X {
X if (sumb < beta) { new = WHITE; wf++; }
X else { new = BLACK; ubf++; }
X }
X
X obm[i] = new;
X }
X }
X
X
X fprintf (stderr, "Cleaning pass complete for %2d neighbors of %d pixels.\n",
X beta, w*h);
X fprintf (stderr, "Removed %d white pixels and %d black pixels.\n", bf, wf);
X fprintf (stderr, "Left Unchanged %d white and %d black pixels.\n", uwf, ubf);
X
X return (1);
X}
X
X# ifdef UNDEFINED
X/****************************************************************
X * clean_clr: use a digital Laplacian filter to edge detect a CLR image
X ****************************************************************/
X
Xclean_clr (input, output, beta)
XFBM *input, *output;
Xdouble beta;
X{ register unsigned char *b, *obm, *avg;
X register int i, j, k, rowlen, plnlen, w, h, p, sum;
X int new, delta, beta100 = beta * 100;
X unsigned char gray[500000];
X
X fprintf (stderr, "Sharpen color, beta %lg\n", beta);
X
X /* Allocate output */
X output->hdr = input->hdr;
X alloc_fbm (output);
X
X w = input->hdr.cols;
X h = input->hdr.rows;
X p = input->hdr.planes;
X rowlen = input->hdr.rowlen;
X plnlen = input->hdr.plnlen;
X
X /* Calculate the intensity plane */
X/* gray = (unsigned char *) malloc (plnlen); */
X
X fprintf (stderr, "Allocating %d bytes for gray[]\n", plnlen);
X
X for (j=0; j<h; j++)
X { b = &(input->bm[j*rowlen]);
X avg = &(gray[j*rowlen]);
X
X for (i=0; i<w; i++)
X { sum = 0;
X for (k=0; k<p; k++)
X { sum += b[i+k*plnlen]; }
X avg[i] = sum/p;
X }
X }
X
X /* Copy edges directly */
X for (k=0; k<p; k++)
X { for (j=0; j<h; j++)
X { output->bm[k*plnlen + j*rowlen] =
X input->bm[k*plnlen + j*rowlen];
X output->bm[k*plnlen + j*rowlen + w-1] =
X input->bm[k*plnlen + j*rowlen + w-1];
X }
X
X for (i=0; i<w; i++)
X { output->bm[k*plnlen + i] =
X input->bm[k*plnlen + i];
X output->bm[k*plnlen + (h-1)*rowlen + i] =
X input->bm[k*plnlen + (h-1)*rowlen + i];
X }
X }
X
X for (j=1; j < h-1; j++)
X { avg = &(gray[j*rowlen]);
X
X for (i=1; i < w-1; i++)
X { sum = avg[i-rowlen-1] + avg[i-rowlen] + avg[i-rowlen+1] +
X avg[i-1] - 8 * avg[i] + avg[i+1] +
X avg[i+rowlen-1] + avg[i+rowlen] + avg[i+rowlen+1];
X
X for (k=0; k<p; k++)
X { b = &(input->bm[k*plnlen + j*rowlen + i]);
X obm = &(output->bm[k*plnlen + j*rowlen + i]);
X
X if (sum < 0)
X { delta = - (beta100 * *b * -sum / (8*100)); }
X else
X { delta = beta100 * *b * sum / (8*100); }
X
X new = *b - delta;
X
X if (new < BLACK) new = BLACK;
X else if (new > WHITE) new = WHITE;
X
X *obm = new;
X }
X }
X }
X
X return (1);
X}
X# endif
END_OF_FILE
if test 6703 -ne `wc -c <'flklnr.c'`; then
echo shar: \"'flklnr.c'\" unpacked with wrong size!
fi
# end of 'flklnr.c'
fi
if test -f 'flsun.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'flsun.c'\"
else
echo shar: Extracting \"'flsun.c'\" \(8735 characters\)
sed "s/^X//" >'flsun.c' <<'END_OF_FILE'
X/*****************************************************************
X * flsun.c: FBM Library 0.94 (Beta test) 20-May-89 Michael Mauldin
X *
X * Copyright (C) 1989 by Michael Mauldin. Permission is granted to
X * use this file in whole or in part provided that you do not sell it
X * for profit and that this copyright notice is retained unchanged.
X *
X * flsun.c:
X *
X * CONTENTS
X * read_sun (image, rfile, mstr, mlen)
X * write_sun (image, wfile)
X *
X * EDITLOG
X * LastEditDate = Sat May 20 19:08:32 1989 - Michael Mauldin
X * LastFileName = /usr2/mlm/src/misc/fbm/flsun.c
X *
X * HISTORY
X * 20-May-89 Michael Mauldin (mlm) at Carnegie Mellon University
X * Fixed problem with odd length rows on reading
X *
X * 07-Mar-89 Michael Mauldin (mlm) at Carnegie Mellon University
X * Beta release (version 0.9) mlm at cs.cmu.edu
X *
X * 12-Nov-88 Michael Mauldin (mlm) at Carnegie-Mellon University
X * Created.
X *****************************************************************/
X
X# include <stdio.h>
X# include <math.h>
X# include <ctype.h>
X# include "fbm.h"
X
Xtypedef struct rasterfile {
X long ras_magic;
X long ras_width;
X long ras_height;
X long ras_depth;
X long ras_length;
X long ras_type;
X long ras_maptype;
X long ras_maplength;
X} RASHDR;
X
X# define RT_STANDARD 1
X# define RMT_NONE 0
X# define RMT_EQUAL_RGB 1
X# define RMT_RAW 2
X
X# define RED 0
X# define GRN 1
X# define BLU 2
X
X/****************************************************************
X * write_sun (image, wfile)
X ****************************************************************/
X
X#ifndef lint
Xstatic char *fbmid =
X "$FBM flsun.c <0.9> 07-Mar-89 (C) 1989 by Michael Mauldin$";
X#endif
X
Xwrite_sun (image, wfile)
XFBM *image;
XFILE *wfile;
X{ RASHDR rhdr;
X register int i, j, byte;
X register unsigned char *bmp, *rp, *gp, *bp;
X int width, height, plnlen, clrlen, rowlen, depth, bits;
X
X if (image->hdr.planes != 1 && image->hdr.planes != 3)
X { fprintf (stderr,
X "Error, write_sun can only handle images with depth 1 or 3\n");
X return (0);
X }
X
X if (image->hdr.physbits != 8)
X { fprintf (stderr,
X "Error, write_sun can only handle 8 physical bits per pixel\n");
X return (0);
X }
X
X if (image->hdr.physbits == 1 && (image->hdr.rowlen % 16) != 0)
X { fprintf (stderr,
X "Error, 1 bit deep files must have rowlen (%d) divisible by 16");
X return (0);
X }
X
X if (image->hdr.physbits == 8 && image->hdr.bits == 1)
X bits = 1;
X else
X bits = image->hdr.physbits > 1 ? 8 : 1;
X
X# ifdef DEBUG
X fprintf (stderr, "write_sun: [%dx%d] rowlen %d, planes %d, bits %d, physbits %d, using %d\n",
X image->hdr.cols,
X image->hdr.rows,
X image->hdr.rowlen,
X image->hdr.planes,
X image->hdr.bits,
X image->hdr.physbits,
X bits);
X# endif
X
X width = image->hdr.cols;
X height = image->hdr.rows;
X rowlen = image->hdr.rowlen;
X plnlen = image->hdr.plnlen;
X clrlen = image->hdr.clrlen;
X depth = bits * image->hdr.planes;
X
X /* Initialize Sun raster header */
X rhdr.ras_magic = SUN_MAGIC;
X rhdr.ras_width = width;
X rhdr.ras_height = height;
X rhdr.ras_depth = depth;
X rhdr.ras_length = plnlen * bits / 8;
X rhdr.ras_type = RT_STANDARD;
X rhdr.ras_maptype = depth > 8 ? RMT_RAW : clrlen ? RMT_EQUAL_RGB : RMT_NONE;
X rhdr.ras_maplength = clrlen;
X
X /* Write rasterfile header - note: use Sun byte order */
X put_long (rhdr.ras_magic, wfile, BIG);
X put_long (rhdr.ras_width, wfile, BIG);
X put_long (rhdr.ras_height, wfile, BIG);
X put_long (rhdr.ras_depth, wfile, BIG);
X put_long (rhdr.ras_length, wfile, BIG);
X put_long (rhdr.ras_type, wfile, BIG);
X put_long (rhdr.ras_maptype, wfile, BIG);
X put_long (rhdr.ras_maplength, wfile, BIG);
X
X /* Dump colormap if need be */
X if (clrlen > 0)
X { fwrite (image->cm, 1, clrlen, wfile); }
X
X /* Write bytes */
X switch (depth)
X { case 24: rp = &image->bm[0];
X gp = rp + plnlen;
X bp = gp + plnlen;
X
X for (i=0; i<plnlen; i++)
X { fputc (*rp++, wfile);
X fputc (*gp++, wfile);
X fputc (*bp++, wfile);
X }
X break;
X
X case 8: fwrite (image->bm, 1, plnlen, wfile);
X break;
X
X case 1:
X# ifdef DEBUG
X fprintf (stderr, "Writing Sun 1bit file [%dx%d] rowlen %d\n",
X width, height, rowlen);
X# endif
X for (j=0; j<height; j++)
X { bmp = &(image->bm[j*rowlen]);
X byte = 0;
X
X for (i=0; i<rowlen; i++)
X { byte = (byte << 1) | (*bmp++ ? 0 : 1);
X
X if ((i & 7) == 7)
X { fputc (byte, wfile); byte = 0; }
X }
X }
X break;
X
X default: fprintf (stderr,
X "Error, write_sun given invalid depth %d bits\n",
X depth);
X return (0);
X }
X return (1);
X}
X
X/****************************************************************
X * read_sun (image, rfile)
X ****************************************************************/
X
Xread_sun (image, rfile, mstr, mlen)
XFBM *image;
XFILE *rfile;
Xchar *mstr;
Xint mlen;
X{ RASHDR rhdr;
X int width, height, plnlen, rowlen, clrlen, res, depth;
X register int i, j, byte;
X register unsigned char *bmp, *rp, *gp, *bp;
X int m1, m2, m3, m4;
X
X m1 = NEXTMCH(rfile,mstr,mlen) & 0xff;
X m2 = NEXTMCH(rfile,mstr,mlen) & 0xff;
X m3 = NEXTMCH(rfile,mstr,mlen) & 0xff;
X m4 = NEXTMCH(rfile,mstr,mlen) & 0xff;
X
X rhdr.ras_magic = (m1 << 24) | (m2 << 16) | (m3 << 8)| (m4);
X
X /* Write rasterfile header - note: use Sun byte order */
X if (rhdr.ras_magic != SUN_MAGIC)
X { fprintf (stderr, "Error, not a Sun raster file (bad magic %08x)\n",
X rhdr.ras_magic);
X return (0);
X }
X
X rhdr.ras_width = get_long (rfile, BIG);
X rhdr.ras_height = get_long (rfile, BIG);
X rhdr.ras_depth = get_long (rfile, BIG);
X rhdr.ras_length = get_long (rfile, BIG);
X rhdr.ras_type = get_long (rfile, BIG);
X rhdr.ras_maptype = get_long (rfile, BIG);
X rhdr.ras_maplength = get_long (rfile, BIG);
X
X /* Check for nonstandard rasterfile formats */
X if (rhdr.ras_type != RT_STANDARD)
X { fprintf (stderr, "Error: rasterfile is not a Sun RT_STANDARD file\n");
X return (0);
X }
X
X if (rhdr.ras_maplength > 0 && rhdr.ras_maptype != RMT_EQUAL_RGB)
X { fprintf (stderr, "Error: color rasterfile is not RMT_EQUAL_RGB\n");
X return (0);
X }
X
X if (rhdr.ras_maplength == 0 &&
X rhdr.ras_maptype != RMT_NONE &&
X rhdr.ras_maptype != RMT_RAW)
X { fprintf (stderr, "Error: black and white rasterfile is not RMT_NONE\n");
X return (0);
X }
X
X if (rhdr.ras_depth != 24 && rhdr.ras_depth != 8 && rhdr.ras_depth != 1)
X { fprintf (stderr, "Error, bits per pixel (%d) must be 1, 8 or 24\n",
X rhdr.ras_depth);
X return (0);
X }
X
X /* Initialize and allocate input image */
X width = rhdr.ras_width;
X height = rhdr.ras_height;
X depth = rhdr.ras_depth;
X clrlen = rhdr.ras_maplength;
X
X if (depth == 1)
X { rowlen = 16 * ((width + 15) / 16);
X plnlen = rowlen * height;
X }
X else
X { rowlen = width;
X if (rowlen & 1) rowlen++;
X
X plnlen = width * height;
X }
X
X /* Check for consitency between colormap and depth */
X if (depth > 8 && clrlen > 0)
X { fprintf (stderr,
X "Error, input has colormap of length %d, but %d bits per pixel\n",
X clrlen, depth);
X return (0);
X }
X
X /* Initialize image header */
X image->hdr.cols = width;
X image->hdr.rows = height;
X image->hdr.planes = (depth == 24) ? 3 : 1;
X image->hdr.bits = (depth == 24) ? 8 : depth;
X image->hdr.physbits = 8;
X image->hdr.rowlen = rowlen;
X image->hdr.plnlen = plnlen;
X image->hdr.clrlen = clrlen;
X image->hdr.aspect = 1.0;
X image->hdr.title[0] = '\0';
X image->hdr.credits[0] = '\0';
X
X /* Allocate space */
X alloc_fbm (image);
X
X /* Read colormap if need be */
X if (clrlen > 0 && (res = fread (image->cm, 1, clrlen, rfile)) != clrlen)
X { fprintf (stderr, "Error: couldn't read colormap, read %d of %d bytes\n",
X res, clrlen);
X return (0);
X }
X
X /* Read bytes */
X switch (depth)
X { case 24: rp = &image->bm[0];
X gp = rp + plnlen;
X bp = gp + plnlen;
X
X for (i=0; i<plnlen && !feof (rfile); i++)
X { *rp++ = fgetc (rfile);
X *gp++ = fgetc (rfile);
X *bp++ = fgetc (rfile);
X }
X
X if (i<plnlen)
X { fprintf (stderr, "Error: %s %d of %d pixels (%d bytes)\n",
X "EOF on bitmap after",
X i, plnlen, plnlen * image->hdr.planes);
X return (0);
X }
X
X break;
X
X case 8: if ((res = fread (image->bm, 1, plnlen, rfile)) != plnlen)
X { fprintf (stderr,
X "Error: EOF on bitmap after %d of %d bytes\n",
X res, plnlen);
X return (0);
X }
X break;
X
X case 1: for (j=0; j<height; j++)
X { bmp = &(image->bm[j * rowlen]);
X
X for (i=0; i<rowlen; i++)
X { if ((i&7) == 0)
X { if ((byte = fgetc (rfile)) == EOF)
X { fprintf (stderr,
X "Error: EOF on bitmap after %d of %d bytes\n",
X j*rowlen + i, height*rowlen);
X return (0);
X }
X }
X
X *bmp++ = (byte & 0x80) ? BLACK : WHITE;
X byte <<= 1;
X }
X }
X break;
X default: fprintf (stderr, "Invalid depth %d bits\n", depth);
X return (0);
X }
X
X return (1);
X}
END_OF_FILE
if test 8735 -ne `wc -c <'flsun.c'`; then
echo shar: \"'flsun.c'\" unpacked with wrong size!
fi
# end of 'flsun.c'
fi
if test -f 'pbm2ps.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'pbm2ps.c'\"
else
echo shar: Extracting \"'pbm2ps.c'\" \(7263 characters\)
sed "s/^X//" >'pbm2ps.c' <<'END_OF_FILE'
X/*****************************************************************
X * pbm2ps.c: FBM Library 0.9 (Beta test) 07-Mar-89 Michael Mauldin
X *
X * Copyright (C) 1989 by Michael Mauldin. Permission is granted to
X * use this file in whole or in part provided that you do not sell it
X * for profit and that this copyright notice is retained unchanged.
X *
X * pbm2ps.c:
X *
X * USAGE
X * % pbm2ps [ flags ] arguments
X *
X * BUGS
X * Will blow up if the title has PostScript special characters
X * in it (especially unbalanced parens)
X *
X * EDITLOG
X * LastEditDate = Wed Mar 8 14:23:08 1989 - Michael Mauldin
X * LastFileName = /usr2/mlm/src/misc/fbm/pbm2ps.c
X *
X * HISTORY
X * 07-Mar-89 Michael Mauldin (mlm) at Carnegie Mellon University
X * Beta release (version 0.9) mlm at cs.cmu.edu
X *
X * 14-Sep-88 Michael Mauldin (mlm) at Carnegie-Mellon University
X * Created.
X *****************************************************************/
X
X# include <stdio.h>
X# include <ctype.h>
X
X# define MAXBAD 10
X
X# define USAGE "Usage: pbm2ps [ -s ] [ scale ] < pbm > postscript"
X
Xunsigned char *bits;
Xint w, h;
Xchar title[80];
X
X/****************************************************************
X * main: Read a pbm format file and write it out as PostScript
X ****************************************************************/
X
X#ifndef lint
Xstatic char *fbmid =
X "$FBM pbm2ps.c <0.9> 07-Mar-89 (C) 1989 by Michael Mauldin$";
X#endif
X
Xmain (argc, argv)
Xchar *argv[];
X{ int scale = -1, scribe = 0;
X
X /* Get option */
X while (--argc > 0 && (*++argv)[0] == '-')
X { while (*++(*argv))
X { switch (**argv)
X { case 's': scribe++; break;
X default: fprintf (stderr, USAGE);
X exit (1);
X }
X }
X }
X
X if (argc > 0 && (scale = atoi (argv[0])) < 1)
X { fprintf (stderr, USAGE); exit (1); }
X
X if (read_pbm (stdin) && write_ps (scale, scribe)) exit (0);
X
X exit (1);
X}
X
X/****************************************************************
X * read_pbm: Read a pbm bitmap into character array 'bits', setting
X * width, height, and title
X ****************************************************************/
X
Xread_pbm (rfile)
XFILE *rfile;
X{ int ch;
X register unsigned char *bmp, *tail;
X int badcnt=0;
X
X if ((ch = getc (rfile)) != 'P' || (ch = getc (rfile)) != '1')
X { fprintf (stderr, "bad magic number, input not PBM file\n");
X return (0);
X }
X
X title[0] = '\0';
X
X if ((w = pbm_getint (stdin)) < 0 || (h = pbm_getint (stdin)) < 0)
X { return (0); }
X
X bits = (unsigned char *) malloc (w*h);
X
X bmp = bits;
X tail = &bmp[h*w];
X
X /* Read bits, inverting so that 1=white and 0=black */
X while (bmp < tail && (ch = getc (rfile)) != EOF)
X { if (ch == '0') *bmp++ = 1;
X else if (ch == '1') *bmp++ = 0;
X else if (ch == '#') eatcomment ();
X else if (isspace (ch)) /* ignore it */ ;
X else if (++badcnt < MAXBAD)
X { fprintf (stderr, "Ignoring junk character '%c'\n", ch); }
X else
X { fprintf (stderr, "Too many junk characters, bye!\n"); exit (1); }
X }
X
X if (ch == EOF)
X { fprintf (stderr, "premature EOF, read %d of %d bits in [%dx%d]\n",
X (bmp - bits), (tail - bits), w, h);
X return (0);
X }
X
X return (1);
X}
X
X/*****************************************************************
X * pbm_getint: Read a number from a PBM file, ignoring comments
X *****************************************************************/
X
Xpbm_getint (rfile)
XFILE *rfile;
X{ register int ch;
X register int val = 0;
X
X while ((ch = getc (rfile)) != EOF)
X { if (ch == '#') eatcomment ();
X else if (isspace (ch)) /* ignore it */ ;
X else if (isdigit (ch)) break;
X else
X { fprintf (stderr, "Found junk character '%c' in header\n", ch);
X return (-1);
X }
X }
X
X while (isdigit (ch))
X { val = val*10 + ch - '0';
X ch = getc (rfile);
X }
X
X return (val);
X}
X
X/*****************************************************************
X * eatcomment: Read comments and look for titles
X *****************************************************************/
X
Xeatcomment ()
X{ char cmtbuf[80];
X register char *s;
X
X /* Read rest of line, remove trailing newline and skip over leading spaces */
X fgets (cmtbuf, sizeof (cmtbuf), stdin);
X cmtbuf[strlen (cmtbuf) - 1] = '\0';
X for (s=cmtbuf; isspace (*s); s++) ;
X
X /* If the comment contains the title, squirrel it away */
X if (!strncmp (s, "Title: ", 7)) strcpy (title, s+7);
X fprintf (stderr, "Reading '%s'\n", title);
X}
X
X/****************************************************************
X * write_ps: Write out a 1 bit deep bitmap as a PostScript file
X *
X * Output is centered with at least 1" left margin, 1/2" right,
X * top and bottom margins.
X *
X * The title is printed in 14 pt Times-Bold centered at the top.
X * One half inch at the top is reserved for the title
X ****************************************************************/
X
X# define BYTESPERLINE 32
X# define PSRES 300 /* printer resolution, dots per inch */
X# define PPINCH 72 /* Points per inch */
X# define PAGW 8.5 /* page width 8.5 inches */
X# define PAGH 11.0 /* page height 11 inches */
X# define MAXW 7.0 /* maximum image width 7 inches */
X# define MAXH 9.5 /* maximum image height 9.5 inches */
X# define LMRG 1.0 /* left margin 1 inche */
X# define BMRG 0.5 /* bottom margin 1/2 inche */
X# define TMRG 0.125 /* Title margin, 1/8 inch */
X# define FSIZ 14 /* Font size for title (before scaling to 300 dpi) */
X
Xwrite_ps (scale, scribe)
Xint scale, scribe;
X{ register int x, y, k, byte, bytes=0;
X register unsigned char *bmp = bits;
X int dotsx, dotsy;
X double pwidth, pheight, ctrx, ctry;
X
X /* Pick the largest scale factor that makes the image fit */
X if (scale < 1)
X { dotsx = (int) MAXW * PSRES / w;
X dotsy = (int) MAXH * PSRES / h;
X scale = (dotsx < dotsy) ? dotsx : dotsy;
X if (scale < 1) scale = 1;
X }
X
X fprintf (stderr, "pbm2ps: scale %d\n", scale);
X
X /* Determine width and height of output in inches */
X pwidth = (double) w * scale;
X pheight = (double) h * scale;
X ctrx = ((double) MAXW / 2.0 + LMRG) * PSRES;
X ctry = ((double) MAXH / 2.0 + BMRG) * PSRES;
X
X printf ("%%%! %s\n\n", title[0] ? title : "PBM to PostScript");
X printf ("%lg %lg scale\n", (double) PPINCH / PSRES, (double) PPINCH / PSRES);
X if (title[0])
X { printf ("/centershow { dup stringwidth pop");
X printf (" 2 div 0 exch sub 0 rmoveto show } def\n");
X printf ("/Times-Bold findfont %lg scalefont setfont\n",
X (double) FSIZ * PSRES / PPINCH);
X printf ("%lg %lg moveto\n",
X ctrx, ctry + pheight / 2.0 + TMRG*PSRES);
X printf ("(%s) centershow\n\n", title);
X }
X
X printf ("/picstr 32 string def\n");
X
X if (!scribe)
X { printf ("%lg %lg translate\n", ctrx - pwidth / 2, ctry - pheight / 2); }
X printf ("%lg %lg scale\n", pwidth, pheight);
X printf ("%d %d 1 [ %d 0 0 -%d 0 %d ] ", w, h, w, h, h);
X printf ("{ currentfile picstr readhexstring pop }\n");
X printf ("image\n");
X
X for (y=0; y<h; y++)
X { for (x=0; x<w; x += 8)
X { byte = 0;
X for (k=0; k<8; k++)
X { byte = (byte << 1) | (((x+k) < w) ? *bmp++ : 0); }
X
X printf ("%02x", byte);
X if (++bytes % BYTESPERLINE == 0) printf ("\n");
X }
X }
X
X /* Pad so there are exactly BYTESPERLINE bytes in each line */
X if (bytes % BYTESPERLINE)
X { while (bytes++ % BYTESPERLINE) printf ("00");
X printf ("\n");
X }
X
X if (!scribe) printf ("showpage\n");
X
X return (1);
X}
END_OF_FILE
if test 7263 -ne `wc -c <'pbm2ps.c'`; then
echo shar: \"'pbm2ps.c'\" unpacked with wrong size!
fi
# end of 'pbm2ps.c'
fi
echo shar: End of archive 5 \(of 8\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 8 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
--
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
More information about the Comp.sources.unix
mailing list