Blame libdjvu/DjVuFile.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 _DJVUFILE_H
Packit df99a1
#define _DJVUFILE_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 "DjVuInfo.h"
Packit df99a1
#include "DjVuPalette.h"
Packit df99a1
#include "DjVuPort.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 DjVuTXT;
Packit df99a1
class ByteStream;
Packit df99a1
class DataPool;
Packit df99a1
class JB2Image;
Packit df99a1
class JB2Dict;
Packit df99a1
class IW44Image;
Packit df99a1
class IFFByteStream;
Packit df99a1
class GPixmap;
Packit df99a1
class DjVuNavDir;
Packit df99a1
Packit df99a1
Packit df99a1
/** @name DjVuFile.h
Packit df99a1
    Files #"DjVuFile.h"# and #"DjVuFile.cpp"# contain implementation of the
Packit df99a1
    \Ref{DjVuFile} class, which takes the leading role in decoding of
Packit df99a1
    \Ref{DjVuImage}s.
Packit df99a1
Packit df99a1
    In the previous releases of the library the work of decoding has been
Packit df99a1
    entirely done in \Ref{DjVuImage}. Now, due to the introduction of multipage
Packit df99a1
    documents, the decoding procedure became significantly more complex and
Packit df99a1
    has been moved out from \Ref{DjVuImage} into \Ref{DjVuFile}.
Packit df99a1
Packit df99a1
    There is not much point though in creating just \Ref{DjVuFile} alone.
Packit df99a1
    The maximum power of the decoder is achieved when you create the
Packit df99a1
    \Ref{DjVuDocument} and work with {\bf it} when decoding the image.
Packit df99a1
Packit df99a1
    @memo Classes representing DjVu files.
Packit df99a1
    @author Andrei Erofeev <eaf@geocities.com>
Packit df99a1
*/
Packit df99a1
Packit df99a1
//@{
Packit df99a1
Packit df99a1
/** #DjVuFile# plays the central role in decoding \Ref{DjVuImage}s.
Packit df99a1
    First of all, it represents a DjVu file whether it's part of a
Packit df99a1
    multipage all-in-one-file DjVu document, or part of a multipage
Packit df99a1
    DjVu document where every page is in a separate file, or the whole
Packit df99a1
    single page document. #DjVuFile# can read its contents from a file
Packit df99a1
    and store it back when necessary.
Packit df99a1
Packit df99a1
    Second, #DjVuFile# does the greatest part of decoding work. In the
Packit df99a1
    past this was the responsibility of \Ref{DjVuImage}. Now, with the
Packit df99a1
    introduction of the multipage DjVu formats, the decoding routines
Packit df99a1
    have been extracted from the \Ref{DjVuImage} and put into this separate
Packit df99a1
    class #DjVuFile#.
Packit df99a1
Packit df99a1
    As \Ref{DjVuImage} before, #DjVuFile# now contains public class
Packit df99a1
    variables corresponding to every component, that can ever be decoded
Packit df99a1
    from a DjVu file (such as #INFO# chunk, #BG44# chunk, #SJBZ# chunk, etc.).
Packit df99a1
Packit df99a1
    As before, the decoding is initiated by a single function
Packit df99a1
    (\Ref{start_decode}() in this case, and \Ref{DjVuImage::decode}() before).
Packit df99a1
    The difference is that #DjVuFile# now handles threads creation itself.
Packit df99a1
    When you call the \Ref{start_decode}() function, it creates the decoding
Packit df99a1
    thread, which starts decoding, and which can create additional threads:
Packit df99a1
    one per each file included into this one.
Packit df99a1
Packit df99a1
    {\bf Inclusion} is also a new feature specifically designed for a
Packit df99a1
    multipage document. Indeed, inside a given document there can be a lot
Packit df99a1
    of things shared between its pages. Examples can be the document
Packit df99a1
    annotation (\Ref{DjVuAnno}) and other things like shared shapes and
Packit df99a1
    dictionary (to be implemented). To avoid putting these chunks into
Packit df99a1
    every page, we have invented new chunk called #INCL# which purpose is
Packit df99a1
    to make the decoder open the specified file and decode it.
Packit df99a1
    
Packit df99a1
    {\bf Source of data.} The #DjVuFile# can be initialized in two ways:
Packit df99a1
    \begin{itemize}
Packit df99a1
       \item With #URL# and \Ref{DjVuPort}. In this case #DjVuFile# will
Packit df99a1
             request its data thru the communication mechanism provided by
Packit df99a1
	     \Ref{DjVuPort} in the constructor. If this file references
Packit df99a1
	     (includes) any other file, data for them will also be requested
Packit df99a1
	     in the same way.
Packit df99a1
       \item With \Ref{ByteStream}. In this case the #DjVuFile# will read
Packit df99a1
             its data directly from the passed stream. This constructor
Packit df99a1
	     has been added to simplify creation of #DjVuFile#s, which do
Packit df99a1
	     no include anything else. In this case the \Ref{ByteStream}
Packit df99a1
	     is enough for the #DjVuFile# to initialize.
Packit df99a1
    \end{itemize}
Packit df99a1
	     
Packit df99a1
    {\bf Progress information.} #DjVuFile# does not do decoding silently.
Packit df99a1
    Instead, it sends a whole set of notifications through the mechanism
Packit df99a1
    provided by \Ref{DjVuPort} and \Ref{DjVuPortcaster}. It tells the user
Packit df99a1
    of the class about the progress of the decoding, about possible errors,
Packit df99a1
    chunk being decoded, etc. The data is requested using this mechanism too.
Packit df99a1
Packit df99a1
    {\bf Creating.} Depending on where you have data of the DjVu file, the
Packit df99a1
    #DjVuFile# can be initialized in two ways:
Packit df99a1
    \begin{itemize}
Packit df99a1
       \item By providing #URL# and pointer to \Ref{DjVuPort}. In this case
Packit df99a1
             #DjVuFile# will request data using communication mechanism
Packit df99a1
	     provided by \Ref{DjVuPort}. This is useful when the data is on
Packit df99a1
	     the web or when this file includes other files.
Packit df99a1
       \item By providing a \Ref{ByteStream} with the data for the file. Use
Packit df99a1
             it only when the file doesn't include other files.
Packit df99a1
    \end{itemize}
Packit df99a1
    There is also a bunch of functions provided for composing
Packit df99a1
    the desired \Ref{DjVuDocument} and modifying #DjVuFile# structure. The
Packit df99a1
    examples are \Ref{delete_chunks}(), \Ref{insert_chunk}(),
Packit df99a1
    \Ref{include_file}() and \Ref{unlink_file}().
Packit df99a1
Packit df99a1
    {\bf Caching.} In the case of plugin it's important to do the caching
Packit df99a1
    of decoded images or files. #DjVuFile# appears to be the best candidate
Packit df99a1
    for caching, and that's why it supports this procedure. Whenever a
Packit df99a1
    #DjVuFile# is successfully decoded, it's added to the cache by
Packit df99a1
    \Ref{DjVuDocument}. Next time somebody needs it, it will be extracted
Packit df99a1
    from the cache directly by \Ref{DjVuDocument} and won't be decoded again.
Packit df99a1
Packit df99a1
    {\bf URLs.} Historically the biggest strain is put on making the decoder
Packit df99a1
    available for Netscape and IE plugins where the original files reside
Packit df99a1
    somewhere in the net. That is why #DjVuFile# uses {\bf URLs} to
Packit df99a1
    identify itself and other files. If you're working with files on the
Packit df99a1
    hard disk, you have to use the local URLs instead of file names.
Packit df99a1
    A good way to do two way conversion is the \Ref{GOS} class. Sometimes it
Packit df99a1
    happens that a given file does not reside anywhere but the memory. No
Packit df99a1
    problem in this case either. There is a special port \Ref{DjVuMemoryPort},
Packit df99a1
    which can associate any URL with the corresponding data in the memory.
Packit df99a1
    All you need to do is to invent your own URL prefix for this case.
Packit df99a1
    "#memory:#" will do. The usage of absolute URLs has many advantages among
Packit df99a1
    which is the capability to cache files with their URL being the cache key.
Packit df99a1
Packit df99a1
    Please note, that the #DjVuFile# class has been designed to work closely
Packit df99a1
    with \Ref{DjVuDocument}. So please review the documentation on this class
Packit df99a1
    too. */
Packit df99a1
Packit df99a1
class DJVUAPI DjVuFile : public DjVuPort
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
   enum { DECODING=1, DECODE_OK=2, DECODE_FAILED=4, DECODE_STOPPED=8,
Packit df99a1
	  DATA_PRESENT=16, ALL_DATA_PRESENT=32, INCL_FILES_CREATED=64,
Packit df99a1
          MODIFIED=128, DONT_START_DECODE=256, STOPPED=512,
Packit df99a1
	  BLOCKED_STOPPED=1024, CAN_COMPRESS=2048, NEEDS_COMPRESSION=4096 };
Packit df99a1
   enum { STARTED=1, FINISHED=2 };
Packit df99a1
Packit df99a1
      /** @name Decoded file contents */
Packit df99a1
      //@{
Packit df99a1
      /// Pointer to the DjVu file information component.
Packit df99a1
   GP<DjVuInfo>		info;
Packit df99a1
      /// Pointer to the background component of DjVu image (IW44 encoded).
Packit df99a1
   GP<IW44Image>	bg44;
Packit df99a1
      /// Pointer to the background component of DjVu image (Raw).
Packit df99a1
   GP<GPixmap>		bgpm;
Packit df99a1
      /// Pointer to the mask of foreground component of DjVu image (JB2 encoded).
Packit df99a1
   GP<JB2Image>		fgjb;
Packit df99a1
      /// Pointer to the optional shape dictionary for the mask (JB2 encoded).
Packit df99a1
   GP<JB2Dict>		fgjd;
Packit df99a1
      /// Pointer to a colors layer for the foreground component of DjVu image.
Packit df99a1
   GP<GPixmap>		fgpm;
Packit df99a1
      /// Pointer to a colors vector for the foreground component of DjVu image.
Packit df99a1
   GP<DjVuPalette>	fgbc;
Packit df99a1
      /// Pointer to collected annotation chunks.
Packit df99a1
   GP<ByteStream>	anno;
Packit df99a1
      /// Pointer to collected hiddentext chunks.
Packit df99a1
   GP<ByteStream>	text;
Packit df99a1
      /// Pointer to meta data chunks.
Packit df99a1
   GP<ByteStream>	meta;
Packit df99a1
      /// Pointer to the *old* navigation directory contained in this file
Packit df99a1
   GP<DjVuNavDir>	dir;
Packit df99a1
      /// Description of the file formed during decoding
Packit df99a1
   GUTF8String		description;
Packit df99a1
      /// MIME type string describing the DjVu data.
Packit df99a1
   GUTF8String		mimetype;
Packit df99a1
      /// Size of the file.
Packit df99a1
   int			file_size;
Packit df99a1
      //@}
Packit df99a1
Packit df99a1
protected:
Packit df99a1
      /** Default constructor.  Must follow with an init() */
Packit df99a1
   DjVuFile(void);
Packit df99a1
public:
Packit df99a1
   virtual ~DjVuFile(void);
Packit df99a1
Packit df99a1
      /** Initializes a #DjVuFile# object. This is a simplified initializer,
Packit df99a1
	  which is not supposed to be used for decoding or creating
Packit df99a1
	  #DjVuFile#s, which include other files.
Packit df99a1
Packit df99a1
	  If the file is stored on the hard drive, you may also use the
Packit df99a1
	  other constructor and pass it the file's URL and #ZERO# #port#.
Packit df99a1
	  The #DjVuFile# will read the data itself.
Packit df99a1
Packit df99a1
	  If you want to receive error messages and notifications, you
Packit df99a1
	  may connect the #DjVuFile# to your own \Ref{DjVuPort} after
Packit df99a1
	  it has been constructed.
Packit df99a1
Packit df99a1
	  @param str The stream containing data for the file. */
Packit df99a1
   void init(const GP<ByteStream> & str);
Packit df99a1
Packit df99a1
      /** Creator, does the init(ByteStream &str) */
Packit df99a1
   static GP<DjVuFile> create( const GP<ByteStream> & str,
Packit df99a1
     const ErrorRecoveryAction recover_action=ABORT,
Packit df99a1
     const bool verbose_eof=true);
Packit df99a1
   
Packit df99a1
      /** Initializes a #DjVuFile# object. As you can notice, the data is not
Packit df99a1
	  directly passed to this function. The #DjVuFile# will ask for it
Packit df99a1
	  through the \Ref{DjVuPort} mechanism before the constructor
Packit df99a1
	  finishes. If the data is stored locally on the hard disk then the
Packit df99a1
	  pointer to \Ref{DjVuPort} may be set to #ZERO#, which will make
Packit df99a1
	  #DjVuFile# read all data from the hard disk and report all errors
Packit df99a1
	  to #stderr#.
Packit df99a1
Packit df99a1
	  {\bf Note}. If the file includes (by means of #INCL# chunks) other
Packit df99a1
	  files then you should be ready to
Packit df99a1
	  \begin{enumerate}
Packit df99a1
	     \item Reply to requests \Ref{DjVuPort::id_to_url}() issued to
Packit df99a1
	           translate IDs (used in #INCL# chunks) to absolute URLs.
Packit df99a1
		   Usually, when the file is created by \Ref{DjVuDocument}
Packit df99a1
		   this job is done by it. If you construct such a file
Packit df99a1
		   manually, be prepared to do the ID to URL translation
Packit df99a1
	     \item Provide data for all included files.
Packit df99a1
	  \end{enumerate}
Packit df99a1
Packit df99a1
	  @param url The URL assigned to this file. It will be used when
Packit df99a1
	         the #DjVuFile# asks for data.
Packit df99a1
	  @param port All communication between #DjVuFile#s and \Ref{DjVuDocument}s
Packit df99a1
	         is done through the \Ref{DjVuPort} mechanism. If the {\em url}
Packit df99a1
		 is not local or the data does not reside on the hard disk,
Packit df99a1
		 the {\em port} parameter must not be #ZERO#. If the {\em port}
Packit df99a1
		 is #ZERO# then #DjVuFile# will create an internal instance
Packit df99a1
		 of \Ref{DjVuSimplePort} for accessing local files and
Packit df99a1
		 reporting errors. It can later be disabled by means
Packit df99a1
		 of \Ref{disable_standard_port}() function. */
Packit df99a1
   void init(const GURL & url, GP<DjVuPort> port=0);
Packit df99a1
Packit df99a1
      /** Creator, does the init(const GURL &url, GP<DjVuPort> port=0) */
Packit df99a1
   static GP<DjVuFile> create(
Packit df99a1
     const GURL & url, GP<DjVuPort> port=0,
Packit df99a1
     const ErrorRecoveryAction recover_action=ABORT,
Packit df99a1
     const bool verbose_eof=true);
Packit df99a1
Packit df99a1
      /** Disables the built-in port for accessing local files, which may
Packit df99a1
	  have been created in the case when the #port# argument to
Packit df99a1
	  the \Ref{DjVuFile::DjVuFile}() constructor is #ZERO# */
Packit df99a1
   void		disable_standard_port(void);
Packit df99a1
Packit df99a1
      /** Looks for #decoded# navigation directory (\Ref{DjVuNavDir}) in this
Packit df99a1
	  or included files. Returns #ZERO# if nothing could be found.
Packit df99a1
Packit df99a1
	  {\bf Note.} This function does {\bf not} attempt to decode #NDIR#
Packit df99a1
	  chunks. It is looking for predecoded components. #NDIR# can be
Packit df99a1
	  decoded either during regular decoding (initiated by
Packit df99a1
	  \Ref{start_decode}() function) or by \Ref{decode_ndir}() function,
Packit df99a1
	  which processes this and included files recursively in search
Packit df99a1
	  of #NDIR# chunks and decodes them. */
Packit df99a1
   GP<DjVuNavDir>	find_ndir(void);
Packit df99a1
Packit df99a1
      /** @name #DjVuFile# flags query functions */
Packit df99a1
      //@{
Packit df99a1
      /** Returns the #DjVuFile# flags. The value returned is the
Packit df99a1
	  result of ORing one or more of the following constants:
Packit df99a1
	  \begin{itemize}
Packit df99a1
	     \item #DECODING# The decoding is in progress
Packit df99a1
	     \item #DECODE_OK# The decoding has finished successfully
Packit df99a1
	     \item #DECODE_FAILED# The decoding has failed
Packit df99a1
	     \item #DECODE_STOPPED# The decoding has been stopped by
Packit df99a1
	           \Ref{stop_decode}() function
Packit df99a1
	     \item #DATA_PRESENT# All data for this file has been received.
Packit df99a1
	           It's especially important in the case of Netscape or IE
Packit df99a1
		   plugins when the data is being received while the
Packit df99a1
		   decoding is done.
Packit df99a1
	     \item #ALL_DATA_PRESENT# Not only data for this file, but also
Packit df99a1
	           for all included file has been received.
Packit df99a1
	     \item #INCL_FILES_CREATED# All #INCL# and #INCF# chunks have been
Packit df99a1
	           processed and the corresponding #DjVuFile#s created. This
Packit df99a1
		   is important to know to be sure that the list returned by
Packit df99a1
		   \Ref{get_included_files}() is OK.
Packit df99a1
	  \end{itemize} */
Packit df99a1
   long		get_flags(void) const;
Packit df99a1
      /// Returns #TRUE# if the file is being decoded.
Packit df99a1
   bool		is_decoding(void) const;
Packit df99a1
      /// Returns #TRUE# if decoding of the file has finished successfully.
Packit df99a1
   bool		is_decode_ok(void) const;
Packit df99a1
      /// Returns #TRUE# if decoding of the file has failed.
Packit df99a1
   bool		is_decode_failed(void) const;
Packit df99a1
      /** Returns #TRUE# if decoding of the file has been stopped by
Packit df99a1
	  \Ref{stop_decode}() function. */
Packit df99a1
   bool		is_decode_stopped(void) const;
Packit df99a1
      /// Returns #TRUE# if this file has received all data.
Packit df99a1
   bool		is_data_present(void) const;
Packit df99a1
      /** Returns #TRUE# if this file {\bf and} all included files have
Packit df99a1
	  received all data. */
Packit df99a1
   bool		is_all_data_present(void) const;
Packit df99a1
      /** Returns #TRUE# if all included files have been created. Only when
Packit df99a1
	  this function returns 1, the \Ref{get_included_files}() returns
Packit df99a1
	  the correct information. */
Packit df99a1
   bool		are_incl_files_created(void) const;
Packit df99a1
   bool		is_modified(void) const;
Packit df99a1
   bool		needs_compression(void) const;
Packit df99a1
   bool		can_compress(void) const;
Packit df99a1
   void		set_modified(bool m);
Packit df99a1
   void		set_needs_compression(bool m);
Packit df99a1
   void		set_can_compress(bool m);
Packit df99a1
      //@}
Packit df99a1
Packit df99a1
      /// Returns the URL assigned to this file
Packit df99a1
   GURL		get_url(void) const;
Packit df99a1
Packit df99a1
      /** @name Decode control routines */
Packit df99a1
      //@{
Packit df99a1
      /** Starts decode. If threads are enabled, the decoding will be
Packit df99a1
	  done in another thread. Be sure to use \Ref{wait_for_finish}()
Packit df99a1
	  or listen for notifications sent through the \Ref{DjVuPortcaster}
Packit df99a1
	  to remain in sync. */
Packit df99a1
   void		start_decode(void);
Packit df99a1
      /** Start the decode iff not already decoded.  If sync is true, wait
Packit df99a1
          wait for decode to complete.  Returns true of start_decode is called.
Packit df99a1
          */
Packit df99a1
   bool   resume_decode(const bool sync=false);
Packit df99a1
      /** Stops decode. If #sync# is 1 then the function will not return
Packit df99a1
	  until the decoding thread actually dies. Otherwise it will
Packit df99a1
	  just signal the thread to stop and will return immediately.
Packit df99a1
	  Decoding of all included files will be stopped too. */
Packit df99a1
   void		stop_decode(bool sync);
Packit df99a1
      /** Recursively stops all data-related operations.
Packit df99a1
Packit df99a1
	  Depending on the value of #only_blocked# flag this works as follows:
Packit df99a1
	  \begin{itemize}
Packit df99a1
	     \item If #only_blocked# is #TRUE#, the function will make sure,
Packit df99a1
	           that any further access to the file's data will result
Packit df99a1
		   in a #STOP# exception if the desired data is not available
Packit df99a1
		   (and the thread would normally block).
Packit df99a1
	     \item If #only_blocked# is #FALSE#, then {\bf any} further
Packit df99a1
	           access to the file's data will result in immediate
Packit df99a1
		   #STOP# exception.
Packit df99a1
	  \end{itemize}
Packit df99a1
Packit df99a1
	  The action of this function is recursive, meaning that any #DjVuFile#
Packit df99a1
	  included into this one will also be stopped.
Packit df99a1
Packit df99a1
	  Use this function when you don't need the #DjVuFile# anymore. The
Packit df99a1
	  results cannot be undone, and the whole idea is to make all threads
Packit df99a1
	  working with this file exit with the #STOP# exception. */
Packit df99a1
   void		stop(bool only_blocked);
Packit df99a1
      /** Wait for the decoding to finish. This will wait for the
Packit df99a1
	  termination of included files too. */
Packit df99a1
   void		wait_for_finish(void);
Packit df99a1
      /** Looks for #NDIR# chunk (navigation directory), and decodes its
Packit df99a1
	  contents. If the #NDIR# chunk has not been found in {\em this} file,
Packit df99a1
	  but this file includes others, the procedure will continue
Packit df99a1
	  recursively. This function is useful to obtain the document
Packit df99a1
	  navigation directory before any page has been decoded. After it
Packit df99a1
	  returns the directory can be obtained by calling \Ref{find_ndir}()
Packit df99a1
	  function.
Packit df99a1
Packit df99a1
	  {\bf Warning.} Contrary to \Ref{start_decode}(), this function
Packit df99a1
	  does not return before it completely decodes the directory.
Packit df99a1
	  Make sure, that this file and all included files have enough data. */
Packit df99a1
   GP<DjVuNavDir>	decode_ndir(void);
Packit df99a1
      /// Clears all decoded components.
Packit df99a1
   void		reset(void);
Packit df99a1
      /** Processes #INCL# chunks and creates included files.
Packit df99a1
	  Normally you won't need to call this function because included
Packit df99a1
	  files are created automatically when the file is being decoded.
Packit df99a1
	  But if due to some reason you'd like to obtain the list of included
Packit df99a1
	  files without decoding this file, this is an ideal function to call.
Packit df99a1
Packit df99a1
	  {\bf Warning.} This function does not return before it reads the
Packit df99a1
	  whole file, which may block your application under some circumstances
Packit df99a1
	  if not all data is available. */
Packit df99a1
   void		process_incl_chunks(void);
Packit df99a1
      //@}
Packit df99a1
   
Packit df99a1
      // Function needed by the cache
Packit df99a1
   unsigned int	get_memory_usage(void) const;
Packit df99a1
Packit df99a1
      /** Returns the list of included DjVuFiles.
Packit df99a1
	  
Packit df99a1
	  {\bf Warning.} Included files are normally created during decoding.
Packit df99a1
	  Before that they do not exist.   If you call this function at
Packit df99a1
	  that time and set #only_created# to #FALSE# then it will have to
Packit df99a1
	  read all the data from this file in order to find #INCL# chunks,
Packit df99a1
	  which may block your application, if not all data is available.
Packit df99a1
Packit df99a1
	  @param only_created If #TRUE#, the file will not try to process
Packit df99a1
	         #INCL# chunks and load referenced files. It will return
Packit df99a1
		 just those files, which have already been created during
Packit df99a1
		 the decoding procedure. */
Packit df99a1
   GPList<DjVuFile>	get_included_files(bool only_created=true);
Packit df99a1
Packit df99a1
      /** Includes a #DjVuFile# with the specified #id# into this one.
Packit df99a1
	  This function will also insert an #INCL# chunk at position
Packit df99a1
	  #chunk_num#. The function will request data for the included
Packit df99a1
	  file and will create it before returning. */
Packit df99a1
   void		insert_file(const GUTF8String &id, int chunk_num=1);
Packit df99a1
      /// Will get rid of included file with the given #id#
Packit df99a1
   void		unlink_file(const GUTF8String &id;;
Packit df99a1
      /** Will find an #INCL# chunk containing #name# in input #data# and
Packit df99a1
	  will remove it */
Packit df99a1
   static GP<DataPool>	unlink_file(const GP<DataPool> & data, const GUTF8String &name);
Packit df99a1
Packit df99a1
      /// Returns the number of chunks in the IFF file data
Packit df99a1
   int		get_chunks_number(void);
Packit df99a1
      /// Returns the name of chunk number #chunk_num#
Packit df99a1
   GUTF8String	get_chunk_name(int chunk_num);
Packit df99a1
      /// Returns 1 if this file contains chunk with name #chunk_name#
Packit df99a1
   bool		contains_chunk(const GUTF8String &chunk_name);
Packit df99a1
Packit df99a1
      /** Processes the included files hierarchy and returns merged
Packit df99a1
	  annotations. This function may be used even when the #DjVuFile#
Packit df99a1
	  has not been decoded yet. If all data has been received for
Packit df99a1
	  this #DjVuFile# and all included #DjVuFile#s, it will will
Packit df99a1
	  gather annotations from them and will return the result.
Packit df99a1
	  If no annotations have been found, #ZERO# will be returned.
Packit df99a1
	  If either this #DjVuFile# or any of the included files do not
Packit df99a1
	  have all the data, the function will use the results of
Packit df99a1
	  decoding, which may have been started with the \Ref{start_decode}()
Packit df99a1
	  function. Otherwise #ZERO# will be returned as well.
Packit df99a1
Packit df99a1
	  If #max_level_ptr# pointer is not zero, the function will use
Packit df99a1
	  it to store the maximum level number from which annotations
Packit df99a1
	  have been obtained. #ZERO# level corresponds to the top-level
Packit df99a1
	  page file.
Packit df99a1
Packit df99a1
	  {\bf Summary:} This function will return complete annotations only
Packit df99a1
	  when the \Ref{is_all_data_present}() returns #TRUE#. */
Packit df99a1
   GP<ByteStream>	get_merged_anno(int * max_level_ptr=0);
Packit df99a1
Packit df99a1
      /** Returns the annotation chunks (#"ANTa"# and #"ANTz"#).  This
Packit df99a1
          function may be used even when the #DjVuFile# has not been decoded
Packit df99a1
          yet. If all data has been received for this #DjVuFile#, it will
Packit df99a1
          gather hidden text and return the result.  If no hidden text has
Packit df99a1
          been found, #ZERO# will be returned.
Packit df99a1
Packit df99a1
	  {\bf Summary:} This function will return complete annotations
Packit df99a1
	  only when the \Ref{is_all_data_present}() returns #TRUE#. */
Packit df99a1
   GP<ByteStream>	get_anno(void);
Packit df99a1
Packit df99a1
      /** Returns the text chunks (#"TXTa"# and #"TXTz"#).  This function may
Packit df99a1
          be used even when the #DjVuFile# has not been decoded yet. If all
Packit df99a1
          data has been received for this #DjVuFile#, it will gather hidden
Packit df99a1
          text and return the result.  If no hidden text has been found,
Packit df99a1
          #ZERO# will be returned.
Packit df99a1
Packit df99a1
	  {\bf Summary:} This function will return complete hidden text layers
Packit df99a1
	  only when the \Ref{is_all_data_present}() returns #TRUE#. */
Packit df99a1
   GP<ByteStream>	get_text(void);
Packit df99a1
Packit df99a1
      /** Returns the meta chunks (#"METa"# and #"METz"#).  This function may
Packit df99a1
          be used even when the #DjVuFile# has not been decoded yet. If all
Packit df99a1
          data has been received for this #DjVuFile#, it will gather metadata
Packit df99a1
          and return the result.  If no hidden text has been found, #ZERO#
Packit df99a1
          will be returned.
Packit df99a1
Packit df99a1
	  {\bf Summary:} This function will return complete meta data only
Packit df99a1
	  when the \Ref{is_all_data_present}() returns #TRUE#. */
Packit df99a1
   GP<ByteStream>	get_meta(void);
Packit df99a1
Packit df99a1
      /** Goes down the hierarchy of #DjVuFile#s and merges their annotations.
Packit df99a1
          (shouldn't this one be private?).
Packit df99a1
	  @param max_level_ptr If this pointer is not ZERO, the function
Packit df99a1
	         will use it to store the maximum level at which annotations
Packit df99a1
		 were found. Top-level page files have ZERO #level#.
Packit df99a1
	  @param ignore_list The function will not process included #DjVuFile#s
Packit df99a1
	         with URLs matching those mentioned in this #ignore_list#. */
Packit df99a1
   GP<ByteStream>	get_merged_anno(const GList<GURL> & ignore_list,
Packit df99a1
					int * max_level_ptr);
Packit df99a1
Packit df99a1
      /** Clears this file of all annotations. */
Packit df99a1
   void	remove_anno(void);
Packit df99a1
Packit df99a1
      /** Clears the hidden text. */
Packit df99a1
   void	remove_text(void);
Packit df99a1
Packit df99a1
      /// Clears the meta data.
Packit df99a1
   void remove_meta(void);
Packit df99a1
Packit df99a1
      /** Returns #TRUE# if the file contains annotation chunks.
Packit df99a1
	  Known annotation chunks at the time of writing this help are:
Packit df99a1
	  {\bf ANTa}, {\bf ANTz}, {\bf FORM:ANNO}. */
Packit df99a1
   bool		contains_anno(void);
Packit df99a1
Packit df99a1
      /** Returns #TRUE# if the file contains hiddentext chunks.
Packit df99a1
	  Known hiddentext chunks at the time of writing this help are:
Packit df99a1
	  {\bf TXTa}, and {\bf TXTz}. */
Packit df99a1
   bool		contains_text(void);
Packit df99a1
Packit df99a1
      /** Returns #TRUE# if the file contains metadata chunks.
Packit df99a1
	  Known metadata chunks at the time of writing this help are:
Packit df99a1
	  {\bf METa}, and {\bf METz}. */
Packit df99a1
   bool		contains_meta(void);
Packit df99a1
Packit df99a1
     /** Changes the value of the hiddentext. */
Packit df99a1
   void change_info(GP<DjVuInfo> info, const bool do_reset=false);
Packit df99a1
   
Packit df99a1
     /** Changes the value of the hiddentext. */
Packit df99a1
   void change_text(GP<DjVuTXT> txt, const bool do_reset=false);
Packit df99a1
   
Packit df99a1
     /** Changes the value of the metadata. */
Packit df99a1
   void change_meta(const GUTF8String &meta, const bool do_reset=false);
Packit df99a1
   
Packit df99a1
      /** @name Encoding routines */
Packit df99a1
      //@{
Packit df99a1
      /** The main function that encodes data back into binary stream.
Packit df99a1
	  The data returned will reflect possible changes made into the
Packit df99a1
	  chunk structure, annotation chunks and navigation directory
Packit df99a1
	  chunk #NDIR#.
Packit df99a1
Packit df99a1
	  {\bf Note:} The file stream will not have the magic
Packit df99a1
          #0x41,0x54,0x26,0x54#
Packit df99a1
	  at the beginning.
Packit df99a1
	  
Packit df99a1
	  @param included_too Process included files too. */
Packit df99a1
   GP<ByteStream>	get_djvu_bytestream(const bool included_too, const bool no_ndir=true);
Packit df99a1
Packit df99a1
      /** Same as \Ref{get_djvu_bytestream}(), returning a DataPool.
Packit df99a1
	  @param included_too Process included files too. */
Packit df99a1
   GP<DataPool>		get_djvu_data(const bool included_too, const bool no_ndir=true );
Packit df99a1
      //@}
Packit df99a1
Packit df99a1
      // Internal. Used by DjVuDocument
Packit df99a1
   GP<DataPool>		get_init_data_pool(void) const { return data_pool; };
Packit df99a1
Packit df99a1
      // Internal. Used by DjVuDocument. May block for data.
Packit df99a1
   void			move(const GURL & dir_url);
Packit df99a1
Packit df99a1
      /** Internal. Used by DjVuDocument. The #name# should {\bf not}
Packit df99a1
	  be encoded with \Ref{GOS::encode_reserved}(). */
Packit df99a1
   void			set_name(const GUTF8String &name);
Packit df99a1
Packit df99a1
      // Internal. Used by DjVuDocument
Packit df99a1
   GSafeFlags &		get_safe_flags(void);
Packit df99a1
Packit df99a1
      // Internal. Used by DjVuImage
Packit df99a1
   void                 merge_anno(ByteStream &out;;
Packit df99a1
Packit df99a1
      // Internal. Used by DjVuImage
Packit df99a1
   void                 get_text(ByteStream &out;;
Packit df99a1
Packit df99a1
      // Internal. Used by DjVuImage
Packit df99a1
   void                 get_meta(ByteStream &out;;
Packit df99a1
Packit df99a1
      // Internal. Used by DjVuDocEditor
Packit df99a1
   void			rebuild_data_pool(void);
Packit df99a1
Packit df99a1
      // Functions inherited from DjVuPort
Packit df99a1
   virtual bool		inherits(const GUTF8String &class_name) const;
Packit df99a1
   virtual void		notify_chunk_done(const DjVuPort * source, const GUTF8String &name);
Packit df99a1
   virtual void		notify_file_flags_changed(const DjVuFile * source,
Packit df99a1
						  long set_mask, long clr_mask);
Packit df99a1
   virtual void		set_recover_errors(const ErrorRecoveryAction=ABORT);
Packit df99a1
   virtual void		set_verbose_eof(const bool verbose_eof=true);
Packit df99a1
   virtual void		report_error(const GException &ex,const bool=true);
Packit df99a1
   static void set_decode_codec(GP<GPixmap> (*codec)(ByteStream &bs);;
Packit df99a1
Packit df99a1
protected:
Packit df99a1
   GURL			url;
Packit df99a1
   GP<DataPool>		data_pool;
Packit df99a1
Packit df99a1
   GPList<DjVuFile>	inc_files_list;
Packit df99a1
   GCriticalSection	inc_files_lock;
Packit df99a1
   GCriticalSection	anno_lock;
Packit df99a1
   GCriticalSection	text_lock;
Packit df99a1
   GCriticalSection	meta_lock;
Packit df99a1
   ErrorRecoveryAction	recover_errors;
Packit df99a1
   bool			verbose_eof;
Packit df99a1
   int			chunks_number;
Packit df99a1
private:
Packit df99a1
   bool                 initialized;
Packit df99a1
   GSafeFlags		flags;
Packit df99a1
Packit df99a1
   GThread		* decode_thread;
Packit df99a1
   GP<DataPool>		decode_data_pool;
Packit df99a1
   GP<DjVuFile>		decode_life_saver;
Packit df99a1
Packit df99a1
   GP<DjVuPort>		simple_port;
Packit df99a1
Packit df99a1
   GMonitor		chunk_mon, finish_mon;
Packit df99a1
Packit df99a1
      // Functions called when the decoding thread starts
Packit df99a1
   static void	static_decode_func(void *);
Packit df99a1
   void	decode_func(void);
Packit df99a1
   void	decode(const GP<ByteStream> &str);
Packit df99a1
   GUTF8String decode_chunk(const GUTF8String &chkid,
Packit df99a1
     const GP<ByteStream> &str, bool djvi, bool djvu, bool iw44);
Packit df99a1
   int		get_dpi(int w, int h);
Packit df99a1
Packit df99a1
      // Functions dealing with the shape directory (fgjd)
Packit df99a1
   static GP<JB2Dict> static_get_fgjd(void *);
Packit df99a1
   GP<JB2Dict> get_fgjd(int block=0);
Packit df99a1
Packit df99a1
      // Functions used to wait for smth
Packit df99a1
   void		wait_for_chunk(void);
Packit df99a1
   bool		wait_for_finish(bool self);
Packit df99a1
Packit df99a1
      // INCL chunk processor
Packit df99a1
   GP<DjVuFile>	process_incl_chunk(ByteStream & str, int file_num=-1);
Packit df99a1
Packit df99a1
      // Trigger: called when DataPool has all data
Packit df99a1
   static void	static_trigger_cb(void *);
Packit df99a1
   void		trigger_cb(void);
Packit df99a1
   
Packit df99a1
      // Progress callback: called from time to time
Packit df99a1
   static void	progress_cb(int pos, void *);
Packit df99a1
   static void	get_merged_anno(const GP<DjVuFile> & file,
Packit df99a1
     const GP<ByteStream> &str_out, const GList<GURL> & ignore_list,
Packit df99a1
     int level, int & max_level, GMap<GURL, void *> & map);
Packit df99a1
   static void	get_anno(const GP<DjVuFile> & file,
Packit df99a1
     const GP<ByteStream> &str_out);
Packit df99a1
   static void	get_text(const GP<DjVuFile> & file,
Packit df99a1
     const GP<ByteStream> &str_out);
Packit df99a1
   static void	get_meta(const GP<DjVuFile> & file,
Packit df99a1
     const GP<ByteStream> &str_out);
Packit df99a1
Packit df99a1
   void          check() const;
Packit df99a1
   GP<DjVuNavDir>find_ndir(GMap<GURL, void *> & map);
Packit df99a1
   GP<DjVuNavDir>decode_ndir(GMap<GURL, void *> & map);
Packit df99a1
   void		add_djvu_data(IFFByteStream & str,
Packit df99a1
			      GMap<GURL, void *> & map,
Packit df99a1
			      const bool included_too, const bool no_ndir=true);
Packit df99a1
   void		move(GMap<GURL, void *> & map, const GURL & dir_url);
Packit df99a1
private: // dummy stuff
Packit df99a1
   static void decode(ByteStream *);
Packit df99a1
   static GUTF8String decode_chunk(const GUTF8String &, ByteStream *,bool,bool,bool);
Packit df99a1
   static void	get_merged_anno(const GP<DjVuFile> &,ByteStream *,
Packit df99a1
     const GList<GURL> &, int, int &, GMap<GURL, void *> &);
Packit df99a1
   static void	get_text(const GP<DjVuFile> &,ByteStream *);
Packit df99a1
   static void	get_meta(const GP<DjVuFile> &,ByteStream *);
Packit df99a1
Packit df99a1
};
Packit df99a1
Packit df99a1
inline long
Packit df99a1
DjVuFile::get_flags(void) const
Packit df99a1
{
Packit df99a1
   return flags;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline GSafeFlags &
Packit df99a1
DjVuFile::get_safe_flags(void)
Packit df99a1
{
Packit df99a1
   return flags;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuFile::is_decoding(void) const
Packit df99a1
{
Packit df99a1
   return (flags & DECODING)!=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuFile::is_decode_ok(void) const
Packit df99a1
{
Packit df99a1
   return (flags & DECODE_OK)!=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuFile::is_decode_failed(void) const
Packit df99a1
{
Packit df99a1
   return (flags & DECODE_FAILED)!=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuFile::is_decode_stopped(void) const
Packit df99a1
{
Packit df99a1
   return (flags & DECODE_STOPPED)!=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuFile::is_data_present(void) const
Packit df99a1
{
Packit df99a1
   return (flags & DATA_PRESENT)!=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuFile::is_all_data_present(void) const
Packit df99a1
{
Packit df99a1
   return (flags & ALL_DATA_PRESENT)!=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuFile::are_incl_files_created(void) const
Packit df99a1
{
Packit df99a1
   return (flags & INCL_FILES_CREATED)!=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuFile::is_modified(void) const
Packit df99a1
{
Packit df99a1
   return (flags & MODIFIED)!=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
DjVuFile::set_modified(bool m)
Packit df99a1
{
Packit df99a1
  flags=m ? (flags | MODIFIED) : (flags & ~MODIFIED);
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuFile::needs_compression(void) const
Packit df99a1
{
Packit df99a1
   return (flags & NEEDS_COMPRESSION)!=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
DjVuFile::set_needs_compression(bool m)
Packit df99a1
{
Packit df99a1
   if (m) flags=flags | NEEDS_COMPRESSION;
Packit df99a1
   else flags=flags & ~NEEDS_COMPRESSION;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuFile::can_compress(void) const
Packit df99a1
{
Packit df99a1
   return (flags & CAN_COMPRESS)!=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
DjVuFile::set_can_compress(bool m)
Packit df99a1
{
Packit df99a1
   if (m)
Packit df99a1
     flags=flags | CAN_COMPRESS;
Packit df99a1
   else
Packit df99a1
     flags=flags & ~CAN_COMPRESS;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
DjVuFile::disable_standard_port(void)
Packit df99a1
{
Packit df99a1
   simple_port=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuFile::inherits(const GUTF8String &class_name) const
Packit df99a1
{
Packit df99a1
   return
Packit df99a1
      (GUTF8String("DjVuFile") == class_name) ||
Packit df99a1
      DjVuPort::inherits(class_name);
Packit df99a1
//      !strcmp("DjVuFile", class_name) ||
Packit df99a1
//      DjVuPort::inherits(class_name);
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
DjVuFile::wait_for_finish(void)
Packit df99a1
{
Packit df99a1
   while(wait_for_finish(1))
Packit df99a1
     EMPTY_LOOP;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline GURL
Packit df99a1
DjVuFile::get_url(void) const
Packit df99a1
{
Packit df99a1
   return url;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
DjVuFile::set_verbose_eof
Packit df99a1
(const bool verbose)
Packit df99a1
{
Packit df99a1
  verbose_eof=verbose;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
DjVuFile::set_recover_errors
Packit df99a1
(const ErrorRecoveryAction action)
Packit df99a1
{
Packit df99a1
  recover_errors=action;
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