diff options
author | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
---|---|---|
committer | toma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2009-11-25 17:56:58 +0000 |
commit | 47d455dd55be855e4cc691c32f687f723d9247ee (patch) | |
tree | 52e236aaa2576bdb3840ebede26619692fed6d7d /kviewshell/plugins/djvu/libdjvu/GBitmap.h | |
download | tdegraphics-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.h | 673 |
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 |