v09i053: xloadimage, Part06/09
saber.com!jimf at saber.com
saber.com!jimf at saber.com
Fri Sep 28 11:55:51 AEST 1990
Submitted-by: saber.com!jimf at saber.com
Posting-number: Volume 9, Issue 53
Archive-name: xloadimage/part06
#! /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 6 (of 9)."
# Contents: rle.c send.c smooth.c sunraster.c xbitmap.c zio.c
# Wrapped by jimf at armory on Tue Sep 25 19:37:41 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'rle.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'rle.c'\"
else
echo shar: Extracting \"'rle.c'\" \(11071 characters\)
sed "s/^X//" >'rle.c' <<'END_OF_FILE'
X/*
X * rle - read in a Utah RLE Toolkit type image.
X *
X * Author: Graeme Gill
X * Date: 30/5/90
X *
X * Bugs - doesn't free up memory used by rle functions.
X *
X */
X
X#undef DEBUG
X
X#ifdef DEBUG
X# define debug(xx) fprintf(stderr,xx)
X#else
X# define debug(xx)
X#endif
X
X
X#define MIN(a,b) ( (a)<(b) ? (a) : (b))
X
X#include <math.h>
X#include <stdio.h>
X#include "image.h"
X#include "rle.h"
X
X/* input file stuff */
Xstatic int ptype; /* picture type : */
X#define BW_NM 0 /* black and white, no map */
X#define BW_M 1 /* black and white, and a map */
X#define SC_M 2 /* single colour channel and colour map */
X#define C_NM 3 /* full colour, no maps */
X#define C_M 4 /* full colour with colour maps */
Xstatic rle_pixel **fmaps; /* file colour maps from buildmap() */
Xstatic unsigned char **scan; /* buffer for input data */
Xstatic int x_min; /* copy of picture x_min */
Xstatic int y_min; /* copy of picture y_min */
X
X/* option stuff (Not functional) */
Xstatic float disp_gam = 2.0; /* default display gamma correction factor */
Xstatic int gflag = 0; /* if user supplies display gamma */
Xstatic int iflag=0; /* user suplied image gamma */
Xstatic int lflag=0; /* user supplied levels */
Xstatic float img_gam = 1.0; /* image gamma */
Xstatic int bwflag = 0; /* black and white flag */
Xstatic int gammamap[256];
Xstatic int background[3] = {0,0,0}; /* our background colour */
X
X/* stuff for dithering colour pictures */
Xint colmap[216][3]; /* for dither map */
Xint magic[16][16];
Xint modN[256];
Xint divN[256];
X
Xint rleIdent(fullname,name)
Xchar *fullname, *name;
X {
X ZFILE *rlefile;
X int x_len,y_len;
X int rv;
X
X debug("rleIdent called\n");
X rlefile = zopen(fullname);
X if(!rlefile)
X {
X perror("rleIdent: Unable to open file");
X return(0);
X }
X debug("rleIdent: Opened file ok\n");
X sv_globals.svfb_fd = rlefile;
X rv = rle_get_setup(&sv_globals);
X debug("rleIdent: got setup ok\n");
X zclose(rlefile);
X debug("rleIdent: closed file ok\n");
X switch(rv)
X {
X case -1:
X return 0; /* Not rle format */
X case 0:
X /* now figure out the picture type */
X switch(sv_globals.sv_ncolors)
X {
X case 0:
X perror("rleIdent: no colour channels to display");
X return(0);
X case 1:
X x_len = sv_globals.sv_xmax - sv_globals.sv_xmin + 1;
X y_len = sv_globals.sv_ymax - sv_globals.sv_ymin + 1;
X printf("%s is a %dx%d,",name,x_len,y_len);
X switch(sv_globals.sv_ncmap)
X {
X case 0:
X /* black and white, no map */
X printf(" 8 bit grey scale image with no map");
X break;
X case 1:
X /* black and white with a map */
X printf(" 8 bit grey scale image with map");
X break;
X case 3:
X /* single channel encoded colour with decoding map */
X printf(" 8 bit colour image with colour map");
X break;
X default:
X perror(" 8 bit image with an illegal colour map");
X return 0;
X }
X break;
X case 3:
X switch(sv_globals.sv_ncmap)
X {
X case 0:
X printf(" 24 bit colour image with no map");
X break;
X case 3:
X printf(" 24 bit colour image with colour map");
X break;
X default:
X perror(" 24 bit colour image with an illegal colour map");
X return 0;
X }
X break;
X default:
X perror(" image with an illegal number of colour planes");
X return 0;
X }
X return 1;
X default: /* Some sort of error */
X/* perror("rleIdent");*/
X return 0;
X }
X }
X
X
XImage *rleLoad(fullname,name,verbose)
Xchar *fullname,*name;
Xunsigned int verbose;
X {
X int x_len, y_len;
X int i,j;
X ZFILE *rlefile;
X int ncol; /* number of colors */
X int depth;
X unsigned char *bufp;
X char *v;
X Image *image;
X unsigned char *buf;
X
X dith_levels = 256; /* aim for 128 levels of each colour */
X
X debug("rleLoad called\n");
X rlefile = zopen(fullname);
X if(!rlefile)
X {
X perror("rleLoad: Cannot open input file");
X return(NULL);
X }
X sv_globals.svfb_fd = rlefile;
X debug("rleLoad: About to call get_setup\n");
X if(rle_get_setup( &sv_globals )) {
X zclose(rlefile);
X return(NULL);
X }
X
X debug("rleLoad: get_setup called ok\n");
X if(iflag == 1) /* -i flag */
X img_gam = 1.0/img_gam; /* convert to display gamma */
X
X /* If no image gamma on command line, check comments in file */
X if (!iflag)
X {
X char * v;
X if ( (v = rle_getcom( "image_gamma", &sv_globals )) != NULL )
X {
X img_gam = atof( v );
X /* Protect against bogus information */
X if ( img_gam == 0.0 )
X img_gam = 1.0;
X else
X img_gam = 1.0 / img_gam; /* convert to display gamma */
X }
X else if ( (v = rle_getcom( "display_gamma", &sv_globals )) != NULL )
X {
X img_gam = atof( v );
X /* Protect */
X if ( img_gam == 0.0 )
X img_gam = 1.0;
X }
X }
X
X x_len = sv_globals.sv_xmax - sv_globals.sv_xmin + 1;
X y_len = sv_globals.sv_ymax - sv_globals.sv_ymin + 1;
X
X x_min = sv_globals.sv_xmin;
X y_min = sv_globals.sv_ymin;
X
X /* fix this so that we don't waste space */
X sv_globals.sv_xmax -= sv_globals.sv_xmin;
X sv_globals.sv_xmin = 0;
X
X /* turn off the alpha channel (don't waste time and space)*/
X sv_globals.sv_alpha = 0;
X SV_CLR_BIT(sv_globals,SV_ALPHA);
X
X /* for now, force background clear */
X if(sv_globals.sv_background ==1) /* danger setting */
X {
X debug("Forcing clear of background\n");
X sv_globals.sv_background = 2;
X if(sv_globals.sv_bg_color==0) /* if none allocated */
X sv_globals.sv_bg_color = background; /* use this one */
X }
X
X /* now figure out the picture type */
X switch(sv_globals.sv_ncolors)
X {
X case 0:
X perror("rleLoad: no colour channels to display");
X zclose(rlefile);
X return(NULL);
X case 1:
X switch(sv_globals.sv_ncmap)
X {
X case 0:
X ptype = BW_NM; /* black and white, no map */
X break;
X case 1:
X ptype = BW_M; /* black and white with a map */
X break;
X case 3:
X ptype = SC_M; /* single channel encoded colour with decoding map */
X break;
X default:
X zclose(rlefile);
X perror("rleLoad: Illegal number of maps for one colour channel");
X return(NULL);
X }
X break;
X case 3:
X switch(sv_globals.sv_ncmap)
X {
X case 0:
X ptype = C_NM; /* colour, no map */
X break;
X case 3:
X ptype = C_M; /* colour with maps */
X break;
X default:
X perror("rleLoad: Illegal number of maps for colour picture");
X zclose(rlefile);
X return(NULL);
X }
X break;
X default:
X perror("rleLoad: Illegal number of colour channels");
X zclose(rlefile);
X return(NULL);
X break;
X }
X
X if(verbose)
X {
X printf("rleLoad: %s is a %dx%d,",name,x_len,y_len);
X switch(ptype)
X {
X case BW_NM:
X printf(" 8 bit grey scale image with no map");
X break;
X case BW_M:
X printf(" 8 bit grey scale image with map");
X break;
X case SC_M:
X printf(" 8 bit colour image with colour map");
X break;
X case C_NM:
X printf(" 24 bit colour image with no map (will dither to 8 bits)");
X break;
X case C_M:
X printf(" 24 bit colour image with colour map (will dither to 8 bits)");
X break;
X }
X printf(", and has an image gama of %4.2f\n",img_gam);
X }
X
X if(ptype==SC_M)
X { /* don't mess with the image, but change their colour map a bit if needed */
X disp_gam /= img_gam; /* amount to change their map */
X img_gam = 1.0; /* not to the image coming in */
X }
X
X /* get hold of the colour maps, and set to undo their images gamma */
X fmaps = buildmap(&sv_globals,sv_globals.sv_ncolors,img_gam);
X
X /* now we had better sort out the picture data */
X debug("done colour map\n");
X
X /* rle stufff */
X /* Get space for a full colour scan line */
X scan = (unsigned char **) lmalloc( (sv_globals.sv_ncolors +
X sv_globals.sv_alpha) *
X sizeof( unsigned char * ) );
X for ( i = 0; i < sv_globals.sv_ncolors + sv_globals.sv_alpha; i++ )
X scan[i] = (unsigned char *)lmalloc(x_len);
X if ( sv_globals.sv_alpha )
X scan++;
X debug("got space for get_row\n");
X
X depth = 8; /* We always supply 8bit images */
X image = newRGBImage(x_len,y_len,depth);
X image->title = dupString(name);
X debug("got image structure\n");
X
X buf = image->data;
X
X /* If we are going to dither - then create the dither matrix. */
X if(!bwflag && ptype!=SC_M && ptype != BW_NM && ptype != BW_M)
X {
X dith_np2 = 1; /* allow non-power of 2 dither map size */
X dithermap( 6, disp_gam, colmap, divN, modN, magic );
X }
X
X debug("About to read image in\n");
X bufp = buf + (y_len-1) * x_len;
X for(j=y_len;j>0;j--,bufp -= x_len)
X {
X rle_getrow(&sv_globals,scan);
X switch(ptype)
X {
X case SC_M:
X memcpy(bufp,&scan[0][0],x_len);
X break;
X case BW_NM:
X case BW_M:
X bw_m_line(bufp,x_len);
X break;
X case C_NM:
X case C_M:
X c_m_line(bufp,x_len,j);
X break;
X }
X }
X debug("Image Read in\n");
X
X /* Deal with colour maps */
X /* set up our gamma correction */
X make_gamma(disp_gam,gammamap); /* we'll need it */
X
X debug("Creating color map\n");
X /* now load an appropriate colour map */
X if(!bwflag && ptype==SC_M)
X {
X /* use their maps & correct their gamma */
X ncol = 1<<sv_globals.sv_cmaplen; /* number of entries */
X for(i=0;i<ncol;i++)
X {
X *(image->rgb.red + i) = gammamap[fmaps[0][i]]<<8;
X *(image->rgb.green + i) = gammamap[fmaps[1][i]]<<8;
X *(image->rgb.blue + i) = gammamap[fmaps[2][i]]<<8;
X }
X }
X else if(bwflag || ptype == BW_NM || ptype == BW_M)
X {
X /* load a black and white map (gamma corrected for this display)*/
X ncol = 256; /* don't know whats been used */
X for(i=0;i<ncol;i++)
X {
X *(image->rgb.red + i) =
X *(image->rgb.green + i) =
X *(image->rgb.blue + i) = gammamap[i]<<8;
X }
X }
X else
X {
X /* must be colour, so use dither map (gamma corrected for this display)*/
X ncol = 6*6*6;
X /* Dither map has already been created above */
X for(i = 0; i < ncol; i++)
X {
X *(image->rgb.red + i) = colmap[i][0]<<8;
X *(image->rgb.green + i) = colmap[i][1]<<8;
X *(image->rgb.blue + i) = colmap[i][2]<<8;
X }
X }
X image->rgb.used = ncol;
X
X zclose(rlefile);
X debug("finished\n");
X return(image);
X }
X
X#define DMAP(v,x,y) (modN[v]>magic[x][y] ? divN[v] + 1 : divN[v])
X
X /* run the black and white through its map */
X bw_m_line(dp,number)
X int number;
X register unsigned char *dp;
X {
X register unsigned char *r;
X register int i;
X
X for(i=number,r= &scan[0][0];i>0;i--,r++,dp++)
X {
X *dp = fmaps[0][*r];
X }
X }
X
X /* convert a colour line with map to 8 bits per pixel */
X c_m_line(dp,number,line)
X int number,line;
X register unsigned char *dp;
X {
X register unsigned char *r, *g, *b;
X register int i, col, row;
X
X if(!bwflag)
X {
X for ( row = line % dith_size, col = x_min % dith_size, i = number, r = &scan[0][0]
X ,g= &scan[1][0], b= &scan[2][0];
X i > 0; i--, r++, g++, b++, dp++, col = ((col + 1) % dith_size) )
X {
X *dp = DMAP(fmaps[0][*r], col, row) +
X DMAP(fmaps[1][*g], col, row) * 6 +
X DMAP(fmaps[2][*b], col, row) * 36;
X }
X }
X else
X {
X int red,green,blue;
X for (i = number, r= &scan[0][0], g= &scan[1][0]
X ,b= &scan[2][0]; i>0;i--,r++,g++,b++,dp++)
X {
X red = fmaps[0][*r];green=fmaps[1][*g];blue = fmaps[2][*b];
X *dp = 0.35* red + 0.55* green + 0.1* blue;
X }
X }
X }
X
END_OF_FILE
if test 11071 -ne `wc -c <'rle.c'`; then
echo shar: \"'rle.c'\" unpacked with wrong size!
fi
# end of 'rle.c'
fi
if test -f 'send.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'send.c'\"
else
echo shar: Extracting \"'send.c'\" \(6580 characters\)
sed "s/^X//" >'send.c' <<'END_OF_FILE'
X/* send.c:
X *
X * send an Image to an X pixmap
X *
X * jim frost 10.02.89
X *
X * Copyright 1989, 1990 Jim Frost. See included file "copyright.h" for
X * complete copyright information.
X */
X
X#include "copyright.h"
X#include "xloadimage.h"
X
Xunsigned int sendImageToX(disp, scrn, visual, image, pixmap, cmap, verbose)
X Display *disp;
X int scrn;
X Visual *visual;
X Image *image;
X Pixmap *pixmap;
X Colormap *cmap;
X unsigned int verbose;
X{ Pixel *index;
X unsigned int a, b, newmap, x, y, linelen, ddepth, dpixlen;
X unsigned long plane;
X byte *pixptr, *destline, *destptr, *bitplane, destmask;
X byte *modimageptr;
X XColor xcolor;
X XGCValues gcv;
X GC gc;
X XImage *ximage;
X
X goodImage(image, "sendImageToX");
X
X switch(visual->class) {
X case PseudoColor:
X case GrayScale:
X case StaticColor:
X case StaticGray:
X break;
X default:
X printf("sendImageToX: unsupported display visual\n");
X exit(1);
X }
X
X index= (Pixel *)lmalloc(sizeof(Pixel) * image->rgb.used);
X xcolor.flags= DoRed | DoGreen | DoBlue;
X
X /* get the colormap to use
X */
X
X if (visual == DefaultVisual(disp, scrn)) {
X *cmap= DefaultColormap(disp, scrn);
X newmap= 0;
X
X /* allocate colors shareable (if we can)
X */
X
X for (a= 0; a < image->rgb.used; a++) {
X xcolor.red= *(image->rgb.red + a);
X xcolor.green= *(image->rgb.green + a);
X xcolor.blue= *(image->rgb.blue + a);
X if (! XAllocColor(disp, *cmap, &xcolor))
X if ((visual->class == StaticColor) || (visual->class == StaticGray)) {
X printf("sendImageToX: XAllocColor failed on a static visual\n");
X return(0);
X }
X else {
X
X /* we can't allocate the colors shareable so free all the colors
X * we had allocated and create a private colormap
X */
X
X for (b= 0; b < a; b++)
X XFreeColors(disp, *cmap, index + b, 1, 0);
X *cmap= XCreateColormap(disp, RootWindow(disp, scrn), visual,
X AllocNone);
X newmap= 1;
X break;
X }
X *(index + a)= xcolor.pixel;
X }
X }
X else {
X if ((visual->class == PseudoColor) || (visual->class == GrayScale)) {
X *cmap= XCreateColormap(disp, RootWindow(disp, scrn), visual, AllocNone);
X }
X else
X *cmap= XCreateColormap(disp, RootWindow(disp, scrn), visual, AllocAll);
X newmap= 1;
X }
X
X if (newmap) {
X for (a= 0; a < image->rgb.used; a++) /* count entries we got */
X if (! XAllocColorCells(disp, *cmap, False, NULL, 0, index + a, 1))
X break;
X
X if (a < image->rgb.used) /* can't get enough colors, so reduce */
X reduce(image, a, verbose); /* the colormap to fit what we have */
X
X for (b= 0; b < a; b++) {
X xcolor.pixel= *(index + b);
X xcolor.red= *(image->rgb.red + b);
X xcolor.green= *(image->rgb.green + b);
X xcolor.blue= *(image->rgb.blue + b);
X XStoreColor(disp, *cmap, &xcolor);
X }
X }
X
X ddepth= DefaultDepth(disp, scrn);
X *pixmap= XCreatePixmap(disp, RootWindow(disp, scrn), image->width,
X image->height, ddepth);
X
X /* blast the image across
X */
X
X switch (image->type) {
X case IBITMAP:
X gcv.function= GXcopy;
X gcv.foreground= *(index + 1);
X gcv.background= *index;
X gc= XCreateGC(disp, *pixmap, GCFunction | GCForeground | GCBackground,
X &gcv);
X ximage= XCreateImage(disp, visual, image->depth, XYBitmap, 0, image->data,
X image->width, image->height, 8, 0);
X ximage->bitmap_bit_order= MSBFirst;
X ximage->byte_order= MSBFirst;
X XPutImage(disp, *pixmap, gc, ximage, 0, 0, 0, 0,
X image->width, image->height);
X XFreeGC(disp, gc);
X break;
X
X case IRGB:
X
X /* modify image data to match colormap and pack pixels if necessary
X */
X
X if (verbose) {
X printf(" Building XImage...");
X fflush(stdout);
X }
X pixptr= image->data;
X modimageptr = image->data;
X dpixlen = ddepth / 8;
X if(image->pixlen != dpixlen) { /* Need to convert depth */
X modimageptr = (byte *)lmalloc(image->height * image->width * dpixlen);
X }
X destptr = modimageptr;
X
X for (y= 0; y < image->height; y++)
X for (x= 0; x < image->width; x++) {
X valToMem(*(index + memToVal(pixptr, image->pixlen)),
X destptr, dpixlen);
X pixptr += image->pixlen;
X destptr += dpixlen;
X }
X
X if (verbose)
X printf("done\n");
X
X /* if the destination depth is not a multiple of 8, then we send each
X * plane as a bitmap because otherwise we would have to pack the pixel
X * data and the XImage format is pretty vague about how that should
X * be done. this is not as fast as it would be if it were packed but
X * it should be a lot more portable and only slightly slower.
X */
X
X if (ddepth % 8) {
X#ifndef SERVER_HAS_BROKEN_PLANEMASK /* see README */
X gcv.function= GXcopy;
X#else
X gcv.function= GXor;
X#endif
X gcv.background= 0;
X gc= XCreateGC(disp, *pixmap, GCFunction | GCBackground, &gcv);
X linelen= (image->width / 8) + (image->width % 8 ? 1 : 0);
X bitplane= lmalloc(image->height * linelen);
X ximage= XCreateImage(disp, visual, 1, XYBitmap, 0, bitplane,
X image->width, image->height, 8, 0);
X ximage->bitmap_bit_order= MSBFirst;
X ximage->byte_order= MSBFirst;
X
X for (plane= 1 << (ddepth - 1); plane; plane >>= 1) {
X pixptr= image->data;
X destline= bitplane;
X for (y= 0; y < image->height; y++) {
X destmask= 0x80;
X destptr= destline;
X for (x= 0; x < image->width; x++) {
X if (*pixptr & plane)
X *destptr |= destmask;
X else
X *destptr &= ~destmask;
X if (!(destmask >>= 1)) {
X destmask= 0x80;
X destptr++;
X }
X pixptr += image->pixlen;
X }
X destline += linelen;
X }
X XSetForeground(disp, gc, plane);
X XSetPlaneMask(disp, gc, plane);
X XPutImage(disp, *pixmap, gc, ximage, 0, 0, 0, 0,
X image->width, image->height);
X }
X
X ximage->data= NULL;
X XDestroyImage(ximage);
X lfree(bitplane);
X break;
X }
X
X /* send image across in one whack
X */
X
X gcv.function= GXcopy;
X gc= XCreateGC(disp, *pixmap, GCFunction, &gcv);
X ximage= XCreateImage(disp, visual, ddepth, ZPixmap, 0, modimageptr,
X image->width, image->height, 8, 0);
X ximage->byte_order= MSBFirst; /* trust me, i know what i'm talking about */
X
X XPutImage(disp, *pixmap, gc, ximage, 0, 0,
X 0, 0, image->width, image->height);
X if(image->data == modimageptr)
X ximage->data= NULL;
X XDestroyImage(ximage); /* waste not want not */
X XFreeGC(disp, gc);
X break;
X
X default:
X printf("sendImageToX: bad image type\n");
X return(0);
X }
X lfree((byte *)index);
X return(1);
X}
END_OF_FILE
if test 6580 -ne `wc -c <'send.c'`; then
echo shar: \"'send.c'\" unpacked with wrong size!
fi
# end of 'send.c'
fi
if test -f 'smooth.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'smooth.c'\"
else
echo shar: Extracting \"'smooth.c'\" \(6012 characters\)
sed "s/^X//" >'smooth.c' <<'END_OF_FILE'
X/* smooth.c:
X *
X * this performs a smoothing convolution using a 3x3 area.
X *
X * jim frost 09.20.90
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/* this stuff is all used to pick the best possible color out of the
X * image's colormap. it creates a table sorted by the sum of the rgb
X * values. we then do a binary search to find the colors which are
X * closest to our sum. we then search those colors to find the best
X * possible color. this will have a complexity between log n base 2 and
X * n depending on the distribution of colormap sums. usually it's pretty
X * good.
X */
X
Xextern unsigned int squareInit;
Xextern unsigned long squareTable[];
X
Xstruct colorarray {
X Pixel pixel; /* pixel value */
X unsigned long sum; /* sum of rgb values */
X};
X
Xstatic int colorPredicate(c1, c2)
X struct colorarray *c1, *c2;
X{
X return(c1->sum < c2->sum ? -1 : 1);
X}
X
Xstatic struct colorarray *createColorArray(rgb)
X RGBMap *rgb;
X{ struct colorarray *carray;
X Pixel a;
X
X carray= (struct colorarray *)lmalloc(rgb->used * sizeof(struct colorarray));
X for (a= 0; a < rgb->used; a++) {
X carray[a].pixel= a;
X carray[a].sum= rgb->red[a] + rgb->green[a] + rgb->blue[a];
X }
X qsort(carray, rgb->used, sizeof(struct colorarray), colorPredicate);
X return(carray);
X}
X
X#define DIST(A, B) ((A) < (B) ? (B) - (A) : (A) - (B))
X
Xstatic Pixel bestColorByRGB(rgb, carray, red, green, blue)
X RGBMap *rgb;
X struct colorarray *carray;
X unsigned long red, green, blue;
X{ unsigned long bdist, qdist, sum, sum2;
X Pixel pick, bpick, qpick;
X unsigned int areasize;
X
X sum= red + green + blue;
X
X /* binary search to find colors which are close to us
X */
X
X pick= areasize= rgb->used / 2;
X while ((pick > 0) && (pick < rgb->used - 1)) {
X areasize= (areasize + 1) >> 1;
X pick += (carray[pick].sum > sum ? -areasize : areasize);
X if ((carray[pick].sum <= sum) && (sum < carray[pick + 1].sum))
X break;
X }
X
X /* look at colors that are a little darker than we are
X */
X
X bdist=
X squareTable[DIST(rgb->red[carray[pick].pixel], red) >> 1] +
X squareTable[DIST(rgb->green[carray[pick].pixel], green) >> 1] +
X squareTable[DIST(rgb->blue[carray[pick].pixel], blue) >> 1];
X bpick= pick;
X
X if (pick > 0) {
X qpick= pick - 1;
X sum2= carray[qpick].sum;
X while (carray[qpick].sum == sum2) {
X qdist=
X squareTable[DIST(rgb->red[carray[qpick].pixel], red) >> 1] +
X squareTable[DIST(rgb->green[carray[qpick].pixel], green) >> 1] +
X squareTable[DIST(rgb->blue[carray[qpick].pixel], blue) >> 1];
X if (qdist < bdist) {
X bpick= qpick;
X bdist= qdist;
X if (!bdist)
X return(carray[bpick].pixel);
X }
X if (qpick == 0)
X break;
X qpick--;
X }
X }
X
X if (pick == rgb->used - 1) /* nothing following */
X return(carray[bpick].pixel);
X
X /* look at colors which are a little lighter than we are
X */
X
X qpick= pick + 1;
X sum2= carray[qpick].sum;
X do {
X qdist=
X squareTable[DIST(rgb->red[carray[qpick].pixel], red) >> 1] +
X squareTable[DIST(rgb->green[carray[qpick].pixel], green) >> 1] +
X squareTable[DIST(rgb->blue[carray[qpick].pixel], blue) >> 1];
X if (qdist < bdist) {
X bpick= qpick;
X bdist= qdist;
X if (!bdist)
X return(carray[bpick].pixel);
X }
X qpick++;
X } while ((qpick < rgb->used) && (carray[qpick].sum == sum2));
X
X return(carray[bpick].pixel);
X}
X
Xstatic Image *doSmooth(image)
X Image *image;
X{ Image *new;
X int x, y, x1, y1, linelen, reductions;
X int xindex[3];
X byte *yindex[3];
X byte *srcptr, *destptr;
X Pixel pixval;
X unsigned long avgred, avggreen, avgblue;
X struct colorarray *carray;
X
X /* create new image and copy colormap
X */
X
X new= newRGBImage(image->width, image->height, image->depth);
X new->title= (char *)lmalloc(strlen(image->title) + 12);
X sprintf(new->title, "%s (smoothed)", image->title);
X bcopy(image->rgb.red, new->rgb.red, image->rgb.used * sizeof(Intensity));
X bcopy(image->rgb.green, new->rgb.green, image->rgb.used * sizeof(Intensity));
X bcopy(image->rgb.blue, new->rgb.blue, image->rgb.used * sizeof(Intensity));
X new->rgb.used= image->rgb.used;
X
X carray= createColorArray(&(new->rgb));
X
X /* run through image and take a guess as to what the color should
X * actually be.
X */
X
X for (y= 0; y < image->height; y++) {
X linelen= image->pixlen * image->width;
X destptr= new->data + (y * linelen);
X yindex[1]= image->data + (y * linelen);
X yindex[0]= yindex[1] - (y > 0 ? linelen : 0);
X yindex[2]= yindex[1] + (y < image->height - 1 ? linelen : 0);
X for (x= 0; x < image->width; x++) {
X avgred= avggreen= avgblue= 0;
X xindex[1]= x * image->pixlen;
X xindex[0]= xindex[1] - (x > 0 ? image->pixlen : 0);
X xindex[2]= xindex[1] + (x < image->width - 1 ? image->pixlen : 0);
X for (y1= 0; y1 < 3; y1++) {
X for (x1= 0; x1 < 3; x1++) {
X pixval= memToVal(yindex[y1] + xindex[x1], image->pixlen);
X avgred += *(image->rgb.red + pixval);
X avggreen += *(image->rgb.green + pixval);
X avgblue += *(image->rgb.blue + pixval);
X }
X }
X
X /* pick the pixel that's closest to this average and put in image
X */
X
X avgred= ((avgred + 8) / 9);
X avggreen= ((avggreen + 8) / 9);
X avgblue= ((avgblue + 8) / 9);
X pixval= bestColorByRGB(&(new->rgb), carray, avgred, avggreen, avgblue);
X valToMem(pixval, destptr, new->pixlen);
X destptr += new->pixlen;
X }
X }
X
X lfree(carray);
X return(new);
X}
X
XImage *smooth(image, iterations, verbose)
X Image *image;
X int verbose;
X{ int a;
X Image *new;
X
X if (!squareInit)
X initSquareTable();
X
X if (!RGBP(image)) /* no effect unless color image (yet) */
X return(image);
X
X if (verbose) {
X printf(" Smoothing...");
X fflush(stdout);
X }
X
X for (a= 0; a < iterations; a++) {
X new= doSmooth(image);
X freeImage(image);
X image= new;
X }
X
X if (verbose)
X printf("done\n");
X
X return(image);
X}
END_OF_FILE
if test 6012 -ne `wc -c <'smooth.c'`; then
echo shar: \"'smooth.c'\" unpacked with wrong size!
fi
# end of 'smooth.c'
fi
if test -f 'sunraster.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'sunraster.c'\"
else
echo shar: Extracting \"'sunraster.c'\" \(5487 characters\)
sed "s/^X//" >'sunraster.c' <<'END_OF_FILE'
X/* sunraster.c:
X *
X * sun rasterfile image type
X *
X * jim frost 09.27.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#include "sunraster.h"
X
Xstatic void babble(name, header)
X char *name;
X struct rheader *header;
X{
X printf("%s is a", name);
X switch (memToVal(header->type, 4)) {
X case ROLD:
X printf("n old-style");
X break;
X case RSTANDARD:
X printf(" standard");
X break;
X case RRLENCODED:
X printf(" run-length encoded");
X break;
X default:
X printf(" unknown-type");
X }
X printf(" %dx%d ", memToVal(header->width, 4), memToVal(header->height, 4));
X if (memToVal(header->depth, 4) > 1)
X printf("%d plane %s",
X memToVal(header->depth, 4),
X (memToVal(header->maplen, 4) > 0 ? "color" : "greyscale")
X );
X else
X printf("monochrome");
X printf(" Sun rasterfile\n");
X}
X
Xint sunRasterIdent(fullname, name)
X char *fullname, *name;
X{ ZFILE *zf;
X struct rheader header;
X int r;
X
X if (! (zf= zopen(fullname))) {
X perror("sunRasterIdent");
X return(0);
X }
X switch (zread(zf, &header, sizeof(struct rheader))) {
X case -1:
X perror("sunRasterIdent");
X r= 0;
X break;
X
X case sizeof(struct rheader):
X if (memToVal(header.magic, 4) != RMAGICNUMBER) {
X r= 0;
X break;
X }
X babble(name, &header);
X r= 1;
X break;
X
X default:
X r= 0;
X break;
X }
X zclose(zf);
X return(r);
X}
X
X/* read either rl-encoded or normal image data
X */
X
Xstatic void sunread(zf, buf, len, enc)
X ZFILE *zf;
X byte *buf;
X unsigned int len;
X unsigned int enc; /* true if encoded file */
X{ static byte repchar, remaining= 0;
X
X /* rl-encoded read
X */
X
X if (enc) {
X while (len--)
X if (remaining) {
X remaining--;
X *(buf++)= repchar;
X }
X else {
X if (zread(zf, &repchar, 1) != 1) {
X printf("sunRasterLoad: Bad read on image data\n");
X exit(1);
X }
X if (repchar == RESC) {
X if (zread(zf, &remaining, 1) != 1) {
X printf("sunRasterLoad: Bad read on image data\n");
X exit(1);
X }
X if (remaining == 0)
X *(buf++)= RESC;
X else {
X if (zread(zf, &repchar, 1) != 1) {
X printf("sunRasterLoad: Bad read on image data\n");
X exit(1);
X }
X *(buf++)= repchar;
X }
X }
X else
X *(buf++)= repchar;
X }
X }
X
X /* normal read
X */
X
X else {
X if (zread(zf, buf, len) < len) {
X printf("sunRasterLoad: Bad read on image data\n");
X exit(1);
X }
X }
X}
X
XImage *sunRasterLoad(fullname, name, verbose)
X char *fullname, *name;
X unsigned int verbose;
X{ ZFILE *zf;
X struct rheader header;
X unsigned int mapsize;
X byte *map;
X byte *mapred, *mapgreen, *mapblue;
X unsigned int depth;
X unsigned int linelen; /* length of raster line in bytes */
X unsigned int fill; /* # of fill bytes per raster line */
X unsigned int enc;
X byte fillchar;
X Image *image;
X byte *lineptr;
X unsigned int y;
X
X if (! (zf= zopen(fullname))) {
X perror("sunRasterLoad");
X return(NULL);
X }
X switch (zread(zf, &header, sizeof(struct rheader))) {
X case -1:
X perror("sunRasterLoad");
X zclose(zf);
X exit(1);
X
X case sizeof(struct rheader):
X if (memToVal(header.magic, 4) != RMAGICNUMBER) {
X zclose(zf);
X return(NULL);
X }
X if (verbose)
X babble(name, &header);
X break;
X
X default:
X zclose(zf);
X return(NULL);
X }
X
X /* get an image to put the data in
X */
X
X depth= memToVal(header.depth, 4);
X if (depth == 1)
X image= newBitImage(memToVal(header.width, 4),
X memToVal(header.height, 4));
X else
X image= newRGBImage(memToVal(header.width, 4),
X memToVal(header.height, 4),
X memToVal(header.depth, 4));
X
X /* set up the colormap
X */
X
X if (depth == 1)
X linelen= (image->width / 8) + (image->width % 8 ? 1 : 0);
X else
X linelen= image->width * image->pixlen;
X fill= (linelen % 2 ? 1 : 0);
X /*
X * Handle color...
X */
X if (mapsize= memToVal(header.maplen, 4)) {
X map= lmalloc(mapsize);
X if (zread(zf, map, mapsize) < mapsize) {
X printf("sunRasterLoad: Bad read on colormap\n");
X exit(1);
X }
X mapsize /= 3;
X mapred= map;
X mapgreen= mapred + mapsize;
X mapblue= mapgreen + mapsize;
X for (y= 0; y < mapsize; y++) {
X *(image->rgb.red + y)= (*(mapred++) << 8);
X *(image->rgb.green + y)= (*(mapgreen++) << 8);
X *(image->rgb.blue + y)= (*(mapblue++) << 8);
X }
X lfree(map);
X image->rgb.used= mapsize;
X }
X
X /*
X * Handle 8-bit greyscale via a simple ramp function...
X */
X else if (depth > 1) {
X mapsize = 256*3;
X map= lmalloc(mapsize);
X for (y = 0; y < 256; y += 1) {
X map[y] = map[256+y] = map[2*256+y] = y;
X }
X mapsize /= 3;
X mapred= map;
X mapgreen= mapred + mapsize;
X mapblue= mapgreen + mapsize;
X for (y= 0; y < mapsize; y++) {
X *(image->rgb.red + y)= (*(mapred++) << 8);
X *(image->rgb.green + y)= (*(mapgreen++) << 8);
X *(image->rgb.blue + y)= (*(mapblue++) << 8);
X }
X lfree(map);
X image->rgb.used= mapsize;
X }
X
X
X enc= (memToVal(header.type, 4) == RRLENCODED);
X lineptr= image->data;
X for (y= 0; y < image->height; y++) {
X sunread(zf, lineptr, linelen, enc);
X lineptr += linelen;
X if (fill)
X sunread(zf, &fillchar, fill, enc);
X }
X zclose(zf);
X image->title= dupString(name);
X return(image);
X}
END_OF_FILE
if test 5487 -ne `wc -c <'sunraster.c'`; then
echo shar: \"'sunraster.c'\" unpacked with wrong size!
fi
# end of 'sunraster.c'
fi
if test -f 'xbitmap.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'xbitmap.c'\"
else
echo shar: Extracting \"'xbitmap.c'\" \(5417 characters\)
sed "s/^X//" >'xbitmap.c' <<'END_OF_FILE'
X/* xbitmap.c:
X *
X * at one time this was XRdBitF.c. it bears very little resemblence to it
X * now. that was ugly code. this is cleaner, faster, and more reliable
X * in most cases.
X *
X * jim frost 10.06.89
X *
X * Copyright, 1987, Massachusetts Institute of Technology
X *
X * Copyright 1989 Jim Frost. See included file "copyright.h" for complete
X * copyright information.
X */
X
X#include "mit.cpyrght"
X#include "copyright.h"
X#include "image.h"
X#include <ctype.h>
X
X#ifdef SYSV
X#include <string.h>
X#define rindex strrchr
X#else
Xchar *rindex();
X#endif
X
X#define MAX_SIZE 255
X
Xstatic short HexTable[256]; /* conversion value */
Xstatic unsigned int Initialized= 0; /* easier to fill in at run time */
X
X#define b0000 0 /* things make more sense if you see them by bit */
X#define b0001 1
X#define b0010 2
X#define b0011 3
X#define b0100 4
X#define b0101 5
X#define b0110 6
X#define b0111 7
X#define b1000 8
X#define b1001 9
X#define b1010 10
X#define b1011 11
X#define b1100 12
X#define b1101 13
X#define b1110 14
X#define b1111 15
X
X#define HEXSTART -1
X#define HEXDELIM -2
X#define HEXBAD -3
X
X/* build a hex digit value table with the bits inverted
X */
X
Xstatic void initHexTable()
X{ int a;
X
X for (a= 0; a < 256; a++)
X HexTable[a]= HEXBAD;
X
X HexTable['0']= b0000;
X HexTable['1']= b1000;
X HexTable['2']= b0100;
X HexTable['3']= b1100;
X HexTable['4']= b0010;
X HexTable['5']= b1010;
X HexTable['6']= b0110;
X HexTable['7']= b1110;
X HexTable['8']= b0001;
X HexTable['9']= b1001;
X HexTable['A']= b0101; HexTable['a']= HexTable['A'];
X HexTable['B']= b1101; HexTable['b']= HexTable['B'];
X HexTable['C']= b0011; HexTable['c']= HexTable['C'];
X HexTable['D']= b1011; HexTable['d']= HexTable['D'];
X HexTable['E']= b0111; HexTable['e']= HexTable['E'];
X HexTable['F']= b1111; HexTable['f']= HexTable['F'];
X HexTable['x']= HEXSTART;
X HexTable['\r']= HEXDELIM;
X HexTable['\n']= HEXDELIM;
X HexTable['\t']= HEXDELIM;
X HexTable[' ']= HEXDELIM;
X HexTable[',']= HEXDELIM;
X HexTable['}']= HEXDELIM;
X
X Initialized = 1;
X}
X
X/* read a hex value and return its value
X */
X
Xstatic int nextInt(zf)
X ZFILE *zf;
X{ int c;
X int value= 0;
X int shift= 0;
X
X for (;;) {
X c= zgetc(zf);
X if (c == EOF)
X return(-1);
X else {
X c= HexTable[c & 0xff];
X switch(c) {
X case HEXSTART:
X shift= 0; /* reset shift counter */
X break;
X case HEXDELIM:
X if (shift)
X return(value);
X break;
X case HEXBAD:
X return(-1);
X default:
X value += (c << shift);
X shift += 4;
X }
X }
X }
X}
X
Xstatic void badFile(name)
X char *name;
X{
X printf("%s: bad X bitmap file\n", name);
X exit(1);
X}
X
XImage *xbitmapLoad(fullname, name, verbose)
X char *fullname, *name;
X unsigned int verbose;
X{ ZFILE *zf;
X Image *image;
X char line[MAX_SIZE];
X char name_and_type[MAX_SIZE];
X char *type;
X int value;
X int v10p;
X unsigned int linelen, dlinelen;
X unsigned int x, y;
X unsigned int w = 0, h = 0;
X byte *dataptr;
X
X if (!Initialized)
X initHexTable();
X
X if (! (zf= zopen(fullname)))
X return(NULL);
X
X /* get width/height values */
X
X while (zgets(line, MAX_SIZE, zf)) {
X if (strlen(line) == MAX_SIZE-1) {
X zclose(zf);
X return(NULL);
X }
X
X /* width/height/hot_x/hot_y scanning
X */
X
X if (sscanf(line,"#define %s %d", name_and_type, &value) == 2) {
X if (!(type = rindex(name_and_type, '_')))
X type = name_and_type;
X else
X type++;
X
X if (!strcmp("width", type))
X w= (unsigned int)value;
X if (!strcmp("height", type))
X h= (unsigned int)value;
X }
X
X /* if start of data, determine if it's X10 or X11 data and break
X */
X
X if (sscanf(line, "static short %s = {", name_and_type) == 1) {
X v10p = 1;
X break;
X }
X if ((sscanf(line,"static unsigned char %s = {", name_and_type) == 1) ||
X (sscanf(line, "static char %s = {", name_and_type) == 1)) {
X v10p = 0;
X break;
X }
X }
X
X if (!w || !h) {
X zclose(zf);
X return(NULL);
X }
X image= newBitImage(w, h);
X
X /* get title of bitmap if any
X */
X
X if ((type = rindex(name_and_type, '_')) && !strcmp("bits[]", type + 1)) {
X *type= '\0';
X image->title= dupString(name_and_type);
X }
X
X /* read bitmap data
X */
X
X linelen= (w / 8) + (w % 8 ? 1 : 0); /* internal line length */
X if (v10p) {
X dlinelen= (w / 8) + (w % 16 ? 2 : 0);
X dataptr= image->data;
X for (y= 0; y < h; y++) {
X for (x= 0; x < dlinelen; x++) {
X if ((value= nextInt(zf)) < 0) {
X freeImage(image);
X zclose(zf);
X return(NULL);
X }
X *(dataptr++)= value >> 8;
X if (++x < linelen)
X *(dataptr++)= value & 0xff;
X }
X }
X }
X else {
X dataptr= image->data;
X for (y= 0; y < h; y++)
X for (x= 0; x < linelen; x++) {
X if ((value= nextInt(zf)) < 0)
X badFile(name);
X *(dataptr++)= value;
X }
X }
X
X if (verbose) {
X printf("%s is a %dx%d X", name, image->width, image->height);
X if (v10p)
X printf("10");
X else
X printf("11");
X if (image->title)
X printf(" bitmap file titled '%s'", image->title);
X printf("\n");
X }
X zclose(zf);
X return(image);
X}
X
X/* this is the easiest way to do this. it's not likely we'll have mondo
X * x bitmaps anyway given their size
X */
X
Xint xbitmapIdent(fullname, name)
X char *fullname, *name;
X{ Image *image;
X
X if (image= xbitmapLoad(fullname, name, (unsigned int)1)) {
X freeImage(image);
X return(1);
X }
X return(0);
X}
END_OF_FILE
if test 5417 -ne `wc -c <'xbitmap.c'`; then
echo shar: \"'xbitmap.c'\" unpacked with wrong size!
fi
# end of 'xbitmap.c'
fi
if test -f 'zio.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'zio.c'\"
else
echo shar: Extracting \"'zio.c'\" \(4983 characters\)
sed "s/^X//" >'zio.c' <<'END_OF_FILE'
X/* zio.c:
X *
X * this properly opens and reads from an image file, compressed or otherwise.
X *
X * jim frost 10.03.89
X *
X * this was hacked on 09.12.90 to cache reads and to use stdin.
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#define MAX_ZFILES 32
X
Xstatic ZFILE ZFileTable[MAX_ZFILES];
X
X/* read some info through the read cache
X */
X
Xstatic int doRead(zf, buf, len)
X ZFILE *zf;
X byte *buf;
X int len;
X{ int bread, readlen;
X
X /* loop through the read
X */
X
X for (bread= 0; bread < len; bread += readlen, zf->bufptr += readlen) {
X
X /* read new or move to next data block if necessary
X */
X
X if (!zf->dataptr || (zf->bufptr == zf->dataptr->len)) {
X if (zf->dataptr && zf->dataptr->next)
X zf->dataptr= zf->dataptr->next;
X else {
X if (!zf->dataptr)
X zf->data= zf->dataptr= (struct cache *)lmalloc(sizeof(struct cache));
X else {
X zf->dataptr->next= (struct cache *)lmalloc(sizeof(struct cache));
X zf->dataptr= zf->dataptr->next;
X }
X zf->dataptr->next= NULL;
X zf->dataptr->len= fread(zf->dataptr->buf, 1, BUFSIZ, zf->stream);
X if (zf->dataptr->len < 0) {
X perror("fread");
X exit(1);
X }
X }
X zf->bufptr= 0;
X }
X
X /* calculate length we can get out of read buffer
X */
X
X readlen= (len - bread > zf->dataptr->len - zf->bufptr ?
X zf->dataptr->len - zf->bufptr : len - bread);
X if (!readlen) /* we're at EOF */
X return(bread);
X bcopy(zf->dataptr->buf + zf->bufptr, buf + bread, readlen);
X }
X return(bread);
X}
X
X/* reset a read cache
X */
X
Xvoid zreset(filename)
X char *filename;
X{ int a;
X struct cache *old;
X
X /* if NULL filename, reset the entire table
X */
X
X if (!filename) {
X for (a= 0; a < MAX_ZFILES; a++)
X if (ZFileTable[a].filename)
X zreset(ZFileTable[a].filename);
X return;
X }
X
X for (a= 0; a < MAX_ZFILES; a++)
X if (ZFileTable[a].filename && !strcmp(filename, ZFileTable[a].filename))
X break;
X
X if (a == MAX_ZFILES) /* no go joe */
X return;
X
X if (ZFileTable[a].dataptr != ZFileTable[a].data)
X printf("zreset: warning: ZFILE for %s was not closed properly\n",
X ZFileTable[a].filename);
X while (ZFileTable[a].data) {
X old= ZFileTable[a].data;
X ZFileTable[a].data= ZFileTable[a].data->next;
X free(old);
X }
X lfree(ZFileTable[a].filename);
X ZFileTable[a].filename= NULL;
X ZFileTable[a].dataptr= NULL;
X ZFileTable[a].bufptr= 0;
X
X switch(ZFileTable[a].type) {
X case ZSTANDARD:
X fclose(ZFileTable[a].stream);
X break;
X case ZPIPE:
X pclose(ZFileTable[a].stream);
X break;
X case ZSTDIN:
X break;
X default:
X printf("zreset: bad ZFILE structure\n");
X exit(1);
X }
X}
X
XZFILE *zopen(name)
X char *name;
X{ int a;
X ZFILE *zf;
X char buf[BUFSIZ];
X
X /* look for filename in open file table
X */
X
X for (a= 0; a < MAX_ZFILES; a++)
X if (ZFileTable[a].filename && !strcmp(name, ZFileTable[a].filename)) {
X if (ZFileTable[a].dataptr != ZFileTable[a].data)
X printf("zopen: warning: file doubly opened\n");
X ZFileTable[a].dataptr= ZFileTable[a].data;
X ZFileTable[a].bufptr= 0;
X return(ZFileTable + a);
X }
X
X /* find open ZFileTable entry
X */
X
X for (a= 0; (a < MAX_ZFILES) && ZFileTable[a].filename; a++)
X /* EMPTY */
X ;
X
X if (a == MAX_ZFILES) {
X printf("zopen: no more files available\n");
X exit(1);
X }
X zf= ZFileTable + a;
X
X zf->filename= dupString(name);
X zf->dataptr= NULL;
X zf->bufptr= 0;
X
X /* file filename is `stdin' then use stdin
X */
X
X if (!strcmp(name, "stdin")) {
X zf->type= ZSTDIN;
X zf->stream= stdin;
X return(zf);
X }
X
X /* if filename ends in `.Z' then open pipe to uncompress. if your
X * system doesn't have uncompress you can define NO_UNCOMPRESS and
X * it just won't check for this.
X */
X
X#ifndef NO_UNCOMPRESS
X if ((strlen(name) > 2) && !strcmp(".Z", name + (strlen(name) - 2))) {
X zf->type= ZPIPE;
X sprintf(buf, "uncompress -c %s", name);
X if (! (zf->stream= popen(buf, "r"))) {
X return(NULL);
X }
X return(zf);
X }
X#endif
X
X /* default to normal stream
X */
X
X zf->type= ZSTANDARD;
X if (! (zf->stream= fopen(name, "r"))) {
X return(NULL);
X }
X return(zf);
X}
X
Xint zread(zf, buf, len)
X ZFILE *zf;
X byte *buf;
X unsigned int len;
X{
X return(doRead(zf, buf, len));
X}
X
Xint zgetc(zf)
X ZFILE *zf;
X{ unsigned char c;
X
X if (doRead(zf, &c, 1) > 0)
X return(c);
X else
X return(EOF);
X}
X
Xchar *zgets(buf, size, zf)
X byte *buf;
X unsigned int size;
X ZFILE *zf;
X{ int p= 0;
X
X while (doRead(zf, buf + p, 1) > 0) {
X if (p == size)
X return((char *)buf);
X if (*(buf + p) == '\n') {
X *(buf + p + 1)= '\0';
X return((char *)buf);
X }
X p++;
X }
X return(NULL);
X}
X
X/* reset cache pointers in a ZFILE. nothing is actually reset until a
X * zreset() is called with the filename.
X */
X
Xvoid zclose(zf)
X ZFILE *zf;
X{
X zf->dataptr= zf->data;
X zf->bufptr= 0;
X}
END_OF_FILE
if test 4983 -ne `wc -c <'zio.c'`; then
echo shar: \"'zio.c'\" unpacked with wrong size!
fi
# end of 'zio.c'
fi
echo shar: End of archive 6 \(of 9\).
cp /dev/null ark6isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 9 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0
dan
----------------------------------------------------
O'Reilly && Associates argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.
More information about the Comp.sources.x
mailing list