-pm0-LV5 ENCODER.Cï/* * GIF Encoder and associated routines * scancode adapted from fractint */ #include #include #include #define XOR (unsigned char)3 extern void pset(); /* pset(x,y,color,logop) */ extern unsigned char point(); /* color=point(x,y) */ extern int getch(); extern int xdots,ydots,colors; extern unsigned char bitsperpixel,interlaced; extern FILE * fout; #define MAXTEST 100 #define MAXENTRY 4093 /* a prime number is best for hashing */ #define MAXSTRING 16384 #define toextra(a,b,c) memcpy((char *)&buffer+a,b,c) #define cmpextra(a,b,c) memcmp((char *)&buffer+a,b,c) static unsigned char buffer[MAXSTRING]; static int strlocn[MAXENTRY]; static int entrynum[MAXENTRY]; static unsigned char teststring[MAXTEST]; static int lentest, lastentry, numentries, numrealentries, nextentry; static int clearcode, endcode; static unsigned int hashcode; static unsigned char blockcount, block[266]; static int startbits, codebits, bytecount, bitcount; static int i, ydot, xdot, color; static unsigned int hashentry; scandots() { color = point(xdot,ydot); /* get the next dot */ pset(xdot,ydot,255,XOR); /* show progress */ teststring[0] = ++lentest; teststring[lentest] = color; if (lentest == 1) { /* root entry? */ lastentry = color; return; } if (lentest == 2) /* init the hash code */ hashcode = 301 * (teststring[1]+1); hashcode *= (color + lentest); /* update the hash code */ hashentry = ++hashcode % MAXENTRY; for( i = 0; i < MAXENTRY; i++) { if (++hashentry >= MAXENTRY) hashentry = 0; if (cmpextra(strlocn[hashentry], teststring,lentest+1) == 0) break; if (strlocn[hashentry] == 0) i = MAXENTRY; } /* found an entry and string length isn't too bad */ if (strlocn[hashentry] != 0 && lentest < MAXTEST-3) { lastentry = entrynum[hashentry]; return; } raster(lastentry); /* write entry */ numentries++; /* act like you added one, anyway */ if (strlocn[hashentry] == 0) { /* add new string, if any */ entrynum[hashentry] = numentries+endcode; strlocn[hashentry] = nextentry; toextra(nextentry, teststring,lentest+1); nextentry += lentest+1; numrealentries++; } teststring[0] = 1; /* reset current entry */ teststring[1] = color; lentest = 1; lastentry = color; if ((numentries+endcode) == (1< 4093 || /* out of room? */ numrealentries > (MAXENTRY*2)/3 || nextentry > MAXSTRING-MAXTEST-3) { raster(lastentry); /* flush & restart */ inittable(); } } savepicture() /* save-to-disk routine */ { int kydot,gydot; di(); startbits = bitsperpixel+1; /* start coding with this many bits */ if (colors == 2) startbits++; /* B&W Klooge */ clearcode = 1<<(startbits-1); /* set clear and end codes */ endcode = clearcode+1; bitsperpixel = startbits - 1; /* raster data starts here */ if(interlaced) bitsperpixel += 0x40; /* set interlaced bit */ fwrite(&bitsperpixel,1,1,fout); codebits = startbits; /* start encoding */ raster(9999); /* initialize the raster routine */ inittable(); /* initialize the LZW tables */ di(); ydots++; /* +1 for loop */ if (!interlaced) for (ydot = 0; ydot < ydots; ydot++) /* scan through the dots */ for (xdot = 0; xdot < xdots; xdot++) scandots(); else /* if(interlaced) */ for (gydot = 0; gydot < 4; gydot++) for (kydot = 0; kydot < ydots; kydot += 4) for (xdot = 0; xdot < xdots; xdot++) { ydot = gydot+kydot; scandots(); } raster(lastentry); /* tidy up - dump the last code */ raster(endcode); /* finish the map */ i = 0; /* raster data ends here */ fwrite(&i,1,1,fout); fwrite(";",1,1,fout); /* GIF Terminator */ fclose(fout); ei(); beep(); } inittable() /* routine to init tables */ { int i; raster(clearcode); /* signal that table is initialized */ numentries = 0; /* initialize the table */ numrealentries = 0; nextentry = 1; lentest = 0; codebits = startbits; toextra(0,"\0",1); /* clear the hash entries */ for (i = 0; i < MAXENTRY; i++) strlocn[i] = 0; } raster(code) /* routine to block and output codes */ unsigned int code; { unsigned int icode, i, j; if (code == 9999) { /* special start-up signal */ bytecount = 0; bitcount = 0; for (i = 0; i < 266; i++) block[i] = 0; return; } icode = code << bitcount; /* update the bit string */ block[bytecount ] |= (icode & 255); block[bytecount+1] |= ((icode>>8) & 255); icode = (code>>8) << bitcount; block[bytecount+2] |= ((icode>>8) & 255); bitcount += codebits; while (bitcount >= 8) { /* locate next starting point */ bitcount -= 8; bytecount++; } if (bytecount > 250 || code == endcode) { /* time to write a block */ if (code == endcode) while (bitcount > 0) { /* if EOF, find the real end */ bitcount -= 8; bytecount++; } i = bytecount; blockcount = i; fwrite(&blockcount,1,1,fout); /* write the block */ fwrite(block,i,1,fout); bytecount = 0; /* now re-start the block */ for (j = 0; j < 5; j++) /* (may have leftover bits) */ block[j] = block[j+i]; for (j = 5; j < 266; j++) block[j] = 0; } } #asm global _savepicture,_bitsperpixel,_fout global _xdots,_ydots,_colors,_interlaced,_buffer #endasm ù-pm0- 6 ENGIF.C_/* * Gif encoder part 1 * PD by PGN 1/94 * N.b. interlaced GIF werkt nog niet naar behoren */ #include #include #include extern int getch(); extern char toupper(char); extern void savepicture(); void getgraphinfo(); #define MAXSTRING 16380 extern char buffer[MAXSTRING]; #define SCRNUM 8 /* screen mode */ static FILE *fin, *fout; /* infile, outfile */ static unsigned int xdots,ydots; /* # of dots on the screen */ static unsigned int colors; /* maximum colors available */ static unsigned char bitsperpixel; /* bits per pixel */ static unsigned char interlaced=0; /* make interlaced gif */ static unsigned char screennum=SCRNUM; /* screen mode (5,7,8) */ static unsigned int r,g,b; /* palette values */ main(argc, argv) char ** argv; { char usepalet = 0; unsigned int sa,ea,dx; char * p; static char infile[65]; static char outfile[65]; static char palfile[65]; FILE * palet; puts("ENGIF 1.0á --PGN 1994"); puts("Convert MSX screen 5/7/8 pictures to GIF\n"); if(argc == 1) { puts("USE: ENGIF [/Ppalette] [/{5|7|8}]\n"); puts("The input file must be a picture saved with BLOAD \"file\",0,?????,S"); puts("The palette file for screen 5 pictures must be a binary copy of VRAM"); puts("from &h07680 to &h769F.\n"); puts("The output file will be named after the input file with extension GIF."); puts("Option /5 /7 or /8 selects a certain screen mode (default is 8)"); /* puts("Option /I saves the GIF picture interlaced."); */ puts("\r\nThis program is Public Domain software. Do with it what you like."); exit(-1); } if(argc > 2) { for(dx=1; dx %s",infile,outfile); if(interlaced) puts(" (interlaced)"); else puts(" "); if(usepalet) { printf("Using palette %s\n",palfile); palet = fopen(palfile,"rb"); if(palet==NULL) { printf("*** Palette %s not found\n",palfile); exit(-1); } fread(palfile,39,1,palet); /* 7 bytes header + data */ fclose(palet); /* close paletfile */ } fin = fopen(infile,"rb"); if(fin==NULL) { printf("*** %s not found\n",infile); exit(-1); } fread(buffer,7,1,fin); if ((unsigned char)buffer[0]!=0xfe) { printf("*** %s is not a binary picture\n",infile); exit(-1); } sa = buffer[1]+(buffer[2] << 8); ea = buffer[3]+(buffer[4] << 8); printf("\n Start: %u\n",sa); printf(" End: %u\n",ea); printf("Length: %u\n\n",ea-sa); puts("Press any key to load the picture. When you hear the beep,"); printf("press [S] to save the GIF file or [ESC] to quit."); getch(); di(); ginit(); if(screennum==8) colors=256; else colors=16; screen(screennum); while((dx=fread(buffer,1,MAXSTRING,fin)) > 0) { ldirvm(sa,&buffer,dx); sa += dx; } fclose(fin); /* close infile */ if(usepalet) ldirvm(0x7680,&palfile+7,32); /* copy palette to VRAM */ rstplt(); /* restore palette */ ei(); do { beep(); dx=toupper((char)getch()); } while((dx!=27) && (dx!='S')); /* get ESC or S */ if(dx=='S') { fout = fopen(outfile,"wb"); /* open GIF file */ if(fout==NULL) { totext(); iniplt(); printf("*** Can't open %s\n",outfile); exit(-1); } getgraphinfo(); /* write GIF header */ savepicture(); /* write GIF picture */ fclose(fout); /* close GIF */ } totext(); iniplt(); } void getpalet(unsigned int c) { unsigned int i; if(screennum==8) { r = ((c >> 2) & 7); g = ((c >> 5) & 7); b = (c & 3) * 2; } else { i = getplt(c); r = ((i >> 4) & 7); g = ((i >> 8) & 7); b = (i & 7); } r *= 36; g *= 36; b *= 36; } void getgraphinfo() { static unsigned int i,x; fwrite("GIF87a",1,6,fout); /* GIF Signature */ xdots = gtxmax(); ydots = gtymax(); fwrite(&xdots,2,1,fout); /* screen descriptor */ fwrite(&ydots,2,1,fout); bitsperpixel = 0; /* calculate bits / pixel */ for(i=colors;i>=2;i/=2) bitsperpixel++; i = bitsperpixel-1; /* color resolution -1 */ x = 0x80 + (i << 4) + i; fwrite(&x,1,1,fout); i = (*(unsigned char *)0xf3ea); /* background color */ fwrite(&i,1,1,fout); i = 0; fwrite(&i,1,1,fout); /* NULL */ for(i=0;i