AWARE [SYSTEMS] Imaging expertise for the Delphi developer
AWare Systems, Imaging expertise for the Delphi developer, Home TIFF and LibTiff Mailing List Archive

LibTiff Mailing List

TIFF and LibTiff Mailing List Archive
May 2004

Previous Thread
Next Thread

Previous by Thread
Next by Thread

Previous by Date
Next by Date

Contact

The TIFF Mailing List Homepage
This list is run by Frank Warmerdam
Archive maintained by AWare Systems



Valid HTML 4.01!



Thread

2004.05.18 09:35 "Further doubt on bits per sample", by <mayankg@iiitb.ac.in>
2004.05.18 13:13 "Re: Further doubt on bits per sample", by Frank Warmerdam
2004.05.19 05:35 "Re: Further doubt on bits per sample", by <mayankg@iiitb.ac.in>
2004.05.19 14:02 "Re: Further doubt on bits per sample", by Bob Friesenhahn
2004.05.19 08:35 "Further doubt on bits per sample", by <mayankg@iiitb.ac.in>
2004.05.19 09:49 "Re: Further doubt on bits per sample", by Andrey Kiselev
2004.05.18 13:53 "Re: Further doubt on bits per sample", by Bob Friesenhahn
2004.05.21 10:16 "Re: Further doubt on bits per sample", by Gerben Vos

2004.05.19 14:02 "Re: Further doubt on bits per sample", by Bob Friesenhahn

On Wed, 19 May 2004 mayankg@iiitb.ac.in wrote:

> I have the ImageMagick software.
> Could anybody provide some pointers (which module or file name) as to where i
> could find the code for packing/unpacking all kinds of bits per samples cases?

In ImageMagick this is done using a combination of code in
coders/tiff.c and PushImagePixels()/PopImagePixels().  However,
GraphicsMagick (http://www.GraphicsMagick.org/) does things quite
differently.  The bit stream sample pack/unpack is so short I have
attached it to this email (bit_stream.h).  See coders/tiff.c in
GraphicsMagick 1.1.1 for how these functions are used.

/*
  Copyright (C) 2003 GraphicsMagick Group

  This program is covered by multiple licenses, which are described in
  Copyright.txt. You should have received a copy of Copyright.txt with this
  package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.

  Interfaces to deal with marshalling quantums to and from a bit-stream.
  Written by Bob Friesenhahn, September 2003

*/
#ifndef _MAGICK_BIT_STREAM_H
#define _MAGICK_BIT_STREAM_H

#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif

  static const unsigned int BitAndMasks[9] =
    {
      /*
        Same as (~(~0 << retrieve_bits))
      */
      0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff
    };

  /*
    Bit stream reader "handle"
  */
  typedef struct _BitStreamReadHandle
  {
    const unsigned char
      *bytes;

    int
      bits_remaining;
  } BitStreamReadHandle;

  /*
    Initialize Bit Stream for reading
  */
  static inline void BitStreamInitializeRead(BitStreamReadHandle *bit_stream,
                                             const unsigned char *bytes)
  {
    bit_stream->bytes          = bytes;
    bit_stream->bits_remaining = 8;
  }

  /*
    Return the requested number of bits from the current position in a
    bit stream. Stream is read in most-significant bit/byte "big endian"
    order.
  */
  static inline unsigned int BitStreamMSBRead(BitStreamReadHandle *bit_stream,
                                              const unsigned int requested_bits)
  {
    register unsigned int
      remaining_quantum_bits,
      quantum;

    remaining_quantum_bits = requested_bits;
    quantum = 0;

    while (remaining_quantum_bits > 0)
      {
        register unsigned int
          octet_bits;

        octet_bits = remaining_quantum_bits;
        if (octet_bits > bit_stream->bits_remaining)
          octet_bits = bit_stream->bits_remaining;

        remaining_quantum_bits -= octet_bits;
        bit_stream->bits_remaining -= octet_bits;

        quantum = (quantum << octet_bits) |
          ((*bit_stream->bytes >> (bit_stream->bits_remaining))
           & BitAndMasks[octet_bits]);

        if (bit_stream->bits_remaining == 0)
          {
            bit_stream->bytes++;
            bit_stream->bits_remaining=8;
          }
      }
    return quantum;
  }

  /*
    Bit stream writer "handle"
  */
  typedef struct _BitStreamWriteHandle
  {
    unsigned char
      *bytes;

    int
      bits_remaining;
  } BitStreamWriteHandle;

  /*
    Initialize Bit Stream for writing
  */
  static inline void BitStreamInitializeWrite(BitStreamWriteHandle *bit_stream,
                                              unsigned char *bytes)
  {
    bit_stream->bytes          = bytes;
    bit_stream->bits_remaining = 8;
  }

  /*
    Write quantum using the specified number of bits at the current
    position in the bit stream. Stream is written in most-significant
    bit/byte "big endian" order.
  */
  static inline void BitStreamMSBWrite(BitStreamWriteHandle *bit_stream,
                                       const unsigned int requested_bits,
                                       const unsigned int quantum)
  {
    register unsigned int
      remaining_quantum_bits = requested_bits;

    while (remaining_quantum_bits > 0)
      {
        register unsigned int
          octet_bits;

        octet_bits = remaining_quantum_bits;
        if (octet_bits > bit_stream->bits_remaining)
          octet_bits = bit_stream->bits_remaining;

        remaining_quantum_bits -= octet_bits;

        if(bit_stream->bits_remaining == 8)
          *bit_stream->bytes = 0;

        bit_stream->bits_remaining -= octet_bits;

        *bit_stream->bytes |=
          (((quantum >> (remaining_quantum_bits)) &
            BitAndMasks[octet_bits]) << (bit_stream->bits_remaining));

        if (bit_stream->bits_remaining == 0)
          {
            bit_stream->bytes++;
            bit_stream->bits_remaining=8;
          }
      }
  }

#if defined(__cplusplus) || defined(c_plusplus)
}
#endif

#endif /* _MAGICK_BIT_STREAM_H */