Original Usenet thread from alt.ascii-art, started 2 Mar 1994.
Code to convert GIF89a to ascii
alt.ascii-art
· 1 message · 2 Mar 1994
Here is my 1 hour hack to enhance ascgif version 1.6 from volume30,
comp.sources.misc to support GIF89a specification.
It worked for the files I tested but there are no warranties.
Enjoy,
Sisira.
--
Sisira Jayasinghe sis...@sdrc.com
Sr. Technical Development Engineer
Structural Dynamics Research Corporation
2000 Eastman Dr. Milford OH 45150 USA
------------8<----------------8<------------8<------------------
#! /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: Makefile ascgif.c gif2txt.c
# Wrapped by spsisira@sgife15 on Wed Mar 2 10:53:34 1994
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Makefile' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(1253 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X#! make
X#
X# Makefile (GenMake 1.2)
X#
X
X#
X# Program definitions and options.
X#
X
XSHELL = /bin/sh
XCC = cc -g
XFC = f77
XC++ = g++
XNROFF = nroff
XLEX = lex
XYACC = yacc -d
XAR = ar
XRANLIB = ar ts
X
XOPT =
XCFLAGS = $(OPT)
XC++FLAGS = $(CFLAGS)
XFFLAGS = $(OPT)
XLDFLAGS =
XLIBS =
X
XTARGETS = ascgif
X
X#
X# Make ALL targets...
X#
X
Xall: $(TARGETS)
X
X
X#
X# Default make rules...
X#
X
X.SUFFIXES: .c .f .F .r .cc .y .l .man .ms .tex .out .o .1 .2 .3 .4 .5 .6 .7 .8 .doc .a
X.c.o:
X $(CC) $(CFLAGS) -c $<
X.cc.o:
X $(C++) $(CFLAGS) -c $<
X.f.o .F.o .r.o:
X $(FC) $(FFLAGS) -c $<
X
X
X.y.o:
X $(YACC) $<
X $(CC) $(CFLAGS) -c y.tab.c -o $@
X rm -f y.tab.c
X.l.o:
X $(LEX) $<
X $(CC) $(CFLAGS) -c lex.yy.c -o $@
X rm -f lex.yy.c
X.o.out .o:
X $(CC) $(OPT) $(LDFLAGS) $< -o $@ $(LIBS)
X.o.a:
X rm -f $@
X $(AR) -cr $@ $<
X $(RANLIB) $@
X.man.1 .man.2 .man.3 .man.4 .man.5 .man.6 .man.7 .man.8:
X rm -f $@
X $(NROFF) -man $< >$@
X.ms.doc:
X rm -f $@
X $(NROFF) -ms $< >$@
X.tex.doc: tex $<
X dvidoc $(<:.tex=.dvi) >$@
Xveryclean:
X /bin/rm -f $(GENMAKE_OBJS) $(TARGETS) *~ *.bak *.BAK
Xclean:
X /bin/rm -f $(GENMAKE_OBJS) *~ *.bak *.BAK
X#
X# ascgif
X#
X
XASCGIF_SRCS = ascgif.c
XASCGIF_HDRS =
XASCGIF_OBJS = ascgif.o
X
Xascgif: $(ASCGIF_OBJS)
X $(CC) -o ascgif $(ASCGIF_OBJS) $(LDFLAGS) $(LIBS)
X$(ASCGIF_OBJS): $(ASCGIF_HDRS)
X
END_OF_FILE
if test 1253 -ne `wc -c <'Makefile'`; then
echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'ascgif.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'ascgif.c'\"
else
echo shar: Extracting \"'ascgif.c'\" \(17621 characters\)
sed "s/^X//" >'ascgif.c' <<'END_OF_FILE'
X/* Ascii Gif Viewer Version 1.6 May (c) 1992 John Ferrell jwf...@juts.ccc.amdahl.com */
X/* 5 changes for pc to mainframe portability. (search on 'mainframes') */
X/*
X * March2, 1994, Sisira Y. Jayasinghe sis...@sdrc.com
X * Added SkipBlock to skip graphics control extension of GIF89a
X * Specification.
X */
X
X#include <string.h>
X /* #include <libc.h> i *//* libc.h for mainframes, stdlib.h for pc */
X#include <stdio.h>
X
X#define UBYTE unsigned char /* 8Bit */
X#define UWORD unsigned short /* 16Bit */
X#define ULONG unsigned int /* 32Bit int for mainframes, long for pc */
X#define BOOL unsigned short
X
X#define TRUE 1
X#define FALSE 0
X#define min(a,b) (a) > (b) ? (b) : (a)
X
X
Xstruct GIFdescriptor
X{
X UWORD gd_Width;
X UWORD gd_Height;
X UBYTE gd_ColInfo;
X UBYTE gd_BackGround;
X UBYTE gd_PixelAspect;
X};
X
Xstruct ImageDesc
X{
X UWORD id_Left;
X UWORD id_Top;
X UWORD id_Width;
X UWORD id_Height;
X UBYTE id_Info;
X};
X
Xstruct RGB
X{
X UBYTE rgb_Red;
X UBYTE rgb_Green;
X UBYTE rgb_Blue;
X};
X
X#define GIF_IMAGE 0x2C
X#define GIF_EXTENSION 0x21
X#define GIF_TERMINATOR 0x3B
X#define GIF_COMMENT_EXT 0xFE
X
X#define GIF87a 87
X#define GIF89a 89
X
X
X /* void *screen; *//* uncomment for pc, comment out for mainframes */
X
Xint gx = 79;
Xint gy = 23;
X
Xstruct GIFdescriptor gdesc;
X
XUBYTE **BitPlane;
Xstruct RGB GlobalColourTable[256];
X
XUBYTE Map[256];
X
XULONG ImageNumber;
X
XFILE *GIFfh = NULL;
XFILE *CAPT = NULL;
X
Xvoid
XERROR (str)
X char *str;
X{
X printf (str);
X exit (1);
X}
X
Xvoid
XFlipWord (word)
X UWORD *word;
X{
X UBYTE swap1;
X UBYTE swap2;
X
X swap1 = *word & 0xFF; /* comment out for pc, needed for
X mainframes */
X swap2 = (*word & 0xFF00) >> 8; /* " " */
X *word = swap1 << 8 | swap2; /* " " */
X}
X
Xstatic struct ImageDesc idesc;
Xstatic struct RGB LocalColourTable[256];
X
Xstatic UWORD Xpos, Ypos;
Xstatic BOOL interleave;
X
Xstatic UBYTE LeaveStep[5] =
X{1, 8, 8, 4, 2};
Xstatic UBYTE LeaveFirst[5] =
X{0, 0, 4, 2, 1};
X
Xstatic int ReadError;
Xstatic UBYTE CodeSize;
Xstatic int EOFCode;
Xstatic UBYTE ReadMask;
Xstatic int CompDataPointer;
Xstatic int CompDataCount;
Xstatic UBYTE CompData[256];
X
Xstatic UWORD Prefix[4096];
Xstatic UBYTE Suffix[4096];
Xstatic UBYTE OutCode[1025];
X
Xstatic UBYTE ByteBuf;
X
Xint
XReadCode (fh)
X FILE *fh;
X{
X register int temp;
X register int DstMasked;
X register int DstMask;
X long size;
X
X temp = 0;
X DstMasked = 1L << CodeSize;
X for (DstMask = 1; DstMask != DstMasked; DstMask <<= 1)
X {
X if (!ReadMask)
X {
X if (CompDataPointer == CompDataCount)
X {
X if ((size = fgetc (fh)) == -1)
X {
X printf ("\nI/O Error during decompression.\n");
X ReadError = 1;
X return EOFCode;
X }
X if (fread ((char *) CompData, 1, size, fh) != size)
X {
X printf ("\nI/O Error during decompression.\n");
X ReadError = 1;
X return EOFCode;
X }
X CompDataCount = size;
X CompDataPointer = 0;
X }
X ReadMask = 1;
X ByteBuf = CompData[CompDataPointer++];
X }
X if (ByteBuf & ReadMask)
X temp |= DstMask;
X ReadMask <<= 1;
X }
X return temp;
X}
X
Xvoid
XAddPixel (index)
X UBYTE index;
X{
X register UWORD XStore;
X register UWORD YStore;
X
X XStore = Xpos + idesc.id_Left;
X YStore = Ypos + idesc.id_Top;
X BitPlane[YStore][XStore] = index;
X if (++Xpos == idesc.id_Width)
X {
X Xpos = 0;
X Ypos += LeaveStep[interleave];
X if (Ypos >= idesc.id_Height)
X Ypos = LeaveFirst[++interleave];
X }
X}
X
XBOOL
XSkipBlock (fh)
X FILE *fh;
X{
X char buf;
X int size, i;
X /* skip the Graphics Control Label */
X if ((buf = fgetc (fh)) == -1) return TRUE;
X /* read the Block size */
X if ((size = fgetc (fh)) == -1) return TRUE;
X /* skip the rest of the block */
X for (i=0;i<size;i++)
X {
X if ((buf = fgetc (fh)) == -1) return TRUE;
X }
X /* skip the block terminator */
X if ((buf = fgetc (fh)) == -1) return TRUE;
X return FALSE;
X}
X
XBOOL
XDoImage (fh)
X FILE *fh;
X{
X register int index;
X register int colours;
X int Code;
X
X printf ("Image #%ld encountered.\n", ImageNumber++);
X if (fread ((char *) &idesc, 1, 9, fh) != 9)
X ERROR ("Error reading image descriptor.\n");
X FlipWord (&idesc.id_Left);
X FlipWord (&idesc.id_Top);
X FlipWord (&idesc.id_Width);
X FlipWord (&idesc.id_Height);
X interleave = idesc.id_Info & 1L << 6;
X if (interleave)
X interleave = 1;
X printf ("Xpos from %d to %d, Ypos from %d to %d, %sinterlaced.\n",
X idesc.id_Left, idesc.id_Left + idesc.id_Width - 1,
X idesc.id_Top, idesc.id_Top + idesc.id_Height - 1,
X interleave ? "" : "not ");
X if (idesc.id_Info & 1L << 7)
X {
X colours = 1L << ((idesc.id_Info & 7) + 1);
X printf ("Local colour map contains %d entries.\n", colours);
X for (index = 0; index < colours; index++)
X if (fread (&LocalColourTable[index], 1, 3, fh) != 3)
X ERROR ("......Error reading local colour\n");
X }
X else
X {
X colours = 1L << ((gdesc.gd_ColInfo & 7) + 1);
X for (index = 0; index < colours; index++)
X LocalColourTable[index] = GlobalColourTable[index];
X }
X Xpos = Ypos = 0;
X
X {
X int MaxCode, ClearCode, CurCode, OldCode, InCode, FreeCode;
X int OutCount;
X int FirstFree;
X UBYTE InitCodeSize, FinChar, BitMask;
X
X if ((CodeSize = fgetc (fh)) == -1)
X ERROR ("\n......I/O Error during decompression.\n");
X ClearCode = 1L << CodeSize;
X EOFCode = ClearCode + 1;
X FreeCode = FirstFree = ClearCode + 2;
X CodeSize++;
X InitCodeSize = CodeSize;
X MaxCode = 1L << CodeSize;
X ReadError = ReadMask = OutCount = 0;
X CompDataPointer = CompDataCount = 0;
X BitMask = colours - 1;
X Code = ReadCode (fh);
X while (Code != EOFCode)
X {
X if (ReadError)
X return TRUE;
X if (Code == ClearCode)
X {
X CodeSize = InitCodeSize;
X MaxCode = 1L << CodeSize;
X FreeCode = FirstFree;
X FinChar = CurCode = OldCode = Code = ReadCode (fh);
X AddPixel (FinChar);
X }
X else
X {
X CurCode = InCode = Code;
X if (CurCode >= FreeCode)
X {
X CurCode = OldCode;
X OutCode[OutCount++] = FinChar;
X }
X while (CurCode > BitMask)
X {
X if (OutCount > 1024)
X {
X printf ("\nCorrupt GIF file (OutCount)\n");
X return TRUE;
X }
X OutCode[OutCount++] = Suffix[CurCode];
X CurCode = Prefix[CurCode];
X }
X FinChar = CurCode;
X AddPixel (FinChar);
X for (index = OutCount - 1; index >= 0; index--)
X AddPixel (OutCode[index]);
X OutCount = 0;
X Prefix[FreeCode] = OldCode;
X Suffix[FreeCode] = FinChar;
X OldCode = InCode;
X if (++FreeCode >= MaxCode)
X {
X if (CodeSize < 12)
X {
X CodeSize++;
X MaxCode <<= 1;
X }
X }
X }
X Code = ReadCode (fh);
X }
X }
X if ((Code = fgetc (fh)) == -1)
X return TRUE;
X if (Code != 0)
X printf ("Warning: Unaligned packet.\n");
X return FALSE;
X}
X
X/* #define gx 79 */
X/* #define gy 23 */
X#define base 5
X#define colors 16
X
Xchar *colortab[colors] =
X{".", ",", ":", ";", "+", "=", "i", ")", "I", "T", "L", "H", "O", "X", "8", "#"};
X
Xvoid
Xshow (name)
X char *name;
X{
X register int i, j, x, y;
X register int ix, iy, ii, jj;
X struct RGB colour;
X char Cbuf[1];
X int flag, cc, zz, dx, dy, z, dcnt, g, gc;
X
X x = y = ix = iy = dx = dy = i = j = zz = z = dcnt = g = 0;
X gc = 20;
X cc = 1;
X dx = (idesc.id_Width << base) / gx;
X dy = (idesc.id_Height << base) / gy;
X do
X {
X printf ("\n(v)iew (z Z)oom (c)opy (l,r,u,d)=PAN (g)rey (+)(-) (s)wap (1-4)=MIX (h)elp: ");
X while ((flag = getchar ()) == (char) 10) ;
X if (flag == 'v' || flag == 'z' || flag == 'Z' ||
X flag == 'l' || flag == 'h' || flag == 'c' ||
X flag == 'r' || flag == 'u' || flag == 'd' || flag == 's' ||
X flag == 'g' || flag == 'G' || flag == '1' || flag == '2' ||
X flag == '3' || flag == '4' || flag == '+' || flag == '-') ;
X else
X return;
X if (flag == 'v')
X cc = 1;
X if (flag == '1')
X {
X cc = 1;
X printf ("\nDefault Mix\n");
X }
X if (flag == '2')
X {
X cc = 2;
X printf ("\nRed Mix Blocked\n");
X }
X if (flag == '3')
X {
X cc = 3;
X printf ("\nGreen Mix Blocked\n");
X }
X if (flag == '4')
X {
X cc = 4;
X printf ("\nBlue Mix Blocked\n");
X }
X if (flag == 'g')
X {
X cc = 5;
X printf ("\nAssuming This Is A Grey Scale Gif\n");
X }
X if (flag == '+')
X {
X cc = 5;
X gc += 5;
X printf ("\nRaising Sensitivity To %d, Assuming This Is A Grey Scale Gif\n", gc);
X }
X if (flag == '-')
X {
X cc = 5;
X gc -= 5;
X printf ("\nLowering Sensitivity To %d Assuming This Is A Grey Scale Gif\n", gc);
X }
X if (flag == 's')
X {
X cc = 5;
X if (g == 0)
X g = 1;
X else
X g = 0;
X printf ("\nSwapping Background For Grey Scale Gif, Assuming This Is A Grey Scale Gif\n");
X }
X if (flag == 'c')
X {
X printf ("\nAppending copy of screen to file ascgifs\n");
X if (!(CAPT = fopen ("ascgifs", "a")))
X ERROR ("Open error\n");
X Cbuf[0] = 10;
X if (fwrite (Cbuf, 1, 1, CAPT) != 1)
X ERROR ("Unable to write to ascgifs.\n");
X if (fwrite (name, 1, strlen (name), CAPT) != strlen (name))
X ERROR ("Unable to write to ascgifs.\n");
X }
X if (flag == 'u')
X {
X if (iy >= dy * gy / 4)
X iy = iy - dy * gy / 4;
X };
X if (flag == 'd')
X {
X if (iy + dy * gy + 2 * dy < ((idesc.id_Height) << base))
X iy = iy + dy * gy / 4;
X };
X if (flag == 'z')
X {
X dx >>= 1;
X dy >>= 1;
X ix = ix + dx * gx / 2;
X iy = iy + dy * gy / 2;
X };
X if (flag == 'Z')
X {
X dx = (idesc.id_Width << base) / gx;
X dy = (idesc.id_Height << base) / gy;
X ix = 0;
X iy = 0;
X };
X if (flag == 'r')
X {
X if (ix + dx * gx + 2 * dx < ((idesc.id_Width) << base))
X ix = ix + dx * gx / 4;
X };
X if (flag == 'l')
X {
X if (ix >= dx * gx / 4)
X ix = ix - dx * gx / 4;
X };
X y = iy;
X if (zz == 0)
X {
X colour = LocalColourTable[BitPlane[(y >> base) + idesc.id_Top]
X [(x >> base) + idesc.id_Left]];
X zz = (colour.rgb_Red + colour.rgb_Green + colour.rgb_Blue) / 3;
X }
X if (flag == 'h')
X {
X printf ("\nv = View The Gif\n");
X printf ("z = Zoom In On The Center\n");
X printf ("Z = Zoom Out To Normal Size\n");
X printf ("c = Capture screen\n");
X printf ("l = Pan Left\n");
X printf ("r = Pan Right\n");
X printf ("u = Pan Up\n");
X printf ("d = Pan Down\n");
X printf ("g = Display A Grey Scale Gif, Use Only With A Grey Scale Gif\n");
X printf ("+ = Raise Sensitivity For A Grey Scale Gif\n");
X printf ("- = Lower Sensitivity For A Grey Scale Gif\n");
X printf ("s = Swap Background For Grey Scale Gif From/To Black/White\n");
X printf ("1 = Default Mix\n");
X printf ("2 = Red Mix Blocked\n");
X printf ("3 = Green Mix Blocked\n");
X printf ("4 = Blue Mix Blocked\n");
X printf ("Any other character will quit\n");
X }
X else
X {
X for (j = 0; j < gy; j++)
X {
X if (flag == 'c')
X {
X Cbuf[0] = 10;
X if (fwrite (Cbuf, 1, 1, CAPT) != 1)
X ERROR ("Unable to write to ascgifs.\n");
X }
X printf ("\n");
X x = ix;
X for (i = 0; i < gx; i++)
X {
X if (cc == 5)
X {
X dcnt = 0;
X for (jj = y; jj - y < dy; jj += 4)
X {
X for (ii = x; ii - x < dx; ii += 4)
X {
X colour = LocalColourTable[BitPlane[(jj >> base) + idesc.id_Top]
X [(ii >> base) + idesc.id_Left]];
X z = (colour.rgb_Red + colour.rgb_Green + colour.rgb_Blue) / 3;
X if (g == 1)
X {
X if (zz == z)
X dcnt++;
X }
X else if (zz != z)
X dcnt++;
X }
X };
X z = dcnt / (dx / gc + dy / gc);
X if (z < 1)
X z = 1;
X if (z > 256)
X z = 256;
X }
X else
X {
X colour = LocalColourTable[BitPlane[(y >> base) + idesc.id_Top]
X [(x >> base) + idesc.id_Left]];
X if (cc == 2)
X {
X z = (colour.rgb_Green + colour.rgb_Blue) / 2;
X }
X else if (cc == 3)
X {
X z = (colour.rgb_Red + colour.rgb_Blue) / 2;
X }
X else if (cc == 4)
X {
X z = (colour.rgb_Red + colour.rgb_Green) / 2;
X }
X else
X {
X z = (colour.rgb_Red + colour.rgb_Green + colour.rgb_Blue) / 3;
X };
X }
X if (flag == 'c')
X {
X Cbuf[0] = *colortab[(z + gc - 20) * colors / 0x100];
X if (fwrite (Cbuf, 1, 1, CAPT) != 1)
X ERROR ("Unable to write to ascgifs.\n");
X }
X printf (colortab[min(colors-1,(z + gc - 20) * colors / 0x100)]);
X x += dx;
X if (x < 0)
X return;
X }
X y += dy;
X }
X }
X if (flag == 'c')
X fclose (CAPT);
X }
X while (TRUE);
X}
X
Xmain (argc, argv)
X int argc;
X char *argv[];
X{
X register int index;
X char sig[7];
X int size, giftype = 0;
X int error;
X int colours;
X long cmdcode;
X
X if (argc < 2)
X ERROR ("ascgif(1.6) use: ascgif name.gif <output width> <output height>\n");
X if (!(GIFfh = fopen (argv[1], "r")))
X ERROR ("Open error\n"); /* "rb" for pc, "r" for SOME mainframes */
X if (argc > 2)
X {
X if (!(gx = atoi (argv[2])))
X ERROR ("3rd parameter not numeric, (width)\n");
X if (!(gy = atoi (argv[3])))
X ERROR ("4th parameter not numeric, (height)\n");
X }
X else
X {
X gx = 79;
X gy = 23;
X };
X sig[6] = '\0';
X if (fread (sig, 1, 6, GIFfh) != 6 )
X ERROR ("Error reading GIF file...\n");
X if (!strcmp ("GIF87a", sig)) giftype = GIF87a;
X if (!strcmp ("GIF89a", sig)) giftype = GIF89a;
X if ( giftype == 0)
X ERROR ("Unsupported GIF type...\n");
X if (fread ((char *) &gdesc, 1, 7, GIFfh) != 7)
X ERROR ("Error reading screen descriptor\n");
X FlipWord (&gdesc.gd_Width);
X FlipWord (&gdesc.gd_Height);
X printf ("Ascgif Ver 1.6\n");
X printf ("Signature = \"%s\", Width = %u, Height = %u\n",
X sig, gdesc.gd_Width, gdesc.gd_Height);
X colours = 1L << ((gdesc.gd_ColInfo & 7) + 1);
X if (!(gdesc.gd_ColInfo & 1L << 7))
X {
X printf ("No global colour map supplied, using internal.\n");
X for (index = 0; index < colours; index++)
X {
X GlobalColourTable[index].rgb_Red =
X GlobalColourTable[index].rgb_Green =
X GlobalColourTable[index].rgb_Blue = index;
X }
X }
X else
X {
X printf ("Global colour map contains %d entries.\n", colours);
X for (index = 0; index < colours; index++)
X if (fread (&GlobalColourTable[index], 1, 3, GIFfh) != 3)
X ERROR ("Error reading global colour\n");
X }
X size = ((gdesc.gd_Width + 7) / 8) + 1;
X size += (size + 127) >> 7;
X if (!(BitPlane = (UBYTE **) malloc (gdesc.gd_Height * sizeof (UBYTE *))))
X ERROR ("Not enough memory\n");
X size = (gdesc.gd_Width + 1) * sizeof (UBYTE);
X for (index = 0; index < gdesc.gd_Height; index++)
X if (!(BitPlane[index] = (UBYTE *) malloc (size)))
X ERROR ("Not enough memory\n");
X ImageNumber = 1;
X for (error = FALSE; error == FALSE;)
X {
X if ((cmdcode = fgetc (GIFfh)) == -1)
X break;
X if (cmdcode ==
X GIF_IMAGE)
X {
X error = DoImage (GIFfh);
X }
X else if (cmdcode ==
X GIF_EXTENSION)
X {
X if (giftype == GIF89a)
X {
X error = SkipBlock(GIFfh);
X }
X else
X {
X error = TRUE;
X }
X }
X else if (cmdcode ==
X GIF_TERMINATOR)
X {
X show (argv[1]);
X break;
X }
X else
X {
X printf ("Unknown directive encountered.\n");
X error = TRUE;
X }
X }
X printf ("End of GIF session\n");
X exit (0);
X}
END_OF_FILE
if test 17621 -ne `wc -c <'ascgif.c'`; then
echo shar: \"'ascgif.c'\" unpacked with wrong size!
fi
# end of 'ascgif.c'
fi
if test -f 'gif2txt.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'gif2txt.c'\"
else
echo shar: Extracting \"'gif2txt.c'\" \(23326 characters\)
sed "s/^X//" >'gif2txt.c' <<'END_OF_FILE'
X/*
X From heimdall!psinntp!psinntp!news.intercon.com!panix!ddsw1!news.kei.com!sol.ctr.columbia.edu!usc!howland.reston.ans.net!agate!doc.ic.ac.uk!warwick!uknet!keele!potter!u2i02 Tue Mar 1 09:34:13 1994
X Path: heimdall!psinntp!psinntp!news.intercon.com!panix!ddsw1!news.kei.com!sol.ctr.columbia.edu!usc!howland.reston.ans.net!agate!doc.ic.ac.uk!warwick!uknet!keele!potter!u2i02
X From: u2i...@cc.keele.ac.uk (RJ Pomeroy)
X Newsgroups: alt.ascii-art
X Subject: Gif to ASCII conversion programme (ascgif v2.1) [big]
X Message-ID: <2knvjo$ac...@gabriel.keele.ac.uk>
X Date: 26 Feb 94 17:07:04 GMT
X References: <2k3pnr$6q...@hebron.connected.com> <199...@uxmail.ust.hk>
X Lines: 677
X NNTP-Posting-Host: potter.cc.keele.ac.uk
X X-Newsreader: TIN [version 1.2 PL2]
X
X Chan Wing Nin Andrew (ph_...@uxmail.ust.hk) wrote:
X : Uncle Waldo (dav...@hebron.connected.com) wrote:
X : : I am looking for a program to convert Gif's to ASCII could someone tell
X : : me a name to look with archie or uuencode one and mail it to me?
X
X : I need one too...! So please mail it to me also.... Thanx....:)
X
X Here is the code for ascgif2.1. Save it as "ascgif.c", make the changes it
X suggests (see first few lines of code for details), and compile it thus:
X
X cc -o ascgif ascgif.c
X
X or
X
X gcc -o ascgif ascgif.c
X
X if you have the gnu compiler. I recommend using the -O2 option as well, for a
X high optimisation degree - useful if space is a limiting factor.
X
X ----8<----Cut here----8<----
X *
X */
X/*
X * Ascii Gif Viewer Version 2.1 Mar (c) 1993 John Ferrell
X * Freeware. Public Domain.
X * Shows gif pictures using text characters.
X 7 changes for pc to mainframe portability. (search on 'mainframes')
X Some mini/workstations might need some of the pc definitions.
X 2.1 changes - added Form Feed (clear screen) before picture
X */
X#include <string.h>
X#include <stdlib.h> /* libc.h for mainframes, stdlib.h for pc */
X#include <stdio.h>
X
X#define UBYTE unsigned char /* 8Bit */
X#define UWORD unsigned short /* 16Bit */
X#define ULONG unsigned int /* 32Bit int for mainframes, long for pc */
X#define BOOL unsigned short
X
X#define TRUE 1
X#define FALSE 0
X
Xstruct GIFdescriptor
X{
X UWORD gd_Width;
X UWORD gd_Height;
X UBYTE gd_ColInfo;
X UBYTE gd_BackGround;
X UBYTE gd_PixelAspect;
X};
X
Xstruct ImageDesc
X{
X UWORD id_Left;
X UWORD id_Top;
X UWORD id_Width;
X UWORD id_Height;
X UBYTE id_Info;
X};
X
Xstruct RGB
X{
X UBYTE rgb_Red;
X UBYTE rgb_Green;
X UBYTE rgb_Blue;
X};
X
X#define GIF_IMAGE 0x2C
X#define GIF_EXTENSION 0x21
X#define GIF_TERMINATOR 0x3B
X#define GIF_COMMENT_EXT 0xFE
X
X#define GIF87a 87
X#define GIF89a 89
X
X /* void *screen; *//* uncomment for pc, comment out for *
X mainframes */
X
Xstruct GIFdescriptor gdesc;
X
XUBYTE **BitPlane;
Xstruct RGB GlobalColourTable[256];
X
XUBYTE Map[256];
X
XULONG ImageNumber;
X
XFILE *GIFfh = NULL;
XFILE *CAPT = NULL;
X
Xvoid
XERROR (str)
X char *str;
X{
X printf (str);
X exit (1);
X}
X
Xvoid
XFlipWord (word)
X UWORD *word;
X{
X UBYTE swap1;
X UBYTE swap2;
X
X swap1 = *word & 0xFF; /* comment out for pc, needed for
X mainframes */
X swap2 = (*word & 0xFF00) >> 8; /* " " */
X *word = swap1 << 8 | swap2; /* " " */
X}
X
Xstatic struct ImageDesc idesc;
Xstatic struct RGB LocalColourTable[256];
X
Xstatic UWORD Xpos, Ypos;
Xstatic BOOL interleave;
X
Xstatic UBYTE LeaveStep[5] =
X{1, 8, 8, 4, 2};
Xstatic UBYTE LeaveFirst[5] =
X{0, 0, 4, 2, 1};
X
Xstatic int ReadError;
Xstatic UBYTE CodeSize;
Xstatic int EOFCode;
Xstatic UBYTE ReadMask;
Xstatic int CompDataPointer;
Xstatic int CompDataCount;
Xstatic UBYTE CompData[256];
X
Xstatic UWORD Prefix[4096];
Xstatic UBYTE Suffix[4096];
Xstatic UBYTE OutCode[1025];
X
Xstatic UBYTE ByteBuf;
X
Xint
XReadCode (fh)
X FILE *fh;
X{
X register int temp;
X register int DstMasked;
X register int DstMask;
X long size;
X
X temp = 0;
X DstMasked = 1L << CodeSize;
X for (DstMask = 1; DstMask != DstMasked; DstMask <<= 1)
X {
X if (!ReadMask)
X {
X if (CompDataPointer == CompDataCount)
X {
X if ((size = fgetc (fh)) == -1)
X {
X printf ("\nI/O Error during decompression.\n");
X ReadError = 1;
X return EOFCode;
X }
X if (fread ((char *) CompData, 1, size, fh) != size)
X {
X printf ("\nI/O Error during decompression.\n");
X ReadError = 1;
X return EOFCode;
X }
X CompDataCount = size;
X CompDataPointer = 0;
X }
X ReadMask = 1;
X ByteBuf = CompData[CompDataPointer++];
X }
X if (ByteBuf & ReadMask)
X temp |= DstMask;
X ReadMask <<= 1;
X }
X return temp;
X}
X
Xvoid
XAddPixel (index)
X UBYTE index;
X{
X register UWORD XStore;
X register UWORD YStore;
X
X XStore = Xpos + idesc.id_Left;
X YStore = Ypos + idesc.id_Top;
X BitPlane[YStore][XStore] = index;
X if (++Xpos == idesc.id_Width)
X {
X Xpos = 0;
X Ypos += LeaveStep[interleave];
X if (Ypos >= idesc.id_Height)
X Ypos = LeaveFirst[++interleave];
X }
X}
X
XBOOL
XSkipBlock (fh)
X FILE *fh;
X{
X char buf;
X int size, i;
X /* skip the Graphics Control Label */
X if ((buf = fgetc (fh)) == -1) return TRUE;
X /* read the Block size */
X if ((size = fgetc (fh)) == -1) return TRUE;
X /* skip the rest of the block */
X for (i=0;i<size;i++)
X {
X if ((buf = fgetc (fh)) == -1) return TRUE;
X }
X /* skip the block terminator */
X if ((buf = fgetc (fh)) == -1) return TRUE;
X return FALSE;
X}
X
XBOOL
XDoImage (fh)
X FILE *fh;
X{
X register int index;
X register int colours;
X int Code;
X
X printf ("Image #%ld encountered.\n", ImageNumber++);
X if (fread ((char *) &idesc, 1, 9, fh) != 9)
X ERROR ("Error reading image descriptor.\n");
X FlipWord (&idesc.id_Left);
X FlipWord (&idesc.id_Top);
X FlipWord (&idesc.id_Width);
X FlipWord (&idesc.id_Height);
X interleave = idesc.id_Info & 1L << 6;
X if (interleave)
X interleave = 1;
X printf ("Xpos from %d to %d, Ypos from %d to %d, %sinterlaced.\n",
X idesc.id_Left, idesc.id_Left + idesc.id_Width - 1,
X idesc.id_Top, idesc.id_Top + idesc.id_Height - 1,
X interleave ? "" : "not ");
X if (idesc.id_Info & 1L << 7)
X {
X colours = 1L << ((idesc.id_Info & 7) + 1);
X printf ("Local colour map contains %d entries.\n", colours);
X for (index = 0; index < colours; index++)
X if (fread (&LocalColourTable[index], 1, 3, fh) != 3)
X ERROR ("......Error reading local colour\n");
X }
X else
X {
X colours = 1L << ((gdesc.gd_ColInfo & 7) + 1);
X for (index = 0; index < colours; index++)
X LocalColourTable[index] = GlobalColourTable[index];
X }
X Xpos = Ypos = 0;
X
X {
X int MaxCode, ClearCode, CurCode, OldCode, InCode, FreeCode;
X int OutCount;
X int FirstFree;
X UBYTE InitCodeSize, FinChar, BitMask;
X
X if ((CodeSize = fgetc (fh)) == -1)
X ERROR ("\n......I/O Error during decompression.\n");
X ClearCode = 1L << CodeSize;
X EOFCode = ClearCode + 1;
X FreeCode = FirstFree = ClearCode + 2;
X CodeSize++;
X InitCodeSize = CodeSize;
X MaxCode = 1L << CodeSize;
X ReadError = ReadMask = OutCount = 0;
X CompDataPointer = CompDataCount = 0;
X BitMask = colours - 1;
X Code = ReadCode (fh);
X while (Code != EOFCode)
X {
X if (ReadError)
X return TRUE;
X if (Code == ClearCode)
X {
X CodeSize = InitCodeSize;
X MaxCode = 1L << CodeSize;
X FreeCode = FirstFree;
X FinChar = CurCode = OldCode = Code = ReadCode (fh);
X AddPixel (FinChar);
X }
X else
X {
X CurCode = InCode = Code;
X if (CurCode >= FreeCode)
X {
X CurCode = OldCode;
X OutCode[OutCount++] = FinChar;
X }
X while (CurCode > BitMask)
X {
X if (OutCount > 1024)
X {
X printf ("\nCorrupt GIF file (OutCount)\n");
X return TRUE;
X }
X OutCode[OutCount++] = Suffix[CurCode];
X CurCode = Prefix[CurCode];
X }
X FinChar = CurCode;
X AddPixel (FinChar);
X for (index = OutCount - 1; index >= 0; index--)
X AddPixel (OutCode[index]);
X OutCount = 0;
X Prefix[FreeCode] = OldCode;
X Suffix[FreeCode] = FinChar;
X OldCode = InCode;
X if (++FreeCode >= MaxCode)
X {
X if (CodeSize < 12)
X {
X CodeSize++;
X MaxCode <<= 1;
X }
X }
X }
X Code = ReadCode (fh);
X }
X }
X if ((Code = fgetc (fh)) == -1)
X return TRUE;
X if (Code != 0)
X printf ("Warning: Unaligned packet.\n");
X return FALSE;
X}
X
X#define base 0
Xint gx = 79;
Xint gy = 21;
Xint bg = 1;
Xint max = 0;
X
X#define clors 16
X
Xchar *clortab[clors] =
X{".", ",", ":", ";", "=", "+", "i", "t", "I", "Y", "V", "X", "R", "B", "M", "W"};
X
Xchar *invcltab[clors] =
X{"W", "M", "B", "R", "X", "V", "Y", "I", "t", "i", "+", "=", ";", ":", ",", "."};
X
Xvoid
Xshow (name)
X char *name;
X{
X int x, y, j, i;
X int ix, iy, ii, jj;
X struct RGB colour;
X char Cbuf[1];
X long best, z;
X int adj, top, bot, flag, cc, dx, dy, f, dcnt, inverse;
X
X adj = x = y = ix = iy = dx = dy = i = j = z = dcnt = f = inverse = 0;
X
X top = 0;
X bot = 256;
X cc = 1;
X dx = 8;
X dy = 16;
X do
X {
X if (!max)
X if (adj && f)
X {
X flag = 'v';
X adj = 0;
X }
X else
X {
X printf ("\nAscgif21 (vi)ew (fF)ocus (zZ)oom (c)opy (l,r,u,d)=PAN (q)uit (h)elp: ");
X while ((flag = getchar ()) == (char) 10) ;
X if (flag == 'v' || flag == 'z' || flag == 'Z' ||
X flag == 'l' || flag == 'h' || flag == 'c' || flag == 'i' ||
X flag == 'f' || flag == 'F' ||
X flag == 'r' || flag == 'u' || flag == 'd' ||
X flag == '1' || flag == '2' || flag == '3' || flag == '4') ;
X else
X return;
X };
X if (flag == 'v')
X cc = 1;
X if (flag == 'f')
X {
X printf ("Adjusting focus...");
X f = 1;
X adj = 1;
X top = 0;
X bot = 256;
X }
X if (flag == 'F')
X f = 0;
X if (flag == 'i')
X if (inverse == 1)
X inverse = 0;
X else
X inverse = 1;
X if (flag == '1')
X {
X cc = 1;
X printf ("\nDefault Mix\n");
X }
X if (flag == '2')
X {
X cc = 2;
X printf ("\nRed Mix Blocked\n");
X }
X if (flag == '3')
X {
X cc = 3;
X printf ("\nGreen Mix Blocked\n");
X }
X if (flag == '4')
X {
X cc = 4;
X printf ("\nBlue Mix Blocked\n");
X }
X if (flag == 'c')
X {
X printf ("\nAppending copy of screen to file ascgifs\n");
X if (!(CAPT = fopen ("ascgifs", "a")))
X ERROR ("Open error\n");
X Cbuf[0] = 10;
X if (fwrite (Cbuf, 1, 1, CAPT) != 1)
X ERROR ("Unable to write to ascgifs.\n");
X if (fwrite (name, 1, strlen (name), CAPT) != strlen (name))
X ERROR ("Unable to write to ascgifs.\n");
X }
X if (flag == 'u')
X {
X if (f)
X {
X printf ("Adjusting focus, Moving up...");
X adj = 1;
X top = 0;
X bot = 256;
X };
X if (iy >= dy * gy / 6)
X iy = iy - dy * gy / 6;
X };
X if (flag == 'd')
X {
X if (f)
X {
X printf ("Adjusting focus, Moving down...");
X adj = 1;
X top = 0;
X bot = 256;
X };
X if (iy + dy * gy + 2 * dy < ((idesc.id_Height) << base))
X iy = iy + dy * gy / 6;
X };
X if (flag == 'z')
X {
X if (f)
X {
X adj = 1;
X top = 0;
X bot = 256;
X printf ("Adjusting focus, Zooming in...");
X };
X dx -= 1;
X dy -= 2;
X if (dx < 1)
X dx = 1;
X else
X ix = ix + dx * gx / 8;
X if (dy < 2)
X dy = 2;
X else
X iy = iy + dy * gy / 8;
X };
X if (flag == 'Z')
X {
X if (f)
X {
X adj = 1;
X printf ("Adjusting focus, Zooming out...");
X };
X dx = 8;
X dy = 16;
X top = 0;
X bot = 256;
X ix = 0;
X iy = 0;
X };
X if (flag == 'r')
X {
X if (f)
X {
X printf ("Adjusting focus, Moving right...");
X adj = 1;
X top = 0;
X bot = 256;
X };
X if (ix + dx * gx + 2 * dx < ((idesc.id_Width) << base))
X ix = ix + dx * gx / 6;
X };
X if (flag == 'l')
X {
X if (f)
X {
X printf ("Adjusting focus, Moving left...");
X adj = 1;
X top = 0;
X bot = 256;
X };
X if (ix >= dx * gx / 6)
X ix = ix - dx * gx / 6;
X };
X if (idesc.id_Width / gx < dx)
X {
X dx = idesc.id_Width / gx;
X if (dx < 1)
X dx = 1;
X }
X if (idesc.id_Height / gy < dy)
X {
X dy = idesc.id_Height / gy;
X if (dy < 1)
X dy = 1;
X }
X if (max)
X {
X gx = idesc.id_Width;
X gy = idesc.id_Height;
X dx = dy = 1;
X }
X y = iy;
X printf ("\f");
X if (flag == 'h')
X {
X printf ("\nascgif(2.1) use: ascgif it.gif <M> <output width> <output height>\n");
X printf (" M shows to stdout with maximum dimensions\n");
X printf (" M invalid with <output width> <output height>\n");
X printf (" M Example: ascgif it.gif M >bigpic\n");
X printf ("v = View the Gif\n");
X printf ("i = Toggle inverse screen\n");
X printf ("f = Focus the screen\n");
X printf ("F = Fuzzy but fast. Good for positioning.\n");
X printf ("z = Zoom in on the center\n");
X printf ("Z = Zoom out to normal size\n");
X printf ("c = Capture screen\n");
X printf ("l = Pan Left\n");
X printf ("r = Pan Right\n");
X printf ("u = Pan Up\n");
X printf ("d = Pan Down\n");
X printf ("1 = Default Mix (in Fuzzy mode only)\n");
X printf ("2 = Red Mix Blocked (in Fuzzy mode only)\n");
X printf ("3 = Green Mix Blocked (in Fuzzy mode only)\n");
X printf ("4 = Blue Mix Blocked (in Fuzzy mode only)\n");
X printf ("Any other character will quit\n");
X }
X else
X {
X for (j = 0; j < gy; j++)
X {
X if (flag == 'c')
X {
X Cbuf[0] = 10;
X if (fwrite (Cbuf, 1, 1, CAPT) != 1)
X ERROR ("Unable to write to ascgifs.\n");
X }
X if (!adj)
X printf ("\n");
X x = ix;
X for (i = 0; i < gx; i++)
X {
X if (f)
X {
X dcnt = 0;
X best = 0;
X for (jj = y; jj - y < dy; jj++)
X {
X for (ii = x; ii - x < dx; ii++)
X {
X colour = LocalColourTable[BitPlane[(jj >> base) + idesc.id_Top]
X [(ii >> base) + idesc.id_Left]];
X z = (colour.rgb_Red + colour.rgb_Green + colour.rgb_Blue) / 3;
X dcnt++;
X best = (best * (dcnt - 1) + z) / dcnt;
X }
X };
X if (best < bot)
X bot = best;
X if (best > top)
X top = best;
X if (top != bot)
X best = (best - bot) * 256 / (top - bot);
X if (best >= 256)
X best = 255;
X if (best < 0)
X best = bg;
X
X if (!adj)
X {
X if (flag == 'c')
X {
X if (inverse)
X {
X Cbuf[0] = *invcltab[(best) * clors / 0x100];
X if (fwrite (Cbuf, 1, 1, CAPT) != 1)
X ERROR ("Unable to write to ascgifs.\n");
X }
X else
X {
X Cbuf[0] = *clortab[(best) * clors / 0x100];
X if (fwrite (Cbuf, 1, 1, CAPT) != 1)
X ERROR ("Unable to write to ascgifs.\n");
X }
X };
X if (inverse)
X printf (invcltab[(best) * clors / 0x100]);
X else
X printf (clortab[(best) * clors / 0x100]);
X };
X x += dx;
X if (x > (idesc.id_Width << base))
X break;
X }
X else
X {
X colour = LocalColourTable[BitPlane[(y >> base) + idesc.id_Top]
X [(x >> base) + idesc.id_Left]];
X if (cc == 2)
X {
X z = (colour.rgb_Green + colour.rgb_Blue) / 2;
X }
X else if (cc == 3)
X {
X z = (colour.rgb_Red + colour.rgb_Blue) / 2;
X }
X else if (cc == 4)
X {
X z = (colour.rgb_Red + colour.rgb_Green) / 2;
X }
X else
X {
X z = (colour.rgb_Red + colour.rgb_Green + colour.rgb_Blue) / 3;
X };
X if (flag == 'c')
X {
X if (inverse)
X {
X Cbuf[0] = *invcltab[(z) * clors / 0x100];
X if (fwrite (Cbuf, 1, 1, CAPT) != 1)
X ERROR ("Unable to write to ascgifs.\n");
X }
X else
X {
X Cbuf[0] = *clortab[(z) * clors / 0x100];
X if (fwrite (Cbuf, 1, 1, CAPT) != 1)
X ERROR ("Unable to write to ascgifs.\n");
X }
X };
X if (inverse)
X printf (invcltab[(z) * clors / 0x100]);
X else
X printf (clortab[(z) * clors / 0x100]);
X x += dx;
X if (x > (idesc.id_Width << base))
X break;
X };
X }
X y += dy;
X if (y > (idesc.id_Height << base))
X break;
X }
X }
X if (max)
X return;
X if (flag == 'c')
X fclose (CAPT);
X }
X while (TRUE);
X}
X
Xmain (argc, argv)
X int argc;
X char *argv[];
X{
X register int index;
X char sig[7];
X int size, giftype = 0;
X int error;
X int colours;
X long cmdcode;
X
X if (argc < 2)
X {
X printf ("ascgif(2.1) use: ascgif name.gif <M> <output width> <output height>\n");
X printf (" M shows to stdout with maximum dimensions\n");
X printf (" M invalid with <output width> <output height>\n");
X ERROR (" M Example: ascgif it.gif M >bigpic\n");
X }
X if (!(GIFfh = fopen (argv[1], "r")))
X /* "rb" for pc, "r" for SOME mainframes */
X ERROR ("Open error\n");
X if (argc > 2)
X {
X if ('M' == *argv[2])
X {
X max = 1;
X }
X else
X {
X if (!(gx = atoi (argv[2])))
X ERROR ("3rd parameter not numeric, (width)\n");
X if (!(gy = atoi (argv[3])))
X ERROR ("4th parameter not numeric, (height)\n");
X };
X }
X else
X {
X gx = 79;
X gy = 21;
X };
X sig[6] = '\0';
X if (fread (sig, 1, 6, GIFfh) != 6 )
X ERROR ("Error reading GIF file...\n");
X if (!strcmp ("GIF87a", sig)) giftype = GIF87a;
X if (!strcmp ("GIF89a", sig)) giftype = GIF89a;
X if ( giftype == 0)
X ERROR ("Unsupported GIF type...\n");
X if (fread ((char *) &gdesc, 1, 7, GIFfh) != 7)
X ERROR ("Error reading screen descriptor\n");
X FlipWord (&gdesc.gd_Width);
X FlipWord (&gdesc.gd_Height);
X printf ("Ascgif Ver 2.1\n");
X printf ("Signature = \"%s\", Width = %u, Height = %u\n",
X sig, gdesc.gd_Width, gdesc.gd_Height);
X colours = 1L << ((gdesc.gd_ColInfo & 7) + 1);
X if (!(gdesc.gd_ColInfo & 1L << 7))
X {
X printf ("No global colour map supplied, using internal.\n");
X for (index = 0; index < colours; index++)
X {
X GlobalColourTable[index].rgb_Red =
X GlobalColourTable[index].rgb_Green =
X GlobalColourTable[index].rgb_Blue = index;
X }
X }
X else
X {
X printf ("Global colour map contains %d entries.\n", colours);
X for (index = 0; index < colours; index++)
X if (fread (&GlobalColourTable[index], 1, 3, GIFfh) != 3)
X ERROR ("Error reading global colour\n");
X }
X size = ((gdesc.gd_Width + 7) / 8) + 1;
X size += (size + 127) >> 7; /* use far,_fmalloc for pc, not for
X mainframes */
X/* if (!(BitPlane = (UBYTE far **) _fmalloc(gdesc.gd_Height * sizeof(UBYTE *)))) */
X if (!(BitPlane = (UBYTE **) malloc (gdesc.gd_Height * sizeof (UBYTE *))))
X ERROR ("Not enough memory\n");
X size = (gdesc.gd_Width + 1) * sizeof (UBYTE);
X for (index = 0; index < gdesc.gd_Height; index++)
X /* use far,_fmalloc for pc, not for mainframes */
X /* if (!(BitPlane[index] = (UBYTE far *) _fmalloc(size))) */
X if (!(BitPlane[index] = (UBYTE *) malloc (size)))
X ERROR ("Not enough memory\n");
X ImageNumber = 1;
X for (error = FALSE; error == FALSE;)
X {
X if ((cmdcode = fgetc (GIFfh)) == -1)
X break;
X if (cmdcode ==
X GIF_IMAGE)
X {
X error = DoImage (GIFfh);
X }
X else if (cmdcode ==
X GIF_EXTENSION)
X {
X if (giftype == GIF89a)
X {
X error = SkipBlock(GIFfh);
X }
X else
X {
X error = TRUE;
X }
X }
X else if (cmdcode ==
X GIF_TERMINATOR)
X {
X show (argv[1]);
X break;
X }
X else
X {
X printf ("Unknown directive encountered.\n");
X error = TRUE;
X }
X }
X printf ("End of GIF session\n");
X
X return (0);
X}
X
X/*
X ----8<----Cut here----8<----
X
X --
X | |
X _ _ --+-- | --+--
X Beware the |\__/| .~ ~. Rob Pomeroy | --+-- | Won by
X killer squirrels /o=o'`./ .' u2i...@keele.ac.uk | | One.
X will get yo {o__, \ { |
X o / . . ) \ (c) /~~~~/ () /~~~~~\
X o `-` '-' \ } 1993 /__ \~ /~~\ \__() /
X u .( _( )_.' /~\ ___\ \ | | ____| |
X :. '---.~_ _ _| \_/ /______\ |__| \_____/
X :.
X
X */
END_OF_FILE
if test 23326 -ne `wc -c <'gif2txt.c'`; then
echo shar: \"'gif2txt.c'\" unpacked with wrong size!
fi
# end of 'gif2txt.c'
fi
echo shar: End of shell archive.
exit 0
Related ASCII art in the Gallery
Explore these categories from our collection of 11,000+ artworks:
.------------. |\\//\\//\\//| |//\\//\\//\\| |\\//\\//\\//| |//\\//\\//\\| '------------'
_______ /` _____ `\;, /__(^===^)__\';, / ::: \ ,; | ::: | ,;' '._______.'`jgs
_ _ (o)(o)--. \../ ( )hjw m\/m--m'`--.
_ _
/` \/ `\_ _
\ /` \/ `\
'. .\ /
\/ '. .'
\/jgs __ . . __ (o.\ \/ /.o) \__\/\/__/ /O /==\ O\ (;O/ \/ \O;)
_______ |.-----.| || jgs || ||_ _|| `--)-(--` __[=== o]___ |:::::::::::|\ `-=========-`()
Make your own ASCII art
Turn images, text or 3D into ASCII, or draw your own – right in your browser.
About this thread.
These messages were posted publicly to the newsgroup
alt.ascii-art
in 1994 and are mirrored here unchanged as part of the Historic Archives – only email addresses are masked.
The artwork and text belong to their original authors: if you copy a piece, keep the artist's initials or signature intact and credit them where you can.
Are you one of the authors? Contact us to get your posts attributed, connected to your artist profile, or removed.
Report this message
Help us keep the archive clean and accurate. Reports are reviewed by a person – nothing is changed automatically.