home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / ddjcompr / hstest / src / hstest.c < prev    next >
C/C++ Source or Header  |  1991-04-28  |  7KB  |  320 lines

  1. //
  2. // HSTEST.C
  3. // this is a little demo & test programm for the kombination
  4. // sliding directory & huffman compression
  5. // the real kompression is done using a sliding directory mechanism pack(),
  6. // which will eventually be farther compressed using a modified huffman
  7. // method which takes some time as well, is currently not very efficient
  8. // implemented, but may be used if space is really important,
  9. // the first method should be chosen if the unpack time is of importance
  10. // unpack(), written in assembler for speed reasons roughly decompresses
  11. // some 25 KByte / Landmark or 1 MB on a 25 MHz 386 maschine
  12. //
  13. // warning : the code is not yet clean for byte ordering, it will work
  14. // only on one type of maschine, the compressed files are probable not
  15. // (yet) portable
  16. //
  17.  
  18. #include <stdio.h>
  19. #include <fcntl.h>
  20. #include <sys\types.h>
  21. #include <sys\stat.h>
  22. #include <io.h>
  23.  
  24. #include <tomlib.h>
  25.  
  26. #include "pack.h"
  27.  
  28. #define BUFFSIZE 0xf000
  29.  
  30. char  far *inbuff = NULL;
  31. char  far * pbuff = NULL;
  32. char  far * hbuff = NULL;
  33. char  far *outbuff = NULL;
  34.  
  35. long p_hufflen = 0;
  36. long p_huffsum = 0;
  37. long p_nohuff  = 0;
  38. long p_huffind = 0;
  39. long p_match,p_nmatch;
  40.  
  41. int fullprint = 0;
  42.  
  43. usage()
  44. {
  45.     printf(
  46.         "HSTEST infile outfile [-options]\n"
  47.         "                     options are\n"
  48.         "    -Uncompress infile to outfile, default is compress\n"
  49.         "    -Full (and slow) compression, default is fast mode\n"
  50.         "    -S print statistics\n"
  51.         "    -Quiet mode\n"
  52.         "        have Fun! tom ehlert\n");
  53.     exit(1);
  54. }
  55.  
  56. int extract         = FALSE;
  57. int fullcompression = FALSE;
  58. int statistics         = FALSE;
  59. int quiet           = FALSE;
  60. int     fdin = 0
  61.         ,fdout = 0;
  62.  
  63.  
  64. //********************************************************************
  65. // some support code
  66. //********************************************************************
  67. void qprintf(char *s)
  68. {
  69.     if (!quiet)
  70.         printf(s);
  71. }
  72.  
  73.  
  74. main(int argc,char *argv[])
  75. {
  76.     unsigned loop,anzblocks;
  77.     char *argptr;
  78.  
  79.     while (argptr = getargs(&argc,argv,"/-"))
  80.         while (*++argptr)
  81.             switch(toupper(*argptr))
  82.                 {
  83.                 case 'U' : extract             = TRUE; break;
  84.                 case 'F' : fullcompression     = TRUE; break;
  85.                 case 'S' : statistics         = TRUE; break;
  86.                 case 'Q' : quiet             = TRUE; break;
  87.                 default  : usage();
  88.                 }
  89.  
  90.     if (argc != 3)
  91.         {
  92.         usage();
  93.         }
  94.  
  95.     if ((fdin = open(argv[1],O_RDONLY | O_BINARY)) < 0)
  96.         {
  97.         printf("can't read %s",argv[1]);
  98.         exit(1);
  99.         }
  100.  
  101.     if ((fdout = open(argv[2],O_WRONLY | O_BINARY | O_CREAT | O_TRUNC,
  102.                             S_IREAD|S_IWRITE)) < 0)
  103.         {
  104.         printf("can't write %s",argv[2]);
  105.         exit(1);
  106.         }
  107.  
  108.  
  109.     if ((inbuff  = dosalloc((long)BUFFSIZE)) == NULL ||
  110.         ( pbuff  = dosalloc((long)BUFFSIZE)) == NULL ||
  111.         ( hbuff  = dosalloc((long)BUFFSIZE)) == NULL ||
  112.         (outbuff = dosalloc((long)BUFFSIZE)) == NULL )
  113.         {
  114.         printf("can't allocate enough memory for buffers");
  115.         exit(1);
  116.         }
  117.  
  118.     tx_init();                // that supports my own custom profiler
  119.                             // forget it
  120.  
  121.     if (!quiet)
  122.         {
  123.         anzblocks = (unsigned)((filelength(fdin)+(BUFFSIZE-1))/BUFFSIZE);
  124.         for (loop = 0; loop < anzblocks; loop++)
  125.             printf("@");
  126.         for (loop = 0; loop < anzblocks; loop++)
  127.             printf("\b");
  128.         }
  129.  
  130.     if (extract)
  131.         decompress();
  132.     else
  133.         compress();
  134. }
  135.  
  136. // this is used for the statistic
  137.         
  138. long rd_time = 0;
  139. long wr_time = 0;
  140. long pack_time = 0;
  141. long huff_time = 0;
  142. long unpack_time = 0;
  143.  
  144. long insum = 0;
  145. long psum  = 0;
  146. long hsum  = 0;
  147. long osum  = 0;
  148.  
  149. # define NOT_COMPRESSED (('N'<<8)|'C')
  150. # define  HS_COMPRESSED (('H'<<8)|'S')
  151. # define  SL_COMPRESSED (('S'<<8)|'L')
  152.  
  153.  
  154. do_write(unsigned mode,unsigned length,void far *buffer)
  155. {
  156.     osum += length;
  157.     mikro_diff();
  158.     far_write(fdout,&mode,2);
  159.     far_write(fdout,&length,2);
  160.     far_write(fdout,buffer,length);
  161.     wr_time += mikro_diff();
  162.     qprintf("W");
  163. }
  164.  
  165. compress()
  166. {
  167.     unsigned rd,plen,hlen;
  168.     unsigned long ltime;
  169.  
  170.     far_write(fdout,"te",2);                          // justy write my initials
  171.                                                 // to begin of file
  172.  
  173.     while (1)
  174.         {
  175.         mikro_diff();                            // perform time analysis
  176.                                                 // for each function
  177.         if ((rd    = far_read(fdin,inbuff,BUFFSIZE)) == 0)
  178.             break;
  179.         rd_time += mikro_diff();
  180.  
  181.         qprintf("R\b");
  182.  
  183.         insum += rd;
  184.  
  185.         mikro_diff();
  186.         plen = pack (pbuff,rd,inbuff,rd);        // PACK
  187.         pack_time += mikro_diff();
  188.  
  189.         if (fullprint)
  190.             printf("%5u packed packlen %5u --> time %5ld \n",rd,plen,ltime);
  191.  
  192.         qprintf("P\b");
  193.  
  194.         if (plen == 0xffff || plen >= rd)
  195.             {
  196.             psum += rd;
  197.             hsum += rd;
  198.             do_write(NOT_COMPRESSED,rd,inbuff);
  199.             continue;
  200.             }
  201.  
  202.         psum += plen;
  203.  
  204.         if (fullcompression)
  205.             {
  206.             mikro_diff();
  207.             hlen = hs_pack (hbuff,plen,pbuff,plen);
  208.             huff_time += mikro_diff();
  209.             qprintf("p\b");
  210.  
  211.             if (hlen != 0xffff && hlen < plen)
  212.                 {
  213.                 hsum += hlen;
  214.                 do_write(HS_COMPRESSED,hlen,hbuff);
  215.                 continue;
  216.                 }
  217.             }
  218.         hsum += plen;
  219.         do_write(SL_COMPRESSED,plen,pbuff);
  220.         }
  221.  
  222.     if (statistics)
  223.         {
  224.         qprintf("\n");
  225.         printf("kompressed %ld Bytes down to %ld ",insum,osum);
  226.         if (fullcompression)
  227.             printf("(packsize %ld",psum);
  228.         printf("\n");
  229.  
  230.         printf("times (in ms) : reading %ld writing %ld packing %ld",
  231.             rd_time/1000,wr_time/1000,pack_time/1000);
  232.         if(fullcompression)
  233.             printf(" huffing %ld",huff_time / 1000);
  234.         printf("\n");
  235.         }
  236. }
  237.  
  238.  
  239. decompress()
  240. {
  241.     char b[2];
  242.     unsigned rd,mode,ulen,length;
  243.  
  244.     read(fdin,b,2);
  245.  
  246.     if (memcmp(b,"te",2))
  247.         quit("this is no known kompressed file,sorry\n");
  248.  
  249.     while (1)
  250.         {
  251.         mikro_diff();                            // perform time analysis
  252.                                                 // for each function
  253.         if ((rd    = far_read(fdin,&mode,2)) != 2)
  254.             {
  255.             if (rd == 0)                        // assume we are ready
  256.                 break;
  257.  
  258.             quit("error reading input file\n");
  259.             }
  260.  
  261.  
  262.         if ((rd    = far_read(fdin,&length,2)) != 2)
  263.             quit("error reading input file\n");
  264.  
  265.         if ((rd    = far_read(fdin,inbuff,length)) != length)
  266.             quit("error reading input file\n");
  267.  
  268.         rd_time += mikro_diff();
  269.  
  270.         qprintf("R\b");
  271.  
  272.         insum += rd;
  273.  
  274.         mikro_diff();
  275.         switch(mode)
  276.             {
  277.             case NOT_COMPRESSED: 
  278.                 mikro_diff();
  279.                 far_write(fdout,inbuff,length);
  280.                 wr_time += mikro_diff();
  281.                 qprintf("W");
  282.                 osum += length;
  283.                 break;
  284.  
  285.             case HS_COMPRESSED: 
  286.                 mikro_diff();
  287.                 ulen = hs_unpack(outbuff,inbuff,length);
  288.                 unpack_time += mikro_diff();
  289.                 qprintf("U\b");
  290.  
  291.                 far_write(fdout,outbuff,ulen);
  292.                 wr_time += mikro_diff();
  293.                 qprintf("W");
  294.                 osum += ulen;
  295.                 break;
  296.  
  297.             case SL_COMPRESSED: 
  298.                 mikro_diff();
  299.                 ulen = unpack(outbuff,inbuff,length);
  300.                 unpack_time += mikro_diff();
  301.                 qprintf("U\b");
  302.  
  303.                 far_write(fdout,outbuff,ulen);
  304.                 wr_time += mikro_diff();
  305.                 qprintf("W");
  306.                 osum += ulen;
  307.                 break;
  308.             }
  309.         }
  310.  
  311.     if (statistics)
  312.         {
  313.         qprintf("\n");
  314.         printf("decompressed %ld Bytes to %ld\n",insum,osum);
  315.  
  316.         printf("times (in ms) : reading %ld writing %ld unpacking %ld\n",
  317.             rd_time/1000,wr_time/1000,unpack_time/1000);
  318.         }
  319. }
  320.