Exemplo n.º 1
0
    public static byte[] compress(byte[] source, int level)
    {
        int  i    = 0;
        int  num  = 13;
        uint num2 = 2147483648u;
        int  i2   = 9;

        byte[] array  = new byte[source.Length + 400];
        int[]  array2 = new int[4096];
        byte[] array3 = new byte[4096];
        int    num3   = 0;
        int    num4   = source.Length - 6 - 4 - 1;
        int    num5   = 0;

        if (level != 1 && level != 3)
        {
            throw new ArgumentException("C# version only supports level 1 and 3");
        }
        int[,] array4;
        if (level == 1)
        {
            array4 = new int[4096, 1];
        }
        else
        {
            array4 = new int[4096, 16];
        }
        if (source.Length == 0)
        {
            return(new byte[0]);
        }
        if (i <= num4)
        {
            num3 = ((int)source[i] | (int)source[i + 1] << 8 | (int)source[i + 2] << 16);
        }
        byte[] array5;
        while (i <= num4)
        {
            if ((num2 & 1u) == 1u)
            {
                if (i > source.Length >> 1 && num > i - (i >> 5))
                {
                    array5 = new byte[source.Length + 9];
                    QuickLZ.write_header(array5, level, false, source.Length, source.Length + 9);
                    Array.Copy(source, 0, array5, 9, source.Length);
                    return(array5);
                }
                QuickLZ.fast_write(array, i2, (int)(num2 >> 1 | 2147483648u), 4);
                i2   = num;
                num += 4;
                num2 = 2147483648u;
            }
            if (level == 1)
            {
                int num6 = (num3 >> 12 ^ num3) & 4095;
                int num7 = array4[num6, 0];
                int num8 = array2[num6] ^ num3;
                array2[num6]    = num3;
                array4[num6, 0] = i;
                if (num8 == 0 && array3[num6] != 0 && (i - num7 > 2 || (i == num7 + 1 && num5 >= 3 && i > 3 && source[i] == source[i - 3] && source[i] == source[i - 2] && source[i] == source[i - 1] && source[i] == source[i + 1] && source[i] == source[i + 2])))
                {
                    num2 = (num2 >> 1 | 2147483648u);
                    if (source[num7 + 3] != source[i + 3])
                    {
                        int num9 = 1 | num6 << 4;
                        array[num]     = (byte)num9;
                        array[num + 1] = (byte)(num9 >> 8);
                        i   += 3;
                        num += 2;
                    }
                    else
                    {
                        int num10 = i;
                        int num11 = (source.Length - 4 - i + 1 - 1 <= 255) ? (source.Length - 4 - i + 1 - 1) : 255;
                        i += 4;
                        if (source[num7 + i - num10] == source[i])
                        {
                            i++;
                            if (source[num7 + i - num10] == source[i])
                            {
                                i++;
                                while (source[num7 + (i - num10)] == source[i] && i - num10 < num11)
                                {
                                    i++;
                                }
                            }
                        }
                        int num12 = i - num10;
                        num6 <<= 4;
                        if (num12 < 18)
                        {
                            int num13 = num6 | num12 - 2;
                            array[num]     = (byte)num13;
                            array[num + 1] = (byte)(num13 >> 8);
                            num           += 2;
                        }
                        else
                        {
                            QuickLZ.fast_write(array, num, num6 | num12 << 16, 3);
                            num += 3;
                        }
                    }
                    num3 = ((int)source[i] | (int)source[i + 1] << 8 | (int)source[i + 2] << 16);
                    num5 = 0;
                }
                else
                {
                    num5++;
                    array3[num6] = 1;
                    array[num]   = source[i];
                    num2       >>= 1;
                    i++;
                    num++;
                    num3 = ((num3 >> 8 & 65535) | (int)source[i + 2] << 16);
                }
            }
            else
            {
                num3 = ((int)source[i] | (int)source[i + 1] << 8 | (int)source[i + 2] << 16);
                int  num14 = (source.Length - 4 - i + 1 - 1 <= 255) ? (source.Length - 4 - i + 1 - 1) : 255;
                int  num15 = (num3 >> 12 ^ num3) & 4095;
                byte b     = array3[num15];
                int  num16 = 0;
                int  num17 = 0;
                int  num18 = 0;
                int  num19;
                while (num18 < 16 && (int)b > num18)
                {
                    num19 = array4[num15, num18];
                    if ((byte)num3 == source[num19] && (byte)(num3 >> 8) == source[num19 + 1] && (byte)(num3 >> 16) == source[num19 + 2] && num19 < i - 2)
                    {
                        int num20 = 3;
                        while (source[num19 + num20] == source[i + num20] && num20 < num14)
                        {
                            num20++;
                        }
                        if (num20 > num16 || (num20 == num16 && num19 > num17))
                        {
                            num17 = num19;
                            num16 = num20;
                        }
                    }
                    num18++;
                }
                num19 = num17;
                array4[num15, (int)(b & 15)] = i;
                b            += 1;
                array3[num15] = b;
                if (num16 >= 3 && i - num19 < 131071)
                {
                    int num21 = i - num19;
                    for (int j = 1; j < num16; j++)
                    {
                        num3  = ((int)source[i + j] | (int)source[i + j + 1] << 8 | (int)source[i + j + 2] << 16);
                        num15 = ((num3 >> 12 ^ num3) & 4095);
                        byte[] expr_4D5_cp_0 = array3;
                        int    expr_4D5_cp_1 = num15;
                        byte   b2;
                        expr_4D5_cp_0[expr_4D5_cp_1] = (b2 = expr_4D5_cp_0[expr_4D5_cp_1]) + 1;
                        b = b2;
                        array4[num15, (int)(b & 15)] = i + j;
                    }
                    i   += num16;
                    num2 = (num2 >> 1 | 2147483648u);
                    if (num16 == 3 && num21 <= 63)
                    {
                        QuickLZ.fast_write(array, num, num21 << 2, 1);
                        num++;
                    }
                    else if (num16 == 3 && num21 <= 16383)
                    {
                        QuickLZ.fast_write(array, num, num21 << 2 | 1, 2);
                        num += 2;
                    }
                    else if (num16 <= 18 && num21 <= 1023)
                    {
                        QuickLZ.fast_write(array, num, num16 - 3 << 2 | num21 << 6 | 2, 2);
                        num += 2;
                    }
                    else if (num16 <= 33)
                    {
                        QuickLZ.fast_write(array, num, num16 - 2 << 2 | num21 << 7 | 3, 3);
                        num += 3;
                    }
                    else
                    {
                        QuickLZ.fast_write(array, num, num16 - 3 << 7 | num21 << 15 | 3, 4);
                        num += 4;
                    }
                    num5 = 0;
                }
                else
                {
                    array[num] = source[i];
                    num2     >>= 1;
                    i++;
                    num++;
                }
            }
        }
        while (i <= source.Length - 1)
        {
            if ((num2 & 1u) == 1u)
            {
                QuickLZ.fast_write(array, i2, (int)(num2 >> 1 | 2147483648u), 4);
                i2   = num;
                num += 4;
                num2 = 2147483648u;
            }
            array[num] = source[i];
            i++;
            num++;
            num2 >>= 1;
        }
        while ((num2 & 1u) != 1u)
        {
            num2 >>= 1;
        }
        QuickLZ.fast_write(array, i2, (int)(num2 >> 1 | 2147483648u), 4);
        QuickLZ.write_header(array, level, true, source.Length, num);
        array5 = new byte[num];
        Array.Copy(array, array5, num);
        return(array5);
    }