Settings

The page will reload to apply your changes.
Theme

ASCII Art Font

ASCII Art Menu

Original Usenet message from alt.ascii-art.animation, 2 Feb 1994.
Re: Automated ascii generators?

Re: Automated ascii generators?

seg...@ecf.toronto.edu (SEGAL  HENRY ALAN) writes:


>Is there software to take a gif (or equivalent) and create an ASCII 
>picture? 

gif2ascii, your mileage may vary depending on your OS (included at the end)
---------------------------------------------------------------------------

>How about those 3-d letters, eh?  

figlet.  ftp.isu.edu:/pub/figlet (I believe, may be a slightly diff dir)
Makes stuff like the following:

/`(`| | /| Peter A. Norby - CSUA Secretary - nor...@soda.berkeley.edu /`(`| | /|
\,_)|_|/-| U.C. Berkeley's Computer Science Undergraduate Assocation \,_)|_|/-|

            ,ad8888ba,    ad88888ba   88        88        db
           d8"'    `"8b  d8"     "8b  88        88       d88b
          d8'            Y8,          88        88      d8'`8b
          88             `Y8aaaaa,    88        88     d8'  `8b
          88               `"""""8b,  88        88    d8YaaaaY8b
          Y8,                    `8b  88        88   d8""""""""8b
           Y8a.    .a8P  Y8a     a8P  Y8a.    .a8P  d8'        `8b
            `"Y8888Y"'    "Y88888P"    `"Y8888Y"'  d8'          `8b

------------------------------------------------------------------------------

/*
 * Ascii Gif Viewer Version 2.1 Mar (c) 1993 John Ferrell
 * Freeware.  Public Domain.
 * Shows gif pictures using text characters.
   7 changes for pc to mainframe portability. (search on 'mainframes')
   Some mini/workstations might need some of the pc definitions.
  2.1 changes - added Form Feed (clear screen) before picture
*/
#include <string.h>
#include <stdlib.h>               /* libc.h for mainframes, stdlib.h for pc */
#include <stdio.h>

#define UBYTE unsigned char	/* 8Bit */
#define UWORD unsigned short	/* 16Bit */
#define ULONG unsigned int      /* 32Bit  int for mainframes, long for pc */
#define BOOL unsigned short

#define TRUE  1
#define FALSE 0


struct GIFdescriptor {
   UWORD           gd_Width;
   UWORD           gd_Height;
   UBYTE           gd_ColInfo;
   UBYTE           gd_BackGround;
   UBYTE           gd_PixelAspect;
};

struct ImageDesc {
   UWORD           id_Left;
   UWORD           id_Top;
   UWORD           id_Width;
   UWORD           id_Height;
   UBYTE           id_Info;
};

struct RGB {
   UBYTE           rgb_Red;
   UBYTE           rgb_Green;
   UBYTE           rgb_Blue;
};


#define GIF_IMAGE       0x2C
#define GIF_EXTENSION   0x21
#define GIF_TERMINATOR  0x3B
#define GIF_COMMENT_EXT 0xFE

/* void        *screen; */      /* uncomment for pc, comment out for
				 * mainframes */

struct GIFdescriptor gdesc;

UBYTE         **BitPlane;
struct RGB      GlobalColourTable[256];

UBYTE           Map[256];

ULONG           ImageNumber;

FILE           *GIFfh = NULL;
FILE           *CAPT = NULL;

void
ERROR(str)
   char           *str;
{
   printf(str);
   exit(1);
}

void
FlipWord(word)
   UWORD          *word;
{
   UBYTE           swap1;
   UBYTE           swap2;
      swap1 = *word & 0xFF;            /* comment out for pc, needed for mainframes */
      swap2 = (*word & 0xFF00) >> 8;   /* "                "                 */
      *word = swap1 << 8 | swap2;      /* "                "                 */
}

static struct ImageDesc idesc;
static struct RGB LocalColourTable[256];

static UWORD    Xpos, Ypos;
static BOOL     interleave;

static UBYTE    LeaveStep[5] = {1, 8, 8, 4, 2};
static UBYTE    LeaveFirst[5] = {0, 0, 4, 2, 1};

static int      ReadError;
static UBYTE    CodeSize;
static int      EOFCode;
static UBYTE    ReadMask;
static int      CompDataPointer;
static int      CompDataCount;
static UBYTE    CompData[256];

static UWORD    Prefix[4096];
static UBYTE    Suffix[4096];
static UBYTE    OutCode[1025];

static UBYTE    ByteBuf;

int
ReadCode(fh)
   FILE           *fh;
{
   register int    temp;
   register int    DstMasked;
   register int    DstMask;
   long            size;
   temp = 0;
   DstMasked = 1L << CodeSize;
   for (DstMask = 1; DstMask != DstMasked; DstMask <<= 1) {
      if (!ReadMask) {
	 if (CompDataPointer == CompDataCount) {
	    if ((size = fgetc(fh)) == -1) {
	       printf("\nI/O Error during decompression.\n");
	       ReadError = 1;
	       return EOFCode;
	    }
	    if (fread((char *) CompData, 1, size, fh) != size) {
	       printf("\nI/O Error during decompression.\n");
	       ReadError = 1;
	       return EOFCode;
	    }
	    CompDataCount = size;
	    CompDataPointer = 0;
	 }
	 ReadMask = 1;
	 ByteBuf = CompData[CompDataPointer++];
      }
      if (ByteBuf & ReadMask)
	 temp |= DstMask;
      ReadMask <<= 1;
   }
   return temp;
}

void
AddPixel(index)
   UBYTE           index;
{
   register UWORD  XStore;
   register UWORD  YStore;
   XStore = Xpos + idesc.id_Left;
   YStore = Ypos + idesc.id_Top;
   BitPlane[YStore][XStore] = index;
   if (++Xpos == idesc.id_Width) {
      Xpos = 0;
      Ypos += LeaveStep[interleave];
      if (Ypos >= idesc.id_Height)
	 Ypos = LeaveFirst[++interleave];
   }
}

BOOL
DoImage(fh)
   FILE           *fh;
{
   register int    index;
   register int    colours;
   int             Code;
   printf("Image #%ld encountered.\n", ImageNumber++);
   if (fread((char *) &idesc, 1, 9, fh) != 9)
      ERROR("Error reading image descriptor.\n");
   FlipWord(&idesc.id_Left);
   FlipWord(&idesc.id_Top);
   FlipWord(&idesc.id_Width);
   FlipWord(&idesc.id_Height);
   interleave = idesc.id_Info & 1L << 6;
   if (interleave)
      interleave = 1;
   printf("Xpos from %d to %d, Ypos from %d to %d, %sinterlaced.\n",
	  idesc.id_Left, idesc.id_Left + idesc.id_Width - 1,
	  idesc.id_Top, idesc.id_Top + idesc.id_Height - 1,
	  interleave ? "" : "not ");
   if (idesc.id_Info & 1L << 7) {
      colours = 1L << ((idesc.id_Info & 7) + 1);
      printf("Local colour map contains %d entries.\n", colours);
      for (index = 0; index < colours; index++)
	 if (fread(&LocalColourTable[index], 1, 3, fh) != 3)
	    ERROR("......Error reading local colour\n");
   } else {
      colours = 1L << ((gdesc.gd_ColInfo & 7) + 1);
      for (index = 0; index < colours; index++)
	 LocalColourTable[index] = GlobalColourTable[index];
   }
   Xpos = Ypos = 0;

   {
      int             MaxCode, ClearCode, CurCode, OldCode, InCode, FreeCode;
      int             OutCount;
      int             FirstFree;
      UBYTE           InitCodeSize, FinChar, BitMask;
      if ((CodeSize = fgetc(fh)) == -1)
	 ERROR("\n......I/O Error during decompression.\n");
      ClearCode = 1L << CodeSize;
      EOFCode = ClearCode + 1;
      FreeCode = FirstFree = ClearCode + 2;
      CodeSize++;
      InitCodeSize = CodeSize;
      MaxCode = 1L << CodeSize;
      ReadError = ReadMask = OutCount = 0;
      CompDataPointer = CompDataCount = 0;
      BitMask = colours - 1;
      Code = ReadCode(fh);
      while (Code != EOFCode) {
	 if (ReadError)
	    return TRUE;
	 if (Code == ClearCode) {
	    CodeSize = InitCodeSize;
	    MaxCode = 1L << CodeSize;
	    FreeCode = FirstFree;
	    FinChar = CurCode = OldCode = Code = ReadCode(fh);
	    AddPixel(FinChar);
	 } else {
	    CurCode = InCode = Code;
	    if (CurCode >= FreeCode) {
	       CurCode = OldCode;
	       OutCode[OutCount++] = FinChar;
	    }
	    while (CurCode > BitMask) {
	       if (OutCount > 1024) {
		  printf("\nCorrupt GIF file (OutCount)\n");
		  return TRUE;
	       }
	       OutCode[OutCount++] = Suffix[CurCode];
	       CurCode = Prefix[CurCode];
	    }
	    FinChar = CurCode;
	    AddPixel(FinChar);
	    for (index = OutCount - 1; index >= 0; index--)
	       AddPixel(OutCode[index]);
	    OutCount = 0;
	    Prefix[FreeCode] = OldCode;
	    Suffix[FreeCode] = FinChar;
	    OldCode = InCode;
	    if (++FreeCode >= MaxCode) {
	       if (CodeSize < 12) {
		  CodeSize++;
		  MaxCode <<= 1;
	       }
	    }
	 }
	 Code = ReadCode(fh);
      }
   }
   if ((Code = fgetc(fh)) == -1)
      return TRUE;
   if (Code != 0)
      printf("Warning:  Unaligned packet.\n");
   return FALSE;
}

#define base 0
int             gx = 79;
int             gy = 21;
int             bg = 1;
int            max = 0;


#define clors 16

char           *clortab[clors] =
{".", ",", ":", ";", "=", "+", "i", "t", "I", "Y", "V", "X", "R", "B", "M", "W"};

char           *invcltab[clors] =
{"W", "M", "B", "R", "X", "V", "Y", "I", "t", "i", "+", "=", ";", ":", ",", "."};


void
show(name)
   char           *name;
{
   int             x, y, j, i;
   int             ix, iy, ii, jj;
   struct RGB      colour;
   char            Cbuf[1];
   long            best, z;
   int             adj, top, bot, flag, cc, dx, dy, f, dcnt, inverse;

   adj = x = y = ix = iy = dx = dy = i = j = z = dcnt = f = inverse = 0;

   top = 0;
   bot = 256;
   cc = 1;
   dx = 8;
   dy = 16;
   do {
      if (!max)
      if (adj && f){
	 flag = 'v';
	 adj = 0;
      } else {
	 printf("\nAscgif21 (vi)ew (fF)ocus (zZ)oom (c)opy (l,r,u,d)=PAN (q)uit (h)elp: ");
	 while ((flag = getchar()) == (char) 10);
	 if (flag == 'v' || flag == 'z' || flag == 'Z' ||
	     flag == 'l' || flag == 'h' || flag == 'c' || flag == 'i' ||
	     flag == 'f' || flag == 'F' ||
	     flag == 'r' || flag == 'u' || flag == 'd' ||
	     flag == '1' || flag == '2' || flag == '3' || flag == '4');
	 else
	     return;
      };
      if (flag == 'v')
	 cc = 1;
      if (flag == 'f'){
	 printf ("Adjusting focus...");
	 f = 1;
	 adj = 1;
	 top = 0;
	 bot = 256;
      }
      if (flag == 'F')
	 f = 0;
      if (flag == 'i')
	 if (inverse == 1)
	    inverse = 0;
	 else
	    inverse = 1;
      if (flag == '1') {
	 cc = 1;
	 printf("\nDefault Mix\n");
      }
      if (flag == '2') {
	 cc = 2;
	 printf("\nRed Mix Blocked\n");
      }
      if (flag == '3') {
	 cc = 3;
	 printf("\nGreen Mix Blocked\n");
      }
      if (flag == '4') {
	 cc = 4;
	 printf("\nBlue Mix Blocked\n");
      }
      if (flag == 'c') {
	 printf("\nAppending copy of screen to file ascgifs\n");
	 if (!(CAPT = fopen("ascgifs", "a")))
	    ERROR("Open error\n");
	 Cbuf[0] = 10;
	 if (fwrite(Cbuf, 1, 1, CAPT) != 1)
	    ERROR("Unable to write to ascgifs.\n");
	 if (fwrite(name, 1, strlen(name), CAPT) != strlen(name))
	    ERROR("Unable to write to ascgifs.\n");
      }
      if (flag == 'u') {
	 if (f){
	    printf ("Adjusting focus, Moving up...");
	    adj = 1;
	    top = 0;
	    bot = 256;
	 };
	 if (iy >= dy * gy / 6)
	    iy = iy - dy * gy / 6;
      };
      if (flag == 'd') {
	 if (f){
	    printf ("Adjusting focus, Moving down...");
	    adj = 1;
	    top = 0;
	    bot = 256;
	 };
	 if (iy + dy * gy + 2 * dy < ((idesc.id_Height) << base))
	    iy = iy + dy * gy / 6;
      };
      if (flag == 'z') {
	 if (f){
	    adj = 1;
	    top = 0;
	    bot = 256;
	    printf ("Adjusting focus, Zooming in...");
	 };
	 dx -= 1;
	 dy -= 2;
	 if (dx < 1)
	    dx = 1;
	 else
	    ix = ix + dx * gx / 8;
	 if (dy < 2)
	    dy = 2;
	 else
	    iy = iy + dy * gy / 8;
      };
      if (flag == 'Z') {
	 if (f){
	    adj = 1;
	    printf ("Adjusting focus, Zooming out...");
	 };
	 dx = 8;
	 dy = 16;
	 top = 0;
	 bot = 256;
	 ix = 0;
	 iy = 0;
      };
      if (flag == 'r') {
	 if (f){
	    printf ("Adjusting focus, Moving right...");
	    adj = 1;
	    top = 0;
	    bot = 256;
	 };
	 if (ix + dx * gx + 2 * dx < ((idesc.id_Width) << base))
	    ix = ix + dx * gx / 6;
      };
      if (flag == 'l') {
	 if (f){
	    printf ("Adjusting focus, Moving left...");
	    adj = 1;
	    top = 0;
	    bot = 256;
	 };
	 if (ix >= dx * gx / 6)
	    ix = ix - dx * gx / 6;
      };
      if (idesc.id_Width / gx < dx){
	      dx = idesc.id_Width / gx;
	      if (dx < 1) dx = 1;
      }
      if (idesc.id_Height / gy < dy){
	      dy = idesc.id_Height / gy;
	      if (dy < 1) dy = 1;
      }
      if (max){
	  gx = idesc.id_Width;
	  gy = idesc.id_Height;
	  dx = dy = 1;
      }
      y = iy;
      printf("\f");
      if (flag == 'h') {
	 printf("\nascgif(2.1) use: ascgif it.gif <M> <output width> <output height>\n");
	 printf("                 M shows to stdout with maximum dimensions\n");
	 printf("                 M invalid with <output width> <output height>\n");
	 printf("                 M Example:  ascgif it.gif M >bigpic\n");
	 printf("v = View the Gif\n");
	 printf("i = Toggle inverse screen\n");
	 printf("f = Focus the screen\n");
	 printf("F = Fuzzy but fast. Good for positioning.\n");
	 printf("z = Zoom in on the center\n");
	 printf("Z = Zoom out to normal size\n");
	 printf("c = Capture screen\n");
	 printf("l = Pan Left\n");
	 printf("r = Pan Right\n");
	 printf("u = Pan Up\n");
	 printf("d = Pan Down\n");
	 printf("1 = Default Mix (in Fuzzy mode only)\n");
	 printf("2 = Red Mix Blocked (in Fuzzy mode only)\n");
	 printf("3 = Green Mix Blocked (in Fuzzy mode only)\n");
	 printf("4 = Blue Mix Blocked (in Fuzzy mode only)\n");
	 printf("Any other character will quit\n");
      } else {
	 for (j = 0; j < gy; j++) {
	    if (flag == 'c') {
	       Cbuf[0] = 10;
	       if (fwrite(Cbuf, 1, 1, CAPT) != 1)
		  ERROR("Unable to write to ascgifs.\n");
	    }
	    if (!adj)
	       printf("\n");
	    x = ix;
	    for (i = 0; i < gx; i++) {
	       if (f) {
		  dcnt = 0;
		  best = 0;
		  for (jj = y; jj - y < dy; jj++) {
		     for (ii = x; ii - x < dx; ii++) {
			colour = LocalColourTable[BitPlane[(jj >> base) + idesc.id_Top]
					    [(ii >> base) + idesc.id_Left]];
			z = (colour.rgb_Red + colour.rgb_Green + colour.rgb_Blue) / 3;
			dcnt++;
			best = (best * (dcnt - 1) + z) / dcnt;
		     }
		  };
		  if (best < bot)
		     bot = best;
		  if (best > top)
		     top = best;
		  if (top != bot)
		     best = (best - bot) * 256 / (top - bot);
		  if (best >= 256)
		     best = 255;
		  if (best < 0)
		     best = bg;

		  if (!adj){
		     if (flag == 'c') {
			if (inverse) {
			   Cbuf[0] = *invcltab[(best) * clors / 0x100];
			   if (fwrite(Cbuf, 1, 1, CAPT) != 1)
			      ERROR("Unable to write to ascgifs.\n");
			} else {
			   Cbuf[0] = *clortab[(best) * clors / 0x100];
			   if (fwrite(Cbuf, 1, 1, CAPT) != 1)
			      ERROR("Unable to write to ascgifs.\n");
			}
		     };
		     if (inverse)
			printf(invcltab[(best) * clors / 0x100]);
		     else
			printf(clortab[(best) * clors / 0x100]);
		  };
		  x += dx;
		  if (x > (idesc.id_Width << base))
		     break;
	       } else {
		  colour = LocalColourTable[BitPlane[(y >> base) + idesc.id_Top]
					    [(x >> base) + idesc.id_Left]];
		  if (cc == 2) {
		     z = (colour.rgb_Green + colour.rgb_Blue) / 2;
		  } else if (cc == 3) {
		     z = (colour.rgb_Red + colour.rgb_Blue) / 2;
		  } else if (cc == 4) {
		     z = (colour.rgb_Red + colour.rgb_Green) / 2;
		  } else {
		     z = (colour.rgb_Red + colour.rgb_Green + colour.rgb_Blue) / 3;
		  };
		  if (flag == 'c') {
		     if (inverse) {
			Cbuf[0] = *invcltab[(z) * clors / 0x100];
			if (fwrite(Cbuf, 1, 1, CAPT) != 1)
			   ERROR("Unable to write to ascgifs.\n");
		     } else {
			Cbuf[0] = *clortab[(z) * clors / 0x100];
			if (fwrite(Cbuf, 1, 1, CAPT) != 1)
			   ERROR("Unable to write to ascgifs.\n");
		     }
		  };
		  if (inverse)
		     printf(invcltab[(z) * clors / 0x100]);
		  else
		     printf(clortab[(z) * clors / 0x100]);
		  x += dx;
		  if (x > (idesc.id_Width << base))
		     break;
	       };
	    }
	    y += dy;
	    if (y > (idesc.id_Height << base))
	       break;
	 }
      }
      if (max)
	 return;
      if (flag == 'c')
         fclose(CAPT);
   } while (TRUE);
}

main(argc, argv)
   int             argc;
   char           *argv[];
{
   register int    index;
   char            sig[7];
   int             size;
   int             error;
   int             colours;
   long            cmdcode;
   if (argc < 2){
     printf("ascgif(2.1) use: ascgif name.gif <M> <output width> <output height>\n");
     printf("                 M shows to stdout with maximum dimensions\n");
     printf("                 M invalid with <output width> <output height>\n");
      ERROR("                 M Example:  ascgif it.gif M >bigpic\n");
   }
   if (!(GIFfh = fopen(argv[1],"r")))
                            /* "rb" for pc, "r" for SOME mainframes */
      ERROR("Open error\n");
   if (argc > 2) {
      if ('M' == *argv[2]){
	      max = 1;
       } else {
	    if (!(gx = atoi(argv[2])))
	       ERROR("3rd parameter not numeric, (width)\n");
            if (!(gy = atoi(argv[3])))
	       ERROR("4th parameter not numeric, (height)\n");
	 };
   } else {
      gx = 79;
      gy = 21;
   };
   sig[6] = '\0';
   if (fread(sig, 1, 6, GIFfh) != 6 || strcmp("GIF87a", sig))
      ERROR("Not an 87a GIF file...\n");
   if (fread((char *) &gdesc, 1, 7, GIFfh) != 7)
      ERROR("Error reading screen descriptor\n");
   FlipWord(&gdesc.gd_Width);
   FlipWord(&gdesc.gd_Height);
   printf("Ascgif Ver 2.1\n");
   printf("Signature = \"%s\", Width = %u, Height = %u\n",
	  sig, gdesc.gd_Width, gdesc.gd_Height);
   colours = 1L << ((gdesc.gd_ColInfo & 7) + 1);
   if (!(gdesc.gd_ColInfo & 1L << 7)) {
      printf("No global colour map supplied, using internal.\n");
      for (index = 0; index < colours; index++) {
	 GlobalColourTable[index].rgb_Red =
	    GlobalColourTable[index].rgb_Green =
	    GlobalColourTable[index].rgb_Blue = index;
      }
   } else {
      printf("Global colour map contains %d entries.\n", colours);
      for (index = 0; index < colours; index++)
	 if (fread(&GlobalColourTable[index], 1, 3, GIFfh) != 3)
	    ERROR("Error reading global colour\n");
   }
   size = ((gdesc.gd_Width + 7) / 8) + 1;
   size += (size + 127) >> 7; /* use far,_fmalloc for pc, not for mainframes */
/* if (!(BitPlane = (UBYTE far **) _fmalloc(gdesc.gd_Height * sizeof(UBYTE *)))) */
   if (!(BitPlane = (UBYTE **) malloc(gdesc.gd_Height * sizeof(UBYTE *))))
      ERROR("Not enough memory\n");
   size = (gdesc.gd_Width + 1) * sizeof(UBYTE);
   for (index = 0; index < gdesc.gd_Height; index++)
	 /* use far,_fmalloc for pc, not for mainframes */
 /*   if (!(BitPlane[index] = (UBYTE far *) _fmalloc(size)))  */
      if (!(BitPlane[index] = (UBYTE *) malloc(size)))
	 ERROR("Not enough memory\n");
   ImageNumber = 1;
   for (error = FALSE; error == FALSE;) {
      if ((cmdcode = fgetc(GIFfh)) == -1)
	 break;
      if (cmdcode ==
	  GIF_IMAGE) {
	 error = DoImage(GIFfh);
      } else if (cmdcode ==
		 GIF_EXTENSION) {
	 error = TRUE;
      } else if (cmdcode ==
		 GIF_TERMINATOR) {
	 show(argv[1]);
	 break;
      } else {
	 printf("Unknown directive encountered.\n");
	 error = TRUE;
      }
   }
   printf("End of GIF session\n");

   return (0);
}

------------------------------------------------------------------------------

--
Peter A. Norby - OCF Staff - nor...@ocf.berkeley.edu  | If it wasn't for | T |
nor...@soda.berkeley.edu     /=====================\  | dissappointment, | M |
clu...@ocf.berkeley.edu   | This Space For Rent |  | I wouldn't have  | B |
dis...@ocf.berkeley.edu   \=====================/  | any appointments | G |

Original message headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: fd588,d065d698fbe162
X-Google-Attributes: gidfd588,public
X-Google-ArrivalTime: 1994-02-02 09:59:51 PST
Path: gmd.de!xlink.net!sol.ctr.columbia.edu!howland.reston.ans.net!agate!soda!norby
From: nor...@soda.berkeley.edu (Peter Norby)
Newsgroups: alt.ascii-art.animation
Subject: Re: Automated ascii generators?
Date: 2 Feb 94 17:59:51 GMT
Organization: University of California, Berkeley
Lines: 680
Message-ID: <norby.760211991@soda>
References: <CKI...@ecf.toronto.edu>
NNTP-Posting-Host: soda.berkeley.edu
X-Newsreader: NN version 6.5.0 #3 (NOV)
About this message. This message was posted publicly to the newsgroup alt.ascii-art.animation in 1994 and is 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 the author? 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.

Help classify this post