📄 stdentropycoder.java
字号:
/** * Compresses the code-block in 'srcblk' and puts the results in 'ccb', * using the specified options and temporary storage. * * @param c The component for which to return the next code-block. * * @param ccb The object where the compressed data will be stored. If the * 'data' array of 'cbb' is not null it may be reused to return the * compressed data. * * @param srcblk The code-block data to code * * @param mq The MQ-coder to use * * @param bout The bit level output to use. Used only if 'OPT_BYPASS' is * turned on in the 'options' argument. * * @param out The byte buffer trough which the compressed data is stored. * * @param state The state information for the code-block * * @param distbuf The buffer where to store the distortion at * the end of each coding pass. * * @param ratebuf The buffer where to store the rate (i.e. coded lenth) at * the end of each coding pass. * * @param istermbuf The buffer where to store the terminated flag for each * coding pass. * * @param symbuf The buffer to hold symbols to send to the MQ coder * * @param ctxtbuf A buffer to hold the contexts to use in sending the * buffered symbols to the MQ coder. * * @param options The options to use when coding this code-block * * @param rev The reversible flag. Should be true if the source of this * code-block's data is reversible. * * @param lcType The type of length calculation to use with the MQ coder. * * @param tType The type of termination to use with the MQ coder. * * @see #getNextCodeBlock * */ static private void compressCodeBlock(int c, CBlkRateDistStats ccb, CBlkWTData srcblk, MQCoder mq, BitToByteOutput bout, ByteOutputBuffer out, int state[], double distbuf[], int ratebuf[], boolean istermbuf[], int symbuf[], int ctxtbuf[], int options, boolean rev, int lcType, int tType) { // NOTE: This method should not access any non-final instance or // static variables, either directly or indirectly through other // methods in order to be sure that the method is thread safe. int zc_lut[]; // The ZC lookup table to use int skipbp; // The number of non-significant bit-planes to skip int curbp; // The current magnitude bit-plane (starts at 30) int fm[]; // The distortion estimation lookup table for MR int fs[]; // The distortion estimation lookup table for SC int lmb; // The least significant magnitude bit int npass; // The number of coding passes, for R-D statistics double msew; // The distortion (MSE weight) for the current bit-plane double totdist;// The total cumulative distortion decrease int ltpidx; // The index of the last pass which is terminated // Check error-resilient termination if ((options & OPT_ER_TERM) != 0 && tType != MQCoder.TERM_PRED_ER) { throw new IllegalArgumentException("Embedded error-resilient info "+ "in MQ termination option "+ "specified but incorrect MQ "+ "termination "+ "policy specified"); } // Set MQ flags mq.setLenCalcType(lcType); mq.setTermType(tType); lmb = 30-srcblk.magbits+1; // If there are are more bit-planes to code than the implementation // bitdepth set lmb to 0 lmb = (lmb < 0) ? 0:lmb; // Reset state ArrayUtil.intArraySet(state,0); // Find the most significant bit-plane skipbp = calcSkipMSBP(srcblk,lmb); // Initialize output code-block ccb.m = srcblk.m; ccb.n = srcblk.n; ccb.sb = srcblk.sb; ccb.nROIcoeff = srcblk.nROIcoeff; ccb.skipMSBP = skipbp; if(ccb.nROIcoeff!=0) { ccb.nROIcp = 3*(srcblk.nROIbp-skipbp-1)+1; } else { ccb.nROIcp = 0; } // Choose correct ZC lookup table for global orientation switch (srcblk.sb.gOrient) { case Subband.WT_ORIENT_HL: zc_lut = ZC_LUT_HL; break; case Subband.WT_ORIENT_LL: case Subband.WT_ORIENT_LH: zc_lut = ZC_LUT_LH; break; case Subband.WT_ORIENT_HH: zc_lut = ZC_LUT_HH; break; default: throw new Error("JJ2000 internal error"); } // Loop on significant magnitude bit-planes doing the 3 passes curbp = 30-skipbp; fs = FS_LOSSY; fm = FM_LOSSY; msew = Math.pow(2,((curbp-lmb)<<1)-MSE_LKP_FRAC_BITS)* srcblk.sb.stepWMSE*srcblk.wmseScaling; totdist = 0f; npass = 0; ltpidx = -1; // First significant bit-plane has only the pass pass if (curbp >= lmb) { // Do we need the "lossless" 'fs' table ? if (rev && curbp == lmb) { fs = FM_LOSSLESS; } // We terminate if regular termination, last bit-plane, or next // bit-plane is "raw". istermbuf[npass] = (options & OPT_REG_TERM) != 0 || curbp == lmb || ((options & OPT_BYPASS) != 0 && (31-NUM_NON_BYPASS_MS_BP-skipbp)>=curbp); totdist += cleanuppass(srcblk,mq,istermbuf[npass],curbp,state, fs,zc_lut,symbuf,ctxtbuf,ratebuf, npass,ltpidx,options)*msew; distbuf[npass] = totdist; if (istermbuf[npass]) ltpidx = npass; npass++; msew *= 0.25; curbp--; } // Other bit-planes have all passes while (curbp >= lmb) { // Do we need the "lossless" 'fs' and 'fm' tables ? if (rev && curbp == lmb) { fs = FS_LOSSLESS; fm = FM_LOSSLESS; } // Do the significance propagation pass // We terminate if regular termination only istermbuf[npass] = (options & OPT_REG_TERM) != 0; if ((options & OPT_BYPASS) == 0 || (31-NUM_NON_BYPASS_MS_BP-skipbp<=curbp)) { // No bypass coding totdist += sigProgPass(srcblk,mq,istermbuf[npass],curbp, state,fs,zc_lut, symbuf,ctxtbuf,ratebuf, npass,ltpidx,options)*msew; } else { // Bypass ("raw") coding totdist += rawSigProgPass(srcblk,bout,istermbuf[npass],curbp, state,fs,ratebuf,npass,ltpidx, options)*msew; } distbuf[npass] = totdist; if (istermbuf[npass]) ltpidx = npass; npass++; // Do the magnitude refinement pass // We terminate if regular termination or bypass ("raw") coding istermbuf[npass] = (options & OPT_REG_TERM) != 0 || ((options & OPT_BYPASS) != 0 && (31-NUM_NON_BYPASS_MS_BP-skipbp>curbp)); if ((options & OPT_BYPASS) == 0 || (31-NUM_NON_BYPASS_MS_BP-skipbp<=curbp)) { // No bypass coding totdist += magRefPass(srcblk,mq,istermbuf[npass],curbp,state, fm,symbuf,ctxtbuf,ratebuf, npass,ltpidx,options)*msew; } else { // Bypass ("raw") coding totdist += rawMagRefPass(srcblk,bout,istermbuf[npass],curbp, state,fm,ratebuf, npass,ltpidx,options)*msew; } distbuf[npass] = totdist; if (istermbuf[npass]) ltpidx = npass; npass++; // Do the clenup pass // We terminate if regular termination, last bit-plane, or next // bit-plane is "raw". istermbuf[npass] = (options & OPT_REG_TERM) != 0 || curbp == lmb || ((options & OPT_BYPASS) != 0 && (31-NUM_NON_BYPASS_MS_BP-skipbp)>=curbp); totdist += cleanuppass(srcblk,mq,istermbuf[npass],curbp,state, fs,zc_lut,symbuf,ctxtbuf,ratebuf, npass,ltpidx,options)*msew; distbuf[npass] = totdist; if (istermbuf[npass]) ltpidx = npass; npass++; // Goto next bit-plane msew *= 0.25; curbp--; } // Copy compressed data and rate-distortion statistics to output ccb.data = new byte[out.size()]; out.toByteArray(0,out.size(),ccb.data,0); checkEndOfPassFF(ccb.data,ratebuf,istermbuf,npass); ccb.selectConvexHull(ratebuf,distbuf, (options&(OPT_BYPASS|OPT_REG_TERM))!=0?istermbuf: null,npass,rev); // Reset MQ coder and bit output for next code-block mq.reset(); if (bout != null) bout.reset(); // Done } /** * Calculates the number of magnitude bit-planes that are to be skipped, * because they are non-significant. The algorithm looks for the largest * magnitude and calculates the most significant bit-plane of it. * * @param cblk The code-block of data to scan * * @param lmb The least significant magnitude bit in the data * * @return The number of magnitude bit-planes to skip (i.e. all zero most * significant bit-planes). **/ static private int calcSkipMSBP(CBlkWTData cblk, int lmb) { int k,kmax,mask; int data[]; int maxmag; int mag; int w,h; int msbp; int l; data = (int[]) cblk.getData(); w = cblk.w; h = cblk.h; // First look for the maximum magnitude in the code-block maxmag = 0; // Consider only magnitude bits that are in non-fractional bit-planes. mask = 0x7FFFFFFF&(~((1<<lmb)-1)); for (l=h-1, k=cblk.offset; l>=0; l--) { for (kmax = k+w; k<kmax; k++) { mag = data[k]&mask; if (mag > maxmag) maxmag = mag; } k += cblk.scanw-w; } // Now calculate the number of all zero most significant bit-planes for // the maximum magnitude. msbp = 30; do { if (((1<<msbp)&maxmag)!=0) break; msbp--; } while (msbp>=lmb); // Return the number of non-significant bit-planes to skip return 30-msbp; } /** * Performs the significance propagation pass on the specified data and * bit-plane. It codes all insignificant samples which have, at least, one * of its immediate eight neighbors already significant, using the ZC and * SC primitives as needed. It toggles the "visited" state bit to 1 for * all those samples. * * @param srcblk The code-block data to code * * @param mq The MQ-coder to use * * @param doterm If true it performs an MQ-coder termination after the end * of the pass * * @param bp The bit-plane to code * * @param state The state information for the code-block * * @param fs The distortion estimation lookup table for SC * * @param zc_lut The ZC lookup table to use in ZC. * * @param symbuf The buffer to hold symbols to send to the MQ coder * * @param ctxtbuf A buffer to hold the contexts to use in sending the * buffered symbols to the MQ coder. * * @param ratebuf The buffer where to store the rate (i.e. coded lenth) at * the end of this coding pass.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -