- #include <stdio.h> 
- #include <stdlib.h> 
- #include <string.h> 
-   
- #include "mhmt-types.h" 
- #include "mhmt-globals.h" 
- #include "mhmt-depack.h" 
- #include "mhmt-lz.h" 
- #include "mhmt-emit.h" 
-   
-   
- ULONG buf_size=0; 
- ULONG buf_ptr=0; 
- UBYTE * buffer=NULL; 
-   
- LONG backptr, frontptr; 
-   
-   
- ULONG depack(void) 
- { 
-         ULONG (*checker) (void) = NULL; 
-         ULONG (*depacker)(void) = NULL; 
-   
-   
-         ULONG success=1; 
-   
-   
-         // some preparations 
-         // 
-         if( wrk.packtype==PK_MLZ ) 
-         { 
-                 checker  = &checker_megalz; 
-                 depacker = &depacker_megalz; 
-         } 
-         else if( wrk.packtype==PK_HRM ) 
-         { 
-                 checker  = &checker_hrum; 
-                 depacker = &depacker_hrum; 
-         } 
-         else if( wrk.packtype==PK_HST ) 
-         { 
- //              checker  = &checker_hrust; 
-                 depacker = &depacker_hrust; 
-         } 
-         else if( wrk.packtype==PK_ZX7 ) 
-         { 
-                 checker  = &checker_zx7; 
-                 depacker = &depacker_zx7; 
-         } 
-         else 
-         { 
-                 printf("mhmt-depack.c:depack() - format unsupported!\n"); 
-                 return 0; 
-         } 
-   
-   
-   
-         // allocate buffer used for depacking 
-         // 
-         //////buf_size = ( wrk.maxwin==4352 ) ? 8192 : wrk.maxwin; // provided there are no other non-2^n sizes 
-         if( wrk.maxwin==4352 ) 
-                 buf_size = 8192; 
-         else if( wrk.maxwin==2176 ) 
-                 buf_size = 4096; 
-         else 
-                 buf_size = wrk.maxwin; 
-   
-   
-         buffer =(- UBYTE *)malloc(- buf_size );
-         if( !buffer ) 
-         { 
-                 printf("mhmt-depack.c:depack() cannot allocate memory for depack buffer!\n"); 
-                 return 0; 
-         } 
-   
-         buf_ptr=0; 
-   
-   
-         success = success && emit_file(NULL,EMIT_FILE_INIT); 
-   
-         if( wrk.packtype==PK_MLZ || wrk.packtype==PK_ZX7 ) 
-                 success = success && (*checker) (); 
-   
- //#ifdef DBG 
- //      printf("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); 
- //#endif 
-   
-   
-         depack_outbyte( 0, DEPACK_OUTBYTE_INIT ); 
-   
-         success = success && (*depacker)(); 
-   
-         /*success = success && */depack_outbyte( 0, DEPACK_OUTBYTE_FLUSH ); 
-   
-         /*success = success && */emit_file(NULL,EMIT_FILE_FINISH); 
-   
-   
-   
-   
-         if( buffer ) 
-   
-         return success; 
- } 
-   
-   
- // checks input file for consistency 
- #undef  DPK_DEPACK 
- #define DPK_CHECK 
- #define DPK_REPERR 
- ULONG checker_megalz(void) 
- #include "mhmt-depack-megalz.c" 
- ULONG checker_hrum(void) 
- #include "mhmt-depack-hrum.c" 
- ULONG checker_zx7(void) 
- #include "mhmt-depack-zx7.c" 
- //ULONG checker_hrust(void) 
- //#include "mhmt-depack-hrust.c" 
- // 
- // actually depacks without checkings 
- #define DPK_DEPACK 
- #undef  DPK_CHECK 
- #undef  DPK_REPERR 
- ULONG depacker_megalz(void) 
- #include "mhmt-depack-megalz.c" 
- ULONG depacker_hrum(void) 
- #include "mhmt-depack-hrum.c" 
- ULONG depacker_zx7(void) 
- #include "mhmt-depack-zx7.c" 
- #define  DPK_CHECK 
- #define  DPK_REPERR 
- ULONG depacker_hrust(void) 
- #include "mhmt-depack-hrust.c" 
-   
-   
-   
-   
-   
-   
-   
-   
- // rewind - to the beginning of input stream, byte - next byte 
- // returns 0xFFFFFFFF if error (exhausted stream), otherwise byte (0..255) 
- ULONG depack_getbyte(ULONG operation) 
- { 
-         static ULONG position; 
-   
-         if( operation==DEPACK_GETBYTE_REWIND ) 
-         { 
-                 position=0; 
-                 return 0; 
-         } 
-         else if( operation==DEPACK_GETBYTE_NEXT ) 
-         { 
-                 if( position < wrk.inlen ) 
-                 { 
-                         return (ULONG)wrk.indata[position++]; 
-                 } 
-                 else 
-                 { 
-                         printf("mhmt-depack.c:depack_getbyte() - input file exhausted!\n"); 
-                         return 0xFFFFFFFF; 
-                 } 
-         } 
-         else // should never happen in a correct program 
-                 printf("mhmt-depack.c:depack_getbyte() - wrong operation code\n"); 
-   
-         return 0xFFFFFFFF; 
- } 
-   
- //#define DEPACK_GETBITS_FORCE 1 
- //#define DEPACK_GETBITS_NEXT  2 
- // 
- // returns 0xFFFFFFFF if error, otherwise LSB-aligned, zero-extended bits 
- ULONG depack_getbits(ULONG numbits, ULONG operation) 
- {       static ULONG bits; 
-   
-         static ULONG num_bits_left; 
-   
-         ULONG fetched_bits; 
-   
-   
-         if( operation==DEPACK_GETBITS_FORCE ) // force word retrieval (for start of stream) 
-         { 
-                 bits = depack_getbits_word(); 
-                 if( bits==0xFFFFFFFF) return 0xFFFFFFFF; 
-                 num_bits_left = wrk.wordbit ? 16 : 8; 
-                 return 0; 
-         } 
-         else if( operation==DEPACK_GETBITS_NEXT ) // return bits and fetch new as needed (wrk.fullbits accounted for) 
-         { 
-                 if( (numbits==0) || (numbits>31) ) 
-                 { 
-                         printf("mhmt-depack.c:depack_getbits() - too many (>31) or zero bits requested\n"); 
-                         return 0xFFFFFFFF; 
-                 } 
-   
-                 fetched_bits = 0; 
-                 do 
-                 { 
-                         if( !wrk.fullbits ) // empty bits 
-                         { 
-                                 if( !num_bits_left ) 
-                                 { 
-                                         bits = depack_getbits_word(); 
-                                         if( bits==0xFFFFFFFF) return 0xFFFFFFFF; 
-                                         num_bits_left = wrk.wordbit ? 16 : 8; 
-                                 } 
-                         } 
-   
-                         fetched_bits = ( fetched_bits<<1 ) | ( 1&(bits>>31) ); 
-                         bits <<= 1; 
-                         num_bits_left--; 
-   
-                         if( wrk.fullbits ) 
-                         { 
-                                 if( !num_bits_left ) 
-                                 { 
-                                         bits = depack_getbits_word(); 
-                                         if( (bits==0xFFFFFFFF) && (numbits>1) ) return 0xFFFFFFFF; 
-                                         num_bits_left = wrk.wordbit ? 16 : 8; 
-                                 } 
-                         } 
-   
-                 } while( --numbits ); 
-   
-                 return fetched_bits; 
-         } 
-         else 
-         { 
-                 printf("mhmt-depack.c:depack_getbits() - wrong operation code\n"); 
-                 return 0xFFFFFFFF; 
-         } 
- } 
-   
- // gets word of bits (UBYTE or UWORD), accounts for big-little endian 
- // returns 0xFFFFFFFF if no bytes in input stream (depack_getbyte()), otherwise 
- // left-aligned bits. 
- ULONG depack_getbits_word(void) 
- { 
-         ULONG bits,bits2; 
-   
-         if( wrk.wordbit ) // 16bits 
-         { 
-                 if( wrk.bigend ) 
-                 { 
-                         bits  = depack_getbyte(DEPACK_GETBYTE_NEXT); 
-                         if( bits  == 0xFFFFFFFF ) return 0xFFFFFFFF; 
-                         bits2 = depack_getbyte(DEPACK_GETBYTE_NEXT); 
-                         if( bits2 == 0xFFFFFFFF ) return 0xFFFFFFFF; 
-                 } 
-                 else 
-                 { 
-                         bits2 = depack_getbyte(DEPACK_GETBYTE_NEXT); 
-                         if( bits2 == 0xFFFFFFFF ) return 0xFFFFFFFF; 
-                         bits  = depack_getbyte(DEPACK_GETBYTE_NEXT); 
-                         if( bits  == 0xFFFFFFFF ) return 0xFFFFFFFF; 
-                 } 
-   
-                 bits = (bits<<24) | ( 0x00FF0000&(bits2<<16) ); 
-         } 
-         else // 8bits 
-         { 
-                 bits=depack_getbyte(DEPACK_GETBYTE_NEXT); 
-                 if( bits!=0xFFFFFFFF) 
-                         bits <<= 24; 
-         } 
-   
-         return bits; 
- } 
-   
-   
-   
- // puts byte to the output buffer. if it is full, flushes via mhmt-emit.c:emit_file() 
- // relies on initialized globals: buffer, buf_size, buf_ptr 
- // returns zero if error (in emit_file()), otherwise non-zero 
- ULONG depack_outbyte(UBYTE byte, ULONG operation) 
- { 
-         LONG pre_size; 
-   
-         if( operation==DEPACK_OUTBYTE_INIT ) 
-         { 
-                 frontptr = 0; 
-   
-                 if( wrk.prebin ) 
-                 { 
-                         // copy some data from prebinary buffer 
-                         pre_size = wrk.prelen; 
-                         if( pre_size > (LONG)buf_size ) 
-                                 pre_size = buf_size; 
-                         // 
-                         memcpy(- buffer +- buf_size -- pre_size ,-  wrk. indata-- pre_size ,-  pre_size );
 
-   
-                         // set backptr 
-                         backptr = 0-pre_size; 
-                 } 
-                 else 
-                 { 
-                         backptr = 0; 
-                 } 
-         } 
-         else if( operation==DEPACK_OUTBYTE_ADD ) 
-         { 
-                 buffer[buf_ptr++] = byte; 
-   
-                 frontptr++; 
-   
-   
-   
-                 if( buf_ptr >= buf_size ) 
-                 { 
-                         buf_ptr=0; 
-                         return emit_file( buffer, buf_size ); 
-                 } 
-   
-                 return 1; 
-         } 
-         else if( operation==DEPACK_OUTBYTE_FLUSH ) 
-         { 
-                 if( buf_ptr ) return emit_file( buffer, buf_ptr ); 
-                 return 1; 
-         } 
-         else 
-         { 
-                 printf("mhmt-depack.c:depack_outbyte() - bad operation requested\n"); 
-                 return 0; 
-         } 
- } 
-   
- // repeats data in output buffer, flushes buffer if needed. 
- // relies on initialized globals, also relies on buf_size being 2^N 
- // displacement is back-displacement (negative) 
- // non-zero if success 
- ULONG depack_repeat(LONG disp, ULONG length) 
- { 
-         ULONG back_ptr; 
-         ULONG success=1; 
-   
-   
-         // in a self-consistent system, these three errors should never appear, since there is input stream check before actual depacking 
-         if( !length ) 
-         { 
-                 printf("mhmt-depack.c:depack_repeat() - zero length!\n"); 
-                 return 0; 
-         } 
-         else if( disp>=0 ) 
-         { 
-                 printf("mhmt-depack.c:depack_repeat() - non-negative displacement!\n"); 
-                 return 0; 
-         } 
-         else if( (ULONG)(-disp)>buf_size ) 
-         { 
-                 printf("mhmt-depack.c:depack_repeat() - displacement greater than buffer size!\n"); 
-                 return 0; 
-         } 
-         else 
-         { 
-                 back_ptr = (disp+buf_ptr) & (buf_size-1); // buf_size MUST BE 2^N! 
-   
-                 if( (frontptr+disp) < backptr ) 
-                 { 
-                         printf("mhmt-depack.c:depack_repeat() - displacement is out of prebinary or already depacked data!\n"); 
-                         return 0; 
-                 } 
-   
-   
-                 do 
-                 { 
-                         success = success && depack_outbyte( buffer[back_ptr], DEPACK_OUTBYTE_ADD ); // also increases buf_ptr 
-   
-                         back_ptr = (back_ptr+1) & (buf_size-1); // buf_size MUST BE 2^N! 
-   
-                 } while( --length ); 
-         } 
-   
-         return success; 
- } 
-