From: sjreeves@eng.auburn.edu (Stan Reeves)
Subject: Re: anything to ASCII image converter
Organization: Auburn University Engineering
Date: Wed, 4 Nov 1992 16:29:34 GMT

In article <1992Nov2.231556.20933@sol.ctr.columbia.edu> anselmo@cumesb.mech.columbia.edu (Andrew P. Anselmo) writes:
>
>
>Hello Netland-
>
>I was wondering if anyone knew of a nice widget to convert gif/pbx/pbm/tiff
>whatever to crude ASCII images, suitable for display on a crude 80x25
>character device.  

Here's one:



#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# Contents:  ascgif.c
# Wrapped by kent@sparky on Sat May 23 22:57:11 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
echo If this archive is complete, you will see the following message:
echo '          "shar: End of archive."'
if test -f 'ascgif.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'ascgif.c'\"
else
  echo shar: Extracting \"'ascgif.c'\" \(17535 characters\)
  sed "s/^X//" >'ascgif.c' <<'END_OF_FILE'
X/* Ascii Gif Viewer Version 1.6 May (c) 1992 John Ferrell jwf10@juts.ccc.amdahl.com*/
X/* 5 changes for pc to mainframe portability. (search on 'mainframes') */
X
X#include <string.h>
X#include <libc.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
X
Xstruct GIFdescriptor {
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   UWORD id_Left;
X   UWORD id_Top;
X   UWORD id_Width;
X   UWORD id_Height;
X   UBYTE id_Info;
X};
X
Xstruct RGB {
X   UBYTE rgb_Red;
X   UBYTE rgb_Green;
X   UBYTE rgb_Blue;
X};
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/* 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 ERROR(str)
X   char *str;
X   {
X   printf(str);
X   exit(1);
X   }
X
Xvoid FlipWord(word)
X   UWORD *word;
X   {
X   UBYTE swap1;
X   UBYTE swap2;
X   swap1 = *word & 0xFF;                /*comment out for pc, needed for 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]  = {1, 8, 8, 4, 2};
Xstatic UBYTE LeaveFirst[5] = {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 ReadCode(fh)
X   FILE *fh;
X   {
X   register int temp;
X   register int DstMasked;
X   register int DstMask;
X   long size;
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) temp |= DstMask;
X      ReadMask <<= 1;                    
X      }                                  
X   return temp;                          
X   }                                     
X                                         
Xvoid AddPixel(index)                     
X   UBYTE index;                          
X   {                                     
X   register UWORD XStore;
X   register UWORD YStore;
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) Ypos = LeaveFirst[++interleave];
X      }                                  
X   }                                     
X                                         
XBOOL DoImage(fh)                         
X   FILE *fh;                             
X   {                                     
X   register int index;
X   register int colours;
X   int Code;
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) 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,   
X          OldCode, InCode, FreeCode;     
X      int OutCount;                      
X      int FirstFree;                     
X      UBYTE InitCodeSize, FinChar, BitMask;
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) 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) return TRUE;
X   if (Code != 0) 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 show(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=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 == '-'); else return;
X   if (flag=='v')cc=1;
X   if (flag=='1'){cc=1; printf("\nDefault Mix\n");}
X   if (flag=='2'){cc=2; printf("\nRed Mix Blocked\n");}
X   if (flag=='3'){cc=3; printf("\nGreen Mix Blocked\n");}
X   if (flag=='4'){cc=4; printf("\nBlue Mix Blocked\n");}
X   if (flag=='g'){cc=5; printf("\nAssuming This Is A Grey Scale Gif\n");}
X   if (flag=='+'){cc=5; gc+=5; printf("\nRaising Sensitivity To %d, Assuming This Is A Grey Scale Gif\n", gc);}
X   if (flag=='-'){cc=5; gc-=5; printf("\nLowering Sensitivity To %d Assuming This Is A Grey Scale Gif\n", gc);}
X   if (flag=='s'){cc=5;if (g==0)g=1; else g=0; printf("\nSwapping Background For Grey Scale Gif, Assuming This Is A Grey Scale Gif\n");}
X   if (flag=='c'){
X      printf("\nAppending copy of screen to file ascgifs\n");
X      if (!(CAPT = fopen("ascgifs","a"))) 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'){if(iy>=dy*gy/4) iy=iy-dy*gy/4;};
X   if (flag=='d'){if(iy+dy*gy+2*dy<((idesc.id_Height)<<base)) iy=iy+dy*gy/4;};
X   if (flag=='z'){
X      dx>>=1;                            
X      dy>>=1;
X      ix=ix+dx*gx/2;
X      iy=iy+dy*gy/2;
X      };
X   if (flag=='Z'){
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'){if(ix+dx*gx+2*dx<((idesc.id_Width)<<base)) ix=ix+dx*gx/4;};
X   if (flag=='l'){if(ix>=dx*gx/4) ix=ix-dx*gx/4;};
X   y=iy;
X   if (zz == 0){
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   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   for (j=0; j<gy; j++)
X      {
X      if (flag== 'c'){
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          dcnt=0;
X           for (jj=y; jj-y<dy; jj+=4){
X              for (ii=x; ii-x<dx; ii+=4){
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                  if (zz==z)dcnt++;}
X                else if (zz!=z) dcnt++;
X              }
X           };
X           z=dcnt/(dx/gc+dy/gc);
X           if (z<1)z=1;
X           if (z>256)z=256;
X         }
X         else {
X          colour=LocalColourTable[BitPlane[(y>>base)+idesc.id_Top]
X                                         [(x>>base)+idesc.id_Left]];
X          if (cc==2){
X            z=(colour.rgb_Green+colour.rgb_Blue)/2;}
X          else if (cc==3){
X                 z=(colour.rgb_Red+colour.rgb_Blue)/2;}
X              else if (cc==4){
X                      z=(colour.rgb_Red+colour.rgb_Green)/2;}
X                   else {
X                        z=(colour.rgb_Red+colour.rgb_Green+colour.rgb_Blue)/3;
X                        };
X         }
X         if (flag=='c'){
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[(z+gc-20)*colors/0x100]);
X         x+=dx;
X         if (x<0)return;
X      }
X      y+=dy;                             
X      }
X      }
X   if (flag== 'c') fclose(CAPT);
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;
X   int error;                            
X   int colours;                          
X   long cmdcode;                         
X   if (argc < 2) ERROR("ascgif(1.6) use: ascgif name.gif <output width> <output height>\n");
X   if (!(GIFfh = fopen(argv[1],"r"))) ERROR("Open error\n"); /*"rb" for pc, "r" for SOME mainframes */
X   if (argc > 2){
X     if (!(gx=atoi(argv[2]))) ERROR("3rd parameter not numeric, (width)\n");
X     if (!(gy=atoi(argv[3]))) ERROR("4th parameter not numeric, (height)\n");
X     }
X   else { gx = 79;
X          gy = 23;
X        };
X   sig[6] = '\0';
X   if (fread(sig,1,6,GIFfh) != 6 || strcmp("GIF87a", sig))
X      ERROR("Not an 87a GIF file...\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) break;
X      if (cmdcode ==
X          GIF_IMAGE){
X            error = DoImage(GIFfh);
X            } else
X      if (cmdcode ==
X           GIF_EXTENSION){
X            error = TRUE;                
X           } else
X      if (cmdcode ==
X           GIF_TERMINATOR){
X            show(argv[1]);
X            break;
X           }
X           else {
X            printf("Unknown directive encountered.\n");                         
X            error = TRUE;                
X           }
X      }                                  
X      printf("End of GIF session\n");    
X      exit(0);                           
X   } 
X
END_OF_FILE
  if test 17535 -ne `wc -c <'ascgif.c'`; then
    echo shar: \"'ascgif.c'\" unpacked with wrong size!
  fi
  # end of 'ascgif.c'
fi
echo shar: End of archive.
exit 0
exit 0 # Just in case...


--
Stan Reeves
Auburn University, Department of Electrical Engineering, Auburn, AL  36849
INTERNET: sjreeves@eng.auburn.edu