Blame libdjvu/GBitmap.h

Packit df99a1
//C-  -*- C++ -*-
Packit df99a1
//C- -------------------------------------------------------------------
Packit df99a1
//C- DjVuLibre-3.5
Packit df99a1
//C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
Packit df99a1
//C- Copyright (c) 2001  AT&T
Packit df99a1
//C-
Packit df99a1
//C- This software is subject to, and may be distributed under, the
Packit df99a1
//C- GNU General Public License, either Version 2 of the license,
Packit df99a1
//C- or (at your option) any later version. The license should have
Packit df99a1
//C- accompanied the software or you may obtain a copy of the license
Packit df99a1
//C- from the Free Software Foundation at http://www.fsf.org .
Packit df99a1
//C-
Packit df99a1
//C- This program is distributed in the hope that it will be useful,
Packit df99a1
//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit df99a1
//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit df99a1
//C- GNU General Public License for more details.
Packit df99a1
//C- 
Packit df99a1
//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library from
Packit df99a1
//C- Lizardtech Software.  Lizardtech Software has authorized us to
Packit df99a1
//C- replace the original DjVu(r) Reference Library notice by the following
Packit df99a1
//C- text (see doc/lizard2002.djvu and doc/lizardtech2007.djvu):
Packit df99a1
//C-
Packit df99a1
//C-  ------------------------------------------------------------------
Packit df99a1
//C- | DjVu (r) Reference Library (v. 3.5)
Packit df99a1
//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
Packit df99a1
//C- | The DjVu Reference Library is protected by U.S. Pat. No.
Packit df99a1
//C- | 6,058,214 and patents pending.
Packit df99a1
//C- |
Packit df99a1
//C- | This software is subject to, and may be distributed under, the
Packit df99a1
//C- | GNU General Public License, either Version 2 of the license,
Packit df99a1
//C- | or (at your option) any later version. The license should have
Packit df99a1
//C- | accompanied the software or you may obtain a copy of the license
Packit df99a1
//C- | from the Free Software Foundation at http://www.fsf.org .
Packit df99a1
//C- |
Packit df99a1
//C- | The computer code originally released by LizardTech under this
Packit df99a1
//C- | license and unmodified by other parties is deemed "the LIZARDTECH
Packit df99a1
//C- | ORIGINAL CODE."  Subject to any third party intellectual property
Packit df99a1
//C- | claims, LizardTech grants recipient a worldwide, royalty-free, 
Packit df99a1
//C- | non-exclusive license to make, use, sell, or otherwise dispose of 
Packit df99a1
//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the 
Packit df99a1
//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU 
Packit df99a1
//C- | General Public License.   This grant only confers the right to 
Packit df99a1
//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to 
Packit df99a1
//C- | the extent such infringement is reasonably necessary to enable 
Packit df99a1
//C- | recipient to make, have made, practice, sell, or otherwise dispose 
Packit df99a1
//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to 
Packit df99a1
//C- | any greater extent that may be necessary to utilize further 
Packit df99a1
//C- | modifications or combinations.
Packit df99a1
//C- |
Packit df99a1
//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
Packit df99a1
//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
Packit df99a1
//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
Packit df99a1
//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
Packit df99a1
//C- +------------------------------------------------------------------
Packit df99a1
Packit df99a1
#ifndef _GBITMAP_H_
Packit df99a1
#define _GBITMAP_H_
Packit df99a1
#ifdef HAVE_CONFIG_H
Packit df99a1
#include "config.h"
Packit df99a1
#endif
Packit df99a1
#if NEED_GNUG_PRAGMAS
Packit df99a1
# pragma interface
Packit df99a1
#endif
Packit df99a1
Packit df99a1
Packit df99a1
#include "GSmartPointer.h"
Packit df99a1
#ifndef NDEBUG
Packit df99a1
#include "GException.h"
Packit df99a1
#endif
Packit df99a1
Packit df99a1
#ifdef HAVE_NAMESPACES
Packit df99a1
namespace DJVU {
Packit df99a1
# ifdef NOT_DEFINED // Just to fool emacs c++ mode
Packit df99a1
}
Packit df99a1
#endif
Packit df99a1
#endif
Packit df99a1
Packit df99a1
Packit df99a1
class GRect;
Packit df99a1
class GMonitor;
Packit df99a1
class ByteStream;
Packit df99a1
Packit df99a1
/** @name GBitmap.h
Packit df99a1
Packit df99a1
    Files #"GBitmap.h"# and #"GBitmap.cpp"# implement class \Ref{GBitmap}.
Packit df99a1
    Instances of this class represent bilevel or gray-level images. The
Packit df99a1
    ``bottom left'' coordinate system is used consistently in the DjVu library.
Packit df99a1
    Line zero of a bitmap is the bottom line in the bitmap.  Pixels are
Packit df99a1
    organized from left to right within each line.  As suggested by its name,
Packit df99a1
    class #GBitmap# was initially a class for bilevel images only.  It was
Packit df99a1
    extended to handle gray-level images when arose the need to render
Packit df99a1
    anti-aliased images.  This class has been a misnomer since then.
Packit df99a1
Packit df99a1
    {\bf ToDo} --- Class #GBitmap# can internally represent bilevel images
Packit df99a1
    using a run-length encoded representation.  Some algorithms may benefit
Packit df99a1
    from a direct access to this run information.
Packit df99a1
Packit df99a1
    @memo
Packit df99a1
    Generic support for bilevel and gray-level images.
Packit df99a1
    @author
Packit df99a1
    L\'eon Bottou <leonb@research.att.com>
Packit df99a1
Packit df99a1
 */
Packit df99a1
//@{
Packit df99a1
Packit df99a1
Packit df99a1
/** Bilevel and gray-level images.  Instances of class #GBitmap# represent
Packit df99a1
    bilevel or gray-level images.  Images are usually represented using one
Packit df99a1
    byte per pixel.  Value zero represents a white pixel.  A value equal to
Packit df99a1
    the number of gray levels minus one represents a black pixel.  The number
Packit df99a1
    of gray levels is returned by the function \Ref{get_grays} and can be
Packit df99a1
    manipulated by the functions \Ref{set_grays} and \Ref{change_grays}.
Packit df99a1
Packit df99a1
    The bracket operator returns a pointer to the bytes composing one line of
Packit df99a1
    the image.  This pointer can be used to read or write the image pixels.
Packit df99a1
    Line zero represents the bottom line of the image.
Packit df99a1
Packit df99a1
    The memory organization is setup in such a way that you can safely read a
Packit df99a1
    few pixels located in a small border surrounding all four sides of the
Packit df99a1
    image.  The width of this border can be modified using the function
Packit df99a1
    \Ref{minborder}.  The border pixels are initialized to zero and therefore
Packit df99a1
    represent white pixels.  You should never write anything into border
Packit df99a1
    pixels because they are shared between images and between lines.  */
Packit df99a1
Packit df99a1
class DJVUAPI GBitmap : public GPEnabled
Packit df99a1
{
Packit df99a1
protected:
Packit df99a1
  GBitmap(void);
Packit df99a1
  GBitmap(int nrows, int ncolumns, int border=0);
Packit df99a1
  GBitmap(const GBitmap &ref;;
Packit df99a1
  GBitmap(const GBitmap &ref, int border);
Packit df99a1
  GBitmap(const GBitmap &ref, const GRect &rect, int border=0);
Packit df99a1
  GBitmap(ByteStream &ref, int border=0);
Packit df99a1
public:
Packit df99a1
  virtual ~GBitmap();
Packit df99a1
  void destroy(void);
Packit df99a1
  /** @name Construction. */
Packit df99a1
  //@{
Packit df99a1
  /** Constructs an empty GBitmap object.  The returned GBitmap has zero rows
Packit df99a1
      and zero columns.  Use function \Ref{init} to change the size of the
Packit df99a1
      image. */
Packit df99a1
  static GP<GBitmap> create(void) {return new GBitmap;}
Packit df99a1
Packit df99a1
  /** Constructs a GBitmap with #nrows# rows and #ncolumns# columns.  All
Packit df99a1
      pixels are initialized to white. The optional argument #border#
Packit df99a1
      specifies the size of the optional border of white pixels surrounding
Packit df99a1
      the image.  The number of gray levels is initially set to #2#.  */
Packit df99a1
  static GP<GBitmap> create(const int nrows, const int ncolumns, const int border=0)
Packit df99a1
  {return new GBitmap(nrows,ncolumns, border); }
Packit df99a1
Packit df99a1
  /** Copy constructor. Constructs a GBitmap by replicating the size, the
Packit df99a1
      border and the contents of GBitmap #ref#. */
Packit df99a1
  static GP<GBitmap> create(const GBitmap &ref)
Packit df99a1
  {return new GBitmap(ref);}
Packit df99a1
Packit df99a1
  /** Constructs a GBitmap by copying the contents of GBitmap #ref#.  
Packit df99a1
      Argument #border# specifies the width of the optional border. */
Packit df99a1
  static GP<GBitmap> create(const GBitmap &ref, const int border)
Packit df99a1
  { return new GBitmap(ref,border); }
Packit df99a1
Packit df99a1
  /** Constructs a GBitmap by copying a rectangular segment #rect# of GBitmap
Packit df99a1
      #ref#.  The optional argument #border# specifies the size of the
Packit df99a1
      optional border of white pixels surrounding the image. */
Packit df99a1
  static GP<GBitmap> create(const GBitmap &ref, const GRect &rect, const int border=0)
Packit df99a1
  { return new GBitmap(ref,rect,border); }
Packit df99a1
Packit df99a1
  /** Constructs a GBitmap by reading PBM, PGM or RLE data from ByteStream
Packit df99a1
      #ref# into this GBitmap. The optional argument #border# specifies the
Packit df99a1
      size of the optional border of white pixels surrounding the image.  See
Packit df99a1
      \Ref{PNM and RLE file formats} for more information.  */
Packit df99a1
  static GP<GBitmap> create(ByteStream &ref, const int border=0)
Packit df99a1
  { return new GBitmap(ref,border); }
Packit df99a1
Packit df99a1
  //@}
Packit df99a1
Packit df99a1
  /** @name Initialization. */
Packit df99a1
  //@{
Packit df99a1
  /** Resets this GBitmap size to #nrows# rows and #ncolumns# columns and sets
Packit df99a1
      all pixels to white.  The optional argument #border# specifies the size
Packit df99a1
      of the optional border of white pixels surrounding the image.  The
Packit df99a1
      number of gray levels is initialized to #2#. */
Packit df99a1
  void init(int nrows, int ncolumns, int border=0);
Packit df99a1
  /** Initializes this GBitmap with the contents of the GBitmap #ref#.  The
Packit df99a1
      optional argument #border# specifies the size of the optional border of
Packit df99a1
      white pixels surrounding the image. */
Packit df99a1
  void init(const GBitmap &ref, int border=0);
Packit df99a1
  /** Initializes this GBitmap with a rectangular segment #rect# of GBitmap
Packit df99a1
      #ref#.  The optional argument #border# specifies the size of the
Packit df99a1
      optional border of white pixels surrounding the image. */
Packit df99a1
  void init(const GBitmap &ref, const GRect &rect, int border=0);
Packit df99a1
  /** Reads PBM, PGM or RLE data from ByteStream #ref# into this GBitmap.  The
Packit df99a1
      previous content of the GBitmap object is lost. The optional argument
Packit df99a1
      #border# specifies the size of the optional border of white pixels
Packit df99a1
      surrounding the image. See \Ref{PNM and RLE file formats} for more
Packit df99a1
      information. */
Packit df99a1
  void init(ByteStream &ref, int border=0);
Packit df99a1
  /** Assignment operator. Initializes this GBitmap by copying the size, the
Packit df99a1
      border and the contents of GBitmap #ref#. */
Packit df99a1
  GBitmap& operator=(const GBitmap &ref;;
Packit df99a1
  /** Initializes all the GBitmap pixels to value #value#. */
Packit df99a1
  void fill(unsigned char value);
Packit df99a1
  //@}
Packit df99a1
Packit df99a1
  /** @name Accessing the pixels. */
Packit df99a1
  //@{
Packit df99a1
  /** Returns the number of rows (the image height). */
Packit df99a1
  unsigned int rows() const;
Packit df99a1
  /** Returns the number of columns (the image width). */
Packit df99a1
  unsigned int columns() const;
Packit df99a1
  /** Returns a constant pointer to the first byte of row #row#.
Packit df99a1
      This pointer can be used as an array to read the row elements. */
Packit df99a1
  const unsigned char *operator[] (int row) const;
Packit df99a1
  /** Returns a pointer to the first byte of row #row#.
Packit df99a1
      This pointer can be used as an array to read or write the row elements. */
Packit df99a1
  unsigned char *operator[] (int row);
Packit df99a1
  /** Returns the size of a row in memory (in pixels).  This number is equal
Packit df99a1
      to the difference between pointers to pixels located in the same column
Packit df99a1
      in consecutive rows.  This difference can be larger than the number of
Packit df99a1
      columns in the image. */
Packit df99a1
  unsigned int rowsize() const;
Packit df99a1
  /** Makes sure that the border is at least #minimum# pixels large.  This
Packit df99a1
      function does nothing it the border width is already larger than
Packit df99a1
      #minimum#.  Otherwise it reorganizes the data in order to provide a
Packit df99a1
      border of #minimum# pixels. */
Packit df99a1
  void minborder(int minimum);
Packit df99a1
  //@}
Packit df99a1
Packit df99a1
  /** @name Managing gray levels. */
Packit df99a1
  //@{
Packit df99a1
  /** Returns the number of gray levels. 
Packit df99a1
      Value #2# denotes a bilevel image. */
Packit df99a1
  int  get_grays() const;
Packit df99a1
  /** Sets the number of gray levels without changing the pixels.
Packit df99a1
      Argument #grays# must be in range #2# to #256#. */
Packit df99a1
  void set_grays(int grays);
Packit df99a1
  /** Changes the number of gray levels.  The argument #grays# must be in the
Packit df99a1
      range #2# to #256#.  All the pixel values are then rescaled and clipped
Packit df99a1
      in range #0# to #grays-1#. */
Packit df99a1
  void change_grays(int grays);
Packit df99a1
  /** Binarizes a gray level image using a threshold.  The number of gray
Packit df99a1
      levels is reduced to #2# as in a bilevel image.  All pixels whose value
Packit df99a1
      was strictly greater than #threshold# are set to black. All other pixels
Packit df99a1
      are set to white. */
Packit df99a1
  void binarize_grays(int threshold=0);
Packit df99a1
  //@}
Packit df99a1
Packit df99a1
  /** @name Optimizing the memory usage.  
Packit df99a1
      The amount of memory used by bilevel images can be reduced using
Packit df99a1
      function \Ref{compress}, which encodes the image using a run-length
Packit df99a1
      encoding scheme.  The bracket operator decompresses the image on demand.
Packit df99a1
      A few highly optimized functions (e.g. \Ref{blit}) can use a run-length
Packit df99a1
      encoded bitmap without decompressing it.  There are unfortunate locking
Packit df99a1
      issues associated with this capability (c.f. \Ref{share} and
Packit df99a1
      \Ref{monitor}). */
Packit df99a1
  //@{
Packit df99a1
  /** Reduces the memory required for a bilevel image by using a run-length
Packit df99a1
      encoded representation.  Functions that need to access the pixel array
Packit df99a1
      will decompress the image on demand. */
Packit df99a1
  void compress();
Packit df99a1
  /** Decodes run-length encoded bitmaps and recreate the pixel array.
Packit df99a1
      This function is usually called by #operator[]# when needed. */
Packit df99a1
  void uncompress();
Packit df99a1
  /** Returns the number of bytes allocated for this image. */
Packit df99a1
  unsigned int get_memory_usage() const;
Packit df99a1
  /** Returns a possibly null pointer to a \Ref{GMonitor} for this bitmap.
Packit df99a1
      You should use this monitor to ensure that the data representation of the 
Packit df99a1
      bitmap will not change while you are using it.  We suggest using
Packit df99a1
      class \Ref{GMonitorLock} which properly handles null monitor pointers. */
Packit df99a1
  GMonitor *monitor() const;
Packit df99a1
  /** Associates a \Ref{GMonitor} with this bitmap. This function should be
Packit df99a1
      called on all bitmaps susceptible of being simultaneously used by
Packit df99a1
      several threads.  It will make sure that function \Ref{monitor} returns
Packit df99a1
      a pointer to a suitable monitor for this bitmap. */
Packit df99a1
  void share();
Packit df99a1
  //@}
Packit df99a1
Packit df99a1
  /** @name Accessing RLE data.
Packit df99a1
      The next functions are useful for processing bilevel images
Packit df99a1
      encoded using the run length encoding scheme.  These functions always return
Packit df99a1
      zero if the bitmap is not RLE encoded.  Function \Ref{compress} must
Packit df99a1
      be used to ensure that the bitmap is RLE encoded.  */
Packit df99a1
  //@{
Packit df99a1
  /** Gets the pixels for line #rowno#.  One line of pixel is stored as
Packit df99a1
      #unsigned char# values into array #bits#.  Each pixel is either 1 or 0.
Packit df99a1
      The array must be large enough to hold the whole line.  The number of
Packit df99a1
      pixels is returned. */
Packit df99a1
Packit df99a1
  int rle_get_bits(int rowno, unsigned char *bits) const;
Packit df99a1
Packit df99a1
  /** Gets the bitmap line rle data passed.  One line of pixel is stored one
Packit df99a1
      with 8 bits per #unsigned char# in an array.  The array must be large
Packit df99a1
      enough to hold the whole line.  */
Packit df99a1
Packit df99a1
  static void rle_get_bitmap(const int ncolumns,const unsigned char *&runs,
Packit df99a1
    unsigned char *bitmap, const bool invert );
Packit df99a1
Packit df99a1
  /** Gets the lengths of all runs in line #rowno#.  The array #rlens# must be
Packit df99a1
      large enough to accomodate #w+2# integers where #w# is the number of
Packit df99a1
      columns in the image.  These integers represent the lengths of
Packit df99a1
      consecutive runs of alternatively white or black pixels.  Lengths can be
Packit df99a1
      zero in order to allow for lines starting with black pixels.  This
Packit df99a1
      function returns the total number of runs in the line. */
Packit df99a1
  int rle_get_runs(int rowno, int *rlens) const;
Packit df99a1
  /** Gets the smallest rectangle enclosing black pixels.
Packit df99a1
      Rectangle rect gives the coordinates of the smallest rectangle
Packit df99a1
      containing all black pixels. Returns the number of black pixels. */
Packit df99a1
  int rle_get_rect(GRect &rect) const;
Packit df99a1
  //@}
Packit df99a1
Packit df99a1
  /** @name Additive Blit.  
Packit df99a1
      The blit functions are designed to efficiently construct an anti-aliased
Packit df99a1
      image by copying smaller images at predefined locations.  The image of a
Packit df99a1
      page, for instance, is composed by copying the images of characters at
Packit df99a1
      predefined locations.  These functions are fairly optimized.  They can
Packit df99a1
      directly use compressed GBitmaps (see \Ref{compress}).  We consider in
Packit df99a1
      this section that each GBitmap comes with a coordinate system defined as
Packit df99a1
      follows.  Position (#0#,#0#) corresponds to the bottom left corner of
Packit df99a1
      the bottom left pixel.  Position (#1#,#1#) corresponds to the top right
Packit df99a1
      corner of the bottom left pixel, which is also the bottom left corner of
Packit df99a1
      the second pixel of the second row.  Position (#w#,#h#), where #w# and
Packit df99a1
      #h# denote the size of the GBitmap, corresponds to the top right corner
Packit df99a1
      of the top right pixel. */
Packit df99a1
Packit df99a1
  //@{
Packit df99a1
  /** Performs an additive blit of the GBitmap #bm#.  The GBitmap #bm# is
Packit df99a1
      first positioned above the current GBitmap in such a way that position
Packit df99a1
      (#u#,#v#) in GBitmap #bm# corresponds to position (#u#+#x#,#v#+#y#) in
Packit df99a1
      the current GBitmap.  The value of each pixel in GBitmap #bm# is then
Packit df99a1
      added to the value of the corresponding pixel in the current GBitmap.
Packit df99a1
      
Packit df99a1
      {\bf Example}: Assume for instance that the current GBitmap is initially
Packit df99a1
      white (all pixels have value zero).  This operation copies the pixel
Packit df99a1
      values of GBitmap #bm# at position (#x#,#y#) into the current GBitmap.
Packit df99a1
      Note that function #blit# does not change the number of gray levels in
Packit df99a1
      the current GBitmap.  You may have to call \Ref{set_grays} to specify
Packit df99a1
      how the pixel values should be interpreted. */
Packit df99a1
  void blit(const GBitmap *bm, int x, int y);
Packit df99a1
  /** Performs an additive blit of the GBitmap #bm# with anti-aliasing.  The
Packit df99a1
      GBitmap #bm# is first positioned above the current GBitmap in such a
Packit df99a1
      way that position (#u#,#v#) in GBitmap #bm# corresponds to position
Packit df99a1
      (#u#+#x#/#subsample#,#v#+#y#/#subsample#) in the current GBitmap.  This
Packit df99a1
      mapping results in a contraction of GBitmap #bm# by a factor
Packit df99a1
      #subsample#.  Each pixel of the current GBitmap can be covered by a
Packit df99a1
      maximum of #subsample^2# pixels of GBitmap #bm#.  The value of
Packit df99a1
      each pixel in GBitmap #bm# is then added to the value of the
Packit df99a1
      corresponding pixel in the current GBitmap.
Packit df99a1
Packit df99a1
      {\bf Example}: Assume for instance that the current GBitmap is initially
Packit df99a1
      white (all pixels have value zero).  Each pixel of the current GBitmap
Packit df99a1
      then contains the sum of the gray levels of the corresponding pixels in
Packit df99a1
      GBitmap #bm#.  There are up to #subsample*subsample# such pixels.  If
Packit df99a1
      for instance GBitmap #bm# is a bilevel image (pixels can be #0# or #1#),
Packit df99a1
      the pixels of the current GBitmap can take values in range #0# to
Packit df99a1
      #subsample*subsample#.  Note that function #blit# does not change the
Packit df99a1
      number of gray levels in the current GBitmap.  You must call
Packit df99a1
      \Ref{set_grays} to indicate that there are #subsample^2+1# gray
Packit df99a1
      levels.  Since there is at most 256 gray levels, this also means that
Packit df99a1
      #subsample# should never be greater than #15#.
Packit df99a1
Packit df99a1
      {\bf Remark}: Arguments #x# and #y# do not represent a position in the
Packit df99a1
      coordinate system of the current GBitmap.  According to the above
Packit df99a1
      discussion, the position is (#x/subsample#,#y/subsample#).  In other
Packit df99a1
      words, you can position the blit with a sub-pixel resolution.  The
Packit df99a1
      resulting anti-aliasing changes are paramount to the image quality. */
Packit df99a1
  void blit(const GBitmap *shape, int x, int y, int subsample);
Packit df99a1
  //@}
Packit df99a1
  
Packit df99a1
  /** @name Saving images.  
Packit df99a1
      The following functions write PBM, PGM and RLE files.  PBM and PGM are
Packit df99a1
      well known formats for bilevel and gray-level images.  The RLE is a
Packit df99a1
      simple run-length encoding scheme for bilevel images. These files can be
Packit df99a1
      read using the ByteStream based constructor or initialization function.
Packit df99a1
      See \Ref{PNM and RLE file formats} for more information. */
Packit df99a1
  //@{
Packit df99a1
  /** Saves the image into ByteStream #bs# using the PBM format.  Argument
Packit df99a1
      #raw# selects the ``Raw PBM'' (1) or the ``Ascii PBM'' (0) format.  The
Packit df99a1
      image is saved as a bilevel image.  All non zero pixels are considered
Packit df99a1
      black pixels. See section \Ref{PNM and RLE file formats}. */
Packit df99a1
  void save_pbm(ByteStream &bs, int raw=1);
Packit df99a1
  /** Saves the image into ByteStream #bs# using the PGM format.  Argument
Packit df99a1
      #raw# selects the ``Raw PGM'' (1) or the ``Ascii PGM'' (0) format.  The
Packit df99a1
      image is saved as a gray level image.  See section
Packit df99a1
      \Ref{PNM and RLE file formats}. */
Packit df99a1
  void save_pgm(ByteStream &bs, int raw=1);
Packit df99a1
  /** Saves the image into ByteStream #bs# using the RLE file format.
Packit df99a1
      The image is saved as a bilevel image. All non zero pixels are
Packit df99a1
      considered black pixels. See section \Ref{PNM and RLE file formats}. */
Packit df99a1
  void save_rle(ByteStream &bs);
Packit df99a1
  //@}
Packit df99a1
Packit df99a1
  /** @name Stealing or borrowing the memory buffer (advanced). */
Packit df99a1
  //@{
Packit df99a1
  /** Steals the memory buffer of a GBitmap.  This function returns the
Packit df99a1
      address of the memory buffer allocated by this GBitmap object.  The
Packit df99a1
      offset of the first pixel in the bottom line is written into variable
Packit df99a1
      #offset#.  Other lines can be accessed using pointer arithmetic (see
Packit df99a1
      \Ref{rowsize}).  The GBitmap object no longer ``owns'' the buffer: you
Packit df99a1
      must explicitly de-allocate the buffer using #operator delete []#.  This
Packit df99a1
      de-allocation should take place after the destruction or the
Packit df99a1
      re-initialization of the GBitmap object.  This function will return a
Packit df99a1
      null pointer if the GBitmap object does not ``own'' the buffer in the
Packit df99a1
      first place.  */
Packit df99a1
  unsigned char *take_data(size_t &offset);
Packit df99a1
  /** Initializes this GBitmap by borrowing a memory segment.  The GBitmap
Packit df99a1
      then directly addresses the memory buffer #data# provided by the user.
Packit df99a1
      This buffer must be large enough to hold #w*h# bytes representing each
Packit df99a1
      one pixel.  The GBitmap object does not ``own'' the buffer: you must
Packit df99a1
      explicitly de-allocate the buffer using #operator delete []#.  This
Packit df99a1
      de-allocation should take place after the destruction or the
Packit df99a1
      re-initialization of the GBitmap object.  */
Packit df99a1
  inline void borrow_data(unsigned char &data, int w, int h);
Packit df99a1
  /** Same as borrow_data, except GBitmap will call #delete[]#. */
Packit df99a1
  void donate_data(unsigned char *data, int w, int h);
Packit df99a1
  /** Return a pointer to the rle data. */
Packit df99a1
  const unsigned char *get_rle(unsigned int &rle_length);
Packit df99a1
  /** Initializes this GBitmap by setting the size to #h# rows and #w#
Packit df99a1
      columns, and directly addressing the memory buffer #rledata# provided by
Packit df99a1
      the user.  This buffer contains #rledatalen# bytes representing the
Packit df99a1
      bitmap in run length encoded form.  The GBitmap object then ``owns'' the
Packit df99a1
      buffer (unlike #borrow_data#, but like #donate_data#) and will
Packit df99a1
      deallocate this buffer when appropriate: you should not deallocate this
Packit df99a1
      buffer yourself.  The encoding of buffer #rledata# is similar to the
Packit df99a1
      data segment of the RLE file format (without the header) documented in
Packit df99a1
      \Ref{PNM and RLE file formats}.  */
Packit df99a1
  void donate_rle(unsigned char *rledata, unsigned int rledatalen, int w, int h);
Packit df99a1
  /** Static function for parsing run data.
Packit df99a1
      This function returns one run length encoded at position #data# 
Packit df99a1
      and increments the pointer #data# accordingly. */
Packit df99a1
  static inline int read_run(const unsigned char *&data);
Packit df99a1
  static inline int read_run(unsigned char *&data);
Packit df99a1
  /** Static function for generating run data.
Packit df99a1
      This function encoded run length #count# at position #data#
Packit df99a1
      and increments the pointer accordingly.  The pointer must
Packit df99a1
      initially point to a large enough data buffer. */
Packit df99a1
  static inline void append_run(unsigned char *&data, int count);
Packit df99a1
  /** Rotates bitmap by 90, 180 or 270 degrees anticlockwise
Packit df99a1
      and returns a new pixmap, input bitmap is not changed. 
Packit df99a1
      count can be 1, 2, or 3 for 90, 180, 270 degree rotation.
Packit df99a1
      It returns the same bitmap if not rotated. 
Packit df99a1
      The input bitmap will be uncompressed for rotation*/
Packit df99a1
  GP<GBitmap> rotate(int count=0);
Packit df99a1
  //@}
Packit df99a1
Packit df99a1
// These are constants, but we use enum because that works on older compilers.
Packit df99a1
  enum {MAXRUNSIZE=0x3fff};
Packit df99a1
  enum {RUNOVERFLOWVALUE=0xc0};
Packit df99a1
  enum {RUNMSBMASK=0x3f};
Packit df99a1
  enum {RUNLSBMASK=0xff};
Packit df99a1
Packit df99a1
Packit df99a1
protected:
Packit df99a1
  // bitmap components
Packit df99a1
  unsigned short nrows;
Packit df99a1
  unsigned short ncolumns;
Packit df99a1
  unsigned short border;
Packit df99a1
  unsigned short bytes_per_row;
Packit df99a1
  unsigned short grays;
Packit df99a1
  unsigned char  *bytes;
Packit df99a1
  unsigned char  *bytes_data;
Packit df99a1
  GPBuffer<unsigned char> gbytes_data;
Packit df99a1
  unsigned char  *rle;
Packit df99a1
  GPBuffer<unsigned char> grle;
Packit df99a1
  unsigned char  **rlerows;
Packit df99a1
  GPBuffer<unsigned char *> grlerows;
Packit df99a1
  unsigned int   rlelength;
Packit df99a1
private:
Packit df99a1
  GMonitor       *monitorptr;
Packit df99a1
public:
Packit df99a1
  class ZeroBuffer;
Packit df99a1
  friend class ZeroBuffer;
Packit df99a1
  GP<ZeroBuffer> gzerobuffer; 
Packit df99a1
private:
Packit df99a1
  static int zerosize;
Packit df99a1
  static unsigned char *zerobuffer;
Packit df99a1
  static GP<ZeroBuffer> zeroes(int ncolumns);
Packit df99a1
  static unsigned int read_integer(char &lookahead, ByteStream &ref;;
Packit df99a1
  static void euclidian_ratio(int a, int b, int &q, int &r);
Packit df99a1
  int encode(unsigned char *&pruns,GPBuffer<unsigned char> &gpruns) const;
Packit df99a1
  void decode(unsigned char *runs);
Packit df99a1
  void read_pbm_text(ByteStream &ref;; 
Packit df99a1
  void read_pgm_text(ByteStream &ref, int maxval); 
Packit df99a1
  void read_pbm_raw(ByteStream &ref;; 
Packit df99a1
  void read_pgm_raw(ByteStream &ref, int maxval); 
Packit df99a1
  void read_rle_raw(ByteStream &ref;; 
Packit df99a1
  static void append_long_run(unsigned char *&data, int count);
Packit df99a1
  static void append_line(unsigned char *&data,const unsigned char *row,
Packit df99a1
                          const int rowlen,bool invert=false);
Packit df99a1
  static void makerows(int,const int, unsigned char *, unsigned char *[]);
Packit df99a1
  friend class DjVu_Stream;
Packit df99a1
  friend class DjVu_PixImage;
Packit df99a1
public:
Packit df99a1
#ifndef NDEBUG
Packit df99a1
  void check_border() const;
Packit df99a1
#endif
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
/** @name PNM and RLE file formats
Packit df99a1
Packit df99a1
    {\bf PNM} --- There are actually three PNM file formats: PBM for bilevel
Packit df99a1
    images, PGM for gray level images, and PPM for color images.  These
Packit df99a1
    formats are widely used by popular image manipulation packages such as
Packit df99a1
    NetPBM \URL{http://www.arc.umn.edu/GVL/Software/netpbm.html} or
Packit df99a1
    ImageMagick \URL{http://www.wizards.dupont.com/cristy/}.
Packit df99a1
    
Packit df99a1
    {\bf RLE} --- The binary RLE file format is a simple run-length encoding
Packit df99a1
    scheme for storing bilevel images.  Encoding or decoding a RLE encoded
Packit df99a1
    file is extremely simple. Yet RLE encoded files are usually much smaller
Packit df99a1
    than the corresponding PBM encoded files.  RLE files always begin with a
Packit df99a1
    header line composed of:\\
Packit df99a1
    - the two characters #"R4"#,\\
Packit df99a1
    - one or more blank characters,\\
Packit df99a1
    - the number of columns, encoded using characters #"0"# to #"9"#,\\
Packit df99a1
    - one or more blank characters,\\
Packit df99a1
    - the number of lines, encoded using characters #"0"# to #"9"#,\\
Packit df99a1
    - exactly one blank character (usually a line-feed character).
Packit df99a1
Packit df99a1
    The rest of the file encodes a sequence of numbers representing the
Packit df99a1
    lengths of alternating runs of white and black pixels.  Lines are encoded
Packit df99a1
    starting with the top line and progressing towards the bottom line.  Each
Packit df99a1
    line starts with a white run. The decoder knows that a line is finished
Packit df99a1
    when the sum of the run lengths for that line is equal to the number of
Packit df99a1
    columns in the image.  Numbers in range #0# to #191# are represented by a
Packit df99a1
    single byte in range #0x00# to #0xbf#.  Numbers in range #192# to #16383#
Packit df99a1
    are represented by a two byte sequence: the first byte, in range #0xc0# to
Packit df99a1
    #0xff#, encodes the six most significant bits of the number, the second
Packit df99a1
    byte encodes the remaining eight bits of the number. This scheme allows
Packit df99a1
    for runs of length zero, which are useful when a line starts with a black
Packit df99a1
    pixel, and when a very long run (whose length exceeds #16383#) must be
Packit df99a1
    split into smaller runs.
Packit df99a1
Packit df99a1
    @memo
Packit df99a1
    Simple image file formats.  */
Packit df99a1
Packit df99a1
//@}
Packit df99a1
Packit df99a1
Packit df99a1
// ---------------- IMPLEMENTATION
Packit df99a1
Packit df99a1
inline unsigned int
Packit df99a1
GBitmap::rows() const
Packit df99a1
{
Packit df99a1
  return nrows;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline unsigned int
Packit df99a1
GBitmap::columns() const
Packit df99a1
{
Packit df99a1
  return ncolumns;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline unsigned int 
Packit df99a1
GBitmap::rowsize() const
Packit df99a1
{
Packit df99a1
  return bytes_per_row;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline int
Packit df99a1
GBitmap::get_grays() const
Packit df99a1
{
Packit df99a1
  return grays;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline unsigned char *
Packit df99a1
GBitmap::operator[](int row) 
Packit df99a1
{
Packit df99a1
  if (!bytes) 
Packit df99a1
    uncompress();
Packit df99a1
  if (row<0 || row>=nrows) {
Packit df99a1
#ifndef NDEBUG
Packit df99a1
    if (zerosize < bytes_per_row + border)
Packit df99a1
      G_THROW( ERR_MSG("GBitmap.zero_small") );
Packit df99a1
#endif
Packit df99a1
    return zerobuffer + border;
Packit df99a1
  }
Packit df99a1
  return &bytes[row * bytes_per_row + border];
Packit df99a1
}
Packit df99a1
Packit df99a1
inline const unsigned char *
Packit df99a1
GBitmap::operator[](int row) const
Packit df99a1
{
Packit df99a1
  if (!bytes) 
Packit df99a1
    ((GBitmap*)this)->uncompress();
Packit df99a1
  if (row<0 || row>=nrows) {
Packit df99a1
#ifndef NDEBUG
Packit df99a1
    if (zerosize < bytes_per_row + border)
Packit df99a1
      G_THROW( ERR_MSG("GBitmap.zero_small") );
Packit df99a1
#endif
Packit df99a1
    return zerobuffer + border;
Packit df99a1
  }
Packit df99a1
  return &bytes[row * bytes_per_row + border];
Packit df99a1
}
Packit df99a1
Packit df99a1
inline GBitmap& 
Packit df99a1
GBitmap::operator=(const GBitmap &ref)
Packit df99a1
{
Packit df99a1
  init(ref, ref.border);
Packit df99a1
  return *this;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline GMonitor *
Packit df99a1
GBitmap::monitor() const
Packit df99a1
{
Packit df99a1
  return monitorptr;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void 
Packit df99a1
GBitmap::euclidian_ratio(int a, int b, int &q, int &r)
Packit df99a1
{
Packit df99a1
  q = a / b;
Packit df99a1
  r = a - b*q;
Packit df99a1
  if (r < 0)
Packit df99a1
  {
Packit df99a1
    q -= 1;
Packit df99a1
    r += b;
Packit df99a1
  }
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
inline int
Packit df99a1
GBitmap::read_run(unsigned char *&data)
Packit df99a1
{
Packit df99a1
  register int z=*data++;
Packit df99a1
  return (z>=RUNOVERFLOWVALUE)?
Packit df99a1
    ((z&~RUNOVERFLOWVALUE)<<8)|(*data++):z;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline int
Packit df99a1
GBitmap::read_run(const unsigned char *&data)
Packit df99a1
{
Packit df99a1
  register int z=*data++;
Packit df99a1
  return (z>=RUNOVERFLOWVALUE)?
Packit df99a1
    ((z&~RUNOVERFLOWVALUE)<<8)|(*data++):z;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
GBitmap::append_run(unsigned char *&data, int count)
Packit df99a1
{
Packit df99a1
  if (count < RUNOVERFLOWVALUE)
Packit df99a1
    {
Packit df99a1
      data[0] = count;
Packit df99a1
      data += 1;
Packit df99a1
    }
Packit df99a1
  else if (count <= MAXRUNSIZE)
Packit df99a1
    {
Packit df99a1
      data[0] = (count>>8) + GBitmap::RUNOVERFLOWVALUE;
Packit df99a1
      data[1] = (count & 0xff);
Packit df99a1
      data += 2;
Packit df99a1
    }
Packit df99a1
  else
Packit df99a1
    {
Packit df99a1
      append_long_run(data, count);
Packit df99a1
    }
Packit df99a1
}
Packit df99a1
Packit df99a1
Packit df99a1
inline void
Packit df99a1
GBitmap::borrow_data(unsigned char &data,int w,int h)
Packit df99a1
{
Packit df99a1
  donate_data(&data,w,h);
Packit df99a1
  bytes_data=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
// ---------------- THE END
Packit df99a1
Packit df99a1
#ifdef HAVE_NAMESPACES
Packit df99a1
}
Packit df99a1
# ifndef NOT_USING_DJVU_NAMESPACE
Packit df99a1
using namespace DJVU;
Packit df99a1
# endif
Packit df99a1
#endif
Packit df99a1
#endif