corrade-vassal – Rev 1
?pathlinks?
/*
* CVS identifier:
*
* $Id: BitOutputBuffer.java,v 1.9 2002/07/19 12:40:05 grosbois Exp $
*
* Class: BitOutputBuffer
*
* Description: <short description of class>
*
*
*
* 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.util;
namespace CSJ2K.j2k.codestream.writer
{
/// <summary> This class implements a buffer for writing bits, with the required bit
/// stuffing policy for the packet headers. The bits are stored in a byte array
/// in the order in which they are written. The byte array is automatically
/// reallocated and enlarged whenever necessary. A BitOutputBuffer object may
/// be reused by calling its 'reset()' method.
///
/// <P>NOTE: The methods implemented in this class are intended to be used only
/// in writing packet heads, since a special bit stuffing procedure is used, as
/// required for the packet heads.
///
/// </summary>
public class BitOutputBuffer
{
/// <summary> Returns the current length of the buffer, in bytes.
///
/// <P>This method is declared final to increase performance.
///
/// </summary>
/// <returns> The currebt length of the buffer in bytes.
///
/// </returns>
virtual public int Length
{
get
{
if (avbits == 8)
{
// A integral number of bytes
return curbyte;
}
else
{
// Some bits in last byte
return curbyte + 1;
}
}
}
/// <summary> Returns the byte buffer. This is the internal byte buffer so it should
/// not be modified. Only the first N elements have valid data, where N is
/// the value returned by 'getLength()'
///
/// <P>This method is declared final to increase performance.
///
/// </summary>
/// <returns> The internal byte buffer.
///
/// </returns>
virtual public byte[] Buffer
{
get
{
return buf;
}
}
/// <summary>The buffer where we store the data </summary>
internal byte[] buf;
/// <summary>The position of the current byte to write </summary>
internal int curbyte;
/// <summary>The number of available bits in the current byte </summary>
internal int avbits = 8;
/// <summary>The increment size for the buffer, 16 bytes. This is the
/// number of bytes that are added to the buffer each time it is
/// needed to enlarge it.
/// </summary>
// This must be always 6 or larger.
public const int SZ_INCR = 16;
/// <summary>The initial size for the buffer, 32 bytes. </summary>
public const int SZ_INIT = 32;
/// <summary> Creates a new BitOutputBuffer width a buffer of length
/// 'SZ_INIT'.
///
/// </summary>
public BitOutputBuffer()
{
buf = new byte[SZ_INIT];
}
/// <summary> Resets the buffer. This rewinds the current position to the start of
/// the buffer and sets all tha data to 0. Note that no new buffer is
/// allocated, so this will affect any data that was returned by the
/// 'getBuffer()' method.
///
/// </summary>
public virtual void reset()
{
//int i;
// Reinit pointers
curbyte = 0;
avbits = 8;
ArrayUtil.byteArraySet(buf, (byte) 0);
}
/// <summary> Writes a bit to the buffer at the current position. The value 'bit'
/// must be either 0 or 1, otherwise it corrupts the bits that have been
/// already written. The buffer is enlarged, by 'SZ_INCR' bytes, if
/// necessary.
///
/// <P>This method is declared final to increase performance.
///
/// </summary>
/// <param name="bit">The bit to write, 0 or 1.
///
/// </param>
public void writeBit(int bit)
{
buf[curbyte] |= (byte) (bit << --avbits);
if (avbits > 0)
{
// There is still place in current byte for next bit
return ;
}
else
{
// End of current byte => goto next
if (buf[curbyte] != (byte) SupportClass.Identity(0xFF))
{
// We don't need bit stuffing
avbits = 8;
}
else
{
// We need to stuff a bit (next MSBit is 0)
avbits = 7;
}
curbyte++;
if (curbyte == buf.Length)
{
// We are at end of 'buf' => extend it
byte[] oldbuf = buf;
buf = new byte[oldbuf.Length + SZ_INCR];
Array.Copy(oldbuf, 0, buf, 0, oldbuf.Length);
}
}
}
/// <summary> Writes the n least significant bits of 'bits' to the buffer at the
/// current position. The least significant bit is written last. The 32-n
/// most significant bits of 'bits' must be 0, otherwise corruption of the
/// buffer will result. The buffer is enlarged, by 'SZ_INCR' bytes, if
/// necessary.
///
/// <P>This method is declared final to increase performance.
///
/// </summary>
/// <param name="bits">The bits to write.
///
/// </param>
/// <param name="n">The number of LSBs in 'bits' to write.
///
/// </param>
public void writeBits(int bits, int n)
{
// Check that we have enough place in 'buf' for n bits, and that we do
// not fill last byte, taking into account possibly stuffed bits (max
// 2)
if (((buf.Length - curbyte) << 3) - 8 + avbits <= n + 2)
{
// Not enough place, extend it
byte[] oldbuf = buf;
buf = new byte[oldbuf.Length + SZ_INCR];
Array.Copy(oldbuf, 0, buf, 0, oldbuf.Length);
// SZ_INCR is always 6 or more, so it is enough to hold all the
// new bits plus the ones to come after
}
// Now write the bits
if (n >= avbits)
{
// Complete the current byte
n -= avbits;
buf[curbyte] |= (byte) (bits >> n);
if (buf[curbyte] != (byte) SupportClass.Identity(0xFF))
{
// We don't need bit stuffing
avbits = 8;
}
else
{
// We need to stuff a bit (next MSBit is 0)
avbits = 7;
}
curbyte++;
// Write whole bytes
while (n >= avbits)
{
n -= avbits;
// CONVERSION PROBLEM?
buf[curbyte] |= (byte)((bits >> n) & (~ (1 << avbits)));
if (buf[curbyte] != (byte) SupportClass.Identity(0xFF))
{
// We don't need bit
// stuffing
avbits = 8;
}
else
{
// We need to stuff a bit (next MSBit is 0)
avbits = 7;
}
curbyte++;
}
}
// Finish last byte (we know that now n < avbits)
if (n > 0)
{
avbits -= n;
buf[curbyte] |= (byte) ((bits & ((1 << n) - 1)) << avbits);
}
if (avbits == 0)
{
// Last byte is full
if (buf[curbyte] != (byte) SupportClass.Identity(0xFF))
{
// We don't need bit stuffing
avbits = 8;
}
else
{
// We need to stuff a bit (next MSBit is 0)
avbits = 7;
}
curbyte++; // We already ensured that we have enough place
}
}
/// <summary> Returns the byte buffer data in a new array. This is a copy of the
/// internal byte buffer. If 'data' is non-null it is used to return the
/// data. This array should be large enough to contain all the data,
/// otherwise a IndexOutOfBoundsException is thrown by the Java system. The
/// number of elements returned is what 'getLength()' returns.
///
/// </summary>
/// <param name="data">If non-null this array is used to return the data, which
/// mus be large enough. Otherwise a new one is created and returned.
///
/// </param>
/// <returns> The byte buffer data.
///
/// </returns>
public virtual byte[] toByteArray(byte[] data)
{
if (data == null)
{
data = new byte[(avbits == 8)?curbyte:curbyte + 1];
}
Array.Copy(buf, 0, data, 0, (avbits == 8)?curbyte:curbyte + 1);
return data;
}
/// <summary> Prints information about this object for debugging purposes
///
/// </summary>
/// <returns> Information about the object.
///
/// </returns>
public override System.String ToString()
{
return "bits written = " + (curbyte * 8 + (8 - avbits)) + ", curbyte = " + curbyte + ", avbits = " + avbits;
}
}
}
Generated by GNU Enscript 1.6.5.90.