home *** CD-ROM | disk | FTP | other *** search
- //
- // HSTEST.C
- // this is a little demo & test programm for the kombination
- // sliding directory & huffman compression
- // the real kompression is done using a sliding directory mechanism pack(),
- // which will eventually be farther compressed using a modified huffman
- // method which takes some time as well, is currently not very efficient
- // implemented, but may be used if space is really important,
- // the first method should be chosen if the unpack time is of importance
- // unpack(), written in assembler for speed reasons roughly decompresses
- // some 25 KByte / Landmark or 1 MB on a 25 MHz 386 maschine
- //
- // warning : the code is not yet clean for byte ordering, it will work
- // only on one type of maschine, the compressed files are probable not
- // (yet) portable
- //
-
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys\types.h>
- #include <sys\stat.h>
- #include <io.h>
-
- #include <tomlib.h>
-
- #include "pack.h"
-
- #define BUFFSIZE 0xf000
-
- char far *inbuff = NULL;
- char far * pbuff = NULL;
- char far * hbuff = NULL;
- char far *outbuff = NULL;
-
- long p_hufflen = 0;
- long p_huffsum = 0;
- long p_nohuff = 0;
- long p_huffind = 0;
- long p_match,p_nmatch;
-
- int fullprint = 0;
-
- usage()
- {
- printf(
- "HSTEST infile outfile [-options]\n"
- " options are\n"
- " -Uncompress infile to outfile, default is compress\n"
- " -Full (and slow) compression, default is fast mode\n"
- " -S print statistics\n"
- " -Quiet mode\n"
- " have Fun! tom ehlert\n");
- exit(1);
- }
-
- int extract = FALSE;
- int fullcompression = FALSE;
- int statistics = FALSE;
- int quiet = FALSE;
- int fdin = 0
- ,fdout = 0;
-
-
- //********************************************************************
- // some support code
- //********************************************************************
- void qprintf(char *s)
- {
- if (!quiet)
- printf(s);
- }
-
-
- main(int argc,char *argv[])
- {
- unsigned loop,anzblocks;
- char *argptr;
-
- while (argptr = getargs(&argc,argv,"/-"))
- while (*++argptr)
- switch(toupper(*argptr))
- {
- case 'U' : extract = TRUE; break;
- case 'F' : fullcompression = TRUE; break;
- case 'S' : statistics = TRUE; break;
- case 'Q' : quiet = TRUE; break;
- default : usage();
- }
-
- if (argc != 3)
- {
- usage();
- }
-
- if ((fdin = open(argv[1],O_RDONLY | O_BINARY)) < 0)
- {
- printf("can't read %s",argv[1]);
- exit(1);
- }
-
- if ((fdout = open(argv[2],O_WRONLY | O_BINARY | O_CREAT | O_TRUNC,
- S_IREAD|S_IWRITE)) < 0)
- {
- printf("can't write %s",argv[2]);
- exit(1);
- }
-
-
- if ((inbuff = dosalloc((long)BUFFSIZE)) == NULL ||
- ( pbuff = dosalloc((long)BUFFSIZE)) == NULL ||
- ( hbuff = dosalloc((long)BUFFSIZE)) == NULL ||
- (outbuff = dosalloc((long)BUFFSIZE)) == NULL )
- {
- printf("can't allocate enough memory for buffers");
- exit(1);
- }
-
- tx_init(); // that supports my own custom profiler
- // forget it
-
- if (!quiet)
- {
- anzblocks = (unsigned)((filelength(fdin)+(BUFFSIZE-1))/BUFFSIZE);
- for (loop = 0; loop < anzblocks; loop++)
- printf("@");
- for (loop = 0; loop < anzblocks; loop++)
- printf("\b");
- }
-
- if (extract)
- decompress();
- else
- compress();
- }
-
- // this is used for the statistic
-
- long rd_time = 0;
- long wr_time = 0;
- long pack_time = 0;
- long huff_time = 0;
- long unpack_time = 0;
-
- long insum = 0;
- long psum = 0;
- long hsum = 0;
- long osum = 0;
-
- # define NOT_COMPRESSED (('N'<<8)|'C')
- # define HS_COMPRESSED (('H'<<8)|'S')
- # define SL_COMPRESSED (('S'<<8)|'L')
-
-
- do_write(unsigned mode,unsigned length,void far *buffer)
- {
- osum += length;
- mikro_diff();
- far_write(fdout,&mode,2);
- far_write(fdout,&length,2);
- far_write(fdout,buffer,length);
- wr_time += mikro_diff();
- qprintf("W");
- }
-
- compress()
- {
- unsigned rd,plen,hlen;
- unsigned long ltime;
-
- far_write(fdout,"te",2); // justy write my initials
- // to begin of file
-
- while (1)
- {
- mikro_diff(); // perform time analysis
- // for each function
- if ((rd = far_read(fdin,inbuff,BUFFSIZE)) == 0)
- break;
- rd_time += mikro_diff();
-
- qprintf("R\b");
-
- insum += rd;
-
- mikro_diff();
- plen = pack (pbuff,rd,inbuff,rd); // PACK
- pack_time += mikro_diff();
-
- if (fullprint)
- printf("%5u packed packlen %5u --> time %5ld \n",rd,plen,ltime);
-
- qprintf("P\b");
-
- if (plen == 0xffff || plen >= rd)
- {
- psum += rd;
- hsum += rd;
- do_write(NOT_COMPRESSED,rd,inbuff);
- continue;
- }
-
- psum += plen;
-
- if (fullcompression)
- {
- mikro_diff();
- hlen = hs_pack (hbuff,plen,pbuff,plen);
- huff_time += mikro_diff();
- qprintf("p\b");
-
- if (hlen != 0xffff && hlen < plen)
- {
- hsum += hlen;
- do_write(HS_COMPRESSED,hlen,hbuff);
- continue;
- }
- }
- hsum += plen;
- do_write(SL_COMPRESSED,plen,pbuff);
- }
-
- if (statistics)
- {
- qprintf("\n");
- printf("kompressed %ld Bytes down to %ld ",insum,osum);
- if (fullcompression)
- printf("(packsize %ld",psum);
- printf("\n");
-
- printf("times (in ms) : reading %ld writing %ld packing %ld",
- rd_time/1000,wr_time/1000,pack_time/1000);
- if(fullcompression)
- printf(" huffing %ld",huff_time / 1000);
- printf("\n");
- }
- }
-
-
- decompress()
- {
- char b[2];
- unsigned rd,mode,ulen,length;
-
- read(fdin,b,2);
-
- if (memcmp(b,"te",2))
- quit("this is no known kompressed file,sorry\n");
-
- while (1)
- {
- mikro_diff(); // perform time analysis
- // for each function
- if ((rd = far_read(fdin,&mode,2)) != 2)
- {
- if (rd == 0) // assume we are ready
- break;
-
- quit("error reading input file\n");
- }
-
-
- if ((rd = far_read(fdin,&length,2)) != 2)
- quit("error reading input file\n");
-
- if ((rd = far_read(fdin,inbuff,length)) != length)
- quit("error reading input file\n");
-
- rd_time += mikro_diff();
-
- qprintf("R\b");
-
- insum += rd;
-
- mikro_diff();
- switch(mode)
- {
- case NOT_COMPRESSED:
- mikro_diff();
- far_write(fdout,inbuff,length);
- wr_time += mikro_diff();
- qprintf("W");
- osum += length;
- break;
-
- case HS_COMPRESSED:
- mikro_diff();
- ulen = hs_unpack(outbuff,inbuff,length);
- unpack_time += mikro_diff();
- qprintf("U\b");
-
- far_write(fdout,outbuff,ulen);
- wr_time += mikro_diff();
- qprintf("W");
- osum += ulen;
- break;
-
- case SL_COMPRESSED:
- mikro_diff();
- ulen = unpack(outbuff,inbuff,length);
- unpack_time += mikro_diff();
- qprintf("U\b");
-
- far_write(fdout,outbuff,ulen);
- wr_time += mikro_diff();
- qprintf("W");
- osum += ulen;
- break;
- }
- }
-
- if (statistics)
- {
- qprintf("\n");
- printf("decompressed %ld Bytes to %ld\n",insum,osum);
-
- printf("times (in ms) : reading %ld writing %ld unpacking %ld\n",
- rd_time/1000,wr_time/1000,unpack_time/1000);
- }
- }
-