[comp.sources.unix] v19i050: FBM, image manipulation library, Part04/08

rsalz@uunet.uu.net (Rich Salz) (06/09/89)

Submitted-by: Michael.Mauldin@NL.CS.CMU.EDU
Posting-number: Volume 19, Issue 50
Archive-name: fbm/part04

#! /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 4 (of 8)."
# Contents:  fbhalf.c fbm.1 fbm2pod.c flblue.c flextr.c flgife.c
#   flpbm.c flrot.c flshrp.c
# Wrapped by rsalz@fig.bbn.com on Fri Jun  9 08:38:25 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'fbhalf.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fbhalf.c'\"
else
echo shar: Extracting \"'fbhalf.c'\" \(6203 characters\)
sed "s/^X//" >'fbhalf.c' <<'END_OF_FILE'
X/*****************************************************************
X * fbhalf.c: FBM Library 0.93 (Beta test) 03-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 * fbhalf.c: Take an 8bit gray image, resize it to a maximum total
X *	      number of pixels, optionally sharpen it with a digital
X *	      Laplacian filter, and halftone it using one of three
X *	      standard algorithms.  Output the result in PBM format.
X *
X * USAGE
X *	% fbhalf [ -args ]  [ size ] < 8bit > 1bit
X *
X *	size	Choose a width and height as large as possible so that
X *		width is a factor of 8 and width*height <= size (default
X *		is width and height of original 8bit file, ignoring aspect
X *		ratio).
X *
X *	-f	Do Floyd-Steinberg halftoning (the default algorithm)
X *	-b<int>	Do Blue noise halftoning (-b50 or 50% noise is default)
X *	-c<int>	Do Constained average halftoning (-c4 is the default)
X *	-s<int>	Sharpen the image with a given beta (-s2.0 is default)
X *	-t<int>	Use a threshhold of <int> to halftone (127 is default)
X *
X *	-C<int>,-N<int>
X *		Clean up image by flipping isolated pixels.  A pixel is
X *		isolated if there are fewer than C like pixels in the
X *		nearby NxN square.
X *
X * EDITLOG
X *	LastEditDate = Wed May  3 21:50:43 1989 - Michael Mauldin
X *	LastFileName = /usr2/mlm/src/misc/fbm/fbhalf.c
X *
X * HISTORY
X * 03-May-89  Michael Mauldin (mlm) at Carnegie Mellon University
X *	Beta release (version 0.93) mlm@cs.cmu.edu
X *
X *  8-Sep-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 USAGE\
X"Usage: fbhalf [ -fbct<parm> ] [-s<sharpen> ] [ -<type> ]\n\
X              [ -C<clean> -N<nbr>] [ size ] < 8bit > 1bit"
X
X#ifndef lint
Xstatic char *fbmid =
X	"$FBM fbhalf.c <0.93> 03-May-89  (C) 1989 by Michael Mauldin$";
X#endif
X
Xmain (argc, argv)
Xchar *argv[];
X{ int w, h, ow = -1, oh = -1, size = -1, alg = 'b';
X  int clean = -1, nbr = 5, outtype = DEF_1BIT;
X  double beta = -1e9, parm = -1e9;
X  char *title, *credits;
X  FBM input, resized, sharpened, halftoned, cleaned, *image;
X
X  /* Clear pointers */
X  input.bm     = input.cm     = (unsigned char *) NULL;
X  resized.bm   = resized.cm   = (unsigned char *) NULL;
X  sharpened.bm = sharpened.cm = (unsigned char *) NULL;
X  halftoned.bm = halftoned.cm = (unsigned char *) NULL;
X  cleaned.bm   = cleaned.cm   = (unsigned char *) NULL;
X
X  if (read_bitmap (&input, (char *) NULL))
X  {
X    if (input.hdr.bits != 8 || input.hdr.physbits != 8)
X    { fprintf (stderr,
X	       "Can't handle images with %d bits and %d physbits per pixel\n",
X	       input.hdr.bits, input.hdr.physbits);
X      exit (1);
X    }
X
X    if (input.hdr.title[0]) title = input.hdr.title;
X    if (input.hdr.credits[0]) credits = input.hdr.credits;
X
X    /* Get the options */
X    while (--argc > 0 && (*++argv)[0] == '-')
X    { while (*++(*argv))
X      { switch (**argv)
X        { case 's':	if (argv[0][1]) { beta = atof (*argv+1); SKIPARG; }
X			else		beta = 2.0;
X			break;
X			
X	  case 'f':	alg = 'f'; parm = 0.0; break;
X			
X	  case 'b':	alg = 'b';
X			if (argv[0][1])	{ parm = atof (*argv+1); SKIPARG; }
X			break;
X			
X	  case 'c':	alg = 'c';
X			if (argv[0][1])	{ parm = atof (*argv+1); SKIPARG; }
X			break;
X			
X	  case 't':	alg = 't';
X			if (argv[0][1])	{ parm = atoi (*argv+1); SKIPARG; }
X			else		{ parm = 127; }
X			break;
X			
X	  case 'C':	if (argv[0][1])	{ clean = atoi (*argv+1); SKIPARG; }
X	  		else		{ clean = 10; }
X			break;
X			
X	  case 'N':	if (argv[0][1])	{ nbr = atoi (*argv+1); SKIPARG; }
X	  		else		{ nbr = 5; }
X			
X			if (clean < 0)	{ clean = 10; }
X			break;
X			
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
X
X	  default:	fprintf (stderr, "%s", USAGE);
X			exit (1);
X        }
X      }
X    }
X    
X    if (argc > 0)	size = atoi (argv[0]);
X
X    /* Default parms for algorithms */
X    if (parm <= -1e9)
X    { if      (alg == 'b') parm = 50.0;
X      else if (alg == 'c') parm = 4.0;
X      else if (alg == 't') parm = 128.0;
X    }
X
X    /* Determine output height & width (oh*ow <= size) */
X    h = input.hdr.rows;
X    w = input.hdr.cols;
X
X    if (size < 0)
X    { oh = h; ow = w; }
X    else
X    { ow = sqrt ((double) size * w / (h * input.hdr.aspect));
X      ow &= ~7;			/* Make width multiple of 8 */
X      oh = ow * input.hdr.aspect * h / w;
X    }
X
X    fprintf (stderr,
X	     "Halftone \"%s\" size [%dx%d] => %d pixels\n",
X	     input.hdr.title[0] ? input.hdr.title : "(untitled)",
X	     ow, oh, ow*oh);
X
X    /* Start with image in variable 'input' */
X    image = &input;
X
X    /* If necessary, resize it */
X    if (w != ow || h != oh)
X    { if (extract_fbm (image, &resized, 0, 0, w, h, ow, oh, title, credits))
X      { free_fbm (image);
X	image = &resized;
X      }
X      else
X      { exit (1); }
X    }
X
X    /* Sharpen the image if requested */    
X    if (beta > -1e9)
X    { if (sharpen_fbm (image, &sharpened, beta))
X      { free_fbm (image);
X	image = &sharpened;
X      }
X      else
X      { exit (1); }
X    }
X    
X    /* Now use the appropriate algorithm to halftone it */
X    switch (alg)
X    { case 'b':	bluenoise_fbm (image, &halftoned, parm); break;
X      case 'c': constravg_fbm (image, &halftoned, parm); break;
X      case 't': thesh_fbm (image, &halftoned, (int) parm); break;
X      default:	floyd_fbm (image, &halftoned);
X    }
X
X    /* free_fbm (image); */
X    image = &halftoned;
X
X    if (clean >= 0)
X    { if (!clean_fbm (image, &cleaned, clean, 1, nbr))
X      { exit (1); }
X
X      free_fbm (image);
X      image = &cleaned;      
X    }
X
X    if (write_bitmap (image, stdout, outtype)) exit (0);
X  }
X  
X  exit (1);
X}
END_OF_FILE
if test 6203 -ne `wc -c <'fbhalf.c'`; then
    echo shar: \"'fbhalf.c'\" unpacked with wrong size!
fi
# end of 'fbhalf.c'
fi
if test -f 'fbm.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fbm.1'\"
else
echo shar: Extracting \"'fbm.1'\" \(6127 characters\)
sed "s/^X//" >'fbm.1' <<'END_OF_FILE'
X.TH FBM 1 07-Mar-89
X.CM 3
X.SH NAME
Xfbm \- Fuzzy pixmap manipulation (Sun, GIF, IFF, HAM, PCX, PBM, FBM, PostScript, rasters, bitmaps, pixmaps)
X.SH SYNOPSIS
X.nf
Xclr2gray  Convert color to grayscale
Xfbcat     Copy image (used for format conversion)
Xfbclean   Flip isolated pixels (clean image)
Xfbedge    Compute derivative image (edge detection)
Xfbext     Extract region, resize, change aspect ratio
Xfbhalf    Halftone grayscale image (Blue noise, Floyd-Steinberg, etc)
Xfbham     Convert 24 bit color to Amiga HAM mode
Xfbhist    Compute histogram
Xfbinfo    Dump image header
Xfbm2pod   Convert grayscale image to Diablo graphics (!)
Xfbm2tga   Convert FBM to Targa format
Xfbmask    Set region to gray value
Xfbnorm    Normalize image intensity / increase contrast
Xfbps      Convert greyscale to PostScript
Xfbquant   Color quantization (24 bit to 8..256 colors) Mod. Heckbert
Xfbrot     Rotate 90, 180, or 270 degrees
Xfbsample  Sample a 1bit file to produce an 8bit file
Xfbsharp   Sharpen (edge enhancement) by digital Laplacian
Xgray2clr  Add a "gray" colormap to a grayscale image
Xidiff     (and udiff) convert raw byte stream into byte-by-byte difference
Xpbm2ps    Convert PBM file to PostScript
Xpbmtitle  Add a title to a PBM file
Xpic2fbm   Convert PIC format to FBM
Xqrt2fbm   Convert QRT raytracer output to FBM
Xraw2fbm   Convert raw file to FBM format (eg: Amiga Digiview files)
Xtga2fbm   Convert Targa format to FBM format
X.fi
X.SH DESCRIPTION
X.PP
XThe Fuzzy Pixmap package (FBM) is a collection of routines for the
Xmanipulation and conversion of images from and to a variety of file
Xformats.  
X.SH FILE FORMATS
X.PP
XIn general each routine can read any type of file format (file type is
Xdetermined by examining the magic numbers).  Files that are compressed
Xwith the Lempel-Ziv 'compress' program are automatically uncompressed
Xwhere possible.
X.sp
XOutput file format is specified by an upper case letter in the argument
Xlist.  Each site has a separate default (defined in fbm.h) for 8bit and
X1bit images.  The following upper
Xcase letters are assigned (not all are handled, yet):
X.sp
X.TP
X.BR -A
X.I andrew toolkit
XCMU specific format (not implemented, if at CMU, use 'bmcv' to convert).
X.TP
X.BR -B
X.I face
Xformat, as used by Bennet Yee's
X.I face
Xprogram at CMU. His 'bmcv' program can convert to a number of useful
Xformats.
X.TP
X.BR -F
X.I FBM
Xformat (by default, the default).  You are guaranteed not
Xto lose information by specifying FBM as the default.
X.TP
X.BR -G
X.I GIF
XCompuserve GIF format.  GIF support by David Koblas and David Rowley.
XOn input, the aspect ratio is guessed from the size (for example,
X320x200 and 640x400 images are assumed to have an aspect ratio of 1.2).
XFor unknown sizes, an aspect ratio of 1.0 is assumed.  fbcat can
Xoverride the aspect ratio, if you know the actual value.
X.TP
X.BR -I
X.I IFF
Xformat, interleaved bitmaps (ILBM), used mainly by Amigas (from ELArts).
XTo output HAM mode, create a 24 bit color image and use the fbham(1)
Xcommand to convert it to a 6 plane IFF ILBM HAM mode file.
X.TP
X.BR -L
X.I InterLeaf
Xbitmap format for inclusion in InterLeaf documents (not yet supported).
X.TP
X.BR -M
X.I MacPaint
Xformat (not yet supported).
X.TP
X.BR -P
X.I PBM
XJef Poskanzer's bitmap format.  His pbm(1) package can convert this to
Xa number of useful formats.
X.TP
X.BR -S
X.I sun
Xrasterfiles.  Code does not require any Sun libraries to read or write
XSun format.
X.TP
X.BR -T
X.I TIFF
Xformat, as used by NeXT machines and many scanners (not yet supported).
X.TP
X.BR -Z
X.I ZSoft's PCX
Xformat, as used on IBM PCs (read support only).
X.PP
X.SH OPTIONS
X.PP
XSome options are common, and an attempt has been made to keep the
Xletters the same throughout, although the same letter may mean
Xsomething else in some circumstances.
X.TP
X.BR -a
X.I aspect ratio,
Xsome rasters (like Amiga and IBM PC images) have pixels that are
X"taller" than they are wide.  For example, a standard TV image is 4/3
Xwider than it is tall.  A "standard" screen that is 320 by 200 is
Xsquashed so that it appears normal when displayed as though it were 320
Xby 240 (and 240 / 200 gives a 1.2 aspect ratio).
X.sp
XOn some programs, like 
X.I raw2fbm & fbcat,
Xthe
X.B -a
Xoption specifies the aspect ratio of the input (for GIF and raw bitmaps
Xthe default is 1.2).  Other programs (like
X.I fbext)
Xuse this parameter as the desired output ratio.
XFinally, some programs assume specific ratios (usually 1, although
X.fpm2pod
Xassumes 1.25 for output).
X.TP
X.BR -w, -h
X.I width
Xand
X.I height,
Xspecifies the actual or desired width and height.
X.TP
X.BR -t'title'
X.I title,
Xspecify a character string (up to 80 characters) to describe the image.
XThe default is no title.
X.TP
X.BR -c'credits'
X.I credits or subtitle,
Xspecify a second character string (up to 80 characters) to describe the
Ximage.  The default is no credit string.
X.TP
X.BR -s
X.I size
Xor
X.I sharpen
Xhalftoning programs use
X.B -s
Xto specifiy the amount of sharpening (0=none, values up to 5 look
Xreasonable, higher values generate may be too extreme).  The extraction
Xprogram fbext(1) uses
X.B -s
Xto mean the output size in total number of pixels.
X.sp
XThat's what comes of using one letter argument names.
X.PP
X.SH SEE ALSO
Xclr2gray(1),
Xfbcat(1),
Xfbclean(1),
Xfbedge(1),
Xfbext(1),
Xfbhalf(1),
Xfbham(1),
Xfbhist(1),
Xfbinfo(1),
Xfbm2pod(1),
Xfbmask(1),
Xfbnorm(1),
Xfbps(1),
Xfbquant(1),
Xfbrot(1),
Xfbsample(1),
Xfbsharp(1),
Xgray2clr(1),
Xidiff(1),
Xpbm2ps(1),
Xpbmtitle(1),
Xraw2fbm(1),
Xas well as pbm(1) for PBM routines.
X.SH BUGS
XNone known.
X.SH HISTORY
XCopyright (c) 1989 by Michael L. Mauldin.  
XPermission is granted to use this program in whole or in part provided
Xthat you do not sell it for profit and that this copyright notice is
Xretained unchanged.  User contributed software may also be subject to
Xother copyright restrictions as noted in each individual source file.
X.TP
X20-May-89  Michael L. Mauldin at Carnegie Mellon University
XBeta release (version 0.94) mlm@cs.cmu.edu. User contributed software
Xincludes
X.nf
X	C. Harald Koch	fbham
X	Butler Hines	qrt2fbm
X	Ian MacPhedran	tga2fbm, fbm2tga, pic2fbm
X.fi
X.TP
X07-Mar-89  Michael L. Mauldin at Carnegie Mellon University
XBeta release (version 0.9) mlm@cs.cmu.edu
END_OF_FILE
if test 6127 -ne `wc -c <'fbm.1'`; then
    echo shar: \"'fbm.1'\" unpacked with wrong size!
fi
# end of 'fbm.1'
fi
if test -f 'fbm2pod.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'fbm2pod.c'\"
else
echo shar: Extracting \"'fbm2pod.c'\" \(5563 characters\)
sed "s/^X//" >'fbm2pod.c' <<'END_OF_FILE'
X/*****************************************************************
X * fbm2pod.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 * fbm2pod.c: Take an 8bit gray image, resize it to a maximum total
X *	      number of pixels, optionally sharpen it with a digital
X *	      Laplacian filter, and halftone it using one of three
X *	      standard algorithms.  Output the result in Diablo
X *	      graphics format.
X *
X * USAGE
X *	% fbm2pod [ -args ]  [ size ] < foo.fbm > foo.pod
X *
X *	size	Choose a width and height as large as possible so that
X *		width is a factor of 8 and width*height <= size (default
X *		is width and height of original 8bit file, ignoring aspect
X *		ratio).
X *
X *	-f	Do Floyd-Steinberg halftoning (the default algorithm)
X *	-bNNN	Do Blue noise halftoning (-b50 or 50% noise is default)
X *	-cNNN	Do Constained average halftoning (-c4 is the default)
X *	-sNNN	Sharpen the image with a given beta (-s2.0 is default)
X *
X * EDITLOG
X *	LastEditDate = Wed Mar  8 14:22:04 1989 - Michael Mauldin
X *	LastFileName = /usr2/mlm/src/misc/fbm/fbm2pod.c
X *
X * HISTORY
X * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
X *	Beta release (version 0.9) mlm@cs.cmu.edu
X *
X *  8-Sep-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 PODASPECT 1.25
X
X# define USAGE \
X"Usage: fbm2pod [ -fbc<parm> ] [-s<sharpen> ] [ size ] < 8bit > pod"
X
X#ifndef lint
Xstatic char *fbmid =
X	"$FBM fbm2pod.c <0.9> 07-Mar-89  (C) 1989 by Michael Mauldin$";
X#endif
X
Xmain (argc, argv)
Xchar *argv[];
X{ int w, h, ow = -1, oh = -1, size = -1, alg = 'b';
X  double beta = -1e9, parm = -1e9;
X  char *title;
X  FBM input, resized, sharpened, output, *image;
X
X  /* Clear the memory pointers so alloc_fbm won't be confused */
X  input.cm     = input.bm     = (unsigned char *) NULL;
X  resized.cm   = resized.bm   = (unsigned char *) NULL;
X  sharpened.cm = sharpened.bm = (unsigned char *) NULL;
X  output.cm    = output.bm    = (unsigned char *) NULL;
X
X  /* Read the image */
X  if (read_bitmap (&input, (char *) NULL))
X  {
X    if (input.hdr.bits != 8 || input.hdr.physbits != 8)
X    { fprintf (stderr,
X	       "Can't handle images with %d bits and %d physbits per pixel\n",
X	       input.hdr.bits, input.hdr.physbits);
X      exit (1);
X    }
X
X    if (input.hdr.title[0]) title = input.hdr.title;
X
X    /* Get the options */
X    while (--argc > 0 && (*++argv)[0] == '-')
X    { while (*++(*argv))
X      { switch (**argv)
X        { case 's':	if (argv[0][1]) { beta = atof (*argv+1); SKIPARG; }
X			else		beta = 2.0;
X			break;
X			
X	  case 'f':	alg = 'f'; break;
X			
X	  case 'b':	alg = 'b';
X			if (argv[0][1])	{ parm = atof (*argv+1); SKIPARG; }
X			break;
X			
X	  case 'c':	alg = 'c';
X			if (argv[0][1])	{ parm = atof (*argv+1); SKIPARG; }
X			break;
X			
X	  default:	fprintf (stderr, "%s", USAGE);
X			exit (1);
X        }
X      }
X    }
X    
X    if (argc > 0)	size = atoi (argv[0]);
X
X    /* Default parms for algorithms */
X    if (parm <= -1e9)
X    { if      (alg == 'b') parm = 50.0;
X      else if (alg == 'c') parm = 4.0;
X    }
X
X    /* Determine output height & width (oh*ow <= size) */
X    h = input.hdr.rows;
X    w = input.hdr.cols;
X
X    if (size < 0)
X    { oh = h; ow = w; }
X    else
X    { ow = sqrt ((double) size * w / (h * input.hdr.aspect / PODASPECT));
X      ow &= ~7;			/* Make width multiple of 8 */
X      oh = ow * input.hdr.aspect/PODASPECT * h / w;
X    }
X
X    fprintf (stderr,
X	     "Halftone \"%s\" size [%dx%d] => %d pixels\n",
X	     input.hdr.title[0] ? input.hdr.title : "(untitled)",
X	     ow, oh, ow*oh);
X
X    /* Start with image in variable 'input' */
X    image = &input;
X
X    /* If necessary, resize it */
X    if (w != ow || h != oh)
X    { if (extract_fbm (&input, &resized, 0, 0, w, h, ow, oh, title, (char *) NULL))
X      { image = &resized; }
X      else
X      { exit (1); }
X    }
X
X    /* Sharpen the image if requested */    
X    if (beta > -1e9)
X    { if (sharpen_fbm (image, &sharpened, beta))
X      { image = &sharpened; }
X      else
X      { exit (1); }
X    }
X    
X    /* Now use the appropriate algorithm to halftone it */
X    switch (alg)
X    { case 'b':	bluenoise_fbm (image, &output, parm); break;
X      case 'c': constravg_fbm (image, &output, parm); break;
X      default:	floyd_fbm (image, &output);
X    }
X
X    if (write_pod (&output, stdout)) exit (0);
X  }
X  
X  exit (1);
X}
X
X/****************************************************************
X * write_pod: Write out a binary bitmap as a Diablo file, for use
X *	      by the podtype or mp programs.
X ****************************************************************/
X
X# define FF "\014"
X# define LF "\012"
X# define CR "\015"
X# define GON	"\033\037\005\033\036\003"
X# define GOFF	"\033\037\015\033\036\011"
X# define ABSTAB "\033\011"
X# define STARTCOL 10
X
Xwrite_pod (image, stream)
XFBM *image;
XFILE *stream;
X{ register int i, j, h, w;
X
X  h = image->hdr.rows;
X  w = image->hdr.cols;
X
X  /* Bracket commands with form feeds (for podtype) */
X  fprintf (stream, "%s%s%s", FF, CR, GOFF);
X  
X  for (j=0; j<h; j++)
X  { fprintf (stream, "%s%c%s", ABSTAB, STARTCOL+1, GON);
X    for (i=0; i<w; i++)
X    { putchar (image->bm[j*w + i] ? ' ' : '.'); }
X    fprintf (stream, "%s%s%s", LF, GOFF, CR);
X    
X  }
X  
X  fprintf (stream, "%s", FF);
X  
X  return (1);
X}
END_OF_FILE
if test 5563 -ne `wc -c <'fbm2pod.c'`; then
    echo shar: \"'fbm2pod.c'\" unpacked with wrong size!
fi
# end of 'fbm2pod.c'
fi
if test -f 'flblue.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'flblue.c'\"
else
echo shar: Extracting \"'flblue.c'\" \(5880 characters\)
sed "s/^X//" >'flblue.c' <<'END_OF_FILE'
X/*****************************************************************
X * flblue.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 * flblue.c: Blue noise dithering
X *
X * CONTENTS
X *	bluenoise_fbm (input, output, noiselevel)
X *
X * EDITLOG
X *	LastEditDate = Sat May 20 19:06:08 1989 - Michael Mauldin
X *	LastFileName = /usr2/mlm/src/misc/fbm/flblue.c
X *
X * HISTORY
X * 20-May-89  Michael Mauldin (mlm) at Carnegie Mellon University
X *	Bug fix from Dave Cohrs <dave@cs.wisc.edu>
X *
X * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
X *	Beta release (version 0.9) mlm@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
X/*****************************************************************
X * bluenoise_fbm:  Do Floyd-Steinberg halftoning with serpentine
X *		   raster and 'noiselevel' random weights.
X *		   (noise level runs from 0 to 100 percent)
X *
X * REFERENCES
X *	Digital Halftoning, by Robert Ulichney (1986 MIT Press)
X *****************************************************************/
X
X# define RAND(RN) (((seed = 1103515245 * seed + 12345) >> 12) % (RN))
X# define INITERR(X,Y) \
X	(((int) X) - (((int) Y)?WHITE:BLACK) + ((WHITE/2)-((int) X))/2)
X
X#ifndef lint
Xstatic char *fbmid =
X	"$FBM flblue.c <0.94> 20-May-89  (C) 1989 by Michael Mauldin$";
X#endif
X
Xbluenoise_fbm (input, output, noiselevel)
XFBM *input, *output;
Xdouble noiselevel;
X{ register unsigned char *bmp, *obm;
X  register unsigned seed = 0;
X  register int i, j, rowlen, gray, error, w, h, den, outrow;
X  int w1, w3, w5, w7, smrange, lgrange, smnoise, lgnoise;
X  int *eerr, *oerr;
X
X  if (input->hdr.planes != 1)
X  { fprintf (stderr, "bluenoise_fbm: can't halftone color images\n");
X    return (0);
X  }
X
X  fprintf (stderr, "Blue noise, %1.2lf%% weights\n", noiselevel);
X
X  /* Allocate output */
X  free_fbm (output);
X  output->hdr = input->hdr;
X  output->hdr.bits = 1;
X  output->hdr.physbits = 8;
X  outrow = 16 * ((input->hdr.cols + 15) / 16); /* Pad to even byte boundary */
X  output->hdr.rowlen = outrow;
X  output->hdr.plnlen = outrow*output->hdr.rows;
X  alloc_fbm (output);
X
X  w = input->hdr.cols;
X  h = input->hdr.rows;
X  rowlen = input->hdr.rowlen;
X  
X  /* Allocate space for error arrays */
X  eerr = (int *) malloc ((unsigned) w * sizeof (*eerr));
X  oerr = (int *) malloc ((unsigned) w * sizeof (*oerr));
X  for (i=0; i<w; i++) eerr[i] = oerr[i] = 0;
X
X    /* The left border */
X  error = 0;
X  for (j=0; j<h; j++)
X  { register int thresh = (WHITE/2 + RAND (129) - 64);
X
X    gray = input->bm[j*rowlen] + error;
X    den = gray > thresh ? WHITE : BLACK;
X    error = gray - den;
X    output->bm[j*outrow] = den;
X  }
X
X  /* The right border */
X  error = 0;
X  for (j=0; j<h; j++)
X  { register int thresh = (WHITE/2 + RAND (129) - 64);
X
X    gray = input->bm[j*rowlen + (w-1)] + error;
X    den = gray > thresh ? WHITE : BLACK;
X    error = gray - den;
X    output->bm[j*outrow + (w-1)] = den;
X  }
X
X  /* The top border */
X  error = 0;
X  for (i=0; i<w; i++)
X  { register int inp = input->bm[i], thresh = (WHITE/2 + RAND (129) - 64);
X
X    gray = inp + error;
X    den = gray > thresh ? WHITE : BLACK;
X    error = gray - den;
X    output->bm[i] = den;
X    eerr[i] = INITERR (inp, den);
X  }
X
X  /*
X   * Now process the interior bits
X   *
X   *  Weights:			1+n1  5+n5  3-n1
X   *				7-n5    *
X   *
X   * n1 and n5 are random noise from -0.5 to 0.5 and -2.5 to 2.5
X   */
X   
X  smrange = 2000 * noiselevel/100.0; smrange += 1;
X  lgrange = 10000 * noiselevel/100.0; lgrange += 1;
X  
X# ifdef DEBUG
X  fprintf (stderr, "Blue noise level %6.2lf (small %d..%d, large %d..%d)\n",
X	  noiselevel, -(smrange/2), smrange/2, -(lgrange/2), lgrange/2);
X# endif
X
X  for (j=1; j<h; j++)
X  { bmp = &input->bm[j*rowlen];
X    obm = &output->bm[j*outrow];
X
X    if (j&1)				/* Odd rows */
X    { oerr[0] = INITERR (bmp[0], obm[0]);
X
X      for (i=1; i<w-1; i++)
X      { /* Set random weights */
X	w1 = 1000; w3 = 3000; w5 = 5000; w7 = 7000;
X  
X	smnoise = RAND (smrange) - smrange/2;
X	w1 += smnoise; w3 -= smnoise;
X  
X	lgnoise = RAND (lgrange) - lgrange/2;
X	w5 += lgnoise; w7 -= lgnoise;
X  
X	error =  (w1 * eerr[i-1] +
X		  w5 * eerr[i] +
X		  w3 * eerr[i+1] +
X		  w7 * oerr[i-1]) / 16000;
X	gray = bmp[i] + error;
X  
X# ifdef DEBUG
X	if (j>10 && j<14 && i>40 && i<44)
X	{ fprintf (stderr,
X		   "\n<%3d,%3d> input %d, error %d\n",
X		   i, j, bmp[i], error);
X	  fprintf (stderr, "Noise {%d,%d} Weights {%d,%d,%d,%d}\n",
X		   smnoise, lgnoise, w1, w3, w5, w7);
X	  fprintf (stderr,
X		   "Errs:\t%5d  %5d  %5d\n\t%5d      *\n",
X		   eerr[i-1], eerr[i], eerr[i+1], oerr[i-1]);
X	}
X# endif
X
X	if (gray > (WHITE/2))
X	{ obm[i] = 1;	oerr[i] = gray - WHITE; }
X	else
X	{ obm[i] = 0;	oerr[i] = gray; }
X      }
X      
X      /* Set errors for ends of this row */
X      oerr[0]   = INITERR (bmp[0], obm[0]);
X      oerr[w-1] = INITERR (bmp[w-1], obm[w-1]);
X    }
X    else
X    { eerr[w-1] = INITERR (bmp[w-1], obm[w-1]);
X
X      for (i=w-2; i>0; i--)
X      { /* Set random weights */
X	w1 = 1000; w3 = 3000; w5 = 5000; w7 = 7000;
X  
X	smnoise = RAND (smrange) - smrange/2;
X	w1 += smnoise; w3 -= smnoise;
X  
X	lgnoise = RAND (lgrange) - lgrange/2;
X	w5 += lgnoise; w7 -= lgnoise;
X  
X	error =  (w1 * oerr[i+1] +
X		  w5 * oerr[i] +
X		  w3 * oerr[i-1] +
X		  w7 * eerr[i+1]) / 16000;
X	gray = bmp[i] + error;
X  
X	if (gray > (WHITE/2))
X	{ obm[i] = 1;	eerr[i] = gray - WHITE; }
X	else
X	{ obm[i] = 0;	eerr[i] = gray; }
X      }
X
X      /* Set errors for ends of this row */
X      eerr[0]   = INITERR (bmp[0], obm[0]);
X      eerr[w-1] = INITERR (bmp[w-1], obm[w-1]);
X    }
X  }
X  return (1);
X}
END_OF_FILE
if test 5880 -ne `wc -c <'flblue.c'`; then
    echo shar: \"'flblue.c'\" unpacked with wrong size!
fi
# end of 'flblue.c'
fi
if test -f 'flextr.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'flextr.c'\"
else
echo shar: Extracting \"'flextr.c'\" \(5644 characters\)
sed "s/^X//" >'flextr.c' <<'END_OF_FILE'
X/*****************************************************************
X * flextr.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 * flextr.c: Extract a rectangle and/or resize it.
X *
X * CONTENTS
X *	extract_fbm (input, output, xo, yo, w, h, ow, oh, title, credits)
X *
X * EDITLOG
X *	LastEditDate = Tue Mar  7 19:56:56 1989 - Michael Mauldin
X *	LastFileName = /usr2/mlm/src/misc/fbm/flextr.c
X *
X * HISTORY
X * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
X *	Beta release (version 0.9) mlm@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
X/****************************************************************
X * extract_fbm: Resize a bitmap
X *	copy input [xo:xo+w yo:yo+h] to output [ow oh]
X ****************************************************************/
X
X#ifndef lint
Xstatic char *fbmid =
X	"$FBM flextr.c <0.9> 07-Mar-89  (C) 1989 by Michael Mauldin$";
X#endif
X
Xextract_fbm (input, output, xo, yo, w, h, ow, oh, title, credits)
XFBM *input, *output;
Xint xo, yo, h, w, oh, ow;
Xchar *title, *credits;
X{ int k, rowlen;
X
X  if ((w != ow || h != oh) && input->hdr.bits != 8)
X  { fprintf (stderr,
X	     "Can't resize images with %d bits per pixel\n", input->hdr.bits);
X    return (0);
X  }
X
X  if (input->hdr.physbits != 8)
X  { fprintf (stderr,
X	     "Can't extract images with %d physbits per pixel\n",
X	     input->hdr.physbits);
X    return (0);
X  }
X
X  if (h < 1 || w < 1 || oh < 1 || ow < 1)
X  { fprintf (stderr, "Extract: zero dimension [%dx%d] => [%dx%d]\n", 
X	     w, h, ow, oh);
X    return (0);
X  }
X
X  fprintf (stderr,
X	   "Extract \"%s\" <%d,%d> [%dx%d] => [%dx%d] %d pixels\n",
X	   title ? title : input->hdr.title ? input->hdr.title : "untitled",
X	   xo, yo, w, h, ow, oh, ow*oh);
X
X  if (xo+w > input->hdr.cols)
X  { fprintf (stderr, "Warning, input exceeds image horizontally\n");
X    fprintf (stderr, "	xo %d, w %d, input->hdr.cols %d\n",
X	     xo, w, input->hdr.cols);
X  }
X  if (yo+h > input->hdr.rows)
X  { fprintf (stderr, "Warning, input exceeds image vertically\n");
X    fprintf (stderr, "	yo %d, h %d, input->hdr.rows %d\n",
X	     yo, h, input->hdr.rows);
X  }
X
X  /* Calculate length of row (pad to even byte boundary) */
X  rowlen = 2 * ((ow * input->hdr.physbits + 15) / 16);
X  
X  /* Now build header for output bit map */
X  output->hdr.cols = ow;
X  output->hdr.rows = oh;
X  output->hdr.planes = input->hdr.planes;
X  output->hdr.bits = input->hdr.bits;
X  output->hdr.physbits = input->hdr.physbits;
X  output->hdr.rowlen = rowlen;
X  output->hdr.plnlen = oh * output->hdr.rowlen;
X  output->hdr.clrlen = input->hdr.clrlen;
X  output->hdr.aspect = input->hdr.aspect * ow * h / (oh * w);
X
X  if (title == NULL || *title == '\0')
X  { strncpy (output->hdr.title, input->hdr.title, FBM_MAX_TITLE); }
X  else
X  { strcpy (output->hdr.title, title); }
X    
X  if (credits == NULL || *credits == '\0')
X  { strncpy (output->hdr.credits, input->hdr.credits, FBM_MAX_TITLE); }
X  else
X  { strcpy (output->hdr.credits, credits); }
X    
X  /* Allocate space for output bits */
X  alloc_fbm (output);
X
X  copy_clr (input, output);
X
X  /* Now extract each plane separately */
X  for (k=0; k<output->hdr.planes; k++)
X  { if (! extract_one (&(input->bm[k * input->hdr.plnlen]),
X		       &(output->bm[k * output->hdr.plnlen]),
X		       input->hdr.cols, input->hdr.rows,
X		       input->hdr.rowlen, output->hdr.rowlen,
X		       xo, yo, w, h, ow, oh))
X    { free_fbm (output); return (0); }
X  }
X
X  return (1);
X}
X
X/****************************************************************
X * extract_one: Resize a bitmap
X *	copy input [xo:xo+w yo:yo+h] to output [ow oh]
X ****************************************************************/
X
Xextract_one (inbm, outbm, cols, rows, inlen, outlen, xo, yo, w, h, ow, oh)
Xunsigned char *inbm, *outbm;
Xint inlen, outlen, xo, yo, h, w, oh, ow;
X{ register int xf, yf, xi, i; 
X  register unsigned char *bm1, *bm2,  *obm;
X  int j, yi, dc;
X
X  /* Check for scale of 1-1, special case for speed */
X  if (w == ow && h == oh && xo >= 0 && yo >= 0 && xo+w <= cols && yo+h <= rows)
X  { for (j=0; j<h; j++)
X    { bm1 = &inbm[(j+yo) * inlen];
X      obm = &outbm[j * outlen];
X
X      for (i=0; i<w; i++)
X      { obm[i] = bm1[i + xo]; }
X    }
X  }
X  else
X  {    
X    for (j = 0; j<oh; j++)
X    { yi = (j*h / oh) + yo;
X      yf = (j*h % oh);
X
X      obm = &outbm[j * outlen];
X      bm1 = &inbm[yi * inlen];
X      bm2 = bm1 + inlen;
X
X      for (i=0; i<ow; i++)
X      { xi = (i*w / ow) + xo;
X        xf = (i*w % ow);
X
X	if (xi < 0 || yi < 0 ||
X	    xi > cols-2 ||
X	    yi > rows-2)
X	{ static cntr = 0;
X
X	  /* If right on edge, just use edge value */
X	  if ((xi == cols-1 &&
X	       yi >= 0 && yi <= rows-1) ||
X	      (yi == rows-1 &&
X	       xi >= 0 && xi <= cols-1))
X	  { obm[i] = bm1[xi]; }
X	  else
X	  { obm[i] = 255;
X
X	    if (cntr++ < 3)
X	    { fprintf (stderr,
X		       "i,j %d,%d => xi,yi %d,%d, out of bounds %d,%d\n",
X		       i, j, xi, yi, cols, rows);
X	      fprintf (stderr,
X		       "w %d, h %d, ow %d, oh %d\n\n", 
X		       w, h, ow, oh);
X	    }  
X	  }
X        }
X	else
X	{ dc = ( bm1[xi]   * (ow-xf)*(oh-yf) + 
X		 bm2[xi]   * (ow-xf)*(yf) + 
X		 bm1[xi+1] * (xf)*(oh-yf) + 
X		 bm2[xi+1] * (xf)*(yf) ) / (ow*oh);
X
X	  if (dc < 0)		{ dc = 0; }
X	  else if (dc > 255)	{ dc = 255; }
X
X	  obm[i] = dc;
X	}
X      }
X    }
X  }
X
X  return (1);
X}
END_OF_FILE
if test 5644 -ne `wc -c <'flextr.c'`; then
    echo shar: \"'flextr.c'\" unpacked with wrong size!
fi
# end of 'flextr.c'
fi
if test -f 'flgife.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'flgife.c'\"
else
echo shar: Extracting \"'flgife.c'\" \(5443 characters\)
sed "s/^X//" >'flgife.c' <<'END_OF_FILE'
X/*****************************************************************
X * flgife.c: FBM Library 0.9 (Beta test) 07-Mar-89  Michael Mauldin
X *
X * Portions of this code Copyright (C) 1989 by 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 * and the names of all authors are retained unchanged.
X *
X * flgife.c:
X *
X * CONTENTS
X *	GIFEncode( wfile, GHeight, GWidth, GInterlace, Background, 
X *		   BitsPerPixel, Red, Green, Blue, GetPixel )
X *
X * HISTORY
X * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
X *	Beta release (version 0.9) mlm@cs.cmu.edu
X *
X * 19-Feb-89  Michael Mauldin (mlm) at Carnegie Mellon University
X *	Adapted to FBM package.  Now takes FILE pointer instead of
X *	character name for output file.
X *
X * 13-Feb-89  David Rowley (mgardi@watdcsu.waterloo.edu)
X *	Created (sent by mail on 2/13/89)
X *	original name: GIFENCODE.C - GIF Image compression interface
X *
X *****************************************************************************/
X 
X#include <stdio.h>
X
X/*
X * Pointer to function returning an int
X */
Xtypedef int (* ifunptr)();
X
X#define TRUE 1
X#define FALSE 0
X
Xstatic int Width, Height;
Xstatic int curx, cury;
Xstatic long CountDown;
Xstatic int Pass = 0;
Xstatic int Interlace;
X
X#ifndef lint
Xstatic char *fbmid =
X	"$FBM flgife.c <0.9> 07-Mar-89  (C) 1989 by Michael Mauldin$";
X#endif
X
X
X/*
X * Bump the 'curx' and 'cury' to point to the next pixel
X */
Xstatic
XBumpPixel()
X{
X	/*
X	 * Bump the current X position
X	 */
X	curx++;
X
X	/*
X	 * If we are at the end of a scan line, set curx back to the beginning
X	 * If we are interlaced, bump the cury to the appropriate spot,
X	 * otherwise, just increment it.
X	 */
X	if( curx == Width ) {
X		curx = 0;
X
X	        if( !Interlace ) 
X			cury++;
X		else {
X		     switch( Pass ) {
X	     
X	               case 0:
X        	          cury += 8;
X                	  if( cury >= Height ) {
X		  		Pass++;
X				cury = 4;
X		  	  }
X                          break;
X		  
X	               case 1:
X        	          cury += 8;
X                	  if( cury >= Height ) {
X		  		Pass++;
X				cury = 2;
X		  	  }
X			  break;
X		  
X	               case 2:
X	                  cury += 4;
X	                  if( cury >= Height ) {
X	                     Pass++;
X	                     cury = 1;
X	                  }
X	                  break;
X			  
X	               case 3:
X	                  cury += 2;
X	                  break;
X			}
X		}
X	}
X}
X
X/*
X * Return the next pixel from the image
X */
XGIFNextPixel( getpixel )
Xifunptr getpixel;
X{
X	int r;
X
X	if( CountDown == 0 )
X		return EOF;
X
X	CountDown--;
X
X	r = ( * getpixel )( curx, cury );
X
X	BumpPixel();
X
X	return r;
X}
X
X/* public */
X
XGIFEncode( wfile, GWidth, GHeight, GInterlace, Background, 
X	   BitsPerPixel, Red, Green, Blue, GetPixel )
X	 
XFILE *wfile;
Xint GWidth, GHeight;
Xint GInterlace;
Xint Background;
Xint BitsPerPixel;
Xint Red[], Green[], Blue[];
Xifunptr GetPixel;
X
X{
X	FILE *fp;
X	int B;
X	int RWidth, RHeight;
X	int LeftOfs, TopOfs;
X	int Resolution;
X	int ColorMapSize;
X	int InitCodeSize;
X	int i;
X
X	Interlace = GInterlace;
X	
X	ColorMapSize = 1 << BitsPerPixel;
X	
X	RWidth = Width = GWidth;
X	RHeight = Height = GHeight;
X	LeftOfs = TopOfs = 0;
X	
X	Resolution = BitsPerPixel;
X
X	/*
X	 * Calculate number of bits we are expecting
X	 */
X	CountDown = (long)Width * (long)Height;
X
X	/*
X	 * Indicate which pass we are on (if interlace)
X	 */
X	Pass = 0;
X
X	/*
X	 * The initial code size
X	 */
X	if( BitsPerPixel <= 1 )
X		InitCodeSize = 2;
X	else
X		InitCodeSize = BitsPerPixel;
X
X	/*
X	 * Set up the current x and y position
X	 */
X	curx = cury = 0;
X
X	/*
X	 * Open the GIF file for binary write
X	 */
X	/* fp = fopen( FName, "wb" ); */
X
X	fp = wfile;	/* Change for FBM - mlm 2/19/89 */
X
X	if( fp == (FILE *)0 ) {
X		printf( "error: could not open output file\n" );
X		return (0);
X	}
X
X	/*
X	 * Write the Magic header
X	 */
X	fwrite( "GIF87a", 1, 6, fp );
X
X	/*
X	 * Write out the screen width and height
X	 */
X	Putword( RWidth, fp );
X	Putword( RHeight, fp );
X
X	/*
X	 * Indicate that there is a global colour map
X	 */
X	B = 0x80;	/* Yes, there is a color map */
X
X	/*
X	 * OR in the resolution
X	 */
X	B |= (Resolution - 1) << 5;
X
X	/*
X	 * OR in the Bits per Pixel
X	 */
X	B |= (BitsPerPixel - 1);
X
X	/*
X	 * Write it out
X	 */
X	fputc( B, fp );
X
X	/*
X	 * Write out the Background colour
X	 */
X	fputc( Background, fp );
X
X	/*
X	 * Byte of 0s (future expansion)
X	 */
X	fputc( 0, fp );
X
X	/*
X	 * Write out the Global Colour Map
X	 */
X     	for( i=0; i<ColorMapSize; i++ ) {
X		fputc( Red[i], fp );
X		fputc( Green[i], fp );
X		fputc( Blue[i], fp );
X	}
X
X	/*
X	 * Write an Image separator
X	 */
X	fputc( ',', fp );
X
X	/*
X	 * Write the Image header
X	 */
X
X	Putword( LeftOfs, fp );
X	Putword( TopOfs, fp );
X	Putword( Width, fp );
X	Putword( Height, fp );
X
X	/*
X	 * Write out whether or not the image is interlaced
X	 */
X	if( Interlace )
X		fputc( 0x40, fp );
X	else
X		fputc( 0x00, fp );
X
X	/*
X	 * Write out the initial code size
X	 */
X	fputc( InitCodeSize, fp );
X
X	/*
X	 * Go and actually compress the data
X	 */
X	compress( InitCodeSize+1, fp, GetPixel );
X
X	/*
X	 * Write out a Zero-length packet (to end the series)
X	 */
X	fputc( 0, fp );
X
X	/*
X	 * Write the GIF file terminator
X	 */
X	fputc( ';', fp );
X
X	/*
X	 * And close the file
X	 */
X	fclose( fp );
X	
X	return (1);	/* success - mlm 2/19/89 */
X}
X
X/*
X * Write out a word to the GIF file
X */
Xstatic
XPutword( w, fp )
Xint w;
XFILE *fp;
X{
X	fputc( w & 0xff, fp );
X	fputc( (w / 256) & 0xff, fp );
X}
END_OF_FILE
if test 5443 -ne `wc -c <'flgife.c'`; then
    echo shar: \"'flgife.c'\" unpacked with wrong size!
fi
# end of 'flgife.c'
fi
if test -f 'flpbm.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'flpbm.c'\"
else
echo shar: Extracting \"'flpbm.c'\" \(5001 characters\)
sed "s/^X//" >'flpbm.c' <<'END_OF_FILE'
X/*****************************************************************
X * flpbm.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 * flpbm.c: 
X *
X * CONTENTS
X *	read_pbm (image, infile, mstr, mlen)
X *	write_pbm (image, stream)
X *
X * EDITLOG
X *	LastEditDate = Tue Mar  7 19:57:22 1989 - Michael Mauldin
X *	LastFileName = /usr2/mlm/src/misc/fbm/flpbm.c
X *
X * HISTORY
X * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
X *	Beta release (version 0.9) mlm@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
X/****************************************************************
X * read_pbm: Read a pbm file into an fbm bitmap
X ****************************************************************/
X
X#ifndef lint
Xstatic char *fbmid =
X	"$FBM flpbm.c <0.9> 07-Mar-89  (C) 1989 by Michael Mauldin$";
X#endif
X
Xread_pbm (image, infile, mstr, mlen)
XFBM *image;
XFILE *infile;
Xchar *mstr;
Xint mlen;
X{ register int ch, i, j;
X  register unsigned char *bmp;
X  char cmtbuf[128], *s;
X
X  if ((ch = NEXTMCH (infile, mstr, mlen)) != 'P' || 
X      (ch = NEXTMCH (infile, mstr, mlen)) != '1')
X  { fprintf (stderr, "bad magic number, input not PBM file\n");
X    return (0);
X  }
X
X  image->hdr.cols = pbm_getint (infile);
X  image->hdr.rows = pbm_getint (infile);
X  image->hdr.planes = 1;
X  image->hdr.bits = 1;  
X  image->hdr.physbits = 8;
X  image->hdr.rowlen = 16 * ((image->hdr.cols + 15) / 16);
X  image->hdr.plnlen = image->hdr.rowlen * image->hdr.rows;
X  image->hdr.clrlen = 0;
X  image->hdr.aspect = 1.0;
X  image->hdr.title[0] = '\0';
X  
X  if (image->hdr.cols < 1 || image->hdr.rows < 1)
X  { fprintf (stderr, "Error, specified size %d by %d\n",
X	     image->hdr.cols, image->hdr.rows);
X    return (0);
X  }
X  
X  fprintf (stderr,
X	   "Reading PBM file \"%s\" [%dx%dx1]\n",
X	   image->hdr.title[0] ? image->hdr.title : "",
X	   image->hdr.cols, image->hdr.rows);
X
X  alloc_fbm (image);
X
X  for (j=0; j<image->hdr.rows; j++)
X  { bmp = &(image->bm[j * image->hdr.rowlen]);
X
X    for (i=0; i<image->hdr.cols; i++)
X    { while ((ch = fgetc (infile)) != EOF)
X      { if (ch == '0') { *bmp++ = WHITE; break; }
X
X        else if (ch == '1') { *bmp++ = BLACK; break; }
X
X	else if (ch == '#')
X        { s = cmtbuf; *s++ = '#';
X	  while ((ch = fgetc (infile)) != EOF && ch != '\n') *s++ = ch;
X	  *s = '\0';
X	  for (s=cmtbuf; *s == '#' || isspace (*s); s++) ;
X	  if (!strncmp (s, "Title: ", 7)) strcpy (image->hdr.title, s+7);
X	  fprintf (stderr, "Read_pbm found title '%s'\n",
X		   image->hdr.title);
X	}
X      }
X      
X      if (ch == EOF)
X      { fprintf (stderr, "premature EOF, row %d, col %d\n", j, i);
X        return (0);
X      }
X    }
X  }
X
X  
X  return (1);
X}
X
X/****************************************************************
X * pbm_getint: Read a number from a PBM file, ignoring comments
X ****************************************************************/
X
X# define START 1
X# define COMMENT 2
X# define INTEGER 3
X
Xpbm_getint (infile)
XFILE *infile;
X{ char buf[80];
X  register char *s = buf;
X  register int ch;
X  int state = START;
X
X  while (1)
X  { if ((ch = fgetc (infile)) == EOF)
X    { fprintf (stderr, "premature EOF\n");
X      return (0);
X    }
X
X    switch (state)
X    { case START:	if (isspace (ch)) ;
X			else if (ch == '#') state = COMMENT;
X			else if (isdigit (ch))
X			{ *s++ = ch; state = INTEGER; }
X			else
X			{ fprintf (stderr, "bad INTEGER in input");
X			  return (0);
X			}
X			break;
X
X      case COMMENT:	if (ch == '\n') state = START;
X			break;
X
X      case INTEGER:	if (isdigit (ch)) *s++ = ch;
X			else
X			{ register int result;
X
X			  *s = '\0';
X			  result = atoi (buf);
X			  return (result);
X			}
X			break;
X
X      default:		fprintf (stderr, "impossible state %d\n", state);
X			return (0);
X    }
X  }
X}
X
X/****************************************************************
X * write_pbm: Write a bitmap in PBM format to the output device
X ****************************************************************/
X
Xwrite_pbm (image, stream)
Xregister FBM *image;
XFILE *stream;
X{ register int i, j, outcol = 0;
X  register unsigned char *bmp;
X
X  /* Write PBM header lines */
X  fprintf (stream, "P1\n%d %d\n", image->hdr.cols, image->hdr.rows);
X  if (image->hdr.title[0])
X  { fprintf (stream, "# Title: %s\n", image->hdr.title); }
X  
X  /* Now write out 1s and 0s, in 70 character lines */
X  for (j=0; j < image->hdr.rows; j++)
X  { bmp = &(image->bm[j * image->hdr.rowlen]);
X
X    for (i=0; i < image->hdr.cols; i++)
X    { fputc (*bmp++ ? '0' : '1', stream);	/* In PBM 1=black, not white */
X      if (++outcol >= 70) { fprintf (stream, "\n"); outcol=0; }
X    }
X    if (outcol) { fprintf (stream, "\n"); outcol=0; }
X  }
X  
X  return (1);
X}
END_OF_FILE
if test 5001 -ne `wc -c <'flpbm.c'`; then
    echo shar: \"'flpbm.c'\" unpacked with wrong size!
fi
# end of 'flpbm.c'
fi
if test -f 'flrot.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'flrot.c'\"
else
echo shar: Extracting \"'flrot.c'\" \(5222 characters\)
sed "s/^X//" >'flrot.c' <<'END_OF_FILE'
X/*****************************************************************
X * flrot.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 * flrot.c: 
X *
X * CONTENTS
X *	rotate_fbm (input, output, rot)
X *
X * EDITLOG
X *	LastEditDate = Tue Mar  7 19:57:29 1989 - Michael Mauldin
X *	LastFileName = /usr2/mlm/src/misc/fbm/flrot.c
X *
X * HISTORY
X * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
X *	Beta release (version 0.9) mlm@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
X/****************************************************************
X * rotate_fbm: Rotate input bitmap
X ****************************************************************/
X
X#ifndef lint
Xstatic char *fbmid =
X	"$FBM flrot.c <0.9> 07-Mar-89  (C) 1989 by Michael Mauldin$";
X#endif
X
Xrotate_fbm (input, output, rot)
XFBM *input, *output;
Xint rot;
X{
X  switch (rot)
X  { case 90:	return (rot90_fbm  (input, output));
X    case 180:	return (rot180_fbm (input, output));
X    case 270:	return (rot270_fbm (input, output));
X    default:	fprintf (stderr, "%s %d degrees, must be 90, 180, or 270\n",
X			 "invalid rotation", rot);
X		return (0);
X  }
X}
X
X/****************************************************************
X * rot90_fbm: Rotate input bitmap 90 degrees clockwise
X ****************************************************************/
X
Xrot90_fbm (input, output)
XFBM *input, *output;
X{ register int i, j, k, oi, oj;
X  int iw, ow, ih, oh, irow, orow, ipln, opln;
X
X  if (input->hdr.physbits != 8)
X  { fprintf (stderr,
X	    "Can't handle images %d physical bits per pixel\n",
X	    input->hdr.physbits);
X    exit (1);
X  }
X
X  oh = iw = input->hdr.cols;
X  ow = ih = input->hdr.rows;
X  
X  irow = input->hdr.rowlen;
X  ipln = input->hdr.plnlen;
X
X  /* Calculate row length (input height padded to even byte boundary) */
X  if (input->hdr.bits == 1)
X  { orow = 16 * ((ow + 15) / 16); }
X  else
X  { orow = 2 * ((ow * input->hdr.physbits + 15) / 16); }
X
X  opln = orow * oh; 
X
X  /* Now build header for output bit map */
X  output->hdr = input->hdr;
X  output->hdr.cols = ow;
X  output->hdr.rows = oh;
X  output->hdr.rowlen = orow;
X  output->hdr.plnlen = opln;
X  output->hdr.aspect = 1.0 / input->hdr.aspect;
X  
X  /* Allocate space for output bits */
X  alloc_fbm (output);
X  
X  copy_clr (input, output);
X
X  for (k=0; k<output->hdr.planes; k++)
X  { for (j=0; j<ih; j++)
X    { for (i=0; i<iw; i++)
X      { oj = i; oi = ih - (j+1);
X        output->bm[k*opln + oj*orow + oi] = input->bm[k*ipln + j*irow + i];
X      }
X    }
X  }
X
X  return (1);
X}
X
X/****************************************************************
X * rot180_fbm: Rotate input bitmap 180 degrees clockwise
X ****************************************************************/
X
Xrot180_fbm (input, output)
XFBM *input, *output;
X{ register int i, j, k, oi, oj;
X  int w, h, row, pln;
X
X  if (input->hdr.physbits != 8)
X  { fprintf (stderr,
X	     "Can't handle images %d physical bits per pixel\n",
X	     input->hdr.physbits);
X    exit (1);
X  }
X
X  /* Now build header for output bit map */
X  output->hdr = input->hdr;
X  w = input->hdr.cols;
X  h = input->hdr.rows;
X  row = input->hdr.rowlen;
X  pln = input->hdr.plnlen;
X  
X  /* Allocate space for output bits */
X  alloc_fbm (output);
X  
X  copy_clr (input, output);
X
X  for (k=0; k<output->hdr.planes; k++)
X  { for (j=0; j<h; j++)
X    { for (i=0; i<w; i++)
X      { oj = h - (j+1); oi = w - (i+1);
X        output->bm[k*pln + oj*row + oi] = input->bm[k*pln + j*row + i];
X      }
X    }
X  }
X
X  return (1);
X}
X
X/****************************************************************
X * rot270_fbm: Rotate input bitmap 270 degrees clockwise
X ****************************************************************/
X
Xrot270_fbm (input, output)
XFBM *input, *output;
X{ register int i, j, k, oi, oj;
X  int iw, ow, ih, oh, irow, orow, ipln, opln;
X
X  if (input->hdr.physbits != 8)
X  { fprintf (stderr,
X	    "Can't handle images %d physical bits per pixel\n",
X	    input->hdr.physbits);
X    exit (1);
X  }
X
X  oh = iw = input->hdr.cols;
X  ow = ih = input->hdr.rows;
X  
X  irow = input->hdr.rowlen;
X  ipln = input->hdr.plnlen;
X
X  /* Calculate row length (input height padded to even byte boundary) */
X  if (input->hdr.bits == 1)
X  { orow = 16 * ((ow + 15) / 16); }
X  else
X  { orow = 2 * ((ow * input->hdr.physbits + 15) / 16); }
X
X  opln = orow * oh;
X  
X  /* Now build header for output bit map */
X  output->hdr = input->hdr;
X  output->hdr.cols = ow;
X  output->hdr.rows = oh;
X  output->hdr.rowlen = orow;
X  output->hdr.plnlen = opln;
X  output->hdr.aspect = 1.0 / input->hdr.aspect;
X  
X  /* Allocate space for output bits */
X  alloc_fbm (output);
X  
X  copy_clr (input, output);
X
X  for (k=0; k<output->hdr.planes; k++)
X  { for (j=0; j<ih; j++)
X    { for (i=0; i<iw; i++)
X      { oj = iw - (i+1); oi = j;
X        output->bm[k*opln + oj*orow + oi] = input->bm[k*ipln + j*irow + i];
X      }
X    }
X  }
X
X  return (1);
X}
END_OF_FILE
if test 5222 -ne `wc -c <'flrot.c'`; then
    echo shar: \"'flrot.c'\" unpacked with wrong size!
fi
# end of 'flrot.c'
fi
if test -f 'flshrp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'flshrp.c'\"
else
echo shar: Extracting \"'flshrp.c'\" \(5370 characters\)
sed "s/^X//" >'flshrp.c' <<'END_OF_FILE'
X/*****************************************************************
X * flshrp.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 * flshrp.c: 
X *
X * CONTENTS
X *	sharpen_fbm (input, output, beta)
X *
X * EDITLOG
X *	LastEditDate = Tue Mar  7 19:57:30 1989 - Michael Mauldin
X *	LastFileName = /usr2/mlm/src/misc/fbm/flshrp.c
X *
X * HISTORY
X * 07-Mar-89  Michael Mauldin (mlm) at Carnegie Mellon University
X *	Beta release (version 0.9) mlm@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
X/****************************************************************
X * sharpen_fbm: determine whether image is in color, and call the
X *	        appropriate sharpening routine.
X ****************************************************************/
X
X#ifndef lint
Xstatic char *fbmid =
X	"$FBM flshrp.c <0.9> 07-Mar-89  (C) 1989 by Michael Mauldin$";
X#endif
X
Xsharpen_fbm (input, output, beta)
XFBM *input, *output;
Xdouble beta;
X{
X  if (input->hdr.planes == 1 && input->hdr.clrlen == 0)
X  { return (sharpen_bw (input, output, beta)); }
X  else
X  { return (sharpen_clr (input, output, beta)); }
X}
X
X/****************************************************************
X * sharpen_bw: use a digital Laplacian filter to sharpen a BW image
X ****************************************************************/
X
Xsharpen_bw (input, output, beta)
XFBM *input, *output;
Xdouble beta;
X{ register unsigned char *bmp, *obm;
X  register int i, j, rowlen, w, h, sum;
X  int new, delta, beta100 = beta * 100;
X
X  if (input->hdr.planes != 1)
X  { fprintf (stderr, "sharpen_bw: can't sharpen color images\n");
X    return (0);
X  }
X
X  fprintf (stderr, "Sharpen BW, 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  rowlen = input->hdr.rowlen;
X
X  /* Copy edges directly */
X  for (j=0; j<h; j++)
X  { output->bm[j*rowlen] = input->bm[j*rowlen];
X    output->bm[j*rowlen + w-1] = input->bm[j*rowlen + w-1];
X  }
X
X  for (i=0; i<w; i++)
X  { output->bm[i] = input->bm[i];
X    output->bm[(h-1)*rowlen + i] = input->bm[(h-1)*rowlen + i];
X  }
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 = bmp[i-rowlen-1] +     bmp[i-rowlen] + bmp[i-rowlen+1] +
X	    bmp[i-1]        - 8 * bmp[i]        + bmp[i+1]        +
X	    bmp[i+rowlen-1] +     bmp[i+rowlen] + bmp[i+rowlen+1];
X
X      if (sum < 0)
X      { delta = - (beta100 * bmp[i] * -sum / (8*WHITE*100)); }
X      else
X      { delta = beta100 * bmp[i] * sum / (8*WHITE*100); }
X
X      new = bmp[i] - delta;
X
X      if (new < BLACK) new = BLACK;
X      else if (new > WHITE) new = WHITE;
X      
X      obm[i] = new;
X    }
X  }
X  
X  return (1);
X}
X
X/****************************************************************
X * sharpen_clr: use a digital Laplacian filter to sharpen a CLR image
X ****************************************************************/
X
Xsharpen_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  if (input->hdr.clrlen > 0)
X  { fprintf (stderr,
X	 "cannot sharpen mapped color images, use 'gray2clr -u' first\n");
X    return (0);
X  }
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*WHITE*100)); }
X	else
X	{ delta = beta100 * *bmp * sum / (8*WHITE*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  
X  return (1);
X}
END_OF_FILE
if test 5370 -ne `wc -c <'flshrp.c'`; then
    echo shar: \"'flshrp.c'\" unpacked with wrong size!
fi
# end of 'flshrp.c'
fi
echo shar: End of archive 4 \(of 8\).
cp /dev/null ark4isdone
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@uunet.uu.net.