/// <summary> Reads from the bit stream one bit. If 'bpos' is -1 then a byte is read /// and loaded into the bit buffer, from where the bit is read. If /// necessary the bit unstuffing will be applied. /// /// </summary> /// <returns> The read bit (0 or 1). /// /// </returns> public int readBit() { if (bpos < 0) { if ((bbuf & 0xFF) != 0xFF) { // Normal byte to read bbuf = in_Renamed.read(); bpos = 7; } else { // Previous byte is 0xFF => there was bit stuffing bbuf = in_Renamed.read(); bpos = 6; } } return((bbuf >> bpos--) & 0x01); }
/// <summary> 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. /// /// </summary> /// <returns> True if errors are found, false otherwise. /// /// </returns> public virtual bool checkPredTerm() { int k; // Number of bits that where added in the termination process uint 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 = (uint)in_Renamed.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 = (int)(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 = ((uint)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); }