/// <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);
 }
Exemple #2
0
        /// <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);
        }