⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mqdecoder.java

📁 jpeg2000算法实现
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
                                byteIn();                            la<<=1;                            c<<=1;                            cT--;                        }while(la < 0x8000);                        // -- End renormalization                    }                    // -- End MPS Exchange                    a = la;                }            }            else {                la = a;                c -= (la<<16);                // -- LPS Exchange                if(la < q){                    la = q;                    bits[i] = mPS[ctxt];                    I[ctxt] = nMPS[index];                    // -- Renormalize (MPS: no need for while loop)                    if(cT==0)                        byteIn();                    la<<=1;                    c<<=1;                    cT--;                    // -- End renormalization                }                else {                    la = q;                    bits[i] = 1-mPS[ctxt];                    if(switchLM[index] == 1)                        mPS[ctxt] = 1-mPS[ctxt];                    I[ctxt] = nLPS[index];                    // -- Renormalize                    do{                        if(cT==0)                            byteIn();                        la<<=1;                        c<<=1;                        cT--;                    } while (la < 0x8000);                    // -- End renormalization                }                // -- End LPS Exchange                                a = la;            }        }    }    /**     * Arithmetically decodes one symbol from the bit stream with the given     * context and returns its decoded value.     *     * <P>Each context has a current MPS and an index describing what the      * current probability is for the LPS. Each bit is encoded and if the     * probability of the LPS exceeds .5, the MPS and LPS are switched.     *     * @param context The context to use in decoding the symbol     *     * @return The decoded symbol, 0 or 1.     *     *     */    public final int decodeSymbol(int context){        int q;        int la;        int index;        int decision;        index = I[context];        q = qe[index];                // NOTE: (a < 0x8000) is equivalent to ((a & 0x8000)==0)        // since 'a' is always less than or equal to 0xFFFF        // NOTE: conditional exchange guarantees that A for MPS is        // always greater than 0x4000 (i.e. 0.375)        // => one renormalization shift is enough for MPS        // => no need to do a renormalization while loop for MPS        a -= q;        if ((c>>>16) < a) {            if(a >= 0x8000){                decision = mPS[context];            }            else {                la = a;                // -- MPS Exchange                if(la >= q){                    decision = mPS[context];                    I[context] = nMPS[index];                    // -- Renormalize (MPS: no need for while loop)                    if(cT==0)                        byteIn();                    la<<=1;                    c<<=1;                    cT--;                    // -- End renormalization                }                else{                    decision = 1-mPS[context];                    if(switchLM[index]==1)                        mPS[context] = 1-mPS[context];                    I[context] = nLPS[index];                    // -- Renormalize                    do{                        if(cT==0)                            byteIn();                        la<<=1;                        c<<=1;                        cT--;                    }while(la < 0x8000);                    // -- End renormalization                }                // -- End MPS Exchange                a = la;            }        }        else {            la = a;            c -= (la<<16);            // -- LPS Exchange            if(la < q){                la = q;                decision = mPS[context];                I[context] = nMPS[index];                // -- Renormalize (MPS: no need for while loop)                if(cT==0)                    byteIn();                la<<=1;                c<<=1;                cT--;                // -- End renormalization            }            else {                la = q;                decision = 1-mPS[context];                if(switchLM[index] == 1)                    mPS[context] = 1-mPS[context];                I[context] = nLPS[index];                // -- Renormalize                do{                    if(cT==0)                        byteIn();                    la<<=1;                    c<<=1;                    cT--;                } while (la < 0x8000);                // -- End renormalization            }            // -- End LPS Exchange            a = la;        }        return decision;    }    /**     * Checks for past errors in the decoding process using the predictable     * error resilient termination. This works only if the encoder used the     * predictable error resilient MQ termination, otherwise it reports wrong     * results. If an error is detected it means that the MQ bit stream has     * been wrongly decoded or that the MQ terminated segment length is too     * long. If no errors are detected it does not necessarily mean that the     * MQ bit stream has been correctly decoded.     *     * @return True if errors are found, false otherwise.     * */    public boolean checkPredTerm() {        int k;  // Number of bits that where added in the termination process        int q;        // 1) if everything has been OK, 'b' must be 0xFF if a terminating        // marker has not yet been found        if (b != 0xFF && !markerFound) return true;        // 2) if cT is not 0, we must have already reached the terminating        // marker        if (cT != 0 && !markerFound) return true;        // 3) If cT is 1 there where no spare bits at the encoder, this is all        // that we can check        if (cT == 1) return false;        // 4) if cT is 0, then next byte must be the second byte of a        // terminating marker (i.e. larger than 0x8F) if the terminating        // marker has not been reached yet        if (cT == 0) {            if (!markerFound) {                // Get next byte and check                b=in.read()&0xFF;                if (b <= 0x8F) return true;            }            // Adjust cT for last byte            cT = 8;        }        // 5) Now we can calculate the number 'k' of bits having error        // resilience information, which is the number of bits left to        // normalization in the C register, minus 1.        k = cT-1;        // 6) The predictable termination policy is as if an LPS interval was        // coded that caused a renormalization of 'k' bits, before the        // termination marker started        // We first check if an LPS is decoded, that causes a renormalization        // of 'k' bits. Worst case is smallest LPS probability 'q' that causes        // a renormalization of 'k' bits.        q = 0x8000>>k;        // Check that we can decode an LPS interval of probability 'q'        a -= q;        if ((c>>>16) < a) {            // Error: MPS interval decoded            return true;        }        // OK: LPS interval decoded        c -= (a<<16);        // -- LPS Exchange        // Here 'a' can not be smaller than 'q' because the minimum value        // for 'a' is 0x8000-0x4000=0x4000 and 'q' is set to a value equal        // to or smaller than that.        a = q;        // -- Renormalize        do{            if(cT==0) byteIn();            a<<=1;            c<<=1;            cT--;        } while (a < 0x8000);        // -- End renormalization        // -- End LPS Exchange        // 7) Everything seems OK, we have checked the C register for the LPS        // symbols and ensured that it is followed by bits synthetized by the        // termination marker.        return false;    }    /**     * This function gets one byte of compressed bits from the in-stream.      * the byte is added to c. If the byte is 0xFF and the next byte is greater     * than 0x8F, the byte after 0xFF is a marker.     *     *     *     */    private void byteIn(){        if(!markerFound){            if(b==0xFF){                b=in.read()&0xFF; // Convert EOFs (-1) to 0xFF                if(b>0x8F){                    markerFound=true;                    // software-convention decoder: c unchanged                    cT=8;                }else{                    c += 0xFE00 - (b<<9);                    cT=7;                }            }else{                b=in.read()&0xFF; // Convert EOFs (-1) to 0xFF                c += 0xFF00 - (b<<8);                cT=8;            }        }        else{            // software-convention decoder: c unchanged            cT=8;        }    }    /**      * Returns the number of contexts in the arithmetic coder.      *      * @return The number of contexts      *      *      **/    public final int getNumCtxts(){        return I.length;    }    /**     * Resets a context to the original probability distribution.     *     * @param c The number of the context (it starts at 0).     *     *     *     */    public final void resetCtxt(int c){        I[c] = initStates[c];        mPS[c] = 0;    }    /**     * Resets a context to the original probability distribution. The     * original probability distribution depends on the actual     * implementation of the arithmetic coder or decoder.     *     * @param c The index of the context (it starts at 0).     *     *     *     */    public final void resetCtxts(){        System.arraycopy(initStates,0,I,0,I.length);        ArrayUtil.intArraySet(mPS,0);    }    /**     * Resets the MQ decoder to start a new segment. This is like recreating a      * new MQDecoder object with new input data.     *     * @param buf The byte array containing the MQ encoded data. If null the     * current byte array is assumed.     *     * @param off The index of the first element in 'buf' to be decoded. If     * negative the byte just after the previous segment is assumed, only     * valid if 'buf' is null.     *     * @param len The number of bytes in 'buf' to be decoded. Any subsequent     * bytes are taken to be 0xFF.     *     *     * */    public final void nextSegment(byte buf[], int off, int len) {        // Set the new input        in.setByteArray(buf,off,len);        // Reinitialize MQ        init();    }    /**     * Returns the underlying 'ByteInputBuffer' from where the MQ     * coded input bytes are read.     *     * @return The underlying ByteInputBuffer.     *     * */    public ByteInputBuffer getByteInputBuffer() {        return in;    }    /**     * Initializes the state of the MQ coder, without modifying the current     * context states. It sets the registers (A,C,B) and the "marker found"     * state to the initial state, to start the decoding of a new segment.     *     * <P>To have a complete reset of the MQ (as if a new MQDecoder object was     * created) 'resetCtxts()' should be called after this method.     *     *     * */    private void init() {        // --- INITDEC        markerFound = false;        // Read first byte        b=in.read()&0xFF;        // Software conventions decoder        c=(b^0xFF)<<16;        byteIn();        c=c<<7;        cT=cT-7;        a=0x8000;        // End of INITDEC ---    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -