Example #1
0
 private static void fillBuffer(IntObject testMask, IntObject mask, IntObject buffer, sbyte[] @in, IntObject nextIn)
 {
     // if necessary, fill up in buffer and shift mask
     if (testMask.Value >= 0 && testMask.Value <= 0x00FFFFFF)
     {
         buffer.Value = (buffer.Value << 8) + u8(@in[nextIn.incr()]);
         mask.Value   = testMask.Value << 8;
     }
 }
Example #2
0
        private static int getNumber(int nBits, sbyte[] buf, int bufPtr, int inc, BoolObject flag, IntObject mask, IntObject buffer, sbyte[] @in, IntObject nextIn)
        {
            // Extract and return a number (consisting of n_bits bits) from in stream
            IntObject number = new IntObject(1);

            if (nBits >= 3)
            {
                nextBit(buf, bufPtr + 3 * inc, number, mask, mask, buffer, @in, nextIn);
                if (nBits >= 4)
                {
                    nextBit(buf, bufPtr + 3 * inc, number, mask, mask, buffer, @in, nextIn);
                    if (nBits >= 5)
                    {
                        fillBuffer(mask, mask, buffer, @in, nextIn);
                        for (; nBits >= 5; nBits--)
                        {
                            number.Value = number.Value << 1;
                            mask.Value   = (int)((uint)mask.Value >> 1);
                            if (u32(buffer.Value) < u32(mask.Value))
                            {
                                number.incr();
                            }
                            else
                            {
                                buffer.sub(mask.Value);
                            }
                        }
                    }
                }
            }
            flag.Value = nextBit(buf, bufPtr, number, mask, mask, buffer, @in, nextIn);
            if (nBits >= 1)
            {
                nextBit(buf, bufPtr + inc, number, mask, mask, buffer, @in, nextIn);
                if (nBits >= 2)
                {
                    nextBit(buf, bufPtr + 2 * inc, number, mask, mask, buffer, @in, nextIn);
                }
            }

            return(number.Value);
        }
Example #3
0
        private static bool nextBit(sbyte[] buf, int bufPtr1, IntObject number, IntObject testMask, IntObject mask, IntObject buffer, sbyte[] @in, IntObject nextIn)
        {
            fillBuffer(testMask, mask, buffer, @in, nextIn);
            int value = ((int)((uint)mask.Value >> 8)) * u8(buf[bufPtr1]);

            if (testMask != mask)
            {
                testMask.Value = value;
            }
            buf[bufPtr1] -= (sbyte)(u8(buf[bufPtr1]) >> 3);
            number.Value  = number.Value << 1;
            if (u32(buffer.Value) < u32(value))
            {
                mask.Value    = value;
                buf[bufPtr1] += 31;
                number.incr();
                return(true);
            }

            buffer.sub(value);
            mask.sub(value);

            return(false);
        }
Example #4
0
        public static int decompress(sbyte[] @out, int outCapacity, sbyte[] @in)
        {
            int       type   = @in[0];
            IntObject buffer = new IntObject((u8(@in[1]) << 24) | (u8(@in[2]) << 16) | (u8(@in[3]) << 8) | u8(@in[4]));

            IntObject nextIn  = new IntObject(5);
            int       nextOut = 0;
            int       outEnd  = outCapacity;

            if (type < 0)
            {
                // copy from stream without decompression
                int seqEnd = nextOut + buffer.Value;
                if (seqEnd > outEnd)
                {
                    return(-1);
                }
                while (nextOut < seqEnd)
                {
                    @out[nextOut++] = @in[nextIn.incr()];
                }
                return(nextOut);
            }

            // Create and inti buffer
            sbyte[] buf = new sbyte[2800];
            Arrays.Fill(buf, unchecked ((sbyte)0x80));
            int bufOff = 0;

            IntObject mask     = new IntObject(unchecked ((int)0xFFFFFFFF));
            IntObject testMask = new IntObject(0);
            int       lastChar = 0;

            while (true)
            {
                int bufPtr1 = bufOff + 2488;
                if (!nextBit(buf, bufPtr1, IntObject.Null, mask, mask, buffer, @in, nextIn))
                {
                    // Single new char
                    if (bufOff > 0)
                    {
                        bufOff--;
                    }
                    if (nextOut == outEnd)
                    {
                        return(-1);
                    }
                    bufPtr1 = (((((nextOut & 0x07) << 8) + lastChar) >> type) & 0x07) * 0xFF - 0x01;
                    IntObject j = new IntObject(1);
                    while (j.Value <= 0xFF)
                    {
                        nextBit(buf, bufPtr1 + j.Value, j, mask, mask, buffer, @in, nextIn);
                    }
                    @out[nextOut++] = (sbyte)j.Value;
                }
                else
                {
                    // Sequence of chars that exists in out stream

                    // Find number of bits of sequence Length
                    testMask.Value = mask.Value;
                    int        nBits = -1;
                    BoolObject flag  = new BoolObject();
                    do
                    {
                        bufPtr1   += 8;
                        flag.Value = nextBit(buf, bufPtr1, IntObject.Null, testMask, mask, buffer, @in, nextIn);
                        if (flag.Value)
                        {
                            nBits++;
                        }
                    } while (flag.Value && nBits < 6);

                    // Find sequence Length
                    int bufPtr2 = nBits + 2033;
                    int j       = 64;
                    int seqLen;
                    if (flag.Value || nBits >= 0)
                    {
                        bufPtr1 = (nBits << 5) + (((nextOut << nBits) & 0x03) << 3) + bufOff + 2552;
                        seqLen  = getNumber(nBits, buf, bufPtr1, 8, flag, mask, buffer, @in, nextIn);
                        if (seqLen == 0xFF)
                        {
                            return(nextOut);                            // End of data stream
                        }
                        if (flag.Value || nBits > 0)
                        {
                            bufPtr2 += 56;
                            j        = 352;
                        }
                    }
                    else
                    {
                        seqLen = 1;
                    }

                    // Find number of bits of sequence offset
                    IntObject i = new IntObject(1);
                    do
                    {
                        nBits      = (i.Value << 4) - j;
                        flag.Value = nextBit(buf, bufPtr2 + (i.Value << 3), i, mask, mask, buffer, @in, nextIn);
                    } while (nBits < 0);

                    // Find sequence offset
                    int seqOff;
                    if (flag.Value || nBits > 0)
                    {
                        if (!flag.Value)
                        {
                            nBits -= 8;
                        }
                        seqOff = getNumber(nBits / 8, buf, nBits + 2344, 1, flag, mask, buffer, @in, nextIn);
                    }
                    else
                    {
                        seqOff = 1;
                    }

                    // Copy sequence
                    int nextSeq = nextOut - seqOff;
                    if (nextSeq < 0)
                    {
                        return(-1);
                    }
                    int seqEnd = nextOut + seqLen + 1;
                    if (seqEnd > outEnd)
                    {
                        return(-1);
                    }
                    bufOff = ((seqEnd + 1) & 0x01) + 0x06;
                    do
                    {
                        @out[nextOut++] = @out[nextSeq++];
                    } while (nextOut < seqEnd);
                }
                lastChar = u8(@out[nextOut - 1]);
            }
        }