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