|
|
|
//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 <leonb@research.att.com>
|
|
|
|
@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 *tqshape, 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
|