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