X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: f996b,6f701a8e96b71df6 X-Google-Attributes: gidf996b,public X-Google-ArrivalTime: 1994-12-30 03:54:02 PST Path: nntp.gmd.de!newsserver.jvnc.net!yale.edu!spool.mu.edu!howland.reston.ans.net!pipex!sunic!ugle.unit.no!kari.fm.unit.no!nodland From: nodland@kari.fm.unit.no (Are Nodland) Newsgroups: alt.ascii-art Subject: Re: Gifscii (fact or fantasy) Date: 30 Dec 1994 11:41:31 GMT Organization: Norwegian Institute of Technology, University of Trondheim Lines: 1629 Message-ID: <3e0rlb$2uj@due.unit.no> References: <3e0h38$90b@news.compulink.com> NNTP-Posting-Host: kari.fm.unit.no In article <3e0h38$90b@news.compulink.com>, galactic wrote: >I recently saw a post for a utility called Gifscii. This utility was >supposed to convert a gif file to ascii. I put the name through Archie >with no success and also went to the ftp site in the post (now forgotten). > >If the file does exit does someone know of its whereabouts and location. >I would like to thank all the contributors to this newsgroup, which have >posted some lovely ascii art. > Here's the c++ source-code as I found it. /*GIFSCII 2.2 Source Please direct all questions to the author: Paul Kline pk6811s@acad.drake.edu*/ /* Gifscii version 2.2 (c) 04/94 - Added edge detect toggle */ /* Gifscii version 2.1 (c) 03/94 - Moved platform-dependent code to top of source - attempting source portability. - Much-needed c-code cleanup plus memory-related changes for MSDOS environment provided by Phil Stracchino alaric@netcom.com - Added code to skip extension/comment blocks to process gif89 format. - Added brightness & contrast controls - Added large/small increment panning - Improved small-image conversion - Improved 2-color gif handling - Changed command codes for more flexibility - Animated vt100 screen-reveals - Switch between full and reduced character sets - Error message improvements */ /* Gifscii version 1.0 (c) 02/15/94 Paul Kline pk6811s@acad.drake.edu */ /* ascgif version 1.6 (c) May, 1992 John Ferrell jwf10@juts.ccc.amdahl.com */ /* This program converts graphics stored in gif format to ascii text */ /* Syntax is 'gifscii filename columns lines' */ /* If run without command-line arguments, program will ask for them. */ #include #include /* some Unix compilers use (was )*/ #include #include #if defined( GO32 ) && !defined( GIFSCIIDEFS ) /* msdos, DJGPP compiler */ #define GIFSCIIDEFS #define MAIN_RETURN_TYPE void #define USEFILETYPE "rb" #include typedef unsigned long ULONG; /* 32Bit */ #define FAR #define FLIP_WORD_NEEDED 0 void *screen; /* compile with: cc gifscii.c [ -o ] -lm */ #endif #if defined( MSDOS ) && !defined( GIFSCIIDEFS ) /* msdos platform */ #define GIFSCIIDEFS #define MAIN_RETURN_TYPE void #define USEFILETYPE "rb" #include typedef unsigned long ULONG; /* 32Bit */ #define FAR far #define malloc _fmalloc #define FLIP_WORD_NEEDED 0 void *screen; #endif #if defined( THINK_C ) && !defined( GIFSCIIDEFS ) /* macintosh Think_C */ #define GIFSCIIDEFS #define MAIN_RETURN_TYPE void #define USEFILETYPE "rb" typedef unsigned long ULONG; /* 32Bit */ #define FAR #define FLIP_WORD_NEEDED 1 /* Compiler Information: menu: EDIT/OPTIONS/THINK_C button: Language Extensions ON button: THINK_C ON */ #endif #if defined( VAXC ) && !defined( GIFSCIIDEFS ) /* VAX RMS CC */ #define GIFSCIIDEFS #define MAIN_RETURN_TYPE int #define USEFILETYPE "rb" typedef unsigned int ULONG; /* 32Bit */ #define FAR #define FLIP_WORD_NEEDED 0 /* Compiler Information: $ $ CC GIFSCII/G_FLOAT $ DEFINE LNK$LIBRARY SYS$LIBRARY:VAXCRTLG $ DEFINE LNK$LIBRARY_1 SYS$LIBRARY:VAXCRTL $ LINK GIFSCII */ #endif #if !defined( GIFSCIIDEFS) /* other platform */ #define MAIN_RETURN_TYPE void #define GIFSCIIDEFS #define USEFILETYPE "rb" typedef unsigned int ULONG; /* 32Bit */ #define FAR #define FLIP_WORD_NEEDED 1 #endif typedef unsigned char UBYTE; /* 8Bit */ typedef unsigned short UWORD; /* 16Bit */ typedef UWORD FAR * pUWORD; typedef UBYTE FAR * pUBYTE; typedef pUBYTE FAR * hUBYTE; typedef unsigned short BOOL; typedef char * pchar; typedef FILE * pFILE; #define TRUE 1 #define FALSE 0 typedef struct tagAsciiMetric { UWORD am_ul; UWORD am_ur; UWORD am_ml; UWORD am_mr; UWORD am_bl; UWORD am_br; char am_char; } AscMetric, FAR * pAscMetric; typedef struct tagGIFdesc { UWORD gd_Width; UWORD gd_Height; UBYTE gd_ColInfo; UBYTE gd_BackGround; UBYTE gd_PixelAspect; } GIFdesc, FAR *pGIFdesc; typedef struct tagImageDesc { UWORD id_Left; UWORD id_Top; UWORD id_Width; UWORD id_Height; UBYTE id_Info; } ImageDesc, FAR * pImageDesc; typedef struct tagRGB { UBYTE rgb_Red; UBYTE rgb_Green; UBYTE rgb_Blue; } RGB, FAR *pRGB; #define GIF_EXTENSION 0x21 #define GIF_IMAGE 0x2C #define GIF_TERMINATOR 0x3B #define GIF_INTERLACE 0x40 #define GIF_LOCALMAP 0x80 #define GIF_COMMENT_EXT 0xFE GIFdesc gdesc; static char ascfile[250]; static char rvlfile[250]; static RGB GlobalColourTable[256]; static RGB LocalColourTable [256]; static RGB colour; static ImageDesc idesc; 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 ULONG ImageNumber; static ULONG ImageColours; pFILE GIFfh = NULL; pFILE CAPT = NULL; 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[1024]; static UBYTE ByteBuf; hUBYTE BitPlane; UBYTE b_w = 0; UBYTE x_l = 0; UBYTE edge_detect = 0; char gif_filename[250]; static double aspect; /* image width/height */ static char RevealStore[24][80]; UWORD gri,rdi,bli; int gx=0; int gy=0; int gxd=0; int gyd=0; MAIN_RETURN_TYPE main( int argc, pchar argv[] ); void ERROR( pchar str ); void FlipWord( pUWORD pword ); int ReadCode( pFILE fh ); void AddPixel( UBYTE index ); BOOL DoImage( pFILE fh ); void show(); void ColourValue( int cx, int cy, int cxd, int cyd); void RevealImage( int rvl_type ); MAIN_RETURN_TYPE main( int argc, pchar argv[]) { register int index; char sig[7]; int size; int i; int error; int colours; size_t offset; long cmdcode; long xtension; char gif_width[6] = "00000"; char gif_height[6] = "00000"; if (argc >= 2) { strcpy(gif_filename, argv[1]); } else { printf("\nWhat is the name of the gif file?\n"); gets(gif_filename); } strcpy( ascfile, gif_filename ); if (!(GIFfh = fopen(gif_filename,USEFILETYPE))) ERROR("Error opening file\n"); fread(sig,1,6,GIFfh); sig[3] = '\0'; if (strcmp("GIF", sig) != 0) ERROR("Not a 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("\n\nGifscii: %s\nWidth = %d Height = %d\n", gif_filename,(int)gdesc.gd_Width,(int)gdesc.gd_Height); printf("Optimal Columns = %d Optimal Lines = %d\n", (int)(gdesc.gd_Width / 6),(int)(gdesc.gd_Height / 10)); aspect = (double) gdesc.gd_Width / (double) gdesc.gd_Height; for (offset=0; offset= 3) { strcpy(gif_width,argv[2]); } else { printf("\nOutput will be sized to the number of lines and columns you specify"); printf("\n"); printf("\nLines Columns Lines Columns"); printf("\nSpec. Spec. Output Output"); printf("\n----- ----- ----- -----"); printf("\n 0 0 GH/10 GW/6"); printf("\n 0 C C*GH/GW*.6 C"); printf("\n L 0 L L*GW/GH/.6"); printf("\n L C L C"); printf("\n"); printf("\nGW = GifWidth, GH = GifHeight"); printf("\n"); printf("\nHow many columns to create? "); gets(gif_width); } if (argc >= 4) { strcpy(gif_height,argv[3]); } else { printf("\nHow many lines to create? "); gets(gif_height); } if (strlen( gif_width )) gx=atoi(gif_width); if (strlen( gif_height )) gy=atoi(gif_height); if ((gx == 0) && (gy == 0)) { gx = (int)gdesc.gd_Width/6; gy = (int)gdesc.gd_Height/10; } if (gx == 0 && gy > 0) gx = (int) ((long)gy * (long)gdesc.gd_Width * 10L / ((long)gdesc.gd_Height * 6L)); if (gy == 0 && gx > 0) gy = (int) ((long)gx * (long)gdesc.gd_Height * 6L / ((long)gdesc.gd_Width * 10L)); printf("Width = %d, Height = %d, Columns = %d, Lines = %d,\n", (int)gdesc.gd_Width, (int)gdesc.gd_Height, gx, gy); colours = (int)(1L << ((gdesc.gd_ColInfo & 7) + 1)); ImageColours = (ULONG) colours; 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; if (!(BitPlane = (hUBYTE)malloc(gdesc.gd_Height * sizeof(pUBYTE *)))) { printf("\n>%ld bytes required",(long)((long)gdesc.gd_Height * (long)gdesc.gd_Width * (long)sizeof(UBYTE))); ERROR("\nNot enough memory\n"); } size = (gdesc.gd_Width + 1) * sizeof(UBYTE); for (index = 0; index < (int)gdesc.gd_Height; index++) if (!(BitPlane[index] = (pUBYTE)malloc(size))) { printf("\n>%ld bytes required",(long)((long)gdesc.gd_Height * (long)gdesc.gd_Width * (long)sizeof(UBYTE))); ERROR("\nNot enough memory\n"); } ImageNumber = 1; for (error = FALSE; error == FALSE;) { if ((cmdcode = fgetc(GIFfh)) == -1) break; switch (cmdcode) { case GIF_EXTENSION: { if (xtension = fgetc(GIFfh) < 0) /* gif extension function */ ERROR("Bad Extension Header\n"); while ((cmdcode = fgetc(GIFfh)) > 0) /* byte count */ { printf("\n"); for (i = 0; i < cmdcode; i++) { if (xtension = fgetc(GIFfh) < 0) /* extension data (skip) */ ERROR("Bad Extension Header\n"); } } printf("\n"); if (cmdcode < 0) ERROR("Bad Extension Header\n"); break; } case GIF_IMAGE: { error = DoImage(GIFfh); break; } case GIF_TERMINATOR: { show(); break; } default: { error = TRUE; } } } printf("End of GIF session\n"); exit(0); } void ERROR(pchar str) { printf(str); exit(1); } void FlipWord(pUWORD word) { UWORD swap1; UWORD swap2; swap1 = (UWORD) (*word & 0x00FF); swap2 = (UWORD) (*word & 0xFF00) >> 8; if (FLIP_WORD_NEEDED == 1) *word = (UWORD) swap1 << 8 | (UWORD) swap2; } void BuildSubsTable(asciisub) /* Copyright Feb, 1994 Paul Kline. pk6811s@acad.drake.edu */ /* All rights to these tables and gif-ascii conversion routines reserved. */ /* These tables and routines may be copied and distributed except that no */ /* computer program may be developed from them for commercial or for-profit */ /* purposes without the express written permission of the copyright holder */ /* This notice is not to be understood as granting such permission. */ /* All output of the program is the property of the owner of the input */ UBYTE asciisub [5][5][5][5][5][5]; { pFILE fp_ascsub; UBYTE sub_char; UWORD i1, i2, i3, i4, i5, i6, a1; UWORD d1, d2, d3, d4, d5, d6, subtot, curtot, curix; int asciitabcount = 72; char asciitabfile[12] = "gifscii.tb1"; AscMetric asciitab[73] = { {0,0,0,0,0,0,' '}, {0,0,0,0,2,2,'.'}, {0,0,1,1,2,2,':'}, {0,0,2,2,0,0,'-'}, {0,2,0,1,0,0,'\''}, {0,2,1,2,3,0,'/'}, {1,2,0,1,0,0,'`'}, {1,2,1,1,0,0,'~'}, {1,3,1,0,0,0,'^'}, {2,0,2,1,0,3,'\\'}, {2,2,2,2,3,3,'X'}, {3,3,3,3,3,3,'M'}, {4,4,4,4,4,4,'$'}, {0,1,2,1,1,2,'<'}, {1,0,2,2,2,0,'>'}, {0,0,2,2,3,3,'x'}, {0,0,2,2,4,4,'u'}, {0,0,2,3,4,3,'z'}, {0,0,3,2,3,0,'r'}, {0,0,3,2,4,3,'c'}, {0,0,3,3,0,0,'='}, {0,0,3,3,1,1,'+'}, {0,0,3,3,3,3,'n'}, {0,0,3,3,3,4,'s'}, {0,0,3,3,4,4,'o'}, {0,0,4,4,3,3,'m'}, {0,0,4,4,4,3,'e'}, {0,2,3,3,4,4,'d'}, {1,1,3,2,4,4,'i'}, {1,2,3,3,0,3,'4'}, {1,4,0,2,4,4,'J'}, {2,0,2,0,4,3,'L'}, {2,0,3,2,4,3,'k'}, {2,0,3,3,3,3,'h'}, {2,0,3,3,4,4,'b'}, {2,2,2,2,2,2,'!'}, {2,2,2,2,4,4,'U'}, {2,2,3,3,2,4,'t'}, {2,2,3,3,3,3,'H'}, {2,2,3,3,4,4,'W'}, {2,2,4,1,4,3,'K'}, {2,3,2,0,3,2,'('}, {2,3,3,1,3,0,'f'}, {2,3,4,4,3,3,'@'}, {3,1,3,3,1,2,'%'}, {3,2,0,2,2,3,')'}, {3,2,3,2,4,4,'&'}, {3,2,4,4,3,4,'N'}, {3,3,1,1,0,0,'"'}, {3,3,1,2,2,2,'?'}, {3,3,1,2,4,3,'2'}, {3,3,1,3,3,4,'3'}, {3,3,2,0,4,3,'C'}, {3,3,2,1,4,4,'G'}, {3,3,2,2,3,4,'S'}, {3,3,2,2,4,4,'Q'}, {3,3,2,3,3,4,'9'}, {3,3,3,2,4,4,'6'}, {3,3,3,3,4,4,'8'}, {3,3,4,4,1,1,'*'}, {3,4,1,2,3,3,'7'}, {3,4,2,2,4,3,'Z'}, {4,2,2,2,4,4,'l'}, {4,3,2,2,4,4,'D'}, {4,3,3,1,3,0,'F'}, {4,3,3,1,4,3,'E'}, {4,3,3,2,3,4,'5'}, {4,3,3,3,3,0,'P'}, {4,3,3,3,3,3,'R'}, {4,3,3,3,4,4,'B'}, {4,4,2,2,3,3,'T'}, {4,4,2,2,4,4,'I'}, {4,4,3,3,1,1,'#'} }; if ( x_l ) strcpy( asciitabfile, "gifscii.tb2" ); else strcpy( asciitabfile, "gifscii.tb1" ); if ((fp_ascsub = fopen(asciitabfile,"r")) == NULL ) { if ( x_l ) { asciitabcount = 14; asciitab[10].am_char = '|'; asciitab[11].am_char = '\''; asciitab[12].am_char = ' '; } else { asciitabcount = 72; asciitab[10].am_char = 'X'; asciitab[11].am_char = 'M'; asciitab[12].am_char = '$'; } printf("\nBuilding tables on file %s",asciitabfile); printf("\n(this should only happen the first time)\n"); if ((fp_ascsub = fopen(asciitabfile,"w")) == NULL) ERROR("\nCan't create gifscii.tbx on disk\n"); for (i1 = 0; i1 <= 4; i1++) { for (i2 = 0; i2 <= 4; i2++) { for (i3 = 0; i3 <= 4; i3++) { for (i4 = 0; i4 <= 4; i4++) { for (i5 = 0; i5 <= 4; i5++) { for (i6 = 0; i6 <= 4; i6++) { curtot=65535; curix=5; for (a1 = 0; a1 <= asciitabcount; a1++) { d1 = asciitab[a1].am_ul - i1; d2 = asciitab[a1].am_ur - i2; d3 = asciitab[a1].am_ml - i3; d4 = asciitab[a1].am_mr - i4; d5 = asciitab[a1].am_bl - i5; d6 = asciitab[a1].am_br - i6; d1 = d1 * d1; d2 = d2 * d2; d3 = d3 * d3; d4 = d4 * d4; d5 = d5 * d5; d6 = d6 * d6; subtot = d1 + d2 + d3 + d4 + d5 + d6; if (subtot < curtot) { curtot = subtot; curix = a1; } } sub_char = asciitab[curix].am_char; if ((fwrite(&sub_char,1,1,fp_ascsub)) == 0) ERROR("\nError writing gifscii.tbx to disk\n"); } } } } } } fclose(fp_ascsub); } if ((fp_ascsub = fopen(asciitabfile,"r")) == NULL) ERROR("\nCan't find gifscii.tbx on disk\n"); for (i1 = 0; i1 <= 4; i1++) { for (i2 = 0; i2 <= 4; i2++) { for (i3 = 0; i3 <= 4; i3++) { for (i4 = 0; i4 <= 4; i4++) { for (i5 = 0; i5 <= 4; i5++) { for (i6 = 0; i6 <= 4; i6++) { if (fread(&sub_char,1,1,fp_ascsub) == 0) ERROR("\nError reading gifscii.tbx from disk\n"); asciisub[i1][i2][i3][i4][i5][i6] = sub_char; } } } } } } fclose(fp_ascsub); } int ReadCode( pFILE fh ) { register int temp = 0; register int DstMasked; register int DstMask; long size; DstMasked = (int)(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((pchar)CompData,(size_t)1, (size_t)size, fh) != (size_t)size) { printf("\nI/O Error during decompression.\n"); ReadError = 1; return EOFCode; } CompDataCount = (int)size; CompDataPointer = 0; } ReadMask = 1; ByteBuf = CompData[CompDataPointer++]; } if (ByteBuf & ReadMask) temp |= DstMask; ReadMask <<= 1; } return temp; } void AddPixel(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(pFILE fh) { register int index; register int colours; int Code; printf("Image #%lu 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 = (BOOL) ((ULONG)idesc.id_Info & 1L << 6); if (interleave) interleave = 1; if (idesc.id_Info & 1L << 7) { colours = (int)(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 = (int)(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)) == 255) ERROR("\n......I/O Error during decompression.\n"); ClearCode = (int)(1L << CodeSize); EOFCode = ClearCode + 1; FreeCode = FirstFree = ClearCode + 2; CodeSize++; InitCodeSize = CodeSize; MaxCode = (int)(1L << CodeSize); ReadError = ReadMask = OutCount = 0; CompDataPointer = CompDataCount = 0; BitMask = colours - 1; Code = ReadCode(fh); while (Code != EOFCode) { /* printf("\n%d %d %d %d %d",Code,CodeSize,EOFCode,ClearCode,FreeCode); */ if (ReadError) { printf("Read Error"); return TRUE; } if (Code == ClearCode) { CodeSize = InitCodeSize; MaxCode = (int)(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) { printf("Read Code Error"); return TRUE; } if (Code != 0) printf("Warning: Unaligned packet.\n"); return FALSE; } void show() { UWORD c1, c2, c3, c4, c5, c6; UWORD x1, x2, y1, y2, y3, y4, y5; double SumsqRed, SumsqGreen, SumsqBlue, SumsqTotal; double SumRed, SumGreen, SumBlue, SumTotal, SumWork, SumCt; double VarRed, VarGreen, VarBlue, VarTotal; UWORD Bright1, Bright2, Bright3, Bright4; UWORD AvgBright, StdBright; UWORD contrast, bright; int i, j, x, y; char Cbuf [1]; int flag; int ix, iy; int dx, dy; int rx, ry; int lmargin, tmargin, wmargin, show_width, show_height; char errstring[100]; char rvl_type_char[6] = "00000"; int revealtype = 0; UBYTE asciisub [5][5][5][5][5][5]; x= y = ix = iy = dx = dy = i = j = 0; lmargin = tmargin = 0; show_width = gdesc.gd_Width; show_height = gdesc.gd_Height; aspect = ((double)show_width / (double)gx) / ((double)show_height / (double)gy); contrast = bright = 5; BuildSubsTable(asciisub); do { revealtype = 0; printf("\n(v)iew (zZ)oom (s)ave (lrud)=Pan (i)nvert (h)elp (cC)cont (bB)bright: "); while ((flag=getchar()) == (char)10); if (flag == 'S') flag = 's'; if (flag == 'I') flag = 'i'; if (flag == 'V') flag = 'v'; if (flag == 'H') flag = 'h'; if (flag == 'A') flag = 'a'; if (flag == 'X') flag = 'x'; if (flag == 'E') flag = 'e'; switch(flag) { case 's': { printf("\nAppending copy of screen to file %s\n", ascfile); if (!(CAPT = fopen(ascfile,"a"))) ERROR("Open error\n"); Cbuf[0] = 10; if (fwrite(Cbuf,1,1,CAPT) != 1) { sprintf( errstring, "Unable to write to %s.\n", ascfile); ERROR( errstring ); } if (fwrite(gif_filename, 1, strlen(gif_filename), CAPT) != strlen(gif_filename)) { sprintf( errstring, "Unable to write to %s.\n", ascfile); ERROR( errstring ); } break; } case 'l': { if (lmargin > 0) lmargin = lmargin * 8 / 10; break; } case 'r': { wmargin = (int) idesc.id_Width - (lmargin + show_width); lmargin = lmargin + (int)((long)wmargin * 8L / 10L); break; } case 'u': { if (tmargin > 0) tmargin = tmargin * 8 / 10; break; } case 'd': { wmargin = (int) idesc.id_Height - (tmargin + show_height); tmargin = tmargin + (int)((long)wmargin * 8L / 10L); break; } case 'L': { if (lmargin > 0) lmargin = lmargin * 6 / 10; break; } case 'R': { wmargin = (int) idesc.id_Width - (lmargin + show_width); lmargin = lmargin + (int)((long)wmargin * 6L / 10L); break; } case 'U': { if (tmargin > 0) tmargin = tmargin * 7 / 10; break; } case 'D': { wmargin = (int) idesc.id_Height - (tmargin + show_height); tmargin = tmargin + (int)((long)wmargin * 6L / 10L); break; } case 'i': { b_w = b_w ^ 1; break; } case 'c': { if(contrast > 0) --contrast; break; } case 'C': { if(contrast < 9) ++contrast; break; } case 'B': { if(bright < 9) ++bright; break; } case 'b': { if(bright > 0) --bright; break; } case 'z': { if (aspect < 1) { lmargin = lmargin + (show_width / 20); show_width = show_width * 9 / 10; show_height = (int) ((double)show_width * (double)gy / (double)gx / aspect); tmargin = (gdesc.gd_Height - show_height) / 2; } else { tmargin = tmargin + (show_height / 20); show_height = show_height * 9 / 10; show_width = (int) ((double)show_height * aspect / (double)gx / (double)gy); lmargin = (gdesc.gd_Width - show_width) / 2; } break; } case 'x': { x_l = x_l ^ 1; BuildSubsTable(asciisub); break; case 'e': { edge_detect = edge_detect ^ 1; break; } } case 'Z': { lmargin = tmargin = 0; show_width = gdesc.gd_Width; show_height = gdesc.gd_Height; break; } case 'h': { printf("\n"); printf("v = View The Gif\n"); printf("z = Zoom In On The Center\n"); printf("Z = Zoom Out To Normal Size\n"); printf("s = Save to disk\n"); printf("l/L = Pan Left\n"); printf("r/R = Pan Right\n"); printf("u/U = Pan Up\n"); printf("d/D = Pan Down\n"); printf("i = Invert Black/White\n"); printf("c = Decrease Contrast\n"); printf("C = Increase Contrast\n"); printf("b = Decrease Brightness\n"); printf("B = Increase Brightness\n"); printf("A = Animate vt100 Screen Reveal\n"); printf("X = Toggle between min/max ascii sets\n"); printf("E = Edge detect toggle\n"); printf("Any other character will quit\n"); break; } case 'v': { break; } case 'a': { printf("\n"); printf(" 1 = In->Out\n"); printf(" 2 = Out->In\n"); printf(" 3 = Left->Right\n"); printf(" 4 = Right->Left\n"); printf(" 5 = Sides->In\n"); printf(" 6 = Random\n"); printf("\nEnter Reveal Type:\n"); revealtype = 0; do { gets(rvl_type_char); revealtype = atoi(rvl_type_char); if (revealtype < 1 | revealtype > 6) revealtype = 0; } while (revealtype == 0); for (x1 = 0; x1 < 79; x1++) { for (y1 = 0; y1 < 24; y1++) RevealStore[y1][x1] = 32; } flag = 'v'; break; } default: { return; } } /* Copyright Feb, 1994 Paul Kline. pk6811s@acad.drake.edu */ /* All rights to these tables and gif-ascii conversion routines reserved. */ /* These tables and routines may be copied and distributed except that no */ /* computer program may be developed from them for commercial or for-profit */ /* purposes without the express written permission of the copyright holder */ /* This notice is not to be understood as granting such permission. */ /* All output of the program is the property of the owner of the input */ if (flag != 'h') { ix = lmargin + idesc.id_Left; iy = tmargin + idesc.id_Top; dx = show_width / gx; dy = show_height / gy; rdi=gri=bli=1; SumCt = 1; SumsqRed = SumsqGreen = SumsqBlue = 0; SumRed = SumGreen = SumBlue = 0; switch (dx) { case 1: x1 = 0; x2 = 0; break; case 2: x1 = 1; x2 = 0; break; default: x1 = dx / 3; if (x1 == 0) x1 = 1; x2 = x1 * 2; } switch (dy) { case 1: y1 = 0; y2 = 0; y3 = 0; y4 = 0; y5 = 0; break; case 2: y1 = 0; y2 = 0; y3 = 1; y4 = 1; y5 = 1; break; case 3: y1 = 0; y2 = 1; y3 = 1; y4 = 2; y5 = 2; break; case 4: y1 = 0; y2 = 1; y3 = 2; y4 = 3; y5 = 3; case 5: y1 = 1; y2 = 2; y3 = 2; y4 = 3; y5 = 4; break; default: y1 = dy / 6; y2 = y1 * 2; y3 = y1 * 3; y4 = y1 * 4; y5 = y1 * 5; } if (ImageColours == 2) { LocalColourTable[0].rgb_Red = 255 / 3; LocalColourTable[0].rgb_Green = 255 / 3; LocalColourTable[0].rgb_Blue = 255 / 3; LocalColourTable[1].rgb_Red = 255 * 2 / 3; LocalColourTable[1].rgb_Green = 255 * 2 / 3; LocalColourTable[1].rgb_Blue = 255 * 2 / 3; } y = iy; for (j=1; j 35)) { SumCt++; SumRed += (double) colour.rgb_Red; SumsqRed += ((double)colour.rgb_Red * (double)colour.rgb_Red); SumGreen += (double) colour.rgb_Green; SumsqGreen += ((double)colour.rgb_Green * (double)colour.rgb_Green); SumBlue += (double) colour.rgb_Blue; SumsqBlue += ((double)colour.rgb_Blue * (double)colour.rgb_Blue); } x += dx; } y += dy; } VarRed = (SumsqRed - (SumRed*SumRed / SumCt)) / SumCt; VarGreen = (SumsqGreen - (SumGreen*SumGreen / SumCt)) / SumCt; VarBlue = (SumsqBlue - (SumBlue*SumBlue / SumCt)) / SumCt; VarRed = VarRed * VarRed * VarRed * VarRed; VarGreen = VarGreen * VarGreen * VarGreen * VarGreen; VarBlue = VarBlue * VarBlue * VarBlue * VarBlue; VarTotal = VarRed + VarGreen + VarBlue + 1; rdi = (UWORD) (VarRed * 100 / VarTotal); gri = (UWORD) (VarGreen * 100 / VarTotal); bli = (UWORD) (100 - rdi - gri); SumCt = 1; SumsqTotal = 0; SumTotal = 0; y = iy; for (j=1; j 35)) { SumCt++; SumWork = ((double)colour.rgb_Red * (double)rdi + (double)colour.rgb_Green * (double)gri + (double)colour.rgb_Blue * (double)bli); SumTotal += SumWork; SumsqTotal += SumWork * SumWork; } x += dx; } y += dy; } AvgBright = (UWORD)(SumTotal / SumCt / 100); VarTotal = (SumsqTotal - (SumTotal * SumTotal / SumCt)) / SumCt; StdBright = (UWORD) sqrt(VarTotal) / 100; if (bright < 5) AvgBright = AvgBright + ((255 - AvgBright) * (5 - bright) / 8); else AvgBright = AvgBright - ((AvgBright) * (bright - 5) / 8); if (contrast < 5) StdBright = StdBright + (StdBright * (5 - contrast) / 5); else StdBright = StdBright - (StdBright * (contrast - 5) / 5); if (AvgBright < 20) AvgBright = 20; if (AvgBright > 230) AvgBright = 230; if (StdBright < AvgBright / 10) StdBright = AvgBright / 10; /* printf("\n %d %d",(int)AvgBright,(int)bright); printf(" %d %d",(int)StdBright,(int)contrast); */ StdBright = StdBright * 3 / 5; if (AvgBright > StdBright) Bright2 = AvgBright - StdBright; else Bright2 = AvgBright * 1 / 2; if ((AvgBright + StdBright) < 255) Bright3 = AvgBright + StdBright; else Bright3 = AvgBright + (255 - AvgBright) / 2; if (Bright2 > StdBright) Bright1 = Bright2 - StdBright; else Bright1 = Bright2 / 2; if ((255 - StdBright) > Bright3) Bright4 = Bright3 + StdBright; else Bright4 = (Bright3 + 255) / 2; /* printf("\n %f %f %f %f %f %f",SumsqRed,SumsqGreen,SumsqBlue,SumRed,SumGreen,SumBlue); printf("\n %f %f %f %u %u %u",VarRed,VarGreen,VarBlue,rdi,gri,bli); printf("\n %u %u %u %u %u %u ",AvgBright,StdBright,Bright1,Bright2,Bright3,Bright4); */ y=iy; for (j=0; j> 2; c2 = c2 >> 2; c3 = c3 >> 2; c4 = c4 >> 2; c5 = c5 >> 2; c6 = c6 >> 2; if (c1 < Bright1) c1=0; if (c1 >= Bright4) c1=4; if (c1 >= Bright3) c1=3; if (c1 >= Bright2) c1=2; if (c1 >= Bright1) c1=1; if (c2 < Bright1) c2=0; if (c2 >= Bright4) c2=4; if (c2 >= Bright3) c2=3; if (c2 >= Bright2) c2=2; if (c2 >= Bright1) c2=1; if (c3 < Bright1) c3=0; if (c3 >= Bright4) c3=4; if (c3 >= Bright3) c3=3; if (c3 >= Bright2) c3=2; if (c3 >= Bright1) c3=1; if (c4 < Bright1) c4=0; if (c4 >= Bright4) c4=4; if (c4 >= Bright3) c4=3; if (c4 >= Bright2) c4=2; if (c4 >= Bright1) c4=1; if (c5 < Bright1) c5=0; if (c5 >= Bright4) c5=4; if (c5 >= Bright3) c5=3; if (c5 >= Bright2) c5=2; if (c5 >= Bright1) c5=1; if (c6 < Bright1) c6=0; if (c6 >= Bright4) c6=4; if (c6 >= Bright3) c6=3; if (c6 >= Bright2) c6=2; if (c6 >= Bright1) c6=1; if (b_w) { c1 = 4 - c1; c2 = 4 - c2; c3 = 4 - c3; c4 = 4 - c4; c5 = 4 - c5; c6 = 4 - c6; } if (flag=='s') { Cbuf[0] = (char) asciisub [c1][c2][c3][c4][c5][c6]; if(fwrite(Cbuf,1,1,CAPT) != 1) { sprintf(errstring, "Unable to write to %s.\n", ascfile); ERROR(errstring); } } if (revealtype > 0) { rx = i + (80 - gx) / 2; ry = j + (24 - gy) / 2; if ((rx >= 0) & (ry >= 0) & (rx < 80) & (ry < 24)) RevealStore[ry][rx] = asciisub [c1][c2][c3][c4][c5][c6]; } printf("%c",asciisub [c1][c2][c3][c4][c5][c6]); x += dx; if (x < 0) return; } y+=dy; } } if (revealtype > 0) RevealImage( revealtype ); if (flag == 's') fclose(CAPT); } while (TRUE); } void ColourValue( int cx, int cy, int cxd, int cyd ) { int xm1, xp1, ym1, yp1; int xd, yd; double edge_y_rd, edge_x_rd; double edge_y_gr, edge_x_gr; double edge_y_bl, edge_x_bl; double edge_rd, edge_gr, edge_bl, edge_test; colour = LocalColourTable[BitPlane[cy][cx]]; if (edge_detect) { if (cx >= cxd) xm1 = cx - cxd; else xm1 = cx; if (cy >= cyd) ym1 = cy - cyd; else ym1 = cy; if (cx+cxd <= gx) xp1 = cx + cxd; else xp1 = cx; if (cy+cyd <= gy) yp1 = cy + cyd; else yp1 = cy; colour = LocalColourTable[BitPlane[ym1][cx]]; edge_y_rd = (double) colour.rgb_Red; edge_y_gr = (double) colour.rgb_Green; edge_y_bl = (double) colour.rgb_Blue; colour = LocalColourTable[BitPlane[yp1][cx]]; edge_y_rd -= (double) colour.rgb_Red; edge_y_gr -= (double) colour.rgb_Green; edge_y_bl -= (double) colour.rgb_Blue; edge_y_rd = edge_y_rd / 2 + 125; edge_y_gr = edge_y_gr / 2 + 125; edge_y_bl = edge_y_bl / 2 + 125; colour = LocalColourTable[BitPlane[cy][xm1]]; edge_x_rd = (double) colour.rgb_Red; edge_x_gr = (double) colour.rgb_Green; edge_x_bl = (double) colour.rgb_Blue; colour = LocalColourTable[BitPlane[cy][xp1]]; edge_x_rd -= (double) colour.rgb_Red; edge_x_gr -= (double) colour.rgb_Green; edge_x_bl -= (double) colour.rgb_Blue; edge_x_rd = edge_x_rd / 2 + 125; edge_x_gr = edge_x_gr / 2 + 125; edge_x_bl = edge_x_bl / 2 + 125; edge_test = edge_y_rd*edge_y_rd + edge_y_gr*edge_y_gr + edge_y_bl*edge_y_bl + edge_x_rd*edge_x_rd + edge_x_gr*edge_x_gr + edge_x_bl*edge_x_bl; edge_rd = sqrt(edge_y_rd*edge_y_rd + edge_x_rd*edge_x_rd) / 1.42; edge_gr = sqrt(edge_y_gr*edge_y_gr + edge_x_gr*edge_x_gr) / 1.42; edge_bl = sqrt(edge_y_bl*edge_y_bl + edge_x_bl*edge_x_bl) / 1.42; colour.rgb_Red = (UBYTE) edge_rd; colour.rgb_Green = (UBYTE) edge_gr; colour.rgb_Blue = (UBYTE) edge_bl; } } void RevealImage( int rvl_type ) { int x1,x2,x3,x4,y1,y2,y3,y4,r1,r2,r3,r4,c1,c2,c3,c4; char white_chars[9] = "\x1B[37;40m"; char black_chars[9] = "\x1B[30;47m"; char normal_chars[5] = "\x1B[0m"; char csi[3] = "\x1B["; char curs_up = 'A'; char curs_down = 'B'; char curs_left = 'D'; char curs_right = 'C'; char curs_pos = 'H'; char scroll_region = 'r'; char ch1,ch2,ch3,ch4; char rvlname [255]; int rnd_count = 0; switch (rvl_type) { case 1: /* in -> out */ strcpy(rvlname, rvlfile); strcat(rvlname, ".ito"); printf("\n\nCreating In-Out Reveal -> %s\n", rvlname); if (!(CAPT = fopen(rvlname,"wb"))) ERROR("Open error\n"); if (b_w) fprintf(CAPT,"%s",black_chars); else fprintf(CAPT,"%s",white_chars); x1 = 41; y1 = 13; x2 = x1 - 4; y2 = y1-1; while (x1 >= 4) { x1 -= 4; y1 -= 1; x2 += 4; y2 += 1; fprintf(CAPT,"%s%d;%d%c",csi,y1,x1,curs_pos); fwrite(&RevealStore[y1-1][x1-1],1,x2 - x1 + 4,CAPT); fprintf(CAPT,"%s%d;%d%c",csi,y2,x1,curs_pos); fwrite(&RevealStore[y2-1][x1-1],1,x2 - x1 + 4,CAPT); for (r1 = y1+1; r1 < y2; r1++) { if (r1 != y1 & r1 != y2) { fprintf(CAPT,"%s%d;%d%c",csi,r1,x1,curs_pos); fwrite(&RevealStore[r1-1][x1-1],1,4,CAPT); if (x2 > x1+4) fprintf(CAPT,"%s%d%c",csi,x2-x1-4,curs_right); fwrite(&RevealStore[r1-1][x2-1],1,4,CAPT); } } } fprintf(CAPT,"%s%d;%d%c",csi,2,1,curs_pos); fwrite(&RevealStore[1][0],1,80,CAPT); fprintf(CAPT,"%s%d;%d%c",csi,23,1,curs_pos); fwrite(&RevealStore[22][0],1,80,CAPT); fprintf(CAPT,"%s%d;%d%c",csi,1,1,curs_pos); fwrite(&RevealStore[0][0],1,80,CAPT); fprintf(CAPT,"%s%d;%d%c",csi,24,1,curs_pos); fwrite(&RevealStore[23][0],1,80,CAPT); fprintf(CAPT,"%s",normal_chars); fprintf(CAPT,"%s%d;%d%c",csi,1,1,curs_pos); fclose(CAPT); break; case 2: /* out -> in */ strcpy(rvlname, rvlfile); strcat(rvlname, ".oti"); printf("\n\nCreating Out-In Reveal -> %s\n", rvlname); if (!(CAPT = fopen(rvlname,"wb"))) ERROR("Open error\n"); if (b_w) fprintf(CAPT,"%s",black_chars); else fprintf(CAPT,"%s",white_chars); x1 = -3; y1 = 0; x2 = 81; y2 = 25; while (x1 + 4 < x2 - 4) { x1 += 4; y1 += 1; x2 -= 4; y2 -= 1; fprintf(CAPT,"%s%d;%d%c",csi,y1,x1,curs_pos); fwrite(&RevealStore[y1-1][x1-1],1,x2 - x1 + 4,CAPT); fprintf(CAPT,"%s%d;%d%c",csi,y2,x1,curs_pos); fwrite(&RevealStore[y2-1][x1-1],1,x2 - x1 + 4,CAPT); for (r1 = y1+1; r1 < y2; r1++) { if (r1 != y1 & r1 != y2) { fprintf(CAPT,"%s%d;%d%c",csi,r1,x1,curs_pos); fwrite(&RevealStore[r1-1][x1-1],1,4,CAPT); if (x2-x1-4 > 0) fprintf(CAPT,"%s%d%c",csi,x2-x1-4,curs_right); fwrite(&RevealStore[r1-1][x2-1],1,4,CAPT); } } } fprintf(CAPT,"%s",normal_chars); fprintf(CAPT,"%s%d;%d%c",csi,1,1,curs_pos); fclose(CAPT); break; case 3: /* left -> right */ strcpy(rvlname, rvlfile); strcat(rvlname, ".ltr"); printf("\n\nCreating Left-to-Right Reveal -> %s\n", rvlname); if (!(CAPT = fopen(rvlname,"wb"))) ERROR("Open error\n"); if (b_w) fprintf(CAPT,"%s",black_chars); else fprintf(CAPT,"%s",white_chars); x1 = -3; while (x1 < 77) { x1 += 4; for (r1 = 13; r1 <= 24; r1++) { fprintf(CAPT,"%s%d;%d%c",csi,r1,x1,curs_pos); fwrite(&RevealStore[r1-1][x1-1],1,4,CAPT); fprintf(CAPT,"%s%d;%d%c",csi,25-r1,x1,curs_pos); fwrite(&RevealStore[25-r1-1][x1-1],1,4,CAPT); } } fprintf(CAPT,"%s",normal_chars); fprintf(CAPT,"%s%d;%d%c",csi,1,1,curs_pos); fclose(CAPT); break; case 4: /* right -> left */ strcpy(rvlname, rvlfile); strcat(rvlname, ".rtl"); printf("\n\nCreating Right-to-Left Reveal -> %s\n", rvlname); if (!(CAPT = fopen(rvlname,"wb"))) ERROR("Open error\n"); if (b_w) fprintf(CAPT,"%s",black_chars); else fprintf(CAPT,"%s",white_chars); x1 = 81; while (x1 > 1) { x1 -= 4; for (r1 = 13; r1 <= 24; r1++) { fprintf(CAPT,"%s%d;%d%c",csi,r1,x1,curs_pos); fwrite(&RevealStore[r1-1][x1-1],1,4,CAPT); fprintf(CAPT,"%s%d;%d%c",csi,25-r1,x1,curs_pos); fwrite(&RevealStore[25-r1-1][x1-1],1,4,CAPT); } } fprintf(CAPT,"%s",normal_chars); fprintf(CAPT,"%s%d;%d%c",csi,1,1,curs_pos); fclose(CAPT); break; case 5: /* sides -> in */ strcpy(rvlname, rvlfile); strcat(rvlname, ".sin"); printf("\n\nCreating Sides->In Reveal -> %s\n", rvlname); if (!(CAPT = fopen(rvlname,"wb"))) ERROR("Open error\n"); if (b_w) fprintf(CAPT,"%s",black_chars); else fprintf(CAPT,"%s",white_chars); x1 = -3; x2 = 81; while (x1 + 4 < x2 - 4) { x1 += 4; x2 -= 4; for (r1 = 13; r1 <= 24; r1++) { fprintf(CAPT,"%s%d;%d%c",csi,r1,x1,curs_pos); fwrite(&RevealStore[r1-1][x1-1],1,4,CAPT); if (x2-x1-4 > 0) fprintf(CAPT,"%s%d%c",csi,x2-x1-4,curs_right); fwrite(&RevealStore[r1-1][x2-1],1,4,CAPT); fprintf(CAPT,"%s%d;%d%c",csi,25-r1,x1,curs_pos); fwrite(&RevealStore[25-r1-1][x1-1],1,4,CAPT); if (x2-x1-4 > 0) fprintf(CAPT,"%s%d%c",csi,x2-x1-4,curs_right); fwrite(&RevealStore[25-r1-1][x2-1],1,4,CAPT); } } fprintf(CAPT,"%s",normal_chars); fprintf(CAPT,"%s%d;%d%c",csi,1,1,curs_pos); fclose(CAPT); break; case 6: /* random */ strcpy(rvlname, rvlfile); strcat(rvlname, ".rnd"); printf("\n\nCreating Random Reveal -> %s\n", rvlname); if (!(CAPT = fopen(rvlname,"wb"))) ERROR("Open error\n"); if (b_w) fprintf(CAPT,"%s",black_chars); else fprintf(CAPT,"%s",white_chars); rnd_count = 0; while (rnd_count++ < 2000) { x1 = 4 * ( abs( (int)(rand() / 12 ) % 20 ) ); y1 = 1 * ( abs( (int)(rand() / 12 ) % 24 ) ); if (RevealStore[y1][x1] != 0) { fprintf(CAPT,"%s%d;%d%c",csi,y1+1,x1+1,curs_pos); fwrite(&RevealStore[y1][x1],1,4,CAPT); RevealStore[y1][x1] = 0; } } x1 = -3; x2 = 81; while (x1 + 4 < x2 - 4) { x1 += 4; x2 -= 4; for (r1 = 13; r1 <= 24; r1++) { if (RevealStore[r1-1][x1-1] != 0) { fprintf(CAPT,"%s%d;%d%c",csi,r1,x1,curs_pos); fwrite(&RevealStore[r1-1][x1-1],1,4,CAPT); } if (RevealStore[r1-1][x2-1] != 0) { fprintf(CAPT,"%s%d;%d%c",csi,r1,x2,curs_pos); fwrite(&RevealStore[r1-1][x2-1],1,4,CAPT); } if (RevealStore[25-r1-1][x1-1] != 0) { fprintf(CAPT,"%s%d;%d%c",csi,25-r1,x1,curs_pos); fwrite(&RevealStore[25-r1-1][x1-1],1,4,CAPT); } if (RevealStore[25-r1-1][x2-1] != 0) { if (x2-x1-4 > 0) fprintf(CAPT,"%s%d;%d%c",csi,25-r1,x2,curs_pos); fwrite(&RevealStore[25-r1-1][x2-1],1,4,CAPT); } } } fprintf(CAPT,"%s",normal_chars); fprintf(CAPT,"%s%d;%d%c",csi,1,1,curs_pos); fclose(CAPT); break; } } -- Warning: .signature files should be no longer than 4 lines. (Only 4 lines of your .signature were posted.) ___MMM___ AARRRGGGHHH.....I hate this :-) (snipit from my newsreader) (0-0) e-mail: nodland@kari.fm.unit.no -------------------------------oOO--(_)--OOo--