Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #include "mhmt-types.h"
  6. #include "mhmt-globals.h"
  7. #include "mhmt-depack.h"
  8. #include "mhmt-lz.h"
  9. #include "mhmt-emit.h"
  10.  
  11.  
  12. ULONG buf_size=0;
  13. ULONG buf_ptr=0;
  14. UBYTE * buffer=NULL;
  15.  
  16. LONG backptr, frontptr;
  17.  
  18.  
  19. ULONG depack(void)
  20. {
  21.         ULONG (*checker) (void) = NULL;
  22.         ULONG (*depacker)(void) = NULL;
  23.  
  24.  
  25.         ULONG success=1;
  26.  
  27.  
  28.         // some preparations
  29.         //
  30.         if( wrk.packtype==PK_MLZ )
  31.         {
  32.                 checker  = &checker_megalz;
  33.                 depacker = &depacker_megalz;
  34.         }
  35.         else if( wrk.packtype==PK_HRM )
  36.         {
  37.                 checker  = &checker_hrum;
  38.                 depacker = &depacker_hrum;
  39.         }
  40.         else if( wrk.packtype==PK_HST )
  41.         {
  42. //              checker  = &checker_hrust;
  43.                 depacker = &depacker_hrust;
  44.         }
  45.         else if( wrk.packtype==PK_ZX7 )
  46.         {
  47.                 checker  = &checker_zx7;
  48.                 depacker = &depacker_zx7;
  49.         }
  50.         else
  51.         {
  52.                 printf("mhmt-depack.c:depack() - format unsupported!\n");
  53.                 return 0;
  54.         }
  55.  
  56.  
  57.  
  58.         // allocate buffer used for depacking
  59.         //
  60.         //////buf_size = ( wrk.maxwin==4352 ) ? 8192 : wrk.maxwin; // provided there are no other non-2^n sizes
  61.         if( wrk.maxwin==4352 )
  62.                 buf_size = 8192;
  63.         else if( wrk.maxwin==2176 )
  64.                 buf_size = 4096;
  65.         else
  66.                 buf_size = wrk.maxwin;
  67.  
  68.  
  69.         buffer=(UBYTE*)malloc(buf_size);
  70.         if( !buffer )
  71.         {
  72.                 printf("mhmt-depack.c:depack() cannot allocate memory for depack buffer!\n");
  73.                 return 0;
  74.         }
  75.  
  76.         buf_ptr=0;
  77.  
  78.  
  79.         success = success && emit_file(NULL,EMIT_FILE_INIT);
  80.  
  81.         if( wrk.packtype==PK_MLZ || wrk.packtype==PK_ZX7 )
  82.                 success = success && (*checker) ();
  83.  
  84. //#ifdef DBG
  85. //      printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n");
  86. //#endif
  87.  
  88.  
  89.         depack_outbyte( 0, DEPACK_OUTBYTE_INIT );
  90.  
  91.         success = success && (*depacker)();
  92.  
  93.         /*success = success && */depack_outbyte( 0, DEPACK_OUTBYTE_FLUSH );
  94.  
  95.         /*success = success && */emit_file(NULL,EMIT_FILE_FINISH);
  96.  
  97.  
  98.  
  99.  
  100.         if( buffer )
  101.                 free(buffer);
  102.  
  103.         return success;
  104. }
  105.  
  106.  
  107. // checks input file for consistency
  108. #undef  DPK_DEPACK
  109. #define DPK_CHECK
  110. #define DPK_REPERR
  111. ULONG checker_megalz(void)
  112. #include "mhmt-depack-megalz.c"
  113. ULONG checker_hrum(void)
  114. #include "mhmt-depack-hrum.c"
  115. ULONG checker_zx7(void)
  116. #include "mhmt-depack-zx7.c"
  117. //ULONG checker_hrust(void)
  118. //#include "mhmt-depack-hrust.c"
  119. //
  120. // actually depacks without checkings
  121. #define DPK_DEPACK
  122. #undef  DPK_CHECK
  123. #undef  DPK_REPERR
  124. ULONG depacker_megalz(void)
  125. #include "mhmt-depack-megalz.c"
  126. ULONG depacker_hrum(void)
  127. #include "mhmt-depack-hrum.c"
  128. ULONG depacker_zx7(void)
  129. #include "mhmt-depack-zx7.c"
  130. #define  DPK_CHECK
  131. #define  DPK_REPERR
  132. ULONG depacker_hrust(void)
  133. #include "mhmt-depack-hrust.c"
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142. // rewind - to the beginning of input stream, byte - next byte
  143. // returns 0xFFFFFFFF if error (exhausted stream), otherwise byte (0..255)
  144. ULONG depack_getbyte(ULONG operation)
  145. {
  146.         static ULONG position;
  147.  
  148.         if( operation==DEPACK_GETBYTE_REWIND )
  149.         {
  150.                 position=0;
  151.                 return 0;
  152.         }
  153.         else if( operation==DEPACK_GETBYTE_NEXT )
  154.         {
  155.                 if( position < wrk.inlen )
  156.                 {
  157.                         return (ULONG)wrk.indata[position++];
  158.                 }
  159.                 else
  160.                 {
  161.                         printf("mhmt-depack.c:depack_getbyte() - input file exhausted!\n");
  162.                         return 0xFFFFFFFF;
  163.                 }
  164.         }
  165.         else // should never happen in a correct program
  166.                 printf("mhmt-depack.c:depack_getbyte() - wrong operation code\n");
  167.  
  168.         return 0xFFFFFFFF;
  169. }
  170.  
  171. //#define DEPACK_GETBITS_FORCE 1
  172. //#define DEPACK_GETBITS_NEXT  2
  173. //
  174. // returns 0xFFFFFFFF if error, otherwise LSB-aligned, zero-extended bits
  175. ULONG depack_getbits(ULONG numbits, ULONG operation)
  176. {       static ULONG bits;
  177.  
  178.         static ULONG num_bits_left;
  179.  
  180.         ULONG fetched_bits;
  181.  
  182.  
  183.         if( operation==DEPACK_GETBITS_FORCE ) // force word retrieval (for start of stream)
  184.         {
  185.                 bits = depack_getbits_word();
  186.                 if( bits==0xFFFFFFFF) return 0xFFFFFFFF;
  187.                 num_bits_left = wrk.wordbit ? 16 : 8;
  188.                 return 0;
  189.         }
  190.         else if( operation==DEPACK_GETBITS_NEXT ) // return bits and fetch new as needed (wrk.fullbits accounted for)
  191.         {
  192.                 if( (numbits==0) || (numbits>31) )
  193.                 {
  194.                         printf("mhmt-depack.c:depack_getbits() - too many (>31) or zero bits requested\n");
  195.                         return 0xFFFFFFFF;
  196.                 }
  197.  
  198.                 fetched_bits = 0;
  199.                 do
  200.                 {
  201.                         if( !wrk.fullbits ) // empty bits
  202.                         {
  203.                                 if( !num_bits_left )
  204.                                 {
  205.                                         bits = depack_getbits_word();
  206.                                         if( bits==0xFFFFFFFF) return 0xFFFFFFFF;
  207.                                         num_bits_left = wrk.wordbit ? 16 : 8;
  208.                                 }
  209.                         }
  210.  
  211.                         fetched_bits = ( fetched_bits<<1 ) | ( 1&(bits>>31) );
  212.                         bits <<= 1;
  213.                         num_bits_left--;
  214.  
  215.                         if( wrk.fullbits )
  216.                         {
  217.                                 if( !num_bits_left )
  218.                                 {
  219.                                         bits = depack_getbits_word();
  220.                                         if( (bits==0xFFFFFFFF) && (numbits>1) ) return 0xFFFFFFFF;
  221.                                         num_bits_left = wrk.wordbit ? 16 : 8;
  222.                                 }
  223.                         }
  224.  
  225.                 } while( --numbits );
  226.  
  227.                 return fetched_bits;
  228.         }
  229.         else
  230.         {
  231.                 printf("mhmt-depack.c:depack_getbits() - wrong operation code\n");
  232.                 return 0xFFFFFFFF;
  233.         }
  234. }
  235.  
  236. // gets word of bits (UBYTE or UWORD), accounts for big-little endian
  237. // returns 0xFFFFFFFF if no bytes in input stream (depack_getbyte()), otherwise
  238. // left-aligned bits.
  239. ULONG depack_getbits_word(void)
  240. {
  241.         ULONG bits,bits2;
  242.  
  243.         if( wrk.wordbit ) // 16bits
  244.         {
  245.                 if( wrk.bigend )
  246.                 {
  247.                         bits  = depack_getbyte(DEPACK_GETBYTE_NEXT);
  248.                         if( bits  == 0xFFFFFFFF ) return 0xFFFFFFFF;
  249.                         bits2 = depack_getbyte(DEPACK_GETBYTE_NEXT);
  250.                         if( bits2 == 0xFFFFFFFF ) return 0xFFFFFFFF;
  251.                 }
  252.                 else
  253.                 {
  254.                         bits2 = depack_getbyte(DEPACK_GETBYTE_NEXT);
  255.                         if( bits2 == 0xFFFFFFFF ) return 0xFFFFFFFF;
  256.                         bits  = depack_getbyte(DEPACK_GETBYTE_NEXT);
  257.                         if( bits  == 0xFFFFFFFF ) return 0xFFFFFFFF;
  258.                 }
  259.  
  260.                 bits = (bits<<24) | ( 0x00FF0000&(bits2<<16) );
  261.         }
  262.         else // 8bits
  263.         {
  264.                 bits=depack_getbyte(DEPACK_GETBYTE_NEXT);
  265.                 if( bits!=0xFFFFFFFF)
  266.                         bits <<= 24;
  267.         }
  268.  
  269.         return bits;
  270. }
  271.  
  272.  
  273.  
  274. // puts byte to the output buffer. if it is full, flushes via mhmt-emit.c:emit_file()
  275. // relies on initialized globals: buffer, buf_size, buf_ptr
  276. // returns zero if error (in emit_file()), otherwise non-zero
  277. ULONG depack_outbyte(UBYTE byte, ULONG operation)
  278. {
  279.         LONG pre_size;
  280.  
  281.         if( operation==DEPACK_OUTBYTE_INIT )
  282.         {
  283.                 frontptr = 0;
  284.  
  285.                 if( wrk.prebin )
  286.                 {
  287.                         // copy some data from prebinary buffer
  288.                         pre_size = wrk.prelen;
  289.                         if( pre_size > (LONG)buf_size )
  290.                                 pre_size = buf_size;
  291.                         //
  292.                         memcpy(buffer+buf_size-pre_size, wrk.indata-pre_size, pre_size);
  293.  
  294.                         // set backptr
  295.                         backptr = 0-pre_size;
  296.                 }
  297.                 else
  298.                 {
  299.                         backptr = 0;
  300.                 }
  301.         }
  302.         else if( operation==DEPACK_OUTBYTE_ADD )
  303.         {
  304.                 buffer[buf_ptr++] = byte;
  305.  
  306.                 frontptr++;
  307.  
  308.  
  309.  
  310.                 if( buf_ptr >= buf_size )
  311.                 {
  312.                         buf_ptr=0;
  313.                         return emit_file( buffer, buf_size );
  314.                 }
  315.  
  316.                 return 1;
  317.         }
  318.         else if( operation==DEPACK_OUTBYTE_FLUSH )
  319.         {
  320.                 if( buf_ptr ) return emit_file( buffer, buf_ptr );
  321.                 return 1;
  322.         }
  323.         else
  324.         {
  325.                 printf("mhmt-depack.c:depack_outbyte() - bad operation requested\n");
  326.                 return 0;
  327.         }
  328. }
  329.  
  330. // repeats data in output buffer, flushes buffer if needed.
  331. // relies on initialized globals, also relies on buf_size being 2^N
  332. // displacement is back-displacement (negative)
  333. // non-zero if success
  334. ULONG depack_repeat(LONG disp, ULONG length)
  335. {
  336.         ULONG back_ptr;
  337.         ULONG success=1;
  338.  
  339.  
  340.         // in a self-consistent system, these three errors should never appear, since there is input stream check before actual depacking
  341.         if( !length )
  342.         {
  343.                 printf("mhmt-depack.c:depack_repeat() - zero length!\n");
  344.                 return 0;
  345.         }
  346.         else if( disp>=0 )
  347.         {
  348.                 printf("mhmt-depack.c:depack_repeat() - non-negative displacement!\n");
  349.                 return 0;
  350.         }
  351.         else if( (ULONG)(-disp)>buf_size )
  352.         {
  353.                 printf("mhmt-depack.c:depack_repeat() - displacement greater than buffer size!\n");
  354.                 return 0;
  355.         }
  356.         else
  357.         {
  358.                 back_ptr = (disp+buf_ptr) & (buf_size-1); // buf_size MUST BE 2^N!
  359.  
  360.                 if( (frontptr+disp) < backptr )
  361.                 {
  362.                         printf("mhmt-depack.c:depack_repeat() - displacement is out of prebinary or already depacked data!\n");
  363.                         return 0;
  364.                 }
  365.  
  366.  
  367.                 do
  368.                 {
  369.                         success = success && depack_outbyte( buffer[back_ptr], DEPACK_OUTBYTE_ADD ); // also increases buf_ptr
  370.  
  371.                         back_ptr = (back_ptr+1) & (buf_size-1); // buf_size MUST BE 2^N!
  372.  
  373.                 } while( --length );
  374.         }
  375.  
  376.         return success;
  377. }
  378.