corrade-vassal – Rev 1

Subversion Repositories:
Rev:
/* 
* CVS identifier:
* 
* $Id: BitToByteOutput.java,v 1.16 2001/10/17 16:56:59 grosbois Exp $
* 
* Class:                   BitToByteOutput
* 
* Description:             Adapter to perform bit based output on a byte
*                          based one.
* 
* 
* 
* COPYRIGHT:
* 
* This software module was originally developed by Raphaël Grosbois and
* Diego Santa Cruz (Swiss Federal Institute of Technology-EPFL); Joel
* Askelöf (Ericsson Radio Systems AB); and Bertrand Berthelot, David
* Bouchard, Félix Henry, Gerard Mozelle and Patrice Onno (Canon Research
* Centre France S.A) in the course of development of the JPEG2000
* standard as specified by ISO/IEC 15444 (JPEG 2000 Standard). This
* software module is an implementation of a part of the JPEG 2000
* Standard. Swiss Federal Institute of Technology-EPFL, Ericsson Radio
* Systems AB and Canon Research Centre France S.A (collectively JJ2000
* Partners) agree not to assert against ISO/IEC and users of the JPEG
* 2000 Standard (Users) any of their rights under the copyright, not
* including other intellectual property rights, for this software module
* with respect to the usage by ISO/IEC and Users of this software module
* or modifications thereof for use in hardware or software products
* claiming conformance to the JPEG 2000 Standard. Those intending to use
* this software module in hardware or software products are advised that
* their use may infringe existing patents. The original developers of
* this software module, JJ2000 Partners and ISO/IEC assume no liability
* for use of this software module or modifications thereof. No license
* or right to this software module is granted for non JPEG 2000 Standard
* conforming products. JJ2000 Partners have full right to use this
* software module for his/her own purpose, assign or donate this
* software module to any third party and to inhibit third parties from
* using this software module for non JPEG 2000 Standard conforming
* products. This copyright notice must be included in all copies or
* derivative works of this software module.
* 
* Copyright (c) 1999/2000 JJ2000 Partners.
* */
using System;
using CSJ2K.j2k.io;
namespace CSJ2K.j2k.entropy.encoder
{
        
        /// <summary> This class provides an adapter to perform bit based output on byte based
        /// output objects that inherit from a 'ByteOutputBuffer' class. This class
        /// implements the bit stuffing policy needed for the 'selective arithmetic
        /// coding bypass' mode of the entropy coder. This class also delays the output
        /// of a trailing 0xFF, since they are synthetized be the decoder.
        /// 
        /// </summary>
        class BitToByteOutput
        {
                /// <summary> Set the flag according to whether or not the predictable termination is
                /// requested.
                /// 
                /// </summary>
                /// <param name="isPredTerm">Whether or not predictable termination is requested.
                /// 
                /// </param>
                virtual internal bool PredTerm
                {
                        set
                        {
                                this.isPredTerm = value;
                        }
                        
                }
                
                /// <summary>Whether or not predictable termination is requested. This value is
                /// important when the last byte before termination is an 0xFF  
                /// </summary>
                private bool isPredTerm = false;
                
                /// <summary>The alternating sequence of 0's and 1's used for byte padding </summary>
                internal const int PAD_SEQ = 0x2A;
                
                /// <summary>Flag that indicates if an FF has been delayed </summary>
                internal bool delFF = false;
                
                /// <summary>The byte based output </summary>
                internal ByteOutputBuffer out_Renamed;
                
                /// <summary>The bit buffer </summary>
                internal int bbuf;
                
                /// <summary>The position of the next bit to put in the bit buffer. When it is 7
                /// the bit buffer 'bbuf' is empty. The value should always be between 7
                /// and 0 (i.e. if it gets to -1, the bit buffer should be immediately
                /// written to the byte output). 
                /// </summary>
                internal int bpos = 7;
                
                /// <summary>The number of written bytes (excluding the bit buffer) </summary>
                internal int nb = 0;
                
                /// <summary> Instantiates a new 'BitToByteOutput' object that uses 'out' as the
                /// underlying byte based output.
                /// 
                /// </summary>
                /// <param name="out">The underlying byte based output
                /// 
                /// </param>
                internal BitToByteOutput(ByteOutputBuffer out_Renamed)
                {
                        this.out_Renamed = out_Renamed;
                }
                
                /// <summary> Writes to the bit stream the symbols contained in the 'symbuf'
                /// buffer. The least significant bit of each element in 'symbuf'is
                /// written.
                /// 
                /// </summary>
                /// <param name="symbuf">The symbols to write
                /// 
                /// </param>
                /// <param name="nsym">The number of symbols in symbuf
                /// 
                /// </param>
                internal void  writeBits(int[] symbuf, int nsym)
                {
                        int i;
                        int bbuf, bpos;
                        bbuf = this.bbuf;
                        bpos = this.bpos;
                        // Write symbol by symbol to bit buffer
                        for (i = 0; i < nsym; i++)
                        {
                                bbuf |= (symbuf[i] & 0x01) << (bpos--);
                                if (bpos < 0)
                                {
                                        // Bit buffer is full, write it
                                        if (bbuf != 0xFF)
                                        {
                                                // No bit-stuffing needed
                                                if (delFF)
                                                {
                                                        // Output delayed 0xFF if any
                                                        out_Renamed.write(0xFF);
                                                        nb++;
                                                        delFF = false;
                                                }
                                                out_Renamed.write(bbuf);
                                                nb++;
                                                bpos = 7;
                                        }
                                        else
                                        {
                                                // We need to do bit stuffing on next byte
                                                delFF = true;
                                                bpos = 6; // One less bit in next byte
                                        }
                                        bbuf = 0;
                                }
                        }
                        this.bbuf = bbuf;
                        this.bpos = bpos;
                }
                
                /// <summary> Write a bit to the output. The least significant bit of 'bit' is
                /// written to the output.
                /// 
                /// </summary>
                /// <param name="bit">
                /// </param>
                internal void  writeBit(int bit)
                {
                        bbuf |= (bit & 0x01) << (bpos--);
                        if (bpos < 0)
                        {
                                if (bbuf != 0xFF)
                                {
                                        // No bit-stuffing needed
                                        if (delFF)
                                        {
                                                // Output delayed 0xFF if any
                                                out_Renamed.write(0xFF);
                                                nb++;
                                                delFF = false;
                                        }
                                        // Output the bit buffer
                                        out_Renamed.write(bbuf);
                                        nb++;
                                        bpos = 7;
                                }
                                else
                                {
                                        // We need to do bit stuffing on next byte
                                        delFF = true;
                                        bpos = 6; // One less bit in next byte
                                }
                                bbuf = 0;
                        }
                }
                
                /// <summary> Writes the contents of the bit buffer and byte aligns the output by
                /// filling bits with an alternating sequence of 0's and 1's.
                /// 
                /// </summary>
                internal virtual void  flush()
                {
                        if (delFF)
                        {
                                // There was a bit stuffing
                                if (bpos != 6)
                                {
                                        // Bit buffer is not empty
                                        // Output delayed 0xFF
                                        out_Renamed.write(0xFF);
                                        nb++;
                                        delFF = false;
                                        // Pad to byte boundary with an alternating sequence of 0's
                                        // and 1's.
                                        bbuf |= (SupportClass.URShift(PAD_SEQ, (6 - bpos)));
                                        // Output the bit buffer
                                        out_Renamed.write(bbuf);
                                        nb++;
                                        bpos = 7;
                                        bbuf = 0;
                                }
                                else if (isPredTerm)
                                {
                                        out_Renamed.write(0xFF);
                                        nb++;
                                        out_Renamed.write(0x2A);
                                        nb++;
                                        bpos = 7;
                                        bbuf = 0;
                                        delFF = false;
                                }
                        }
                        else
                        {
                                // There was no bit stuffing
                                if (bpos != 7)
                                {
                                        // Bit buffer is not empty
                                        // Pad to byte boundary with an alternating sequence of 0's and
                                        // 1's.
                                        bbuf |= (SupportClass.URShift(PAD_SEQ, (6 - bpos)));
                                        // Output the bit buffer (bbuf can not be 0xFF)
                                        out_Renamed.write(bbuf);
                                        nb++;
                                        bpos = 7;
                                        bbuf = 0;
                                }
                        }
                }
                
                /// <summary> Terminates the bit stream by calling 'flush()' and then
                /// 'reset()'. Finally, it returns the number of bytes effectively written.
                /// 
                /// </summary>
                /// <returns> The number of bytes effectively written.
                /// 
                /// </returns>
                public virtual int terminate()
                {
                        flush();
                        int savedNb = nb;
                        reset();
                        return savedNb;
                }
                
                /// <summary> Resets the bit buffer to empty, without writing anything to the
                /// underlying byte output, and resets the byte count. The underlying byte
                /// output is NOT reset.
                /// 
                /// </summary>
                internal virtual void  reset()
                {
                        delFF = false;
                        bpos = 7;
                        bbuf = 0;
                        nb = 0;
                }
                
                /// <summary> Returns the length, in bytes, of the output bit stream as written by
                /// this object. If the output bit stream does not have an integer number
                /// of bytes in length then it is rounded to the next integer.
                /// 
                /// </summary>
                /// <returns> The length, in bytes, of the output bit stream.
                /// 
                /// </returns>
                internal virtual int length()
                {
                        if (delFF)
                        {
                                // If bit buffer is empty we just need 'nb' bytes. If not we need
                                // the delayed FF and the padded bit buffer.
                                return nb + 2;
                        }
                        else
                        {
                                // If the bit buffer is empty, we just need 'nb' bytes. If not, we
                                // add length of the padded bit buffer
                                return nb + ((bpos == 7)?0:1);
                        }
                }
        }
}

Generated by GNU Enscript 1.6.5.90.