v05i030: xloadimage, Patch2

jim frost madd at world.std.com
Wed Nov 22 12:07:37 AEST 1989


Submitted-by: uunet!world.std.com!madd (jim frost)
Posting-number: Volume 5, Issue 30
Archive-name: xldimage/patch2
Patch-To: xldimage: Volume 5, Issue 27,28


The following shar contains new files and patches for xloadimage to
bring it to patchlevel 02.  This corrects a bug in zooming bitmaps,
some documentation errors, adds a new image format (XPM), and adds a
new (but still simple) dithering algorithm.

Anyone who would like to implement a better dithering algorithm is
encouraged to do so.

jim frost
software tool & die
madd at std.com

-- cut here --
#! /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 shell archive."
# Contents:  patch.02 halftone.c xpixmap.c
# Wrapped by madd at world on Mon Nov 20 17:07:36 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f patch.02 -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"patch.02\"
else
echo shar: Extracting \"patch.02\" \(18546 characters\)
sed "s/^X//" >patch.02 <<'END_OF_patch.02'
X*** Imakefile.orig	Mon Nov 20 16:10:40 1989
X--- Imakefile	Mon Nov 20 16:17:15 1989
X***************
X*** 1,13 ****
X!         DEFINES = -DSYSPATHFILE=\"/usr/lib/X11/xloadimage/xloadimagerc\"
X          DEPLIBS = $(DEPLIBS)
X  LOCAL_LIBRARIES = $(XLIB)
X             SRCS = bright.c clip.c compress.c dither.c faces.c fill.c \
X! 		  imagetypes.c merge.c misc.c new.c options.c path.c \
X! 		  pbm.c reduce.c root.c send.c sunraster.c value.c \
X! 		  window.c xbitmap.c xloadimage.c zio.c zoom.c
X             OBJS = bright.o clip.o compress.o dither.o faces.o fill.o \
X! 		  imagetypes.o merge.o misc.o new.o options.o path.o \
X! 		  pbm.o reduce.o root.o send.o sunraster.o value.o \
X! 		  window.o xbitmap.o xloadimage.o zio.o zoom.o
X  
X  ComplexProgramTarget(xloadimage)
X--- 1,16 ----
X!     SYSPATHFILE = $(USRLIBDIR)/xloadimagerc
X!         DEFINES = -DSYSPATHFILE=\"$(SYSPATHFILE)\"
X          DEPLIBS = $(DEPLIBS)
X  LOCAL_LIBRARIES = $(XLIB)
X             SRCS = bright.c clip.c compress.c dither.c faces.c fill.c \
X! 		  halftone.c imagetypes.c merge.c misc.c new.c \
X! 		  options.c path.c pbm.c reduce.c root.c send.c \
X! 		  sunraster.c value.c window.c xbitmap.c xloadimage.c \
X! 		  xpixmap.c zio.c zoom.c
X             OBJS = bright.o clip.o compress.o dither.o faces.o fill.o \
X! 		  halftone.o imagetypes.o merge.o misc.o new.o \
X! 		  options.o path.o pbm.o reduce.o root.o send.o \
X! 		  sunraster.o value.o window.o xbitmap.o xloadimage.o \
X! 		  xpixmap.o zio.o zoom.o
X  
X  ComplexProgramTarget(xloadimage)
X*** Makefile.gcc.orig	Mon Nov 20 16:10:41 1989
X--- Makefile.gcc	Mon Nov 20 16:18:54 1989
X***************
X*** 8,16 ****
X  CFLAGS= -O -fstrength-reduce -finline-functions -DSYSPATHFILE=\"/usr/lib/xloadimagerc\"
X  
X  LIBS= -lX11
X! OBJS= bright.o clip.o compress.o dither.o faces.o fill.o imagetypes.o \
X!       merge.o misc.o new.o options.o path.o pbm.o reduce.o root.o send.o \
X!       sunraster.o value.o window.o xbitmap.o xloadimage.o zio.o zoom.o
X  
X  xloadimage: $(OBJS)
X  	$(CC) $(CFLAGS) -o xloadimage $(OBJS) $(LIBS)
X--- 8,17 ----
X  CFLAGS= -O -fstrength-reduce -finline-functions -DSYSPATHFILE=\"/usr/lib/xloadimagerc\"
X  
X  LIBS= -lX11
X! OBJS= bright.o clip.o compress.o dither.o faces.o fill.o \
X!       halftone.o imagetypes.o merge.o misc.o new.o options.o path.o \
X!       pbm.o reduce.o root.o send.o sunraster.o value.o window.o \
X!       xbitmap.o xloadimage.o xpixmap.o zio.o zoom.o
X  
X  xloadimage: $(OBJS)
X  	$(CC) $(CFLAGS) -o xloadimage $(OBJS) $(LIBS)
X*** Makefile.std.orig	Mon Nov 20 16:41:09 1989
X--- Makefile.std	Mon Nov 20 16:38:39 1989
X***************
X*** 8,16 ****
X  CFLAGS= -O -DSYSPATHFILE=\"/usr/lib/xloadimagerc\"
X  
X  LIBS= -lX11
X! OBJS= bright.o clip.o compress.o dither.o faces.o fill.o imagetypes.o \
X!       merge.o misc.o new.o options.o path.o pbm.o reduce.o root.o send.o \
X!       sunraster.o value.o window.o xbitmap.o xloadimage.o zio.o zoom.o
X  
X  xloadimage: $(OBJS)
X  	$(CC) $(CFLAGS) -o xloadimage $(OBJS) $(LIBS)
X--- 8,17 ----
X  CFLAGS= -O -DSYSPATHFILE=\"/usr/lib/xloadimagerc\"
X  
X  LIBS= -lX11
X! OBJS= bright.o clip.o compress.o dither.o faces.o fill.o \
X!       halftone.o imagetypes.o merge.o misc.o new.o options.o path.o \
X!       pbm.o reduce.o root.o send.o sunraster.o value.o window.o \
X!       xbitmap.o xloadimage.o xpixmap.o zio.o zoom.o
X  
X  xloadimage: $(OBJS)
X  	$(CC) $(CFLAGS) -o xloadimage $(OBJS) $(LIBS)
X*** dither.c.orig	Mon Nov 20 16:10:44 1989
X--- dither.c	Mon Nov 20 16:15:07 1989
X***************
X*** 1,13 ****
X  /* dither.c:
X   *
X!  * routine for dithering a color image to monochrome based on color
X!  * intensity.  this is loosely based on an algorithm which barry shein
X!  * (bzs at std.com) used in his "xf" program.
X   *
X   * jim frost 07.10.89
X   *
X!  * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X!  * copyright information.
X   */
X  
X  #include "copyright.h"
X--- 1,14 ----
X  /* dither.c:
X   *
X!  * this is a modified version of the dithering algorithm in halftone.c
X!  * which doesn't enlarge the image.  modifications made by
X!  * Steve Losen (scl at virginia.edu).
X   *
X   * jim frost 07.10.89
X+  * Steve Losen 11.17.89
X   *
X!  * Copyright 1989 Jim Frost and Steve Losen.  See included file
X!  * "copyright.h" for complete copyright information.
X   */
X  
X  #include "copyright.h"
X***************
X*** 21,41 ****
X  
X  static byte DitherBits[GRAYS][4] = {
X    0xf, 0xf, 0xf, 0xf,
X!   0xe, 0xf, 0xf, 0xf,
X!   0xe, 0xf, 0xb, 0xf,
X!   0xa, 0xf, 0xb, 0xf,
X!   0xa, 0xf, 0xa, 0xf,
X!   0xa, 0xd, 0xa, 0xf,
X!   0xa, 0xd, 0xa, 0x7,
X!   0xa, 0x5, 0xa, 0x7,
X!   0xa, 0x5, 0xa, 0x5,
X!   0x8, 0x5, 0xa, 0x5,
X!   0x8, 0x5, 0x2, 0x5,
X!   0x0, 0x5, 0x2, 0x5,
X!   0x0, 0x5, 0x0, 0x5,
X!   0x0, 0x4, 0x0, 0x5,
X!   0x0, 0x4, 0x0, 0x1,
X!   0x0, 0x0, 0x0, 0x1,
X    0x0, 0x0, 0x0, 0x0
X  };
X  
X--- 22,42 ----
X  
X  static byte DitherBits[GRAYS][4] = {
X    0xf, 0xf, 0xf, 0xf,
X!   0xf, 0xf, 0xf, 0x7,
X!   0xf, 0xf, 0xf, 0x3,
X!   0xf, 0xf, 0x7, 0x3,
X!   0xf, 0xf, 0x3, 0x3,
X!   0xf, 0xf, 0x3, 0x1,
X!   0xf, 0x7, 0x3, 0x1,
X!   0xf, 0x7, 0x1, 0x1,
X!   0x7, 0x7, 0x3, 0x0,
X!   0x7, 0x7, 0x1, 0x0,
X!   0x7, 0x3, 0x1, 0x0,
X!   0x7, 0x3, 0x0, 0x0,
X!   0x3, 0x3, 0x0, 0x0,
X!   0x3, 0x1, 0x0, 0x0,
X!   0x3, 0x0, 0x0, 0x0,
X!   0x1, 0x0, 0x0, 0x0,
X    0x0, 0x0, 0x0, 0x0
X  };
X  
X***************
X*** 65,71 ****
X      printf("  Dithering image...");
X      fflush(stdout);
X    }
X!   image= newBitImage(cimage->width * 4, cimage->height * 4);
X    if (cimage->title) {
X      image->title= (char *)malloc(strlen(cimage->title) + 12);
X      sprintf(image->title, "%s (dithered)", cimage->title);
X--- 66,72 ----
X      printf("  Dithering image...");
X      fflush(stdout);
X    }
X!   image= newBitImage(cimage->width, cimage->height);
X    if (cimage->title) {
X      image->title= (char *)malloc(strlen(cimage->title) + 12);
X      sprintf(image->title, "%s (dithered)", cimage->title);
X***************
X*** 99,105 ****
X    dp= image->data;
X    for (y= 0; y < cimage->height; y++) {
X      for (x= 0; x < cimage->width; x++) {
X-       dp2= dp + (x >> 1);
X        color= memToVal(sp, spl);
X        if (index)
X  	dindex= *(index + color);
X--- 100,105 ----
X***************
X*** 107,130 ****
X  	dindex= ((unsigned long)(*(cimage->rgb.red + color)) +
X  		 *(cimage->rgb.green + color) +
X  		 *(cimage->rgb.blue + color)) / GRAYSTEP;
X! 
X!       /* loop for the four Y bits in the dither pattern, putting all
X!        * four X bits in at once.  if you think this would be hard to
X!        * change to be an NxN dithering array, you're right, since we're
X!        * banking on the fact that we need only shift the mask based on
X!        * whether x is odd or not.  an 8x8 array wouldn't even need that,
X!        * but blowing an image up by 64x is probably not a feature.
X!        */
X! 
X!       if (x & 1)
X! 	for (a= 0; a < 4; a++, dp2 += dll)
X! 	  *dp2 |= DitherBits[dindex][a];
X!       else
X! 	for (a= 0; a < 4; a++, dp2 += dll)
X! 	  *dp2 |= (DitherBits[dindex][a] << 4);
X        sp += spl;
X      }
X!     dp += (dll << 2); /* (dll * 4) but I like shifts */
X    }
X    if (verbose)
X      printf("done\n");
X--- 107,117 ----
X  	dindex= ((unsigned long)(*(cimage->rgb.red + color)) +
X  		 *(cimage->rgb.green + color) +
X  		 *(cimage->rgb.blue + color)) / GRAYSTEP;
X!       if (DitherBits[dindex][y & 3] & (1 << (x & 3)))
X! 	 dp[x / 8] |= 1 << (7 - (x & 7));
X        sp += spl;
X      }
X!     dp += dll;
X    }
X    if (verbose)
X      printf("done\n");
X*** image.h.orig	Mon Nov 20 16:10:45 1989
X--- image.h	Mon Nov 20 16:15:08 1989
X***************
X*** 60,65 ****
X--- 60,67 ----
X  
X  void fold(); /* fold.c */
X  
X+ Image *halftone(); /* halftone.c */
X+ 
X  Image *loadImage(); /* imagetypes.c */
X  void   identifyImage();
X  void   goodImage();
X***************
X*** 82,86 ****
X--- 84,90 ----
X  
X  unsigned long memToVal(); /* value.c */
X  void          valToMem();
X+ unsigned long memToValLSB();
X+ void          valToMemLSB();
X  
X  Image *zoom(); /* zoom.c */
X*** imagetypes.h.orig	Mon Nov 20 16:10:46 1989
X--- imagetypes.h	Mon Nov 20 16:19:13 1989
X***************
X*** 19,24 ****
X--- 19,27 ----
X  int xbitmapIdent();
X  int xpixmapIdent();
X  
X+ /* some of these are order-dependent
X+  */
X+ 
X  struct {
X    int    (*identifier)(); /* print out image info if this kind of image */
X    Image *(*loader)();     /* load image if this kind of image */
X***************
X*** 27,32 ****
X--- 30,36 ----
X    sunRasterIdent, sunRasterLoad, "Sun Rasterfile",
X    pbmIdent,       pbmLoad,       "Portable Bit Map (PBM)",
X    facesIdent,     facesLoad,     "Faces Project",
X+   xpixmapIdent,   xpixmapLoad,   "X Pixmap",
X    xbitmapIdent,   xbitmapLoad,   "X Bitmap",
X    NULL,           NULL,          NULL
X  };
X*** misc.c.orig	Mon Nov 20 16:10:47 1989
X--- misc.c	Mon Nov 20 16:15:09 1989
X***************
X*** 39,44 ****
X--- 39,45 ----
X    printf("  -clip X,Y,W,H         - use clipped portion of image\n");
X    printf("  -dither               - dither color image to bitmap image\n");
X    printf("  -foreground colorname - foreground color for bitmap images\n");
X+   printf("  -halftone             - halftone a color image to bitmap image\n");
X    printf("  -name name            - force next argument to be image name\n");
X    printf("  -xzoom percentage     - zoom the X axis by a percentage\n");
X    printf("  -yzoom percentage     - zoom the Y axis by a percentage\n");
X***************
X*** 111,117 ****
X    }
X  
X    if (options->dither && (image->depth > 1)) { /* image is to be dithered */
X!     tmpimage= dither(image, verbose);
X      freeImage(image);
X      image= tmpimage;
X      options->clipx *= 4;      /* image was blown up by 4 */
X--- 112,121 ----
X    }
X  
X    if (options->dither && (image->depth > 1)) { /* image is to be dithered */
X!     if (options->dither == 1)
X!       tmpimage= dither(image, verbose);
X!     else
X!       tmpimage= halftone(image, verbose);
X      freeImage(image);
X      image= tmpimage;
X      options->clipx *= 4;      /* image was blown up by 4 */
X*** value.c.orig	Mon Nov 20 16:10:59 1989
X--- value.c	Mon Nov 20 16:15:11 1989
X***************
X*** 36,38 ****
X--- 36,64 ----
X      val >>= 8;
X    }
X  }
X+ 
X+ unsigned long memToValLSB(p, len)
X+      byte         *p;
X+      unsigned int  len;
X+ { int val, a;
X+ 
X+   val= 0;
X+   for (a= len - 1; a >= 0; a--)
X+     val= (val << 8) + *(p + a);
X+   return(val);
X+ }
X+ 
X+ /* this is provided for orthagonality
X+  */
X+ 
X+ void valToMemLSB(val, p, len)
X+      byte          *p;
X+      unsigned long  val;
X+      unsigned int   len;
X+ { int a;
X+ 
X+   while (len--) {
X+     *(p++)= val & 0xff;
X+     val >>= 8;
X+   }
X+ }
X*** xloadimage.c.orig	Mon Nov 20 16:11:01 1989
X--- xloadimage.c	Mon Nov 20 16:15:12 1989
X***************
X*** 37,42 ****
X--- 37,43 ----
X    "colors",
X    "dither",
X    "foreground",
X+   "halftone",
X    "name",
X    "xzoom",
X    "yzoom",
X***************
X*** 66,76 ****
X  #define COLORS     18
X  #define DITHER     19
X  #define FOREGROUND 20
X! #define NAME       21
X! #define XZOOM      22
X! #define YZOOM      23
X! #define ZOOM       24
X  
X  /* the real thing
X   */
X  
X--- 67,86 ----
X  #define COLORS     18
X  #define DITHER     19
X  #define FOREGROUND 20
X! #define HALFTONE   21
X! #define NAME       22
X! #define XZOOM      23
X! #define YZOOM      24
X! #define ZOOM       25
X  
X+ /* if an image loader needs to have our display and screen, it will get
X+  * them from here.  this is done to keep most of the image routines
X+  * clean
X+  */
X+ 
X+ Display *Disp= NULL;
X+ int      Scrn= 0;
X+ 
X  /* the real thing
X   */
X  
X***************
X*** 246,251 ****
X--- 256,265 ----
X        images[imagecount].fg= argv[++a];
X        break;
X  
X+     case HALFTONE:
X+       images[imagecount].dither= 2;
X+       break;
X+ 
X      case NAME:
X        if (imagecount == MAXIMAGES)
X  	printf("%s: Too many images (ignoring)\n", argv[++a]);
X***************
X*** 287,297 ****
X    /* start talking to the display
X     */
X  
X!   if (! (disp= XOpenDisplay(dname))) {
X      printf("%s: Cannot open display\n", XDisplayName(dname));
X      exit(1);
X    }
X!   scrn= DefaultScreen(disp);
X    XSetIOErrorHandler(ioErrorHandler);
X  
X    dispimage= NULL;
X--- 301,311 ----
X    /* start talking to the display
X     */
X  
X!   if (! (Disp= disp= XOpenDisplay(dname))) {
X      printf("%s: Cannot open display\n", XDisplayName(dname));
X      exit(1);
X    }
X!   Scrn= scrn= DefaultScreen(disp);
X    XSetIOErrorHandler(ioErrorHandler);
X  
X    dispimage= NULL;
X***************
X*** 325,332 ****
X    for (a= 0; a < imagecount; a++) {
X      if (! (newimage= loadImage(images[a].name, verbose)))
X        continue;
X!     if ((dispimage && BITMAPP(dispimage)) || (DefaultDepth(disp, scrn) == 1))
X!       images[a].dither= 1;
X      newimage= processImage(disp, scrn, newimage, &images[a], verbose);
X      if (!images[a].clipw && !images[a].cliph) {
X        images[a].clipw= newimage->width;
X--- 339,347 ----
X    for (a= 0; a < imagecount; a++) {
X      if (! (newimage= loadImage(images[a].name, verbose)))
X        continue;
X!     if (!images[a].dither &&
X! 	((dispimage && BITMAPP(dispimage)) || (DefaultDepth(disp, scrn) == 1)))
X!       images[a].dither= 2;
X      newimage= processImage(disp, scrn, newimage, &images[a], verbose);
X      if (!images[a].clipw && !images[a].cliph) {
X        images[a].clipw= newimage->width;
X*** xloadimage.man.orig	Mon Nov 20 16:53:22 1989
X--- xloadimage.man	Mon Nov 20 17:06:00 1989
X***************
X*** 13,19 ****
X  If the destination display cannot support the number of colors in the
X  image, the image will be dithered (monochrome destination) or have its
X  colormap reduced (color destination) as appropriate.  This can also be
X! done forcibly with the \fI-dither\fR and \fI-colors\fR options.
X  .PP
X  If more than one image is to be loaded, they will be merged into a
X  single image.  The \fI-at\fR and \fI-center\fR options control where
X--- 13,19 ----
X  If the destination display cannot support the number of colors in the
X  image, the image will be dithered (monochrome destination) or have its
X  colormap reduced (color destination) as appropriate.  This can also be
X! done forcibly with the \fI-halftone\fR and \fI-colors\fR options.
X  .PP
X  If more than one image is to be loaded, they will be merged into a
X  single image.  The \fI-at\fR and \fI-center\fR options control where
X***************
X*** 128,136 ****
X  interpreted as the remainder of the image. 
X  .TP
X  -dither
X! Force halftone dithering of a color image when displaying on a color
X! display.  This happens by default when viewing color images on a
X! monochrome display.  This option is ignored on monochrome images. 
X  .TP
X  -foreground \fIcolor\fR
X  Use \fIcolor\fR as the foreground color instead of black if you are
X--- 128,136 ----
X  interpreted as the remainder of the image. 
X  .TP
X  -dither
X! Dither a color image to monochrome.  This algorithm is very trivial;
X! the \fI-halftone\fR option may look better if you don't mind the
X! blown-up image.
X  .TP
X  -foreground \fIcolor\fR
X  Use \fIcolor\fR as the foreground color instead of black if you are
X***************
X*** 138,143 ****
X--- 138,151 ----
X  used to invert the foreground and background colors of a monochrome
X  image. 
X  .TP
X+ -halftone
X+ Force halftone dithering of a color image when displaying on a
X+ monochrome display.  This happens by default when viewing color images
X+ on a monochrome display.  This option is ignored on monochrome images.
X+ This dithering algorithm blows an image up by sixteen times; if you
X+ don't like this, the \fI-dither\fR option will not blow the image up
X+ (but won't look as nice).
X+ .TP
X  -name \fIimage_name\fR
X  Force the next argument to be treated as an image name.  This is
X  useful if the name of the image is \fI-dither\fR, for instance. 
X***************
X*** 208,213 ****
X--- 216,222 ----
X    Sun color RGB rasterfiles
X    X10 bitmap files
X    X11 bitmap files
X+   X pixmap files
X  .fi
X  .PP
X  Both normal and compact PBM images are supported.  Both standard and
X***************
X*** 219,224 ****
X--- 228,235 ----
X  madd at std.com
X  .fi
X  .SH BUGS
X+ Zooming dithered images is UGLY.
X+ .PP
X  Loading images onto the root with PseudoColor or GrayScale displays
X  can cause colormap problems (and may interfere with window manager
X  operation) if there are not enough colors in the default colormap to
X*** zoom.c.orig	Mon Nov 20 16:11:03 1989
X--- zoom.c	Mon Nov 20 16:15:13 1989
X***************
X*** 46,53 ****
X    unsigned int  x, y, xsrc, ysrc;
X    unsigned int  pixlen;
X    unsigned int  srclinelen;
X    byte         *srcline, *srcptr;
X!   byte         *destptr;
X    byte          srcmask, destmask, bit;
X    Pixel         value;
X  
X--- 46,54 ----
X    unsigned int  x, y, xsrc, ysrc;
X    unsigned int  pixlen;
X    unsigned int  srclinelen;
X+   unsigned int  destlinelen;
X    byte         *srcline, *srcptr;
X!   byte         *destline, *destptr;
X    byte          srcmask, destmask, bit;
X    Pixel         value;
X  
X***************
X*** 90,96 ****
X        *(image->rgb.blue + x)= *(oimage->rgb.blue + x);
X      }
X      image->rgb.used= oimage->rgb.used;
X!     destptr= image->data;
X      srcline= oimage->data;
X      srclinelen= (oimage->width / 8) + (oimage->width % 8 ? 1 : 0);
X      for (y= 0, ysrc= *(yindex + y); y < ywidth; y++) {
X--- 91,98 ----
X        *(image->rgb.blue + x)= *(oimage->rgb.blue + x);
X      }
X      image->rgb.used= oimage->rgb.used;
X!     destline= image->data;
X!     destlinelen= (xwidth / 8) + (xwidth % 8 ? 1 : 0);
X      srcline= oimage->data;
X      srclinelen= (oimage->width / 8) + (oimage->width % 8 ? 1 : 0);
X      for (y= 0, ysrc= *(yindex + y); y < ywidth; y++) {
X***************
X*** 99,104 ****
X--- 101,107 ----
X  	srcline += srclinelen;
X        }
X        srcptr= srcline;
X+       destptr= destline;
X        srcmask= 0x80;
X        destmask= 0x80;
X        bit= srcmask & *srcptr;
X***************
X*** 120,125 ****
X--- 123,129 ----
X  	  destptr++;
X  	}
X        }
X+       destline += destlinelen;
X      }
X      break;
X  
X*** README.orig	Mon Nov 20 16:10:42 1989
X--- README	Mon Nov 20 16:33:15 1989
X***************
X*** 97,99 ****
X--- 97,104 ----
X  windows by typing 'q' was submitted by Chris Tengi
X  (tengi at idunno.princeton.edu) and was included.  The previously missing
X  file 'patchlevel' was included.
X+ 
X+ Patch 02 contained modifications to the Makefiles, support for the X
X+ Pixmap image type, a different dithering algorithm that didn't blow
X+ the image up (with the old one moved to halftone.c), and a bug fix to
X+ zoom.c to correct problems when zooming bitmaps.
X*** patchlevel.orig	Mon Nov 20 16:41:17 1989
X--- patchlevel	Mon Nov 20 16:47:04 1989
X***************
X*** 1 ****
X! PATCHLEVEL 01
X--- 1 ----
X! PATCHLEVEL 02
END_OF_patch.02
if test 18546 -ne `wc -c <patch.02`; then
    echo shar: \"patch.02\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f halftone.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"halftone.c\"
else
echo shar: Extracting \"halftone.c\" \(3916 characters\)
sed "s/^X//" >halftone.c <<'END_OF_halftone.c'
X/* dither.c:
X *
X * routine for dithering a color image to monochrome based on color
X * intensity.  this is loosely based on an algorithm which barry shein
X * (bzs at std.com) used in his "xf" program.
X *
X * jim frost 07.10.89
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X#include "image.h"
X
X/* 4x4 arrays used for dithering, arranged by nybble
X */
X
X#define GRAYS    17 /* ((4 * 4) + 1) patterns for a good dither */
X#define GRAYSTEP ((unsigned long)(65536 * 3) / GRAYS)
X
Xstatic byte DitherBits[GRAYS][4] = {
X  0xf, 0xf, 0xf, 0xf,
X  0xe, 0xf, 0xf, 0xf,
X  0xe, 0xf, 0xb, 0xf,
X  0xa, 0xf, 0xb, 0xf,
X  0xa, 0xf, 0xa, 0xf,
X  0xa, 0xd, 0xa, 0xf,
X  0xa, 0xd, 0xa, 0x7,
X  0xa, 0x5, 0xa, 0x7,
X  0xa, 0x5, 0xa, 0x5,
X  0x8, 0x5, 0xa, 0x5,
X  0x8, 0x5, 0x2, 0x5,
X  0x0, 0x5, 0x2, 0x5,
X  0x0, 0x5, 0x0, 0x5,
X  0x0, 0x4, 0x0, 0x5,
X  0x0, 0x4, 0x0, 0x1,
X  0x0, 0x0, 0x0, 0x1,
X  0x0, 0x0, 0x0, 0x0
X};
X
X/* simple dithering algorithm, really optimized for the 4x4 array
X */
X
XImage *halftone(cimage, verbose)
X     Image        *cimage;
X     unsigned int  verbose;
X{ Image         *image;
X  unsigned char *sp, *dp, *dp2; /* data pointers */
X  unsigned int   dindex;        /* index into dither array */
X  unsigned int   spl;           /* source pixel length in bytes */
X  unsigned int   dll;           /* destination line length in bytes */
X  Pixel          color;         /* pixel color */
X  unsigned int  *index;         /* index into dither array for a given pixel */
X  unsigned int   a, x, y;       /* random counters */
X
X  goodImage(cimage, "dither");
X  if (! RGBP(cimage))
X    return(NULL);
X
X  /* set up
X   */
X
X  if (verbose) {
X    printf("  Dithering image...");
X    fflush(stdout);
X  }
X  image= newBitImage(cimage->width * 4, cimage->height * 4);
X  if (cimage->title) {
X    image->title= (char *)malloc(strlen(cimage->title) + 12);
X    sprintf(image->title, "%s (dithered)", cimage->title);
X  }
X  spl= cimage->pixlen;
X  dll= (image->width / 8) + (image->width % 8 ? 1 : 0);
X
X  /* if the number of possible pixels isn't very large, build an array
X   * which we index by the pixel value to find the dither array index
X   * by color brightness.  we do this in advance so we don't have to do
X   * it for each pixel.  things will break if a pixel value is greater
X   * than (1 << depth), which is bogus anyway.  this calculation is done
X   * on a per-pixel basis if the colormap is too big.
X   */
X
X  if (cimage->depth <= 16) {
X    index= (unsigned int *)malloc(sizeof(unsigned int) * cimage->rgb.used);
X    for (x= 0; x < cimage->rgb.used; x++)
X      *(index + x)=
X	((unsigned long)(*(cimage->rgb.red + x)) +
X	 *(cimage->rgb.green + x) +
X	 *(cimage->rgb.blue + x)) / GRAYSTEP;
X  }
X  else
X    index= NULL;
X
X  /* dither each pixel
X   */
X
X  sp= cimage->data;
X  dp= image->data;
X  for (y= 0; y < cimage->height; y++) {
X    for (x= 0; x < cimage->width; x++) {
X      dp2= dp + (x >> 1);
X      color= memToVal(sp, spl);
X      if (index)
X	dindex= *(index + color);
X      else
X	dindex= ((unsigned long)(*(cimage->rgb.red + color)) +
X		 *(cimage->rgb.green + color) +
X		 *(cimage->rgb.blue + color)) / GRAYSTEP;
X
X      /* loop for the four Y bits in the dither pattern, putting all
X       * four X bits in at once.  if you think this would be hard to
X       * change to be an NxN dithering array, you're right, since we're
X       * banking on the fact that we need only shift the mask based on
X       * whether x is odd or not.  an 8x8 array wouldn't even need that,
X       * but blowing an image up by 64x is probably not a feature.
X       */
X
X      if (x & 1)
X	for (a= 0; a < 4; a++, dp2 += dll)
X	  *dp2 |= DitherBits[dindex][a];
X      else
X	for (a= 0; a < 4; a++, dp2 += dll)
X	  *dp2 |= (DitherBits[dindex][a] << 4);
X      sp += spl;
X    }
X    dp += (dll << 2); /* (dll * 4) but I like shifts */
X  }
X  if (verbose)
X    printf("done\n");
X  return(image);
X}
END_OF_halftone.c
if test 3916 -ne `wc -c <halftone.c`; then
    echo shar: \"halftone.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f xpixmap.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"xpixmap.c\"
else
echo shar: Extracting \"xpixmap.c\" \(5707 characters\)
sed "s/^X//" >xpixmap.c <<'END_OF_xpixmap.c'
X/* xpixmap.c:
X *
X * XPixMap format file read and identify routines.  these can handle any
X * "format 1" XPixmap file with up to BUFSIZ - 1 chars per pixel.  it's
X * not nearly as picky as it might be.
X *
X * unlike most image loading routines, this is X specific since it
X * requires X color name parsing.  to handle this we have global X
X * variables for display and screen.  it's ugly but it keeps the rest
X * of the image routines clean.
X *
X * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "copyright.h"
X#include "xloadimage.h"
X
Xchar *rindex();
X
Xextern Display *Disp; /* X display, null if in "identify" mode */
Xextern int      Scrn; /* X screen number */
X
X#define XPM_FORMAT 1
X
Xstatic void corrupted(fullname, zf)
X     char  *fullname;
X     ZFILE *zf;
X{
X  zclose(zf);
X  printf("%s: X Pixmap file is corrupted\n", fullname);
X  exit(1);
X}
X
XImage *xpixmapLoad(fullname, name, verbose)
X     char         *fullname, *name;
X     unsigned int  verbose;
X{ ZFILE         *zf;
X  char           buf[BUFSIZ];
X  char           what[BUFSIZ];
X  char          *p;
X  unsigned int   value;
X  unsigned int   format;  /* image format */
X  unsigned int   w, h;    /* image dimensions */
X  unsigned int   cpp;     /* chars per pixel */
X  unsigned int   ncolors; /* number of colors */
X  unsigned int   depth;   /* depth of image */
X  char         **ctable;  /* color table */
X  Image         *image;
X  XColor         xcolor;
X  unsigned int   a, b, x, y;
X  int            c;
X  byte          *dptr;
X
X  if (! (zf= zopen(fullname)))
X    return(NULL);
X
X  /* read #defines until we have all that are necessary or until we
X   * get an error
X   */
X
X  format= w= h= ncolors= 0;
X  for (;;) {
X    if (! zgets(buf, BUFSIZ - 1, zf)) {
X      zclose(zf);
X      return(NULL);
X    }
X    if (!strncmp(buf, "#define", 7)) {
X      if (sscanf(buf, "#define %s %d", what, &value) != 2) {
X	zclose(zf);
X	return(NULL);
X      }
X      if (! (p= rindex(what, '_')))
X	p= what;
X      else
X	p++;
X      if (!strcmp(p, "format"))
X	format= value;
X      else if (!strcmp(p, "width"))
X	w= value;
X      else if (!strcmp(p, "height"))
X	h= value;
X      else if (!strcmp(p, "ncolors"))
X	ncolors= value;
X
X      /* this one is ugly
X       */
X
X      else if (!strcmp(p, "pixel")) { /* this isn't pretty but it works */
X	if (p == what)
X	  continue;
X	*(--p)= '\0';
X	if (!(p= rindex(what, '_')) || (p == what) || strcmp(++p, "per"))
X	  continue;
X	*(--p)= '\0';
X	if (!(p= rindex(what, '_')))
X	  p= what;
X	if (strcmp(++p, "chars"))
X	  continue;
X	cpp= value;
X      }
X    }
X    else if ((sscanf(buf, "static char * %s", what) == 1) &&
X	     (p= rindex(what, '_')) && !strcmp(++p, "colors[]"))
X      break;
X  }
X
X  if ((format != XPM_FORMAT) || !w || !h || !ncolors || !cpp) {
X    zclose(zf);
X    return(NULL);
X  }
X
X  if (p= rindex(what, '_')) {     /* get the name in the image if there is */
X    *p= '\0';                     /* one */
X    image->title= dupString(what);
X  }
X  else {
X    p= what;
X    image->title= dupString(name);
X  }
X
X  if (verbose)
X    printf("%s is a %dx%d X Pixmap image with %d colors titled '%s'\n",
X	   name, w, h, ncolors, image->title);
X
X  for (depth= 1, value= 2; value < ncolors; value <<= 1, depth++)
X    ;
X  image= newRGBImage(w, h, depth);
X  image->rgb.used= ncolors;
X
X  /* read the colors array and build the image colormap
X   */
X
X  ctable= (char **)lmalloc(sizeof(char *) * ncolors);
X  xcolor.flags= DoRed | DoGreen | DoBlue;
X  for (a= 0; a < ncolors; a++) {
X 
X    /* read pixel value
X     */
X
X    *(ctable + a)= (char *)lmalloc(cpp);
X    while (((c= zgetc(zf)) != EOF) && (c != '"'))
X      ;
X    if (c == EOF)
X      corrupted(fullname, zf);
X    for (b= 0; b < cpp; b++) {
X      if ((c= zgetc(zf)) == '\\')
X	c= zgetc(zf);
X     if (c == EOF)
X	corrupted(fullname, zf);
X      *(*(ctable + a) + b)= (char)c;
X    }
X    if (((c= zgetc(zf)) == EOF) || (c != '"'))
X      corrupted(fullname, zf);
X
X    /* read color definition and parse it
X     */
X
X    while (((c= zgetc(zf)) != EOF) && (c != '"'))
X      ;
X    if (c == EOF)
X      corrupted(fullname, zf);
X    for (b= 0; ((c= zgetc(zf)) != EOF) && (c != '"'); b++) {
X      if (c == '\\')
X	c= zgetc(zf);
X      if (c == EOF)
X	corrupted(fullname, zf);
X      buf[b]= (char)c;
X    }
X    buf[b]= '\0';
X
X    if (Disp) {
X      if (! XParseColor(Disp, DefaultColormap(Disp, Scrn), buf, &xcolor)) {
X	printf("%s: %s: Bad color name\n", fullname, buf);
X	exit(1);
X      }
X      *(image->rgb.red + a)= xcolor.red;
X      *(image->rgb.green + a)= xcolor.green;
X      *(image->rgb.blue + a)= xcolor.blue;
X    }
X  }
X
X  for (;;) {
X    if (! zgets(buf, BUFSIZ - 1, zf))
X      corrupted(fullname, zf);
X    if (sscanf(buf, "static char * %s", what) == 1)
X      break;
X  }
X
X  if (p= rindex(what, '_'))
X    p++;
X  else
X    p= what;
X  if (strcmp(p, "pixels[]"))
X    corrupted(fullname, zf);
X
X  /* read in image data
X   */
X
X  dptr= image->data;
X  for (y= 0; y < h; y++) {
X    while (((c= zgetc(zf)) != EOF) && (c != '"'))
X      ;
X    for (x= 0; x < w; x++) {
X      for (a= 0; a < cpp; a++) {
X	if ((c= zgetc(zf)) == '\\')
X	  c= zgetc(zf);
X	if (c == EOF)
X	  corrupted(fullname, zf);
X	buf[a]= (char)c;
X      }
X      for (a= 0; a < ncolors; a++)
X	if (!strncmp(*(ctable + a), buf, cpp))
X	  break;
X      if (a == ncolors) { /* major uncool */
X	zclose(zf);
X	printf("%s: Pixel data doesn't match color data\n", fullname);
X	exit(1);
X      }
X      valToMem((unsigned long)a, dptr, image->pixlen);
X      dptr += image->pixlen;
X    }
X    if ((c= zgetc(zf)) != '"')
X      corrupted(fullname, zf);
X  }
X  return(image);
X}
X
Xint xpixmapIdent(fullname, name)
X{ Image *image;
X
X  if (image= xpixmapLoad(fullname, name, 1)) {
X    freeImage(image);
X    return(1);
X  }
X  return(0);
X}
END_OF_xpixmap.c
if test 5707 -ne `wc -c <xpixmap.c`; then
    echo shar: \"xpixmap.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of shell archive.
exit 0



More information about the Comp.sources.x mailing list