📄 mqcoder.java
字号:
I[context]=nMPS[li]; // -- Renormalization (MPS: no need for while loop) a <<= 1; // a is doubled c <<= 1; // c is doubled cT--; if(cT==0) { byteOut(); } // -- End of renormalization } }// End Code MPS -- else{ // -- Code LPS la = a; // cache A register in local variable la -= q; // Interval division according to LPS coding if(la<q) c += q; else la = q; if(switchLM[li]!=0){ mPS[context]=1-mPS[context]; } I[context]=nLPS[li]; // -- Renormalization // sligthly better than normal loop n = 0; do { la <<= 1; n++; // count number of necessary shifts } while (la<0x8000); if (cT > n) { c <<= n; cT -= n; } else { do { c <<= cT; n -= cT; // cT = 0; // not necessary byteOut(); } while (cT <= n); c <<= n; cT -= n; } // -- End of renormalization a = la; // save cached A register } } /** * This function puts one byte of compressed bits in the out out stream. * the highest 8 bits of c are then put in b to be the next byte to * write. This method delays the output of any 0xFF bytes until a non 0xFF * byte has to be written to the output bit stream (the 'delFF' variable * signals if there is a delayed 0xff byte). * */ private void byteOut(){ if(nrOfWrittenBytes >= 0){ if(b==0xFF){ // Delay 0xFF byte delFF = true; b=c>>>20; c &= 0xFFFFF; cT=7; } else if(c < 0x8000000){ // Write delayed 0xFF bytes if (delFF) { out.write(0xFF); delFF = false; nrOfWrittenBytes++; } out.write(b); nrOfWrittenBytes++; b=c>>>19; c &= 0x7FFFF; cT=8; } else{ b++; if(b==0xFF){ // Delay 0xFF byte delFF = true; c &= 0x7FFFFFF; b=c>>>20; c &= 0xFFFFF; cT=7; } else{ // Write delayed 0xFF bytes if (delFF) { out.write(0xFF); delFF = false; nrOfWrittenBytes++; } out.write(b); nrOfWrittenBytes++; b=((c>>>19)&0xFF); c &= 0x7FFFF; cT=8; } } } else { // NOTE: carry bit can never be set if the byte buffer was empty b= (c>>>19); c &= 0x7FFFF; cT=8; nrOfWrittenBytes++; } } /** * This function flushes the remaining encoded bits and makes sure that * enough information is written to the bit stream to be able to finish * decoding, and then it reinitializes the internal state of the MQ coder * but without modifying the context states. * * <P>After calling this method the 'finishLengthCalculation()' method * should be called, after cmopensating the returned length for the length * of previous coded segments, so that the length calculation is finalized. * * <P>The type of termination used depends on the one specified at the * constructor. * * @return The length of the arithmetic codeword after termination, in * bytes. * */ public int terminate(){ switch (ttype) { case TERM_FULL: //sets the remaining bits of the last byte of the coded bits. int tempc=c+a; c=c|0xFFFF; if(c>=tempc) c=c-0x8000; int remainingBits = 27-cT; // Flushes remainingBits do{ c <<= cT; if(b != 0xFF) remainingBits -= 8; else remainingBits -= 7; byteOut(); } while(remainingBits > 0); b |= (1<<(-remainingBits))-1; if (b==0xFF) { // Delay 0xFF bytes delFF = true; } else { // Write delayed 0xFF bytes if (delFF) { out.write(0xFF); delFF = false; nrOfWrittenBytes++; } out.write(b); nrOfWrittenBytes++; } break; case TERM_PRED_ER: case TERM_EASY: // The predictable error resilient and easy termination are the // same, except for the fact that the easy one can modify the // spare bits in the last byte to maximize the likelihood of // having a 0xFF, while the error resilient one can not touch // these bits. // In the predictable error resilient case the spare bits will be // recalculated by the decoder and it will check if they are the // same as as in the codestream and then deduce an error // probability from there. int k; // number of bits to push out k = (11-cT)+1; c <<= cT; for (; k > 0; k-=cT, c<<=cT){ byteOut(); } // Make any spare bits 1s if in easy termination if (k < 0 && ttype == TERM_EASY) { // At this stage there is never a carry bit in C, so we can // freely modify the (-k) least significant bits. b |= (1<<(-k))-1; } byteOut(); // Push contents of byte buffer break; case TERM_NEAR_OPT: // This algorithm terminates in the shortest possible way, besides // the fact any previous 0xFF 0x7F sequences are not // eliminated. The probabalility of having those sequences is // extremely low. // The calculation of the length is based on the fact that the // decoder will pad the codestream with an endless string of // (binary) 1s. 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 general, such a calculation needs the value of the next byte // that appears in the codestream. Here, since we are terminating, // the next value can be anything we want that lies within the // interval, we use the lower bound since this minimizes the // length. To calculate the necessary length at any other place // than the termination it is necessary to know the next bytes // that will appear in the codestream, which involves storing the // codestream and the sate of the MQCoder at various points (a // worst case approach can be used, but it is much more // complicated and the calculated length would be only marginally // better than much simple calculations, if not the same). int cLow; int cUp; int bLow; int bUp; // Initialize the upper (exclusive) and lower bound (inclusive) of // the valid interval (the actual interval is the concatenation of // bUp and cUp, and bLow and cLow). cLow = c; cUp = c+a; bLow = bUp = b; // We start by normalizing the C register to the sate cT = 0 // (i.e., just before byteOut() is called) cLow <<= cT; cUp <<= cT; // Progate eventual carry bits and reset them in Clow, Cup NOTE: // carry bit can never be set if the byte buffer was empty so no // problem with propagating a carry into an empty byte buffer. if ((cLow & (1<<27)) != 0) { // Carry bit in cLow if (bLow == 0xFF) { // We can not propagate carry bit, do bit stuffing delFF = true; // delay 0xFF // Get next byte buffer bLow = cLow>>>20; bUp = cUp>>>20; cLow &= 0xFFFFF; cUp &= 0xFFFFF; // Normalize to cT = 0 cLow <<= 7; cUp <<= 7; } else { // we can propagate carry bit bLow++; // propagate cLow &= ~(1<<27); // reset carry in cLow } } if ((cUp & (1<<27)) != 0) { bUp++; // propagate cUp &= ~(1<<27); // reset carry } // From now on there can never be a carry bit on cLow, since we // always output bLow. // Loop testing for the condition and doing byte output if they // are not met. while(true){ // If decoder's codestream is within interval stop // If preceding byte is 0xFF only values [0,127] are valid if(delFF){ // If delayed 0xFF if (bLow <= 127 && bUp > 127) break; // We will write more bytes so output delayed 0xFF now out.write(0xFF); nrOfWrittenBytes++; delFF = false; } else{ // No delayed 0xFF if (bLow <= 255 && bUp > 255) break; } // Output next byte // We could output anything within the interval, but using // bLow simplifies things a lot. // We should not have any carry bit here // Output bLow if (bLow < 255) { // Transfer byte bits from C to B // (if the byte buffer was empty output nothing) if (nrOfWrittenBytes >= 0) out.write(bLow); nrOfWrittenBytes++; bUp -= bLow; bUp <<= 8; // Here bLow would be 0 bUp |= (cUp >>> 19) & 0xFF; bLow = (cLow>>> 19) & 0xFF; // Clear upper bits (just pushed out) from cUp Clow. cLow &= 0x7FFFF; cUp &= 0x7FFFF; // Goto next state where CT is 0 cLow <<= 8; cUp <<= 8; // Here there can be no carry on Cup, Clow } else { // bLow = 0xFF // Transfer byte bits from C to B // Since the byte to output is 0xFF we can delay it delFF = true; bUp -= bLow; bUp <<= 7; // Here bLow would be 0 bUp |= (cUp>>20) & 0x7F; bLow = (cLow>>20) & 0x7F; // Clear upper bits (just pushed out) from cUp Clow. cLow &= 0xFFFFF; cUp &= 0xFFFFF; // Goto next state where CT is 0 cLow <<= 7; cUp <<= 7; // Here there can be no carry on Cup, Clow }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -