Guest User

Untitled

a guest
Jun 1st, 2013
119
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <stdio.h>
  6.  
  7. #ifndef __GNU_C__ // MSVC
  8. typedef __int64 int64_t;
  9. #else
  10. #include <stdint.h>
  11. #endif
  12.  
  13. #define RLZI_WINDOW_SIZE    0x7FED      // *4 = 130,996 bytes (128KB minus 76 bytes)
  14. #define RLZI_DICTIONARY_SIZE    0x3FFFF     // *4 = 1,048,572 bytes (1MB minus 4 bytes)
  15.  
  16. #define ABS_INPUT_POS ((unsigned int)rlzi->input + rlzi->inputpos)
  17.  
  18. /** Function Prototypes **/
  19. int rlzcompress(void *output, int inlen, void *input, unsigned char mode);
  20. void flush_output(void);
  21. void write_output(void);
  22. void write_bit(unsigned char* unk0ptr, unsigned char arg_flag);
  23. void write_special(unsigned char* unk0ptr, int num, int arg_edx);
  24. int write_match_len(unsigned char len, unsigned int arg_4);
  25. int find_match(int *arg_0, unsigned char realMode);
  26.  
  27. // log base 2 of x
  28. #define log2(x) (log((long double)(x)) / (long double)0.30102999566398119521373889472449)
  29.  
  30. typedef struct { // unk_421D80
  31.     unsigned char literals[8 * 0xFF]; //grouped in 8 groups of 0xFF; group selected by has of input position, last byte and mode, the 0xFF part is based on the input byte with various shifts
  32.     unsigned char distDescLong[0xF0]; // 30x8 (match >= 4)
  33.     unsigned char distDescShort[0x40]; // 8x8 (match < 4)
  34.     unsigned char distances[12 * 0x20]; // grouped in 0x20 based on bit position
  35.     unsigned char lenDesc[0x40]; // 8 x 8; group selected by bit position, position is var_C from main function
  36.     unsigned char matchlens[0xFF];
  37.    
  38.     void* input;            // 0xCA8
  39.     void* output;           // 0xCAC
  40.     int64_t rangeOffset;        // 0xCB0 (0x422A30) - only written to in sub_405810(), affected by write_bit and write_match_len
  41.                             // - appears to be a data queue - top 24 bits not used, next 8 bits->data to be written, next 8 bits->data mask; affected by CB8 in some way (CB8 is added to this)
  42.     long rangeSize;         // 0xCB8
  43.     char nextOutputByte;            // 0xCBC - some byte offset; 3rd byte in CB0, only ever used in sub_405810; guaranteed never to == 0xFF
  44.     char bytesToWrite;      // 0xCBD (0x422A3D) - only used in sub_405810
  45.     char writeLock;         // 0xCBE - only ever used as a switch
  46.     char lastSearchBack;            // 0xCBF - some byte flag used in find_match()
  47.     unsigned long outputpos;// 0xCC0 (0x422A40)
  48.     //long unused_CC4;      // 0xCC4   - align 8? - always 0 in program
  49.     unsigned long inputpos; // 0xCC8 (0x422A48)
  50.     unsigned long inputlen; // 0xCCC (0x422A4C)
  51.    
  52.     // window stores positions of stuff; the index itself is based on hashed data
  53.     long window[RLZI_WINDOW_SIZE];  // 0xCD0-0x20C84
  54.     // dictionary stores same stuff as window, but indexed on positions
  55.     long dictionary[RLZI_DICTIONARY_SIZE]; // 1MB - dictionary??
  56.    
  57.     float sgl_120C84;
  58.     float sgl_120C88; // starts as 0.0625 and increments by that amount every time the dictionary coder fails to pack stuff
  59. } RLZ_Info; // about 1.128MB
  60. RLZ_Info rlzip;
  61. RLZ_Info* rlzi = &rlzip;
  62.  
  63. /** Functions **/
  64. // sub_406070
  65. int rlzcompress(void *output, int inlen, void *input, unsigned char mode)
  66. {
  67.     if(!inlen) return -1; // sanity check
  68.    
  69.     /** ABOUT THE MODE ARGUMENT
  70.      *  The mode argument contains two values broken up like (___|45|678)
  71.      *  Bits 678 are the compression mode
  72.      *  Bits 45 determine the default values to store in literals/distances etc array
  73.      *  The first 3 bits aren't used
  74.      */
  75.     int var_C = 0; // var_C appears to do some tracking in regards to how well the dictionary coder is packing things?
  76.     char realMode;
  77.     int dictSearchBack = 0; // just assign something in case... :S
  78.    
  79.     // variables introduced by me
  80.     unsigned int i;
  81.     unsigned int matchLen = 0;
  82.     //unsigned int iInputPosTemp;
  83.    
  84.     realMode = mode & 7;                            // grab the compression mode
  85.    
  86.     // originally init_rlzi()
  87.     rlzi->input = input;
  88.     rlzi->inputlen = inlen;
  89.     rlzi->output = output;
  90.     rlzi->rangeOffset = 0;
  91.     rlzi->rangeSize = -1;
  92.     rlzi->nextOutputByte = 0;
  93.     rlzi->bytesToWrite = 0;
  94.     // no writeLock=0 - writeLock is _always_ assigned before calling the write function anyway
  95.     rlzi->lastSearchBack = 0;
  96.     rlzi->outputpos = 0;
  97.     rlzi->inputpos = 0; //added by me
  98.    
  99.     rlzi->sgl_120C84 = 0;
  100.     rlzi->sgl_120C88 = 0.0625;
  101.     memset(rlzi->window, 0xFF, sizeof(rlzi->window));
  102.    
  103.    
  104.    
  105.     // grab the 2nd number from the mode
  106.     //eax = (4 - ((mode >> 3) & 0x03)) << 5;        // 12345678 -> 45
  107.     /* ^ 4 possible combinations for the above
  108.      *  if bits45 == 00 (should be) then eax => 0x80    (10000000)
  109.      *  if bits45 == 01 then eax => 0x60                (01100000)
  110.      *  if bits45 == 10 then eax => 0x40                (01000000)
  111.      *  if bits45 == 11 then eax => 0x20                (00100000)
  112.      */
  113.     {
  114.         unsigned char byteSet = ((4 - ((mode >> 3) & 0x03)) << 5);
  115.         memset(rlzi->literals, byteSet, sizeof(rlzi->literals));
  116.         memset(rlzi->distDescLong, byteSet, sizeof(rlzi->distDescLong));
  117.         memset(rlzi->distDescShort, byteSet, sizeof(rlzi->distDescShort));
  118.         memset(rlzi->distances, byteSet, sizeof(rlzi->distances));
  119.         memset(rlzi->lenDesc, byteSet, sizeof(rlzi->lenDesc));
  120.         memset(rlzi->matchlens, byteSet, sizeof(rlzi->matchlens));
  121.     }
  122.    
  123.     unsigned char lastInputByte = 0;
  124.    
  125.     // main loop - this will loop until all the data is processed
  126.     while(rlzi->inputpos < rlzi->inputlen) //loc_4060D0
  127.     {
  128.         matchLen = find_match(&dictSearchBack, realMode);
  129.         if(matchLen < 2) matchLen = 1;
  130.         int sub_405B90_ret = write_match_len(matchLen -1, var_C);
  131.         if(matchLen == 1)                       // no match found
  132.         {
  133.             // write literal
  134.             // the following code was previously sub_405A10( (((((unsigned int)rlzi->inputpos & 7) << 8) | lastInputByte) >> realMode) & 7 )
  135.             int arg_ecx = ((
  136.                  (((unsigned int)rlzi->inputpos & 7) << 8) | lastInputByte
  137.                 ) >> realMode) & 7; // top bit in (rlzi->inputpos & 7) will actually be discarded - that is, (rlzi->inputpos & 3) should give the same result
  138.             int oldRangeSize = rlzi->rangeSize;
  139.             unsigned int oldOutputpos = rlzi->outputpos;
  140.             unsigned int inputVal = *(unsigned char*)ABS_INPUT_POS + 0x100;
  141.             for(; !(inputVal & 0x10000); inputVal <<= 1) // loop 8 times
  142.                 write_bit(
  143.                     (unsigned char*)((unsigned int)rlzi->literals + arg_ecx*0xFF + (inputVal >> 8)-1),
  144.                     (inputVal >> 7) & 1
  145.                 ); // last arg (now deleted) is actually ebx, but ebx is 3 at this time
  146.            
  147.             // these values are only ever used if realMode==7, and only in find_match() function
  148.             #define scast_405A10(v) ((long double)((unsigned int)(v)))
  149.             // (int) cast added to make it consistent with good rlz packer, but unsure if this is correct...
  150.             rlzi->sgl_120C84 += (float)(log2(scast_405A10(oldRangeSize) / scast_405A10(rlzi->rangeSize)) + (int)((rlzi->outputpos - oldOutputpos - 1)*8));
  151.             rlzi->sgl_120C88 += 0.0625f; //flt_41A3AC
  152.            
  153.             if(var_C > 0) var_C--;
  154.         }
  155.         else
  156.         {
  157.             // write distance instead of literal
  158.             // originally sub_405C10(dictSearchBack, sub_405B90(matchLen -1, var_C), matchLen)
  159.             int searchBackPlus1 = dictSearchBack +1;
  160.             unsigned char* treeStore;
  161.             //int o_ebx=ebx, o_ebp=ebp, o_esi=esi, o_edi=edi;
  162.             int sbSignifBit = 0;
  163.             int var_edi;
  164.             i = 0;
  165.             if((searchBackPlus1 & 0xFFFFFFFE) > 0) // if searchBackPlus1 has bits other than the first set... (that is, searchBackPlus1 != 0 && searchBackPlus1 != 1)
  166.             { // this condition _should_ always be true, as min dictSearchBack is 1, and with +1, min value for searchBackPlus1 is 2
  167.                 // find the position of the most significant "1"
  168.                 for(i=2; (searchBackPlus1 >> i) > 0; i++);
  169.                 sbSignifBit = --i; // put the bit position in ebp
  170.             }
  171.            
  172.             if(matchLen < 4) {
  173.                 var_edi = 4;
  174.                 treeStore = rlzi->distDescShort;
  175.             } else {
  176.                 var_edi = 16;
  177.                 treeStore = rlzi->distDescLong;
  178.                 sbSignifBit += 0xC;
  179.             }
  180.            
  181.             int var_ebx = 1;
  182.             int var_esi;
  183.             do { // write packed thing - perhaps a length of next number descriptor?
  184.                 var_esi = ((sbSignifBit & var_edi) > 0 ? 1 : 0); // check if certain bit in ebp is set
  185.                 write_bit((unsigned char*)((unsigned int)&treeStore[var_ebx*8] + sub_405B90_ret), var_esi);
  186.                 var_edi >>= 1;
  187.                 var_ebx = var_esi+var_ebx*2;
  188.             } while(var_edi > 0); // loop 3 or 5 times
  189.            
  190.             if(i > 0) // should always be true
  191.             {
  192.                 // write distance
  193.                 i--;
  194.                 write_special(rlzi->distances + i*0x20, searchBackPlus1, i);
  195.             }
  196.            
  197.             var_C = 7 - ((rlzi->inputpos + matchLen) & 1);
  198.         }
  199.        
  200.         unsigned int bytesLeftMinus3 = rlzi->inputlen - rlzi->inputpos - 3;
  201.         if(matchLen < bytesLeftMinus3)
  202.             bytesLeftMinus3 = matchLen;
  203.         for(i=0; i<bytesLeftMinus3; i++) // goes thru all the bytes just written and pushes some things into the dictionary
  204.         {
  205.             unsigned int brHash = *(unsigned int*)(ABS_INPUT_POS +i) << 8;
  206.             brHash %= RLZI_WINDOW_SIZE;
  207.            
  208.             rlzi->dictionary[(rlzi->inputpos+i) & RLZI_DICTIONARY_SIZE] = rlzi->window[brHash];
  209.             rlzi->window[brHash] = rlzi->inputpos+i;
  210.         }
  211.        
  212.         rlzi->inputpos += matchLen;
  213.         lastInputByte = *(unsigned char*)(ABS_INPUT_POS-1);
  214.         if(rlzi->outputpos == rlzi->inputlen) // is the compressed output larger than the original stream?
  215.             return -1;
  216.     }
  217.    
  218.     write_match_len(0xFF, var_C); // end marker or is this used for flushing data?
  219.    
  220.     { // originally sub_4058E0()
  221.         i = (rlzi->writeLock ? 5 : 4);
  222.         //rlzi->writeLock = 0;
  223.         while(i--)
  224.             flush_output();
  225.     }
  226.    
  227.     // stick the mode into the first byte of the output
  228.     // (otherwise, first byte is guaranteed to be 0)
  229.     *(unsigned char*)output = mode;
  230.    
  231.     return rlzi->outputpos; // length of compressed data
  232. }
  233.  
  234. // calls write_bit, write_special
  235. // function handles some packing routines
  236. int write_match_len(unsigned char len, unsigned int arg_4) // arg_4 -> something that keeps track of no. past blocks packed with find_match() (always var_C from rlzcompress())
  237. {
  238.     // len is the length -1 (amount of data removed by dictionary coder), except when 0xFF (when called after loop has finished)
  239.     int i;
  240.     char flagTemp;
  241.     // determine how packed the data is - ie, 1 bytes removed?  2 bytes?, 4?, 8? ...
  242.     // or perhaps, this is actually outputting the length code!
  243.     for(i=0; i<8; i++)
  244.     {
  245.         flagTemp = (len >= (1u << i) ? 1 : 0);
  246.         write_bit((unsigned char*)((unsigned int)&rlzi->lenDesc[i*8] + arg_4), flagTemp);
  247.         if(flagTemp == 0) break;
  248.     }
  249.     i--;
  250.     if(i > 0) // --> identical to if(len != 0); this will only be true if len >= 1 (or len<0) - eg if data was packed
  251.     {
  252.         i--;
  253.         unsigned char* ptr = rlzi->matchlens + ((arg_4 & 7)+i*8)*4;
  254.         write_special(ptr + ((rlzi->inputpos << i) & 3), len, i);
  255.         i++;
  256.     }
  257.     return i; // returns packing threshold?
  258. }
  259.  
  260. // calls sub_405810
  261. void write_bit(unsigned char* unk0ptr, unsigned char arg_flag)
  262. {
  263.     unsigned int range = (unsigned int)rlzi->rangeSize;
  264.    
  265.     unsigned int pMid = (range >> 8) * (*unk0ptr);
  266.     if(!arg_flag)
  267.     {
  268.         rlzi->rangeOffset += pMid;
  269.         range -= pMid;
  270.     }
  271.     else
  272.     {
  273.         range = pMid;
  274.         *unk0ptr += 0xFF; // increase probability
  275.     }
  276.     *unk0ptr -= ((unsigned int)(*unk0ptr) >> 3);
  277.     rlzi->rangeSize = (long)range;
  278.     write_output();
  279. }
  280.  
  281. // calls write_bit  (used to)sub_4059B0
  282. // arg_4, always either rlzi->distances or rlzi->matchlens
  283. // inputpos: either rlzi->inputpos or 0
  284. // arg_edx is likely to be a 8bit value; something to do with bit position in distance
  285. // distance: but can be "len" when called from write_match_len
  286. void write_special(unsigned char* unk0ptr, int num, int arg_edx)
  287. //void write_special(int arg_4, int distance, int inputpos, int arg_ecx, int arg_edx)
  288. {
  289.     if(arg_edx > 255)
  290.         printf("ASSUMPTION FAILURE\n");
  291.     //int var_ebx = ((inputpos << (arg_edx & 0xFF)) & 3) + arg_4 + ((arg_ecx & 7)+arg_edx*8)*4;
  292.     if(arg_edx>=3)
  293.     {
  294.         write_bit(unk0ptr, (num >> arg_edx) & 1);
  295.         arg_edx--;
  296.         if(arg_edx>=3)
  297.         {
  298.             write_bit(unk0ptr, (num >> arg_edx) & 1);
  299.             arg_edx--;
  300.         }
  301.         unk0ptr++;
  302.         if(arg_edx>=3)
  303.         {
  304.             // previously sub_4059B0()
  305.             unsigned int rangeTmp = (unsigned int)rlzi->rangeSize;
  306.             arg_edx -= 2;
  307.             while(arg_edx--) {
  308.                 rangeTmp >>= 1;
  309.                 if(((num >> (3 + arg_edx)) & 1) == 0)
  310.                 {
  311.                     rlzi->rangeOffset += rangeTmp;
  312.                 }
  313.             }
  314.             arg_edx += 3; // 2 (reverse previous subtraction), and +1 for the above loop
  315.             rlzi->rangeSize = (long)rangeTmp;
  316.             write_output();
  317.         }
  318.     }
  319.     do {
  320.         write_bit(unk0ptr, (num >> arg_edx) & 1);
  321.         unk0ptr++;
  322.         arg_edx--;
  323.     } while(arg_edx >= 0);
  324. }
  325.  
  326.  
  327. void flush_output(void)
  328. {
  329.     // if byte CB3 is NOT 0xFF, OR dword CB4 is true
  330.     // -- which means it can only be false if rlzi->rangeOffset == 0x00000000FF??????
  331.     if((rlzi->rangeOffset >> 0x18) != 0xFF)
  332.     {
  333.         unsigned char byteOut = rlzi->nextOutputByte; // starts off as 0, then becomes 3rd byte of rlzi->rangeOffset
  334.         rlzi->nextOutputByte = (rlzi->rangeOffset >> 0x18) & 0xFF;
  335.         do {
  336.             if(rlzi->outputpos == rlzi->inputlen)
  337.                 return;
  338.             *(unsigned char*)((unsigned int)rlzi->output + rlzi->outputpos) = ((rlzi->rangeOffset >> 32) & 0xFF) + byteOut;
  339.             rlzi->bytesToWrite--;
  340.             rlzi->outputpos++;
  341.             byteOut = 0xFF;
  342.         } while(rlzi->bytesToWrite >= 0);
  343.     }
  344.    
  345.     //loc_4058A4:
  346.     rlzi->bytesToWrite++;
  347.     //rlzi->rangeOffset = (arg_CB0 << 8) & 0xFFFFFFFF; // make sure high 32 bits are 0
  348.     //rlzi->rangeSize = arg_CB8 << 8;
  349.     rlzi->rangeOffset <<= 8;
  350.     rlzi->rangeOffset &= 0xFFFFFFFF; // make sure high 32 bits are 0
  351.     rlzi->rangeSize <<= 8;
  352. }
  353.  
  354. void write_output(void)
  355. {
  356.     rlzi->writeLock = ((rlzi->rangeSize >> 0x18) & 0xFF ? 1:0);
  357.     if(!rlzi->writeLock) {
  358.         flush_output();
  359.     }
  360. }
  361.  
  362.  
  363. // sub_405CE0: arg_0 = buf
  364. // this function determines how much data we can pack into a single byte
  365. // return of 1 = can't compress; don't think this can return 0xFF or higher
  366. // NEW: this function searches for distance-length, but doesn't actually encode anything
  367. int find_match(int *searchBackUsed, unsigned char realMode)
  368. {
  369.     int tempCompare = 0;
  370.     int maxBlockSize = 0xFF, matchLen = 1, backRef;
  371.    
  372.     unsigned int bytesLeft = rlzi->inputlen - rlzi->inputpos;
  373.     unsigned int searchBack; // not too sure about this variable's name
  374.    
  375.     char realMode7Threshold;
  376.     int i;
  377.    
  378.     if(bytesLeft < 2)
  379.         return 1;
  380.     if(bytesLeft < 0xFF) // if we have less bytes left than the maximum block size
  381.         maxBlockSize = bytesLeft;
  382.    
  383.     //realMode7Threshold = ((unsigned int)(rlzi->sgl_120C84 / rlzi->sgl_120C88 + 128.5) > 0x64); //dbl_41A3B8
  384.     //realMode7Threshold = ((int)((unsigned int)(rlzi->sgl_120C84 / rlzi->sgl_120C88 + 128.5)) > 0x64);
  385.     #define ROUND(n) ((int)((n) + 0.5))
  386.     realMode7Threshold = (ROUND(rlzi->sgl_120C84 / rlzi->sgl_120C88) > -28);
  387.     // the second line above generates output consistent with the good rlzpacker, but is this typecasting all correct?
  388.    
  389.     // check if we have a continuous copy of something
  390.     searchBack = ABS_INPUT_POS - rlzi->lastSearchBack; // byte_CBF only used by find_match(); is initially 0
  391.     if(
  392.            (unsigned int)rlzi->lastSearchBack < rlzi->inputpos
  393.         && *(unsigned char*)(searchBack-1) == *(unsigned char*)(ABS_INPUT_POS)
  394.         && *(unsigned char*)(searchBack)   == *(unsigned char*)(ABS_INPUT_POS+1)
  395.     ){
  396.         // if we've found repeated bytes...
  397.         *searchBackUsed = rlzi->lastSearchBack;
  398.         matchLen = 2;
  399.     }
  400.     // no continuous copy from previously found stream - check if any similarities in the past few (up to 3) bytes
  401.     else if((realMode == 7 && realMode7Threshold) || realMode != 7)
  402.     {
  403.         //i = (realMode == 7 ? 1 : 0);
  404.         //while((unsigned int)i < rlzi->inputpos && i <= 3)
  405.         for(i=(realMode == 7 ? 1 : 0); i<=3; i++)
  406.         {
  407.             if((unsigned int)i >= rlzi->inputpos)
  408.                 break;
  409.            
  410.             searchBack = ABS_INPUT_POS - i;
  411.             if(
  412.                    *(unsigned char*)(searchBack-1) == *(unsigned char*)(ABS_INPUT_POS)
  413.                 && *(unsigned char*)(searchBack)   == *(unsigned char*)(ABS_INPUT_POS+1)
  414.             ){
  415.                 *searchBackUsed = i;
  416.                 matchLen = 2;
  417.                 break;
  418.             }
  419.             //i++;
  420.         }
  421.     }
  422.     //loc_405DB7:
  423.     // if we have 2 bytes left in the buffer (remember, if there's 1 byte left, this function would've
  424.     //  already returned), we'll either by able to pack 1 or 2 bytes into a single byte
  425.     //  We can pack 2 bytes into a byte if repeat bytes (above) have been found.
  426.     if(maxBlockSize < 3)
  427.     {
  428.         return matchLen;
  429.     }
  430.    
  431.     //loc_405DC9:
  432.     //edx = ABS_INPUT_POS; - never actually read...
  433.     unsigned int brHash = *(unsigned int*)ABS_INPUT_POS << 8; // previously eax
  434.    
  435.     backRef = rlzi->window[(unsigned int)brHash % RLZI_WINDOW_SIZE];
  436.     while(backRef != -1)
  437.     { // found a back reference
  438.         if(backRef < (int)(rlzi->inputpos - RLZI_DICTIONARY_SIZE-1)) // is the backreference out of bounds?
  439.             break;
  440.        
  441.         unsigned int matchAmt = matchLen +1;
  442.        
  443.         // verify that the current matchLen is valid?
  444.         for(i = matchLen; i >= 0; i--)
  445.         {
  446.             if(*(unsigned char*)((unsigned int)rlzi->input + backRef+i) != *(unsigned char*)(ABS_INPUT_POS+i))
  447.                 goto loc_405F97; // jumps to end of while-loop (not valid - search for more references which could be valid)
  448.         }
  449.        
  450.         // see how much more we can match
  451.         for(; matchAmt < maxBlockSize; matchAmt++)
  452.         {
  453.             //loc_405E70:
  454.             if(
  455.                 *(unsigned char*)(((unsigned int)rlzi->input + matchAmt)+backRef) !=
  456.                 *(unsigned char*)(((unsigned int)rlzi->input + matchAmt)+rlzi->inputpos)
  457.             )
  458.                 break;
  459.         }
  460.         i = rlzi->inputpos - backRef - 1; // distance?  penalising short matches which have a large distance??
  461.         if(matchAmt >= 3 && (matchAmt != 3 || (i <= 0x7F && (i <= 0x30 || realMode != 5))))
  462.         {
  463.             tempCompare=0;
  464.             switch(matchAmt)
  465.             {
  466.                 case(3): tempCompare = 0x7E;    break;
  467.                 case(4): tempCompare = 0x4400;  break;
  468.                 case(5): tempCompare = 0x6A00;  break;
  469.                 case(6): tempCompare = 0x28400; break;
  470.             }
  471.             if(!tempCompare || (i <= tempCompare))
  472.             {
  473.                 matchLen = matchAmt; // this is a good match
  474.                 *searchBackUsed = i;
  475.                 if(*searchBackUsed)
  476.                 {
  477.                     // check if all matched is actually the same character
  478.                     for(i=0; i < matchAmt; i++) {
  479.                         if(*(unsigned char*)((unsigned int)rlzi->input+backRef) != *(unsigned char*)(ABS_INPUT_POS + i))
  480.                             break;
  481.                     }
  482.                     if(matchAmt == i)
  483.                     { // all matched is all the same character!
  484.                         do { // see how far ahead we can go
  485.                             if(*(unsigned char*)((unsigned int)rlzi->input+backRef) != *(unsigned char*)(ABS_INPUT_POS + i))
  486.                                 break;
  487.                             i++;
  488.                         } while(i < maxBlockSize);
  489.                         //loc_405F3D:
  490.                         if(i == maxBlockSize)
  491.                         {
  492.                             if(matchAmt <= 3)
  493.                                 return 3;
  494.                            
  495.                             // loc_405F60:
  496.                             for(i=3; i < matchAmt; i++) // loop max of 6 times due to code below
  497.                             {
  498.                                 if(i != 3 || (*searchBackUsed <= 0x7F && (*searchBackUsed <= 0x30 || realMode != 5)))
  499.                                 {
  500.                                     switch(i)
  501.                                     {
  502.                                         case(3): tempCompare = 0x7E;    break;
  503.                                         case(4): tempCompare = 0x4400;  break;
  504.                                         case(5): tempCompare = 0x6A00;  break;
  505.                                         case(6): tempCompare = 0x28400; break;
  506.                                         default:
  507.                                             return i;
  508.                                     }
  509.                                     if(*searchBackUsed <= tempCompare)
  510.                                         break;
  511.                                 }
  512.                             }
  513.                             return i;
  514.                         }
  515.                     }
  516.                 }
  517.                 //loc_405F8F:
  518.                 if(matchAmt == maxBlockSize)
  519.                 {
  520.                     //loc_406009:
  521.                     if(maxBlockSize != 0xFF)
  522.                         return maxBlockSize;
  523.                     // since maxBlockSize <= 0xFF, this implies maxBlockSize==0xFF
  524.                     if(bytesLeft <= 0xFF) // if bytesLeft < 0xFF, then maxBlockSize < 0xFF will be true (enforced above), thus this line is essentially "if(bytesLeft == 0xFF)"
  525.                     {
  526.                         return 0xFD; // or 0x100 - 3
  527.                     }
  528.                     //loc_406030:
  529.                     // note, at this point, matchAmt = maxBlockSize = 0xFF, bytesLeft > 0xFF
  530.                     if(bytesLeft == 0x100) return 0xFD;
  531.                     for(i = matchAmt; i < 0x101; i++)
  532.                         if(*(unsigned char*)(ABS_INPUT_POS+i+backRef-rlzi->inputpos) != *(unsigned char*)(ABS_INPUT_POS+i))
  533.                             return 0xFD;
  534.                     return 0xFF;
  535.                 }
  536.             }
  537.         }
  538.         loc_405F97:
  539.         backRef = rlzi->dictionary[backRef & RLZI_DICTIONARY_SIZE];
  540.     }
  541.    
  542.     //loc_405FB4:
  543.     if(matchLen == 2)
  544.         rlzi->lastSearchBack = *searchBackUsed & 0xFF;
  545.     return matchLen;
  546. }
RAW Paste Data