Guest User

Untitled

a guest
Jun 1st, 2013
140
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

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×