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

📄 mqcoder.java

📁 jpeg2000算法实现
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
            }            break;        default:            throw new Error("Illegal termination type code");        }        // Reinitialize the state (without modifying the contexts)        int len;        len = nrOfWrittenBytes;        a = 0x8000;        c = 0;        b = 0;        cT = 12;        delFF = false;        nrOfWrittenBytes = -1;        // Return the terminated length        return len;    }    /**     * 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, and sets its     * more probable symbol to 0.     *     * @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 all contexts to their original probability distribution and sets     * all more probable symbols to 0.     * */    public final void resetCtxts(){        System.arraycopy(initStates,0,I,0,I.length);        ArrayUtil.intArraySet(mPS,0);    }    /**     * Returns the number of bytes that are necessary from the compressed     * output stream to decode all the symbols that have been coded this     * far. The number of returned bytes does not include anything coded     * previous to the last time the 'terminate()' or 'reset()' methods where     * called.     *     * <P>The values returned by this method are then to be used in finishing     * the length calculation with the 'finishLengthCalculation()' method,     * after compensation of the offset in the number of bytes due to previous     * terminated segments.     *     * <P>This method should not be called if the current coding pass is to be     * terminated. The 'terminate()' method should be called instead.     *     * <P>The calculation is done based on the type of length calculation     * specified at the constructor.     *     * @return The number of bytes in the compressed output stream necessary     * to decode all the information coded this far.     * */    public final int getNumCodedBytes(){        // NOTE: testing these algorithms for correctness is quite        // difficult. One way is to modify the rate allocator so that not all        // bit-planes are output if the distortion estimate for last passes is        // the same as for the previous ones.        switch (ltype) {        case LENGTH_LAZY_GOOD:            // This one is a bit better than LENGTH_LAZY.            int bitsInN3Bytes; // The minimum amount of bits that can be stored                                // in the 3 bytes following the current byte                               // buffer 'b'.            if (b >= 0xFE) {                // The byte after b can have a bit stuffed so ther could be                // one less bit available                bitsInN3Bytes = 22; // 7 + 8 + 7            }            else {                // We are sure that next byte after current byte buffer has no                // bit stuffing                bitsInN3Bytes = 23; // 8 + 7 + 8            }            if ((11-cT+16) <= bitsInN3Bytes) {                return nrOfWrittenBytes+(delFF ? 1 : 0)+1+3;            }            else {                return nrOfWrittenBytes+(delFF ? 1 : 0)+1+4;            }        case LENGTH_LAZY:            // This is the very basic one that appears in the VM text            if ((27-cT) <= 22) {                return nrOfWrittenBytes+(delFF ? 1 : 0)+1+3;            }            else {                return nrOfWrittenBytes+(delFF ? 1 : 0)+1+4;            }        case LENGTH_NEAR_OPT:            // This is the best length calculation implemented in this class.            // It is almost always optimal. In order to calculate the length            // it is necessary to know which bytes will follow in the MQ            // bit stream, so we need to wait until termination to perform it.            // Save the state to perform the calculation later, in            // finishLengthCalculation()            saveState();            // Return current number of output bytes to use it later in            // finishLengthCalculation()            return nrOfWrittenBytes;        default:            throw new Error("Illegal length calculation type code");        }    }    /**     * Reinitializes the MQ coder and the underlying 'ByteOutputBuffer' buffer     * as if a new object was instantaited. All the data in the     * 'ByteOutputBuffer' buffer is erased and the state and contexts of the     * MQ coder are reinitialized). Additionally any saved MQ states are     * discarded.     * */    public final void reset() {        // Reset the output buffer        out.reset();        a=0x8000;        c=0;        b=0;        if(b==0xFF)            cT=13;        else            cT=12;        resetCtxts();        nrOfWrittenBytes = -1;        delFF = false;        nSaved = 0;    }    /**     * Saves the current state of the MQ coder (just the registers, not the     * contexts) so that a near optimal length calculation can be performed     * later.     * */    private void saveState() {        // Increase capacity if necessary        if (nSaved == savedC.length) {            Object tmp;            tmp = savedC;            savedC = new int[nSaved+SAVED_INC];            System.arraycopy(tmp,0,savedC,0,nSaved);            tmp = savedCT;            savedCT = new int[nSaved+SAVED_INC];            System.arraycopy(tmp,0,savedCT,0,nSaved);            tmp = savedA;            savedA = new int[nSaved+SAVED_INC];            System.arraycopy(tmp,0,savedA,0,nSaved);            tmp = savedB;            savedB = new int[nSaved+SAVED_INC];            System.arraycopy(tmp,0,savedB,0,nSaved);            tmp = savedDelFF;            savedDelFF = new boolean[nSaved+SAVED_INC];            System.arraycopy(tmp,0,savedDelFF,0,nSaved);        }        // Save the current sate        savedC[nSaved] = c;        savedCT[nSaved] = cT;        savedA[nSaved] = a;        savedB[nSaved] = b;        savedDelFF[nSaved] = delFF;        nSaved++;    }    /**     * Terminates the calculation of the required length for each coding     * pass. This method must be called just after the 'terminate()' one has     * been called for each terminated MQ segment.     *     * <P>The values in 'rates' must have been compensated for any offset due     * to previous terminated segments, so that the correct index to the     * stored coded data is used.     *     * @param rates The array containing the values returned by     * 'getNumCodedBytes()' for each coding pass.     *     * @param n The index in the 'rates' array of the last terminated length.     * */    public void finishLengthCalculation(int rates[], int n) {        if (ltype != LENGTH_NEAR_OPT) {            // For the simple calculations the only thing we need to do is to            // ensure that the calculated lengths are no greater than the            // terminated one            if (n > 0 && rates[n-1] > rates[n]) {                // We need correction                int tl = rates[n]; // The terminated length                n--;                do {                    rates[n--] = tl;               }  while (n >= 0 && rates[n] > tl);            }        }        else {            // We need to perform the more sophisticated near optimal            // calculation.            // The calculation of the length is based on the fact that the            // decoder will pad the codestream with an endless string of            // (binary) 1s after termination. If the codestream, padded with            // 1s, is within the bounds of the current interval then correct            // decoding is guaranteed. The lower inclusive bound of the            // current interval is the value of C (i.e. if only lower            // intervals would be coded in the future). The upper exclusive            // bound of the current interval is C+A (i.e. if only upper            // intervals would be coded in the future). We therefore calculate            // the minimum length that would be needed so that padding with 1s            // gives a codestream within the interval.            // In order to know what will be appended to the current base of            // the interval we need to know what is in the MQ bit stream after            // the current last output byte until the termination. This is why             // this calculation has to be performed after the MQ segment has            // been entirely coded and terminated.            int cLow; // lower bound on the C register for correct decoding            int cUp;  // upper bound on the C register for correct decoding            int bLow; // lower bound on the byte buffer for correct decoding            int bUp;  // upper bound on the byte buffer for correct decoding            int ridx; // index in the rates array of the pass we are            // calculating            int sidx; // index in the saved state array            int clen; // current calculated length            boolean cdFF; // the current delayed FF state            int nb;   // the next byte of output            int minlen; // minimum possible length            int maxlen; // maximum possible length            // Start on the first pass of this segment            ridx = n-nSaved;            // Minimum allowable length is length of previous termination            minlen = (ridx-1>=0) ? rates[ridx-1] : 0;            // Maximum possible length is the terminated length            maxlen = rates[n];            for (sidx = 0; ridx < n; ridx++, sidx++) {                // Load the initial values of the bounds                cLow = savedC[sidx];                cUp = savedC[sidx]+savedA[sidx];                bLow = savedB[sidx];                bUp = savedB[sidx];                // Normalize to CT = 0 and propagate and reset any carry bits                cLow <<= savedCT[sidx];                if ((cLow & 0x8000000) != 0) {                    bLow++;                    cLow &= 0x7FFFFFF;                }                cUp <<= savedCT[sidx];                if ((cUp & 0x8000000) != 0) {                    bUp++;                    cUp &= 0x7FFFFFF;                }                // Initialize current calculated length                cdFF = savedDelFF[sidx];                // rates[ridx] contains the number of bytes already output                // when the state was saved, compensated for the offset in the                 // output stream.                clen = rates[ridx]+(cdFF? 1 : 0);                while (true) {                    // If we are at end of coded data then this is the length                    if (clen >= maxlen) {                        clen = maxlen;                        break;                    }                    // Check for sufficiency of coded data                    if (cdFF) {                        if (bLow < 128 && bUp >= 128) {                            // We are done for this pass                            clen--; // Don't need delayed FF                            break;                        }                    }                    else {                        if (bLow < 256 && bUp >= 256) {                            // We are done for this pass                            break;                        }                    }                    // Update bounds with next byte of coded data and                    // normalize to CT = 0 again.                    nb =  (clen >= minlen) ? out.getByte(clen) : 0;                    bLow -= nb;                    bUp -= nb;                    clen++;                    if (nb == 0xFF) {                        bLow <<= 7;                        bLow |= (cLow >> 20) & 0x7F;                        cLow &= 0xFFFFF;                        cLow <<= 7;                        bUp <<= 7;                        bUp |= (cUp >> 20) & 0x7F;                        cUp &= 0xFFFFF;                        cUp <<= 7;                        cdFF = true;                    }                    else {                        bLow <<= 8;                        bLow |= (cLow >> 19) & 0xFF;                        cLow &= 0x7FFFF;                        cLow <<= 8;                        bUp <<= 8;                        bUp |= (cUp >> 19) & 0xFF;                        cUp &= 0x7FFFF;                        cUp <<= 8;                        cdFF = false;                    }                    // Test again                }                // Store the rate found                rates[ridx] = (clen>=minlen) ? clen : minlen;            }            // Reset the saved states            nSaved = 0;        }    }}

⌨️ 快捷键说明

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