Blame libdjvu/IW44Image.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 IW44IMAGE_H_
Packit df99a1
#define IW44IMAGE_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
/** @name IW44Image.h
Packit df99a1
Packit df99a1
    Files #"IW44Image.h"# and #"IW44Image.cpp"# implement the DjVu IW44 wavelet
Packit df99a1
    scheme for the compression of gray-level images (see class \Ref{IWBitmap})
Packit df99a1
    and color images (see class \Ref{IWPixmap}).  Programs \Ref{c44} and
Packit df99a1
    \Ref{d44} demonstrate how to encode and decode IW44 files.
Packit df99a1
Packit df99a1
    {\bf IW44 File Structure} --- The IW44 files are structured according to
Packit df99a1
    the EA IFF85 specifications (see \Ref{IFFByteStream.h}).  Gray level IW44
Packit df99a1
    Images consist of a single #"FORM:BM44"# chunk composed of an arbitrary
Packit df99a1
    number of #"BM44"# data chunks.  Color IW44 Images consist of a single
Packit df99a1
    #"FORM:PM44"# chunk composed of an arbitrary number of #"PM44"# data
Packit df99a1
    chunks.  The successive #"PM44"# or #"BM44"# data chunks contain
Packit df99a1
    successive refinements of the encoded image.  Each chunk contains a
Packit df99a1
    certain number of ``data slices''.  The first chunk also contains a small
Packit df99a1
    image header.  You can use program \Ref{djvuinfo} to display all this
Packit df99a1
    structural information:
Packit df99a1
    \begin{verbatim}
Packit df99a1
    % djvuinfo lag.iw4
Packit df99a1
    lag.iw4:
Packit df99a1
      FORM:PM44 [62598] 
Packit df99a1
        PM44 [10807]              #1 - 74 slices - v1.2 (color) - 684x510
Packit df99a1
        PM44 [23583]              #2 - 13 slices 
Packit df99a1
        PM44 [28178]              #3 - 10 slices 
Packit df99a1
    \end{verbatim}
Packit df99a1
Packit df99a1
    {\bf Embedded IW44 Images} --- These IW44 data chunks can also appear within
Packit df99a1
    other contexts.  Files representing a DjVu page, for instance, consist of
Packit df99a1
    a single #"FORM:DJVU"# composite chunk.  This composite chunk may contain
Packit df99a1
    #"BG44"# chunks encoding the background layer and #"FG44"# chunks encoding
Packit df99a1
    the foreground color layer.  These #"BG44"# and #"FG44"# chunks are
Packit df99a1
    actually regular IW44 data chunks with a different chunk identifier.  This
Packit df99a1
    information too can be displayed using program \Ref{djvuinfo}.
Packit df99a1
    \begin{verbatim}
Packit df99a1
    % djvuinfo graham1.djvu 
Packit df99a1
    graham1.djvu:
Packit df99a1
      FORM:DJVU [32553] 
Packit df99a1
        INFO [5]            3156x2325, version 17
Packit df99a1
        Sjbz [17692] 
Packit df99a1
        BG44 [2570]         #1 - 74 slices - v1.2 (color) - 1052x775
Packit df99a1
        FG44 [1035]         #1 - 100 slices - v1.2 (color) - 263x194
Packit df99a1
        BG44 [3048]         #2 - 10 slices 
Packit df99a1
        BG44 [894]          #3 - 4 slices 
Packit df99a1
        BG44 [7247]         #4 - 9 slices 
Packit df99a1
    \end{verbatim}
Packit df99a1
Packit df99a1
    {\bf Performance} --- The main design objective for the DjVu wavelets
Packit df99a1
    consisted of allowing progressive rendering and smooth scrolling of large
Packit df99a1
    images with limited memory requirements.  Decoding functions process the
Packit df99a1
    compressed data and update a memory efficient representation of the
Packit df99a1
    wavelet coefficients.  Imaging function then can quickly render an
Packit df99a1
    arbitrary segment of the image using the available data.  Both process can
Packit df99a1
    be carried out in two threads of execution.  This design plays an
Packit df99a1
    important role in the DjVu system.  We have investigated various
Packit df99a1
    state-of-the-art wavelet compression schemes: although these schemes may
Packit df99a1
    achieve slightly smaller file sizes, the decoding functions did not even
Packit df99a1
    approach our requirements.  
Packit df99a1
Packit df99a1
    The IW44 wavelets satisfy these requirements today. It performs very well
Packit df99a1
    for quality settings resulting in high compression ratios.  It should not
Packit df99a1
    be used for quasi-lossless compression because certain design choices
Packit df99a1
    deliberately sacrifice the IW44 quasi-lossless performance in order to
Packit df99a1
    improve the image quality at high compression ratios.
Packit df99a1
Packit df99a1
    Little care however has been taken to make the IW44 encoder memory
Packit df99a1
    efficient.  This code uses two copies of the wavelet coefficient data
Packit df99a1
    structure (one for the raw coefficients, one for the quantized
Packit df99a1
    coefficients).  A more sophisticated implementation should considerably
Packit df99a1
    reduce the memory requirements.
Packit df99a1
Packit df99a1
    {\bf Masking} --- When we create a DjVu image, we often know that certain
Packit df99a1
    pixels of the background image are going to be covered by foreground
Packit df99a1
    objects like text or drawings.  The DjVu IW44 wavelet decomposition
Packit df99a1
    routine can use an optional bilevel image named the mask.  Every non zero
Packit df99a1
    pixel in the mask means the value of the corresponding pixel in the
Packit df99a1
    background image is irrelevant.  The wavelet decomposition code will
Packit df99a1
    replace these masked pixels by a color value whose coding cost is minimal
Packit df99a1
    (see \URL{http://www.research.att.com/~leonb/DJVU/mask}).
Packit df99a1
Packit df99a1
    {\bf ToDo} --- There are many improvements to be made.  Besides better
Packit df99a1
    quantization algorithms (such as trellis quantization and bitrate
Packit df99a1
    allocation), we should allow for more wavelet transforms.  These
Packit df99a1
    improvements may be implemented in future version, if (and only if) they
Packit df99a1
    can meet our decoding constraints.  Future versions will probably split
Packit df99a1
    file #"IW44Image.cpp"# which currently contains everything.
Packit df99a1
 
Packit df99a1
    @memo
Packit df99a1
    Wavelet encoded images.
Packit df99a1
    @author
Packit df99a1
    L\'eon Bottou <leonb@research.att.com>
Packit df99a1
Packit df99a1
// From: Leon Bottou, 1/31/2002
Packit df99a1
// Lizardtech has split the corresponding cpp file into a decoder and an encoder.
Packit df99a1
// Only superficial changes.  The meat is mine.
Packit df99a1
Packit df99a1
*/
Packit df99a1
//@{
Packit df99a1
Packit df99a1
Packit df99a1
#include "GSmartPointer.h"
Packit df99a1
#include "ZPCodec.h"
Packit df99a1
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
class GRect;
Packit df99a1
class IFFByteStream;
Packit df99a1
class ByteStream;
Packit df99a1
class GBitmap;
Packit df99a1
class GPixmap;
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
/** IW44 encoding parameters.  
Packit df99a1
    This data structure gathers the quality specification parameters needed
Packit df99a1
    for encoding each chunk of an IW44 file.  Chunk data is generated until
Packit df99a1
    meeting either the slice target, the size target or the decibel target.  */
Packit df99a1
Packit df99a1
struct DJVUAPI IWEncoderParms 
Packit df99a1
{
Packit df99a1
  /** Slice target.  Data generation for the current chunk stops if the total
Packit df99a1
      number of slices (in this chunk and all the previous chunks) reaches
Packit df99a1
      value #slice#.  The default value #0# has a special meaning: data will
Packit df99a1
      be generated regardless of the number of slices in the file. */
Packit df99a1
  int    slices;
Packit df99a1
  /** Size target.  Data generation for the current chunk stops if the total
Packit df99a1
      data size (in this chunk and all the previous chunks), expressed in
Packit df99a1
      bytes, reaches value #size#.  The default value #0# has a special
Packit df99a1
      meaning: data will be generated regardless of the file size. */
Packit df99a1
  int    bytes;
Packit df99a1
  /** Decibel target.  Data generation for the current chunk stops if the
Packit df99a1
      estimated luminance error, expressed in decibels, reaches value
Packit df99a1
      #decibel#.  The default value #0# has a special meaning: data will be
Packit df99a1
      generated regardless of the estimated luminance error.  Specifying value
Packit df99a1
      #0# in fact shortcuts the computation of the estimated luminance error
Packit df99a1
      and sensibly speeds up the encoding process.  */
Packit df99a1
  float  decibels;
Packit df99a1
  /** Constructor. Initializes the structure with the default values. */
Packit df99a1
  IWEncoderParms(void);
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
/** IW44 encoded gray-level and color images.  This class acts as a base for
Packit df99a1
    images represented as a collection of IW44 wavelet coefficients.  The
Packit df99a1
    coefficients are stored in a memory efficient data structure.  Member
Packit df99a1
    function \Ref{get_bitmap} renders an arbitrary segment of the image into
Packit df99a1
    a \Ref{GBitmap}.  Member functions \Ref{decode_iff} and \Ref{encode_iff}
Packit df99a1
    read and write DjVu IW44 files (see \Ref{IW44Image.h}).  Both the copy
Packit df99a1
    constructor and the copy operator are declared as private members. It is
Packit df99a1
    therefore not possible to make multiple copies of instances of this
Packit df99a1
    class. */
Packit df99a1
Packit df99a1
class DJVUAPI IW44Image : public GPEnabled
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  /** Chrominance processing selector.  The following constants may be used as
Packit df99a1
      argument to the following \Ref{IWPixmap} constructor to indicate how the
Packit df99a1
      chrominance information should be processed. There are four possible values:
Packit df99a1
      \begin{description}
Packit df99a1
      \item[CRCBnone:] The wavelet transform will discard the chrominance 
Packit df99a1
           information and only keep the luminance. The image will show in shades of gray.
Packit df99a1
      \item[CRCBhalf:] The wavelet transform will process the chrominance at only 
Packit df99a1
           half the image resolution. This option creates smaller files but may create
Packit df99a1
           artifacts in highly colored images.
Packit df99a1
      \item[CRCBnormal:] The wavelet transform will process the chrominance at full 
Packit df99a1
           resolution. This is the default.
Packit df99a1
      \item[CRCBfull:] The wavelet transform will process the chrominance at full 
Packit df99a1
           resolution. This option also disables the chrominance encoding delay
Packit df99a1
           (see \Ref{parm_crcbdelay}) which usually reduces the bitrate associated with the
Packit df99a1
           chrominance information.
Packit df99a1
      \end{description} */
Packit df99a1
  enum CRCBMode { 
Packit df99a1
    CRCBnone, 
Packit df99a1
    CRCBhalf, 
Packit df99a1
    CRCBnormal, 
Packit df99a1
    CRCBfull };
Packit df99a1
  class Transform;
Packit df99a1
  class Map;
Packit df99a1
  class Block;
Packit df99a1
  class Codec;
Packit df99a1
  struct Alloc;
Packit df99a1
  struct PrimaryHeader;
Packit df99a1
  struct SecondaryHeader;
Packit df99a1
  struct TertiaryHeader;
Packit df99a1
  enum ImageType {
Packit df99a1
    GRAY=false,
Packit df99a1
    COLOR=true };
Packit df99a1
protected:
Packit df99a1
  IW44Image(void);
Packit df99a1
public:
Packit df99a1
  /** Null constructor.  Constructs an empty IW44Image object. This object does
Packit df99a1
      not contain anything meaningful. You must call function \Ref{init},
Packit df99a1
      \Ref{decode_iff} or \Ref{decode_chunk} to populate the wavelet
Packit df99a1
      coefficient data structure. You may not use \Ref{encode_iff} or 
Packit df99a1
      \Ref{encode_chunk}. */
Packit df99a1
  static GP<IW44Image> create_decode(const ImageType itype=COLOR);
Packit df99a1
  /** Null constructor.  Constructs an empty IW44Image object. This object does
Packit df99a1
      not contain anything meaningful. You must call function \Ref{init},
Packit df99a1
      \Ref{decode_iff} or \Ref{decode_chunk} to populate the wavelet
Packit df99a1
      coefficient data structure.  You may then use \Ref{encode_iff}
Packit df99a1
      and \Ref{encode_chunk}. */
Packit df99a1
  static GP<IW44Image> create_encode(const ImageType itype=COLOR);
Packit df99a1
  // virtual destructor
Packit df99a1
  virtual ~IW44Image();
Packit df99a1
  /** Initializes an IWBitmap with image #bm#.  This constructor
Packit df99a1
      performs the wavelet decomposition of image #bm# and records the
Packit df99a1
      corresponding wavelet coefficient.  Argument #mask# is an optional
Packit df99a1
      bilevel image specifying the masked pixels (see \Ref{IW44Image.h}). */
Packit df99a1
  static GP<IW44Image> create_encode(const GBitmap &bm, const GP<GBitmap> mask=0);
Packit df99a1
  /** Initializes an IWPixmap with color image #bm#.  This constructor
Packit df99a1
      performs the wavelet decomposition of image #bm# and records the
Packit df99a1
      corresponding wavelet coefficient.  Argument #mask# is an optional
Packit df99a1
      bilevel image specifying the masked pixels (see \Ref{IW44Image.h}).
Packit df99a1
      Argument #crcbmode# specifies how the chrominance information should be
Packit df99a1
      encoded (see \Ref{CRCBMode}). */
Packit df99a1
  static GP<IW44Image> create_encode(const GPixmap &bm, const GP<GBitmap> mask=0, CRCBMode crcbmode=CRCBnormal);
Packit df99a1
  // ACCESS
Packit df99a1
  /** Returns the width of the IWBitmap image. */
Packit df99a1
  int get_width(void) const;
Packit df99a1
  /** Returns the height of the IWBitmap image. */
Packit df99a1
  int get_height(void) const;
Packit df99a1
  /** Reconstructs the complete image.  The reconstructed image
Packit df99a1
      is then returned as a GBitmap object. */
Packit df99a1
  virtual GP<GBitmap> get_bitmap(void) {return 0;}
Packit df99a1
  /** Reconstructs a segment of the image at a given scale.  The subsampling
Packit df99a1
      ratio #subsample# must be a power of two between #1# and #32#.  Argument
Packit df99a1
      #rect# specifies which segment of the subsampled image should be
Packit df99a1
      reconstructed.  The reconstructed image is returned as a GBitmap object
Packit df99a1
      whose size is equal to the size of the rectangle #rect#. */
Packit df99a1
  virtual GP<GBitmap> get_bitmap(int subsample, const GRect &rect) {return 0;}
Packit df99a1
  /** Reconstructs the complete image.  The reconstructed image
Packit df99a1
      is then returned as a GPixmap object. */
Packit df99a1
  virtual GP<GPixmap> get_pixmap(void) {return 0;}
Packit df99a1
  /** Reconstructs a segment of the image at a given scale.  The subsampling
Packit df99a1
      ratio #subsample# must be a power of two between #1# and #32#.  Argument
Packit df99a1
      #rect# specifies which segment of the subsampled image should be
Packit df99a1
      reconstructed.  The reconstructed image is returned as a GPixmap object
Packit df99a1
      whose size is equal to the size of the rectangle #rect#. */
Packit df99a1
  virtual GP<GPixmap> get_pixmap(int subsample, const GRect &rect) {return 0;}
Packit df99a1
  /** Returns the amount of memory used by the wavelet coefficients.  This
Packit df99a1
      amount of memory is expressed in bytes. */
Packit df99a1
  virtual unsigned int get_memory_usage(void) const = 0;
Packit df99a1
  /** Returns the filling ratio of the internal data structure.  Wavelet
Packit df99a1
      coefficients are stored in a sparse array.  This function tells what
Packit df99a1
      percentage of bins have been effectively allocated. */
Packit df99a1
  virtual int get_percent_memory(void) const = 0;
Packit df99a1
  // CODER
Packit df99a1
  /** Encodes one data chunk into ByteStream #bs#.  Parameter #parms# controls
Packit df99a1
      how much data is generated.  The chunk data is written to ByteStream
Packit df99a1
      #bs# with no IFF header.  Successive calls to #encode_chunk# encode
Packit df99a1
      successive chunks.  You must call #close_codec# after encoding the last
Packit df99a1
      chunk of a file. */
Packit df99a1
  virtual int  encode_chunk(GP<ByteStream> gbs, const IWEncoderParms &parms);
Packit df99a1
  /** Writes a gray level image into DjVu IW44 file.  This function creates a
Packit df99a1
      composite chunk (identifier #FORM:BM44# or #FORM:PM44#) composed of
Packit df99a1
      #nchunks# chunks (identifier #BM44# or #PM44#).  Data for each chunk is
Packit df99a1
      generated with #encode_chunk# using the corresponding parameters in
Packit df99a1
      array #parms#. */
Packit df99a1
  virtual void encode_iff(IFFByteStream &iff, int nchunks, const IWEncoderParms *parms);
Packit df99a1
  // DECODER
Packit df99a1
  /** Decodes one data chunk from ByteStream #bs#.  Successive calls to
Packit df99a1
      #decode_chunk# decode successive chunks.  You must call #close_codec#
Packit df99a1
      after decoding the last chunk of a file.  Note that function
Packit df99a1
      #get_bitmap# and #decode_chunk# may be called simultaneously from two
Packit df99a1
      execution threads. */
Packit df99a1
  virtual int  decode_chunk(GP<ByteStream> gbs) = 0;
Packit df99a1
  /** This function enters a composite chunk (identifier #FORM:BM44#, or
Packit df99a1
      #FORM:PM44#), and decodes a maximum of #maxchunks# data chunks
Packit df99a1
      (identifier #BM44#).  Data for each chunk is processed using the
Packit df99a1
      function #decode_chunk#. */
Packit df99a1
  virtual void decode_iff(IFFByteStream &iff, int maxchunks=999) = 0;
Packit df99a1
  // MISCELLANEOUS
Packit df99a1
  /** Resets the encoder/decoder state.  The first call to #decode_chunk# or
Packit df99a1
      #encode_chunk# initializes the coder for encoding or decoding.  Function
Packit df99a1
      #close_codec# must be called after processing the last chunk in order to
Packit df99a1
      reset the coder and release the associated memory. */
Packit df99a1
  virtual void close_codec(void) = 0;
Packit df99a1
  /** Returns the chunk serial number.  This function returns the serial
Packit df99a1
      number of the last chunk encoded with #encode_chunk# or decoded with
Packit df99a1
      #decode_chunk#. The first chunk always has serial number #1#. Successive
Packit df99a1
      chunks have increasing serial numbers.  Value #0# is returned if this
Packit df99a1
      function is called before calling #encode_chunk# or #decode_chunk# or
Packit df99a1
      after calling #close_codec#. */
Packit df99a1
  virtual int get_serial(void) = 0;
Packit df99a1
  /** Sets the chrominance delay parameter.  This function can be called
Packit df99a1
      before encoding the first color IW44 data chunk.  Parameter #parm# is an
Packit df99a1
      encoding delay which reduces the bitrate associated with the
Packit df99a1
      chrominance information. The default chrominance encoding delay is 10. */
Packit df99a1
  virtual int  parm_crcbdelay(const int parm) {return parm;}
Packit df99a1
  /** Sets the #dbfrac# parameter.  This function can be called before
Packit df99a1
      encoding the first IW44 data chunk.  Parameter #frac# modifies the
Packit df99a1
      decibel estimation algorithm in such a way that the decibel target only
Packit df99a1
      pertains to the average error of the fraction #frac# of the most
Packit df99a1
      misrepresented 32x32 pixel blocks.  Setting arguments #frac# to #1.0#
Packit df99a1
      restores the normal behavior.  */
Packit df99a1
  virtual void parm_dbfrac(float frac) = 0;
Packit df99a1
protected:
Packit df99a1
  // Parameter
Packit df99a1
  float db_frac;
Packit df99a1
  // Data
Packit df99a1
  Map *ymap, *cbmap, *crmap;
Packit df99a1
  int cslice;
Packit df99a1
  int cserial;
Packit df99a1
  int cbytes;
Packit df99a1
private:
Packit df99a1
  // Disable assignment semantic
Packit df99a1
  IW44Image(const IW44Image &ref;;
Packit df99a1
  IW44Image& operator=(const IW44Image &ref;;
Packit df99a1
};
Packit df99a1
Packit df99a1
#ifdef IW44IMAGE_IMPLIMENTATION
Packit df99a1
Packit df99a1
/*x IW44 encoded gray-level image.  This class provided functions for managing
Packit df99a1
    a gray level image represented as a collection of IW44 wavelet
Packit df99a1
    coefficients.  The coefficients are stored in a memory efficient data
Packit df99a1
    structure.  Member function \Ref{get_bitmap} renders an arbitrary segment
Packit df99a1
    of the image into a \Ref{GBitmap}.  Member functions \Ref{decode_iff} and
Packit df99a1
    \Ref{encode_iff} read and write DjVu IW44 files (see \Ref{IW44Image.h}).
Packit df99a1
    Both the copy constructor and the copy operator are declared as private
Packit df99a1
    members. It is therefore not possible to make multiple copies of instances
Packit df99a1
    of this class. */
Packit df99a1
Packit df99a1
class DJVUAPI IWBitmap : public IW44Image
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  friend class IW44Image;
Packit df99a1
  class Encode;
Packit df99a1
protected:
Packit df99a1
  /*x Null constructor.  Constructs an empty IWBitmap object. This object does
Packit df99a1
      not contain anything meaningful. You must call function \Ref{init},
Packit df99a1
      \Ref{decode_iff} or \Ref{decode_chunk} to populate the wavelet
Packit df99a1
      coefficient data structure. */
Packit df99a1
  IWBitmap(void);
Packit df99a1
public:
Packit df99a1
  //x virtual destructor
Packit df99a1
  virtual ~IWBitmap();
Packit df99a1
  //x ACCESS
Packit df99a1
  /*x Reconstructs the complete image.  The reconstructed image
Packit df99a1
      is then returned as a GBitmap object. */
Packit df99a1
  virtual GP<GBitmap> get_bitmap(void);
Packit df99a1
  /*x Reconstructs a segment of the image at a given scale.  The subsampling
Packit df99a1
      ratio #subsample# must be a power of two between #1# and #32#.  Argument
Packit df99a1
      #rect# specifies which segment of the subsampled image should be
Packit df99a1
      reconstructed.  The reconstructed image is returned as a GBitmap object
Packit df99a1
      whose size is equal to the size of the rectangle #rect#. */
Packit df99a1
  virtual GP<GBitmap> get_bitmap(int subsample, const GRect &rect);
Packit df99a1
  /*x Returns the amount of memory used by the wavelet coefficients.  This
Packit df99a1
      amount of memory is expressed in bytes. */
Packit df99a1
  virtual unsigned int get_memory_usage(void) const;
Packit df99a1
  /*x Returns the filling ratio of the internal data structure.  Wavelet
Packit df99a1
      coefficients are stored in a sparse array.  This function tells what
Packit df99a1
      percentage of bins have been effectively allocated. */
Packit df99a1
  virtual int get_percent_memory(void) const;
Packit df99a1
  // DECODER
Packit df99a1
  /*x Decodes one data chunk from ByteStream #bs#.  Successive calls to
Packit df99a1
      #decode_chunk# decode successive chunks.  You must call #close_codec#
Packit df99a1
      after decoding the last chunk of a file.  Note that function
Packit df99a1
      #get_bitmap# and #decode_chunk# may be called simultaneously from two
Packit df99a1
      execution threads. */
Packit df99a1
  virtual int  decode_chunk(GP<ByteStream> gbs);
Packit df99a1
  /*x Reads a DjVu IW44 file as a gray level image.  This function enters a
Packit df99a1
      composite chunk (identifier #FORM:BM44#), and decodes a maximum of
Packit df99a1
      #maxchunks# data chunks (identifier #BM44#).  Data for each chunk is
Packit df99a1
      processed using the function #decode_chunk#. */
Packit df99a1
  virtual void decode_iff(IFFByteStream &iff, int maxchunks=999);
Packit df99a1
  // MISCELLANEOUS
Packit df99a1
  /*x Resets the encoder/decoder state.  The first call to #decode_chunk# or
Packit df99a1
      #encode_chunk# initializes the coder for encoding or decoding.  Function
Packit df99a1
      #close_codec# must be called after processing the last chunk in order to
Packit df99a1
      reset the coder and release the associated memory. */
Packit df99a1
  virtual void close_codec(void);
Packit df99a1
  /*x Returns the chunk serial number.  This function returns the serial
Packit df99a1
      number of the last chunk encoded with #encode_chunk# or decoded with
Packit df99a1
      #decode_chunk#. The first chunk always has serial number #1#. Successive
Packit df99a1
      chunks have increasing serial numbers.  Value #0# is returned if this
Packit df99a1
      function is called before calling #encode_chunk# or #decode_chunk# or
Packit df99a1
      after calling #close_codec#. */
Packit df99a1
  virtual int get_serial(void);
Packit df99a1
  /*x Sets the #dbfrac# parameter.  This function can be called before
Packit df99a1
      encoding the first IW44 data chunk.  Parameter #frac# modifies the
Packit df99a1
      decibel estimation algorithm in such a way that the decibel target only
Packit df99a1
      pertains to the average error of the fraction #frac# of the most
Packit df99a1
      misrepresented 32x32 pixel blocks.  Setting arguments #frac# to #1.0#
Packit df99a1
      restores the normal behavior.  */
Packit df99a1
  virtual void parm_dbfrac(float frac);
Packit df99a1
private:
Packit df99a1
  Codec *ycodec;
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
/*x IW44 encoded color image. This class provided functions for managing a
Packit df99a1
    color image represented as a collection of IW44 wavelet coefficients.  The
Packit df99a1
    coefficients are stored in a memory efficient data structure.  Member
Packit df99a1
    function \Ref{get_pixmap} renders an arbitrary segment of the image into a
Packit df99a1
    \Ref{GPixmap}.  Member functions \Ref{decode_iff} and \Ref{encode_iff}
Packit df99a1
    read and write DjVu IW44 files (see \Ref{IW44Image.h}).  Both the copy
Packit df99a1
    constructor and the copy operator are declared as private members. It is
Packit df99a1
    therefore not possible to make multiple copies of instances of this
Packit df99a1
    class. */
Packit df99a1
Packit df99a1
class DJVUAPI IWPixmap : public IW44Image
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  friend class IW44Image;
Packit df99a1
protected:
Packit df99a1
  class Encode;
Packit df99a1
  /*x Null constructor.  Constructs an empty IWPixmap object. This object does
Packit df99a1
      not contain anything meaningful. You must call function \Ref{init},
Packit df99a1
      \Ref{decode_iff} or \Ref{decode_chunk} to populate the wavelet
Packit df99a1
      coefficient data structure. */
Packit df99a1
  IWPixmap(void);
Packit df99a1
public:
Packit df99a1
  // virtual destructor
Packit df99a1
  virtual ~IWPixmap();
Packit df99a1
  // ACCESS
Packit df99a1
  /*x Reconstructs the complete image.  The reconstructed image
Packit df99a1
      is then returned as a GPixmap object. */
Packit df99a1
  virtual GP<GPixmap> get_pixmap(void);
Packit df99a1
  /*x Reconstructs a segment of the image at a given scale.  The subsampling
Packit df99a1
      ratio #subsample# must be a power of two between #1# and #32#.  Argument
Packit df99a1
      #rect# specifies which segment of the subsampled image should be
Packit df99a1
      reconstructed.  The reconstructed image is returned as a GPixmap object
Packit df99a1
      whose size is equal to the size of the rectangle #rect#. */
Packit df99a1
  virtual GP<GPixmap> get_pixmap(int subsample, const GRect &rect);
Packit df99a1
  /*x Returns the amount of memory used by the wavelet coefficients.  This
Packit df99a1
      amount of memory is expressed in bytes. */
Packit df99a1
  virtual unsigned int get_memory_usage(void) const;
Packit df99a1
  /*x Returns the filling ratio of the internal data structure.  Wavelet
Packit df99a1
      coefficients are stored in a sparse array.  This function tells what
Packit df99a1
      percentage of bins have been effectively allocated. */
Packit df99a1
  virtual int get_percent_memory(void) const;
Packit df99a1
  // DECODER
Packit df99a1
  /*x Decodes one data chunk from ByteStream #bs#.  Successive calls to
Packit df99a1
      #decode_chunk# decode successive chunks.  You must call #close_codec#
Packit df99a1
      after decoding the last chunk of a file.  Note that function
Packit df99a1
      #get_bitmap# and #decode_chunk# may be called simultaneously from two
Packit df99a1
      execution threads. */
Packit df99a1
  virtual int  decode_chunk(GP<ByteStream> gbs);
Packit df99a1
  /*x Reads a DjVu IW44 file as a color image.  This function enters a
Packit df99a1
      composite chunk (identifier #FORM:PM44# or #FORM:BM44#), and decodes a
Packit df99a1
      maximum of #maxchunks# data chunks (identifier #PM44# or #BM44#).  Data
Packit df99a1
      for each chunk is processed using the function #decode_chunk#. */
Packit df99a1
  virtual void decode_iff(IFFByteStream &iff, int maxchunks=999);
Packit df99a1
  // MISCELLANEOUS
Packit df99a1
  /*x Resets the encoder/decoder state.  The first call to #decode_chunk# or
Packit df99a1
      #encode_chunk# initializes the coder for encoding or decoding.  Function
Packit df99a1
      #close_codec# must be called after processing the last chunk in order to
Packit df99a1
      reset the coder and release the associated memory. */
Packit df99a1
  virtual void close_codec(void);
Packit df99a1
  /*x Returns the chunk serial number.  This function returns the serial
Packit df99a1
      number of the last chunk encoded with #encode_chunk# or decoded with
Packit df99a1
      #decode_chunk#. The first chunk always has serial number #1#. Successive
Packit df99a1
      chunks have increasing serial numbers.  Value #0# is returned if this
Packit df99a1
      function is called before calling #encode_chunk# or #decode_chunk# or
Packit df99a1
      after calling #close_codec#. */
Packit df99a1
  virtual int  get_serial(void);
Packit df99a1
  /*x Sets the chrominance delay parameter.  This function can be called
Packit df99a1
      before encoding the first IW44 data chunk.  Parameter #parm# is an
Packit df99a1
      encoding delay which reduces the bitrate associated with the
Packit df99a1
      chrominance information. The default chrominance encoding delay is 10. */
Packit df99a1
  virtual int  parm_crcbdelay(const int parm);
Packit df99a1
  /*x Sets the #dbfrac# parameter.  This function can be called before
Packit df99a1
      encoding the first IW44 data chunk.  Parameter #frac# modifies the
Packit df99a1
      decibel estimation algorithm in such a way that the decibel target only
Packit df99a1
      pertains to the average error of the fraction #frac# of the most
Packit df99a1
      misrepresented 32x32 pixel blocks.  Setting arguments #frac# to #1.0#
Packit df99a1
      restores the normal behavior.  */
Packit df99a1
  virtual void parm_dbfrac(float frac);
Packit df99a1
protected:
Packit df99a1
  // Parameter
Packit df99a1
  int   crcb_delay;
Packit df99a1
  int   crcb_half;
Packit df99a1
  // Data
Packit df99a1
private:
Packit df99a1
  Codec *ycodec, *cbcodec, *crcodec;
Packit df99a1
};
Packit df99a1
Packit df99a1
/*x IW44Transform.
Packit df99a1
*/
Packit df99a1
class IW44Image::Transform
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  class Decode;
Packit df99a1
  class Encode;
Packit df99a1
protected:
Packit df99a1
  static void filter_begin(int w, int h);
Packit df99a1
  static void filter_end(void);
Packit df99a1
};
Packit df99a1
Packit df99a1
struct GPixel;
Packit df99a1
class IW44Image::Transform::Decode : public IW44Image::Transform
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
 // WAVELET TRANSFORM
Packit df99a1
  /*x Forward transform. */
Packit df99a1
  static void backward(short *p, int w, int h, int rowsize, int begin, int end);
Packit df99a1
  
Packit df99a1
  // COLOR TRANSFORM
Packit df99a1
  /*x Converts YCbCr to RGB. */
Packit df99a1
  static void YCbCr_to_RGB(GPixel *p, int w, int h, int rowsize);
Packit df99a1
};
Packit df99a1
Packit df99a1
//---------------------------------------------------------------
Packit df99a1
// *** Class IW44Image::Block [declaration]
Packit df99a1
// Represents a block of 32x32 coefficients after zigzagging and scaling
Packit df99a1
Packit df99a1
Packit df99a1
class IW44Image::Block // DJVU_CLASS
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  // creating
Packit df99a1
  Block(void);
Packit df99a1
  // accessing scaled coefficients
Packit df99a1
  short get(int n) const;
Packit df99a1
  void  set(int n, int val, IW44Image::Map *map);
Packit df99a1
  // converting from liftblock
Packit df99a1
  void  read_liftblock(const short *coeff, IW44Image::Map *map);
Packit df99a1
  void  write_liftblock(short *coeff, int bmin=0, int bmax=64) const;
Packit df99a1
  // sparse array access
Packit df99a1
  const short* data(int n) const;
Packit df99a1
  short* data(int n, IW44Image::Map *map);
Packit df99a1
  void   zero(int n);
Packit df99a1
  // sparse representation
Packit df99a1
private:
Packit df99a1
  short **(pdata[4]);
Packit df99a1
};
Packit df99a1
Packit df99a1
//---------------------------------------------------------------
Packit df99a1
// *** Class IW44Image::Map [declaration]
Packit df99a1
// Represents all the blocks of an image
Packit df99a1
Packit df99a1
class IW44Image::Map // DJVU_CLASS
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  class Encode;
Packit df99a1
Packit df99a1
  // construction
Packit df99a1
  Map(int w, int h);
Packit df99a1
  ~Map();
Packit df99a1
  // image access
Packit df99a1
  void image(signed char *img8, int rowsize, 
Packit df99a1
             int pixsep=1, int fast=0);
Packit df99a1
  void image(int subsample, const GRect &rect, 
Packit df99a1
             signed char *img8, int rowsize, 
Packit df99a1
             int pixsep=1, int fast=0);
Packit df99a1
  // array of blocks
Packit df99a1
  IW44Image::Block *blocks;
Packit df99a1
  // geometry
Packit df99a1
  int iw, ih;
Packit df99a1
  int bw, bh;
Packit df99a1
  int nb;
Packit df99a1
  // coefficient allocation stuff
Packit df99a1
  short *alloc(int n);
Packit df99a1
  short **allocp(int n);
Packit df99a1
  IW44Image::Alloc *chain;
Packit df99a1
  int top;
Packit df99a1
  // statistics
Packit df99a1
  int get_bucket_count(void) const;
Packit df99a1
  unsigned int get_memory_usage(void) const;
Packit df99a1
};
Packit df99a1
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
// ENCODING/DECODING WAVELET COEFFICIENTS 
Packit df99a1
//    USING HIERARCHICAL SET DIFFERENCE
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
Packit df99a1
Packit df99a1
//-----------------------------------------------
Packit df99a1
// Class IW44Image::Codec [declaration+implementation]
Packit df99a1
// Maintains information shared while encoding or decoding
Packit df99a1
Packit df99a1
class IW44Image::Codec 
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
  class Decode;
Packit df99a1
  class Encode;
Packit df99a1
Packit df99a1
protected:
Packit df99a1
  // Construction
Packit df99a1
  Codec(IW44Image::Map &map);
Packit df99a1
public:
Packit df99a1
  virtual ~Codec();
Packit df99a1
  // Coding
Packit df99a1
  int finish_code_slice(ZPCodec &zp;;
Packit df99a1
  virtual int code_slice(ZPCodec &zp) = 0;
Packit df99a1
  // Data
Packit df99a1
  IW44Image::Map ↦                  // working map
Packit df99a1
  // status
Packit df99a1
  int curband;                  // current band
Packit df99a1
  int curbit;                   // current bitplane
Packit df99a1
  // quantization tables
Packit df99a1
  int quant_hi[10];             // quantization for bands 1 to 9
Packit df99a1
  int quant_lo[16];             // quantization for band 0.
Packit df99a1
  // bucket state
Packit df99a1
  char coeffstate[256];
Packit df99a1
  char bucketstate[16];
Packit df99a1
  enum { ZERO   = 1,            // this coeff never hits this bit
Packit df99a1
         ACTIVE = 2,            // this coeff is already active
Packit df99a1
         NEW    = 4,            // this coeff is becoming active
Packit df99a1
         UNK    = 8 };          // this coeff may become active
Packit df99a1
  // coding context
Packit df99a1
  BitContext ctxStart [32];
Packit df99a1
  BitContext ctxBucket[10][8];
Packit df99a1
  BitContext ctxMant;
Packit df99a1
  BitContext ctxRoot;
Packit df99a1
  // helper
Packit df99a1
  int is_null_slice(int bit, int band);
Packit df99a1
  int decode_prepare(int fbucket, int nbucket, IW44Image::Block &blk);
Packit df99a1
  void decode_buckets(ZPCodec &zp, int bit, int band,
Packit df99a1
    IW44Image::Block &blk, int fbucket, int nbucket);
Packit df99a1
};
Packit df99a1
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
// DEFINITION OF CHUNK HEADERS
Packit df99a1
//////////////////////////////////////////////////////
Packit df99a1
Packit df99a1
Packit df99a1
struct IW44Image::PrimaryHeader {
Packit df99a1
  unsigned char serial;
Packit df99a1
  unsigned char slices;
Packit df99a1
  void encode(GP<ByteStream> gbs);
Packit df99a1
  void decode(GP<ByteStream> gbs);
Packit df99a1
};  
Packit df99a1
Packit df99a1
struct IW44Image::SecondaryHeader {
Packit df99a1
  unsigned char major;
Packit df99a1
  unsigned char minor;
Packit df99a1
  void encode(GP<ByteStream> gbs);
Packit df99a1
  void decode(GP<ByteStream> gbs);
Packit df99a1
};
Packit df99a1
Packit df99a1
struct IW44Image::TertiaryHeader {
Packit df99a1
  unsigned char xhi, xlo;
Packit df99a1
  unsigned char yhi, ylo;
Packit df99a1
  unsigned char crcbdelay;
Packit df99a1
  void encode(GP<ByteStream> gbs);
Packit df99a1
  void decode(GP<ByteStream> gbs, int major=1, int minor=2);
Packit df99a1
};
Packit df99a1
Packit df99a1
inline const short* 
Packit df99a1
IW44Image::Block::data(int n) const
Packit df99a1
{
Packit df99a1
  if (! pdata[n>>4])
Packit df99a1
    return 0;
Packit df99a1
  return pdata[n>>4][n&15];
Packit df99a1
}
Packit df99a1
Packit df99a1
inline short* 
Packit df99a1
IW44Image::Block::data(int n, IW44Image::Map *map)
Packit df99a1
{
Packit df99a1
  if (! pdata[n>>4])
Packit df99a1
    pdata[n>>4] = map->allocp(16);
Packit df99a1
  if (! pdata[n>>4][n &15])
Packit df99a1
    pdata[n>>4][n &15] = map->alloc(16);
Packit df99a1
  return pdata[n>>4][n&15];
Packit df99a1
}
Packit df99a1
Packit df99a1
inline short 
Packit df99a1
IW44Image::Block::get(int n) const
Packit df99a1
{
Packit df99a1
  int n1 = (n>>4);
Packit df99a1
  const short *d = data(n1);
Packit df99a1
  if (! d)
Packit df99a1
    return 0;
Packit df99a1
  return d[n&15];
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void  
Packit df99a1
IW44Image::Block::set(int n, int val, IW44Image::Map *map)
Packit df99a1
{
Packit df99a1
  int n1 = (n>>4);
Packit df99a1
  short* d = data(n1, map);
Packit df99a1
  d[n&15] = val;
Packit df99a1
}
Packit df99a1
Packit df99a1
#endif /* IW44IMAGE_IMPLIMENTATION */
Packit df99a1
Packit df99a1
//@}
Packit df99a1
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
Packit df99a1