- #include <stdio.h> 
- #include <stdlib.h> 
-   
- #include "mhmt-types.h" 
- #include "mhmt-globals.h" 
- #include "mhmt-pack.h" 
- #include "mhmt-hash.h" 
- #include "mhmt-tb.h" 
- #include "mhmt-lz.h" 
- #include "mhmt-optimal.h" 
- #include "mhmt-emit.h" 
-   
-   
- // entry function to pack data 
- // returns zero if any error 
- ULONG pack(void) 
- { 
-   
-   
-         ULONG (*get_lz_price)(OFFSET position, struct lzcode * lzcode) = NULL; // generates correct bitlen (price) of code 
-   
-         ULONG (*emit)(struct optchain * optch, ULONG actual_len) = NULL; // emits lzcode to the output bit/byte stream 
-   
-   
-         ULONG success=1; 
-   
-   
-         ULONG actual_len; // actual length of packing (to account for ZX headers containing last unpacked bytes) 
-   
-         UBYTE * hash; 
-   
-         struct optchain * optch=NULL; 
-   
-         static struct lzcode codes[MAX_CODES_SIZE]; // generate codes here; static to ensure it's not on the stack 
-   
-   
-         UBYTE curr_byte, last_byte; 
-         UWORD index; 
-         OFFSET position; 
-   
-   
-         // some preparations 
-         // 
-         if( wrk.packtype==PK_MLZ ) 
-         { 
-                 get_lz_price  = &get_lz_price_megalz; 
-                 emit          = &emit_megalz; 
-         } 
-         else if( wrk.packtype==PK_HRM ) 
-         { 
-                 get_lz_price  = &get_lz_price_hrum; 
-                 emit          = &emit_hrum; 
-         } 
-         else if( wrk.packtype==PK_HST ) 
-         { 
-                 get_lz_price  = &get_lz_price_hrust; 
-                 emit          = &emit_hrust; 
-         } 
-         else if( wrk.packtype==PK_ZX7 ) 
-         { 
-                 get_lz_price  = &get_lz_price_zx7; 
-                 emit          = &emit_zx7; 
-         } 
-         else 
-         { 
-                 printf("mhmt-pack.c:pack() - format unsupported!\n"); 
-                 return 0; 
-         } 
-   
-   
-         actual_len = wrk.inlen; 
-         if( wrk.zxheader ) 
-         { 
-                 if( wrk.packtype==PK_HRM ) 
-                 { 
-                         actual_len -= 5; 
-                 } 
-                 else if( wrk.packtype==PK_HST ) 
-                 { 
-                         actual_len -= 6; 
-                 } 
-                 else 
-                 { 
-                         printf("mhmt-pack.c:pack() - there must be no zxheader for anything except hrust or hrum!\n"); 
-                         return 0; 
-                 } 
-         } 
-   
-   
-         // initializations and preparations 
-         init_tb(); 
-   
-         hash = build_hash(wrk.indata, actual_len, wrk.prelen); 
-         if( !hash ) 
-         { 
-                 printf("mhmt-pack.c:pack() - build_hash() failed!\n"); 
-                 success = 0; 
-         } 
-   
-         if( success ) 
-         { 
-                 optch = make_optch(actual_len); 
-                 if( !optch ) 
-                 { 
-                         printf("mhmt-pack.c:pack() - can't make optchain array!\n"); 
-                         success = 0; 
-                 } 
-         } 
-   
-   
-         // go packing! 
-         if( success ) 
-         { 
-                 // fill TBs with prebinary date 
-                 if( wrk.prebin ) 
-                 { 
-                         curr_byte=wrk.indata[0LL-wrk.prelen]; 
-                         // 
-                         for(position=(1LL-wrk.prelen);position<=0;position++) 
-                         { 
-                                 last_byte = curr_byte; 
-                                 curr_byte = wrk.indata[position]; 
-   
-                                 index = (last_byte<<8) + curr_byte; 
-                                  
-                                 if( !add_tb(index,position) ) 
-                                 { 
-                                         printf("mhmt-pack.c:pack() - add_tb() failed!\n"); 
-                                         success = 0; 
-                                         goto ERROR; 
-                                 } 
-                         } 
-                 } 
-   
-                 if( !wrk.greedy ) // default optimal coding 
-                 { 
-                         // go generating lzcodes byte-by-byte 
-                         // 
-                         curr_byte = wrk.indata[0]; 
-                         // 
-                         for(position=1;position<(OFFSET)actual_len;position++) 
-                         { 
-                                 last_byte = curr_byte; 
-                                 curr_byte = wrk.indata[position]; 
-   
-                                 // add current two-byter to the chains 
-                                 index = (last_byte<<8) + curr_byte; 
-                                 if( !add_tb(index,position) ) 
-                                 { 
-                                         printf("mhmt-pack.c:pack() - add_tb() failed!\n"); 
-                                         success = 0; 
-                                         goto ERROR; 
-                                 } 
-   
-                                 // search lzcodes for given position 
-                                 make_lz_codes(position, actual_len, hash, codes); 
-   
-                                 // update optimal chain with lzcodes 
-                                 update_optch(position, codes, get_lz_price, optch); 
-                         } 
-   
-   
-                         // all input bytes scanned, chain built, so now reverse it (prepare for scanning in output generation part) 
-                         reverse_optch(optch, actual_len); 
-                 } 
-                 else // greedy coding 
-                 { 
-                         printf("mhmt-pack.c:pack() - greedy coding not supported!\n"); 
-                         success = 0; 
-                 } 
-   
-                 // data built, now emit packed file 
-                 success = success && (*emit)(optch, actual_len); 
-         } 
-   
-   
-   
-   
-   
- ERROR: 
-         free_optch(optch); 
-   
-         destroy_hash(hash, wrk.prelen); 
-   
-         return success; 
- } 
-