#ifndef ITK_Raster_H
#define ITK_Raster_H

#include <stdlib.h>
#include <assert.h>
#include <itk/defines.h>
#include <itk/colormetric.h>


typedef unsigned char  Raster_Cell;
typedef Raster_Cell   *Raster_Data;
typedef unsigned       Raster_Word;


class Raster {
/**
*** Purpose: Manages raster resources
* <classname>Raster</classname> is a simple class used to contain
* raster information.  The only operations it has are related to
* manipulating the raster space available; there are no operations
* to manipulate the raster information itself.
*
* 
**/
private:
  friend class Assign;

  Dimension   m_width;
  Dimension   m_height;
  Colormetric m_depth;
  ColorInterp m_interp;

  Raster_Data m_raster;
  size_t      m_raster_size;
  size_t      m_row_size;
public:
  //*Constructor/Destructor
  Raster();
  Raster( Dimension   new_width, Dimension   new_height,
          Colormetric new_depth, ColorInterp new_interp);
  /**
  * The first constructor creates a zero-size, zero-pixel image.  The
  * second will allocate resources to contain an image of the specified
  * dimensions, including creating a palette if necessary.
  **/

  ~Raster();
  /**
  * <classname>Raster</classname> is meant to be a simple, concrete class.
  * As a result, <function>~Raster</function> is not declared virtual.
  **/

  //*Accessors
  DECL_ACCESSOR_RO( Raster, Dimension, width )
  DECL_ACCESSOR_RO( Raster, Dimension, height)
  /**
  * These functions return the width and height of the image, respectively,
  * measured in pixels.  To change either of these values, use the
  * <function>redimension()</function> function.
  **/

  DECL_ACCESSOR_RO( Raster, Colormetric, depth       )
  DECL_ACCESSOR_RO( Raster, ColorInterp, interp      )
  DECL_ACCESSOR_RO( Raster, size_t     , sample_size )
  DECL_ACCESSOR_RO( Raster, bool       , is_paletted )
  DECL_ACCESSOR_RW( Raster, bool       , is_black_low)
  /**
  * These functions can be used to examine the colormetric information
  * of the image.  <function>depth()</function> returns the 
  * <type>Colormetric</type> value.  <function>sample_size()</function>
  * and <function>is_paletted()</function> `crack' the colormetric
  * information into the number of bits per sample and an indicator of
  * whether there is a palette, respectively.  To change the colormetric
  * information, use the <function>redimension()</function> function.
  **/

  DECL_ACCESSOR_RO( Raster, size_t, row_size)
  /**
  * <function>row_size()</function> returns the number of bytes used for
  * each row.  This may differ from the number of bytes *needed* to hold
  * the data for each row.
  **/

  DECL_ACCESSOR_RO( Raster, size_t, data_size)
  /**
  * <function>data_size()</function> returns the number of bytes used to
  * contain all raster bits for the image.  More memory than this may be
  * allocated, and there will likely be some padding at the end of each
  * row.
  **/

  DECL_ACCESSOR_RO( Raster, size_t, row_words)
  /**
  * returns the size of the rows, measured in words.
  *
  * `Word' in this context refers to the native integer size of the
  * machine, not an arbitrary size.
  **/

  DECL_ACCESSOR_RO( Raster, size_t, data_words)
  /**
  * returns the number of words (machine-native integers) used to
  * contain all raster bits for the image.
  **/

  DECL_ACCESSOR_RO( Raster, Raster_Data, raster)
  /**
  * <function>raster()</function> returns a pointer to the first byte of
  * raster information for the image.  The data will be stored in as
  * efficient a manner as possible (`packed'), but no compression will
  * be used.  The rows will always be stored from top to bottom.
  *
  * Data will be stored in big-endian order.  For 1-bit images, the 
  * first pixel will be found in the highest bit of the first byte.
  * For 4-bit images (16-color), the first pixel will occupy the
  * highest four bits of the first byte.  For 8-bit images, the
  * pixels will occur in order, one per byte.  For 16-bit images, the
  * first byte will be the high eight bits of the value, and the second
  * byte will be the low eight bits of the value.  For 24-bit images,
  * the first byte will be the red value of the first pixel, the second
  * byte will be the green value of the first pixel, and the third byte
  * will be the blue value of the first pixel.  There will be no padding
  * between bytes, though all rows will be padded to a 4-byte boundary.
  **/

  DECL_ACCESSOR_RO( Raster, Raster_Word *, raster_word)
  /**
  * Returns a word-based pointer to the beginning of raster data.  This
  * is meant as an aid to efficient processing of bit-based operations
  * such as bitblit and bitwise inversion, where the bits of the
  * raster data are manipulated without examination.
  *
  * `Word' in this context refers to the native integer size of the
  * machine, not an arbitrary size.
  **/

  Raster_Data  operator[]( size_t i) const;
  /**
  * <function>operator[]</function> returns the address of the beginning
  * of the raster row identified by <varname>i</varname>.
  **/

  //*Manipulators
  void         flush();
  /**
  * <function>flush()</function> releases all resources used by the
  * <classname>Raster</classname> and resets it to a zero-size,
  * zero-pixel image.
  **/

  bool         redimension( Dimension   new_width, Dimension   new_height,
                            Colormetric new_depth, ColorInterp new_interp);
  /**
  * <function>redimension()</function> changes the dimensions (width,
  * height, and colormetric information) of the <classname>Raster</classname>.
  * It will only reallocate memory as needed; it is assumed that, should
  * a <classname>Raster</classname> require a certain amount of memory
  * once, it will again.  To release all resources used by a
  * <classname>Raster</classname>, use the <function>flush()</function>
  * function.
  *
  * After redimensioning, the raster contents of the
  * <classname>Raster</classname> are undefined.
  **/

private:
  void         init();
  /**
  *  Initializes the image as a zero-size, zero-pixel image.
  **/

  DENY_COPY( Raster)
};


#ifdef DO_ITK_INLINE
#include <itk/raster.inl>
#endif


#endif//ITK_Raster_H
