madd@world.std.com (jim frost) (11/22/89)
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@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@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@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@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@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@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@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