rsalz@uunet.uu.net (Rich Salz) (06/09/89)
Submitted-by: Michael.Mauldin@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@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@cs.wisc.edu> X * X * 20-Apr-89 Michael Mauldin (mlm) at Carnegie Mellon University X * Beta release (version 0.91) mlm@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@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@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@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@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@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@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@uunet.uu.net.