All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.testifyproject.tukaani.xz.lzma.LZMADecoder Maven / Gradle / Ivy

There is a newer version: 1.0.0
Show newest version
/*
 * LZMADecoder
 *
 * Authors: Lasse Collin 
 *          Igor Pavlov 
 *
 * This file has been put into the public domain.
 * You can do whatever you want with this file.
 */

package org.testifyproject.tukaani.xz.lzma;

import java.org.testifyproject.testifyproject.IOException;
import org.testifyproject.tukaani.xz.lz.LZDecoder;
import org.testifyproject.tukaani.xz.rangecoder.RangeDecoder;
import org.testifyproject.tukaani.xz.CorruptedInputException;

public final class LZMADecoder extends LZMACoder {
    private final LZDecoder lz;
    private final RangeDecoder rc;
    private final LiteralDecoder literalDecoder;
    private final LengthDecoder matchLenDecoder = new LengthDecoder();
    private final LengthDecoder repLenDecoder = new LengthDecoder();

    public LZMADecoder(LZDecoder lz, RangeDecoder rc, int lc, int lp, int pb) {
        super(pb);
        this.lz = lz;
        this.rc = rc;
        this.literalDecoder = new LiteralDecoder(lc, lp);
        reset();
    }

    public void reset() {
        super.reset();
        literalDecoder.reset();
        matchLenDecoder.reset();
        repLenDecoder.reset();
    }

    public void org.testifyproject.testifyprojectcode() throws IOException {
        lz.repeatPending();

        while (lz.hasSpace()) {
            int posState = lz.getPos() & posMask;

            if (rc.org.testifyproject.testifyprojectcodeBit(isMatch[state.get()], posState) == 0) {
                literalDecoder.org.testifyproject.testifyprojectcode();
            } else {
                int len = rc.org.testifyproject.testifyprojectcodeBit(isRep, state.get()) == 0
                          ? org.testifyproject.testifyprojectcodeMatch(posState)
                          : org.testifyproject.testifyprojectcodeRepMatch(posState);
                lz.repeat(reps[0], len);
            }
        }

        rc.normalize();

        if (!rc.isInBufferOK())
            throw new CorruptedInputException();
    }

    private int org.testifyproject.testifyprojectcodeMatch(int posState) throws IOException {
        state.updateMatch();

        reps[3] = reps[2];
        reps[2] = reps[1];
        reps[1] = reps[0];

        int len = matchLenDecoder.org.testifyproject.testifyprojectcode(posState);
        int distSlot = rc.org.testifyproject.testifyprojectcodeBitTree(distSlots[getDistState(len)]);

        if (distSlot < DIST_MODEL_START) {
            reps[0] = distSlot;
        } else {
            int limit = (distSlot >> 1) - 1;
            reps[0] = (2 | (distSlot & 1)) << limit;

            if (distSlot < DIST_MODEL_END) {
                reps[0] |= rc.org.testifyproject.testifyprojectcodeReverseBitTree(
                        distSpecial[distSlot - DIST_MODEL_START]);
            } else {
                reps[0] |= rc.org.testifyproject.testifyprojectcodeDirectBits(limit - ALIGN_BITS)
                           << ALIGN_BITS;
                reps[0] |= rc.org.testifyproject.testifyprojectcodeReverseBitTree(distAlign);
            }
        }

        return len;
    }

    private int org.testifyproject.testifyprojectcodeRepMatch(int posState) throws IOException {
        if (rc.org.testifyproject.testifyprojectcodeBit(isRep0, state.get()) == 0) {
            if (rc.org.testifyproject.testifyprojectcodeBit(isRep0Long[state.get()], posState) == 0) {
                state.updateShortRep();
                return 1;
            }
        } else {
            int tmp;

            if (rc.org.testifyproject.testifyprojectcodeBit(isRep1, state.get()) == 0) {
                tmp = reps[1];
            } else {
                if (rc.org.testifyproject.testifyprojectcodeBit(isRep2, state.get()) == 0) {
                    tmp = reps[2];
                } else {
                    tmp = reps[3];
                    reps[3] = reps[2];
                }

                reps[2] = reps[1];
            }

            reps[1] = reps[0];
            reps[0] = tmp;
        }

        state.updateLongRep();

        return repLenDecoder.org.testifyproject.testifyprojectcode(posState);
    }


    private class LiteralDecoder extends LiteralCoder {
        LiteralSubdecoder[] subdecoders;

        LiteralDecoder(int lc, int lp) {
            super(lc, lp);

            subdecoders = new LiteralSubdecoder[1 << (lc + lp)];
            for (int i = 0; i < subdecoders.length; ++i)
                subdecoders[i] = new LiteralSubdecoder();
        }

        void reset() {
            for (int i = 0; i < subdecoders.length; ++i)
                subdecoders[i].reset();
        }

        void org.testifyproject.testifyprojectcode() throws IOException {
            int i = getSubcoderIndex(lz.getByte(0), lz.getPos());
            subdecoders[i].org.testifyproject.testifyprojectcode();
        }


        private class LiteralSubdecoder extends LiteralSubcoder {
            void org.testifyproject.testifyprojectcode() throws IOException {
                int symbol = 1;

                if (state.isLiteral()) {
                    do {
                        symbol = (symbol << 1) | rc.org.testifyproject.testifyprojectcodeBit(probs, symbol);
                    } while (symbol < 0x100);

                } else {
                    int matchByte = lz.getByte(reps[0]);
                    int offset = 0x100;
                    int matchBit;
                    int bit;

                    do {
                        matchByte <<= 1;
                        matchBit = matchByte & offset;
                        bit = rc.org.testifyproject.testifyprojectcodeBit(probs, offset + matchBit + symbol);
                        symbol = (symbol << 1) | bit;
                        offset &= (0 - bit) ^ ~matchBit;
                    } while (symbol < 0x100);
                }

                lz.putByte((byte)symbol);
                state.updateLiteral();
            }
        }
    }


    private class LengthDecoder extends LengthCoder {
        int org.testifyproject.testifyprojectcode(int posState) throws IOException {
            if (rc.org.testifyproject.testifyprojectcodeBit(choice, 0) == 0)
                return rc.org.testifyproject.testifyprojectcodeBitTree(low[posState]) + MATCH_LEN_MIN;

            if (rc.org.testifyproject.testifyprojectcodeBit(choice, 1) == 0)
                return rc.org.testifyproject.testifyprojectcodeBitTree(mid[posState])
                       + MATCH_LEN_MIN + LOW_SYMBOLS;

            return rc.org.testifyproject.testifyprojectcodeBitTree(high)
                   + MATCH_LEN_MIN + LOW_SYMBOLS + MID_SYMBOLS;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy