Blame libdjvu/MMRDecoder.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 _MMRDECODER_H_
Packit df99a1
#define _MMRDECODER_H_
Packit df99a1
#ifdef HAVE_CONFIG_H
Packit df99a1
#include "config.h"
Packit df99a1
#endif
Packit df99a1
#if NEED_GNUG_PRAGMAS
Packit df99a1
# pragma interface
Packit df99a1
#endif
Packit df99a1
Packit df99a1
Packit df99a1
#include "GSmartPointer.h"
Packit df99a1
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 ByteStream;
Packit df99a1
class JB2Image;
Packit df99a1
Packit df99a1
/** @name MMRDecoder.h
Packit df99a1
    Files #"MMRDecoder.h"# and #"MMRDecoder.cpp"# implement a 
Packit df99a1
    CCITT-G4/MMR decoder suitable for use in DjVu.  The main 
Packit df99a1
    entry point is function \Ref{MMRDecoder::decode}.
Packit df99a1
Packit df99a1
    The foreground mask layer of a DjVu file is usually encoded with a
Packit df99a1
    #"Sjbz"# chunk containing JB2 encoded data (cf. \Ref{JB2Image.h}).
Packit df99a1
    Alternatively, the qmask layer may be encoded with a #"Smmr"#
Packit df99a1
    chunk containing a small header followed by MMR encoded data.
Packit df99a1
    This encoding scheme produces significantly larger files. On the
Packit df99a1
    other hand, many scanners a printers talk MMR using very efficient
Packit df99a1
    hardware components.  This is the reason behind the introduction
Packit df99a1
    of #"Smmr"# chunks.
Packit df99a1
Packit df99a1
    The #Smmr# chunk starts by a header containing the following data:
Packit df99a1
    \begin{verbatim}
Packit df99a1
        BYTE*3    :  'M' 'M' 'R'
Packit df99a1
        BYTE      :  0xb000000<s>
Packit df99a1
        INT16     :  <width> (MSB first)
Packit df99a1
        INT16     :  <height> (MSB first)
Packit df99a1
    \end{verbatim}
Packit df99a1
Packit df99a1
    The header is followed by the encoded data.  Bit 0 of the fourth header
Packit df99a1
    byte (##) is similar to TIFF's ``min-is-black'' tag.  This bit is set
Packit df99a1
    for a reverse video image.  The encoded data can be in either ``regular''
Packit df99a1
    MMR form or ``striped'' MMR form.  This is indicated by bit 1 of the
Packit df99a1
    fourth header byte (#<s>#).  This bit is set to indicate ``striped''
Packit df99a1
    data.  The ``regular'' data format consists of ordinary MMR encoded data.
Packit df99a1
    The ``striped'' data format consists of one sixteen bit integer (msb
Packit df99a1
    first) containing the number of rows per stripe, followed by data for each
Packit df99a1
    stripe as follows.
Packit df99a1
    \begin{verbatim}
Packit df99a1
        INT16     :  <rowsperstripe> (MSB first)
Packit df99a1
        INT32          :  <nbytes1>
Packit df99a1
        BYTE*<nbytes1> :  <mmrdata1>
Packit df99a1
        INT32          :  <nbytes2>
Packit df99a1
        BYTE*<nbytes2> :  <mmrdata2>
Packit df99a1
          ...
Packit df99a1
    \end{verbatim}
Packit df99a1
    Static function \Ref{MMRDecoder::decode_header} decodes the header.  You
Packit df99a1
    can then create a \Ref{MMRDecoder} object with the flags #inverted# and
Packit df99a1
    #striped# as obtained when decoding the header.  One can also decode raw
Packit df99a1
    MMR data by simply initialising a \Ref{MMRDecoder} object with flag
Packit df99a1
    #striped# unset.  Each call to \Ref{MMRDecoder::scanruns},
Packit df99a1
    \Ref{MMRDecoder::scanrle} or \Ref{MMRDecoder::scanline} will then decode a
Packit df99a1
    row of the MMR encoded image.
Packit df99a1
Packit df99a1
    Function \Ref{MMRDecoder::decode} is a convenience function for decoding
Packit df99a1
    the contents of a #"Smmr"# chunk.  It returns a \Ref{JB2Image} divided
Packit df99a1
    into manageable blocks in order to provide the zooming and panning
Packit df99a1
    features implemented by class \Ref{JB2Image}.
Packit df99a1
Packit df99a1
    @memo
Packit df99a1
    CCITT-G4/MMR decoder.
Packit df99a1
    @author
Packit df99a1
    Parag Deshmukh <parag@sanskrit.lz.att.com> \\
Packit df99a1
    Leon Bottou <leonb@research.att.com> */
Packit df99a1
//@{
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
#define MMRDECODER_HAS_SCANRUNS  1
Packit df99a1
#define MMRDECODER_HAS_SCANRLE   1
Packit df99a1
Packit df99a1
Packit df99a1
Packit df99a1
/** Class for G4/MMR decoding.  The simplest way to use this class is
Packit df99a1
    the static member function \Ref{MMRDecoder::decode}.  This
Packit df99a1
    function internally creates an instance of #MMRDecoder# which
Packit df99a1
    processes the MMR data scanline by scanline.  */
Packit df99a1
class DJVUAPI MMRDecoder : public GPEnabled
Packit df99a1
{
Packit df99a1
protected:
Packit df99a1
  MMRDecoder(const int width, const int height);
Packit df99a1
  void init(GP<ByteStream> gbs, const bool striped=false);
Packit df99a1
public:
Packit df99a1
  /** Main decoding routine that (a) decodes the header using
Packit df99a1
      #decode_header#, (b) decodes the MMR data using an instance of
Packit df99a1
      #MMRDecoder#, and returns a new \Ref{JB2Image} composed of tiles
Packit df99a1
      whose maximal width and height is derived from the size of the
Packit df99a1
      image. */
Packit df99a1
  static GP<JB2Image> decode(GP<ByteStream> gbs);
Packit df99a1
Packit df99a1
  /// Only decode the header.
Packit df99a1
  static bool decode_header(ByteStream &inp, 
Packit df99a1
                            int &width, int &height, int &invert);
Packit df99a1
Packit df99a1
public:
Packit df99a1
  /// Non-virtual destructor.
Packit df99a1
  ~MMRDecoder();
Packit df99a1
  /** Create a MMRDecoder object for decoding an image
Packit df99a1
      of size #width# by #height#. Flag $striped# must be set
Packit df99a1
      if the image is composed of multiple stripes. */
Packit df99a1
  static GP<MMRDecoder> create(GP<ByteStream> gbs, 
Packit df99a1
                               const int width, const int height,
Packit df99a1
                               const bool striped=false );
Packit df99a1
Packit df99a1
  /** Decodes a scanline and returns a pointer to an array of run lengths.
Packit df99a1
      The returned buffer contains the length of alternative white and black
Packit df99a1
      runs.  These run lengths sum to the image width. They are followed by
Packit df99a1
      two zeroes.  The position of these two zeroes is stored in the pointer
Packit df99a1
      specified by the optional argument #endptr#.  The buffer data should be
Packit df99a1
      processed before calling this function again. */
Packit df99a1
  const unsigned short *scanruns(const unsigned short **endptr=0);
Packit df99a1
  /** Decodes a scanline and returns a pointer to RLE encoded data.  The
Packit df99a1
      buffer contains the length of the runs for the current line encoded as
Packit df99a1
      described in \Ref{PNM and RLE file formats}.)  The flag #invert# can be
Packit df99a1
      used to indicate that the MMR data is encoded in reverse video.  The RLE
Packit df99a1
      data is followed by two zero bytes.  The position of these two zeroes is
Packit df99a1
      stored in the pointer specified by the optional argument #endptr#.  The
Packit df99a1
      buffer data should be processed before calling this function again. This
Packit df99a1
      is implemented by calling \Ref{MMRDecoder::scanruns}. */
Packit df99a1
  const unsigned char  *scanrle(const bool invert, 
Packit df99a1
                                const unsigned char **endptr=0);
Packit df99a1
#if 0
Packit df99a1
  /** Decodes a scanline and returns a pointer to an array of #0# or #1# bytes.
Packit df99a1
      Returns a pointer to the scanline buffer containing one byte per pixel. 
Packit df99a1
      The buffer data should be processed before calling this function again.
Packit df99a1
      This is implemented by calling \Ref{MMRDecoder::scanruns}. */
Packit df99a1
  const unsigned char *scanline();
Packit df99a1
#endif
Packit df99a1
 private:
Packit df99a1
  int width;
Packit df99a1
  int height;
Packit df99a1
  int lineno;
Packit df99a1
  int striplineno;
Packit df99a1
  int rowsperstrip;
Packit df99a1
  unsigned char  *line;
Packit df99a1
  GPBuffer<unsigned char> gline;
Packit df99a1
  unsigned short *lineruns;
Packit df99a1
  GPBuffer<unsigned short> glineruns;
Packit df99a1
  unsigned short *prevruns;
Packit df99a1
  GPBuffer<unsigned short> gprevruns;
Packit df99a1
public:
Packit df99a1
  class VLSource;
Packit df99a1
  class VLTable;
Packit df99a1
private:
Packit df99a1
  GP<VLSource> src;
Packit df99a1
  GP<VLTable> mrtable;
Packit df99a1
  GP<VLTable> wtable;
Packit df99a1
  GP<VLTable> btable;
Packit df99a1
  friend class VLSource;
Packit df99a1
  friend class VLTable;
Packit df99a1
};
Packit df99a1
Packit df99a1
Packit df99a1
//@}
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