Blame libdjvu/DjVuDocument.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 _DJVUDOCUMENT_H
Packit df99a1
#define _DJVUDOCUMENT_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 "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 DjVmDoc;
Packit df99a1
class DjVmDir;
Packit df99a1
class DjVmDir0;
Packit df99a1
class DjVmNav;
Packit df99a1
class DjVuImage;
Packit df99a1
class DjVuFile;
Packit df99a1
class DjVuFileCache;
Packit df99a1
class DjVuNavDir;
Packit df99a1
class ByteStream;
Packit df99a1
Packit df99a1
/** @name DjVuDocument.h
Packit df99a1
    Files #"DjVuDocument.h"# and #"DjVuDocument.cpp"# contain implementation
Packit df99a1
    of the \Ref{DjVuDocument} class - the ideal tool for opening, decoding
Packit df99a1
    and saving DjVu single page and multi page documents.
Packit df99a1
Packit df99a1
    @memo DjVu document class.
Packit df99a1
    @author Andrei Erofeev <eaf@geocities.com>
Packit df99a1
*/
Packit df99a1
Packit df99a1
//@{
Packit df99a1
Packit df99a1
/** #DjVuDocument# provides convenient interface for opening, decoding
Packit df99a1
    and saving back DjVu documents in single page and multi page formats.
Packit df99a1
Packit df99a1
    {\bf Input formats}
Packit df99a1
    It can read multi page DjVu documents in either of the 4 formats: 2
Packit df99a1
    obsolete ({\em old bundled} and {\em old indexed}) and two new
Packit df99a1
    ({\em new bundled} and {\em new indirect}).
Packit df99a1
Packit df99a1
    {\bf Output formats}
Packit df99a1
    To encourage users to switch to the new formats, the #DjVuDocument# can
Packit df99a1
    save documents back only in the new formats: {\em bundled} and
Packit df99a1
    {\em indirect}.
Packit df99a1
Packit df99a1
    {\bf Conversion.} Since #DjVuDocument# can open DjVu documents in
Packit df99a1
    an obsolete format and save it in any of the two new formats
Packit df99a1
    ({\em new bundled} and {\em new indirect}), this class can be used for
Packit df99a1
    conversion from obsolete formats to the new ones. Although it can also
Packit df99a1
    do conversion between the new two formats, it's not the best way to
Packit df99a1
    do it. Please refer to \Ref{DjVmDoc} for details.
Packit df99a1
Packit df99a1
    {\bf Decoding.} #DjVuDocument# provides convenient interface for obtaining
Packit df99a1
    \Ref{DjVuImage} corresponding to any page of the document. It uses
Packit df99a1
    \Ref{DjVuFileCache} to do caching thus avoiding unnecessary multiple decoding of
Packit df99a1
    the same page. The real decoding though is accomplished by \Ref{DjVuFile}.
Packit df99a1
Packit df99a1
    {\bf Messenging.} Being derived from \Ref{DjVuPort}, #DjVuDocument#
Packit df99a1
    takes an active part in exchanging messages (requests and notifications)
Packit df99a1
    between different parties involved in decoding. It reports (relays)
Packit df99a1
    errors, progress information and even handles some requests for data (when
Packit df99a1
    these requests deal with local files).
Packit df99a1
Packit df99a1
    Typical usage of #DjVuDocument# class in a threadless command line
Packit df99a1
    program would be the following:
Packit df99a1
    \begin{verbatim}
Packit df99a1
    static const char file_name[]="/tmp/document.djvu";
Packit df99a1
    GP<DjVuDocument> doc=DjVuDocument::create_wait(file_name);
Packit df99a1
    const int pages=doc->get_pages_num();
Packit df99a1
    for(int page=0;page
Packit df99a1
    {
Packit df99a1
       GP<DjVuImage> dimg=doc->get_page(page);
Packit df99a1
       // Do something
Packit df99a1
    };
Packit df99a1
    \end{verbatim}
Packit df99a1
    
Packit df99a1
    {\bf Comments for the code above}
Packit df99a1
    \begin{enumerate}
Packit df99a1
       \item Since the document is assumed to be stored on the hard drive,
Packit df99a1
             we don't have to cope with \Ref{DjVuPort}s and can pass
Packit df99a1
	     #ZERO# pointer to the \Ref{init}() function. #DjVuDocument#
Packit df99a1
	     can access local data itself. In the case of a plugin though,
Packit df99a1
	     one would have to implement his own \Ref{DjVuPort}, which
Packit df99a1
	     would handle requests for data arising when the document
Packit df99a1
	     is being decoded.
Packit df99a1
       \item In a threaded program instead of calling the \Ref{init}()
Packit df99a1
             function one can call \Ref{start_init}() and \Ref{stop_init}()
Packit df99a1
	     to initiate and interrupt initialization carried out in
Packit df99a1
	     another thread. This possibility of initializing the document
Packit df99a1
	     in another thread has been added specially for the plugin
Packit df99a1
	     because the initialization itself requires data, which is
Packit df99a1
	     not immediately available in the plugin. Thus, to prevent the
Packit df99a1
	     main thread from blocking, we perform initialization in a
Packit df99a1
	     separate thread. To check if the class is completely and
Packit df99a1
	     successfully initialized, use \Ref{is_init_ok}(). To see if
Packit df99a1
	     there was an error, use \Ref{is_init_failed}(). To
Packit df99a1
	     know when initialization is over (whether successfully or not),
Packit df99a1
	     use \Ref{is_init_complete}(). To wait for this to happen use
Packit df99a1
	     \Ref{wait_for_complete_init}(). Once again, all these things are
Packit df99a1
	     not required for single-threaded program.
Packit df99a1
Packit df99a1
	     Another difference between single-threaded and multi-threaded
Packit df99a1
	     environments is that in a single-threaded program, the image is
Packit df99a1
	     fully decoded before it's returned. In a multi-threaded
Packit df99a1
	     application decoding starts in a separate thread, and the pointer
Packit df99a1
	     to the \Ref{DjVuImage} being decoded is returned immediately.
Packit df99a1
	     This has been done to enable progressive redisplay
Packit df99a1
	     in the DjVu plugin. Use communication mechanism provided by
Packit df99a1
	     \Ref{DjVuPort} and \Ref{DjVuPortcaster} to learn about progress
Packit df99a1
	     of decoding.  Or try #dimg->wait_for_complete_decode()# to wait
Packit df99a1
	     until the decoding ends.
Packit df99a1
       \item See Also: \Ref{DjVuFile}, \Ref{DjVuImage}, \Ref{GOS}.
Packit df99a1
    \end{enumerate}
Packit df99a1
Packit df99a1
    {\bf Initialization}
Packit df99a1
    As mentioned above, the #DjVuDocument# can go through several stages
Packit df99a1
    of initialization. The functionality is gradually added while it passes
Packit df99a1
    one stage after another:
Packit df99a1
    \begin{enumerate}
Packit df99a1
       \item First of all, immediately after the object is created \Ref{init}()
Packit df99a1
             or \Ref{start_init}() functions must be called. {\bf Nothing}
Packit df99a1
	     will work until this is done. \Ref{init}() function will not
Packit df99a1
	     return until the initialization is complete. You need to make
Packit df99a1
	     sure, that enough data is available. {\bf Do not call \Ref{init}()
Packit df99a1
	     in the plugin}. \Ref{start_init}() will start initialization
Packit df99a1
	     in another thread. Use \Ref{stop_init}() to interrupt it.
Packit df99a1
	     Use \Ref{is_init_complete}() to check the initialization progress.
Packit df99a1
	     Use \Ref{wait_for_complete_init}() to wait for init to finish.
Packit df99a1
       \item The first thing the initializing code learns about the document
Packit df99a1
	     is its type (#BUNDLED#, #INDIRECT#, #OLD_BUNDLED# or #OLD_INDEXED#).
Packit df99a1
	     As soon as it happens, document flags are changed and
Packit df99a1
	     #notify_doc_flags_changed()# request is sent through the
Packit df99a1
	     communication mechanism provided by \Ref{DjVuPortcaster}.
Packit df99a1
       \item After the document type becomes known, the initializing code
Packit df99a1
             proceeds with learning the document structure. Gradually the
Packit df99a1
	     flags are updated with values:
Packit df99a1
	     \begin{itemize}
Packit df99a1
	        \item #DOC_DIR_KNOWN#: Contents of the document became known.
Packit df99a1
		      This is meaningful for #BUNDLED#, #OLD_BUNDLED# and
Packit df99a1
		      #INDIRECT# documents only.
Packit df99a1
		\item #DOC_NDIR_KNOWN#: Contents of the document navigation
Packit df99a1
		      directory became known. This is meaningful for old-style
Packit df99a1
		      documents (#OLD_BUNDLED# and #OLD_INDEXED#) only
Packit df99a1
		\item #DOC_INIT_OK# or #DOC_INIT_FAILED#:
Packit df99a1
		      The initializating code finished.
Packit df99a1
	     \end{itemize}
Packit df99a1
    \end{enumerate} */
Packit df99a1
    
Packit df99a1
class DJVUAPI DjVuDocument : public DjVuPort
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
      /** Flags describing the document initialization state.
Packit df99a1
	  \begin{itemize}
Packit df99a1
	     \item #DOC_TYPE_KNOWN#: The type of the document has been learnt.
Packit df99a1
	     \item #DOC_DIR_KNOWN#: Contents of the document became known.
Packit df99a1
		   This is meaningful for #BUNDLED#, #OLD_BUNDLED# and
Packit df99a1
		   #INDIRECT# documents only.
Packit df99a1
	     \item #DOC_NDIR_KNOWN#: Contents of the document navigation
Packit df99a1
		   directory became known. This is meaningful for old-style
Packit df99a1
		   documents (#OLD_BUNDLED# and #OLD_INDEXED#) only
Packit df99a1
	     \item #DOC_INIT_OK#: The initialization has completed successfully.
Packit df99a1
	     \item #DOC_INIT_FAILED#: The initialization failed.
Packit df99a1
	  \end{itemize} */
Packit df99a1
   enum DOC_FLAGS { DOC_TYPE_KNOWN=1, DOC_DIR_KNOWN=2,
Packit df99a1
		    DOC_NDIR_KNOWN=4, DOC_INIT_OK=8,
Packit df99a1
		    DOC_INIT_FAILED=16 };
Packit df99a1
      /** Specifies the format of #DjVuDocument#. There are currently 4 DjVu
Packit df99a1
	  multipage formats recognized by the library. Two of them are obsolete
Packit df99a1
	  and should not be used.
Packit df99a1
	  \begin{enumerate}
Packit df99a1
	     \item #OLD_BUNDLED# - Obsolete bundled format
Packit df99a1
	     \item #OLD_INDEXED# - Obsolete multipage format where every page
Packit df99a1
	           is stored in a separate file and "includes" (by means
Packit df99a1
		   of an #INCL# chunk) the file with the document directory.
Packit df99a1
	     \item #SINGLE_PAGE# - Single page document. Basically a file
Packit df99a1
	     	   with either #FORM:DJVU# or #FORM:IW44# and no multipage
Packit df99a1
		   information. For example, #OLD_INDEXED# documents with
Packit df99a1
		   document directory do not qualify even if they contain only
Packit df99a1
		   one page.
Packit df99a1
	     \item #BUNDLED# - Currently supported bundled format
Packit df99a1
	     \item #INDIRECT# - Currently supported "expanded" format, where
Packit df99a1
	           every page and component is stored in a separate file. There
Packit df99a1
		   is also a {\em top-level} file with the document directory.
Packit df99a1
          \end{enumerate} */
Packit df99a1
   enum DOC_TYPE { OLD_BUNDLED=1, OLD_INDEXED, BUNDLED, INDIRECT,
Packit df99a1
		   SINGLE_PAGE, UNKNOWN_TYPE };
Packit df99a1
   enum THREAD_FLAGS { STARTED=1, FINISHED=2 };
Packit df99a1
Packit df99a1
protected:
Packit df99a1
      /** Default creator. Please call functions \Ref{init}() or
Packit df99a1
	  \Ref{start_init}() before you start working with the #DjVuDocument#.
Packit df99a1
        */
Packit df99a1
   DjVuDocument(void);
Packit df99a1
public:
Packit df99a1
Packit df99a1
     /// Virtual Destructor
Packit df99a1
   virtual ~DjVuDocument(void);
Packit df99a1
Packit df99a1
      /** Initializes the #DjVuDocument# object using an existing document.
Packit df99a1
          This function should be called once after creating the object.
Packit df99a1
	  The #url# should point to the real data, and the creator of the
Packit df99a1
	  document should be ready to return this data to the document
Packit df99a1
	  if it's not stored locally (in which case #DjVuDocument# can
Packit df99a1
	  access it itself).
Packit df99a1
Packit df99a1
	  {\bf Initializing thread}
Packit df99a1
	  In a single-threaded application, the #start_init()# function performs
Packit df99a1
	  the complete initialization of the #DjVuDocument# before it returns.
Packit df99a1
	  In a multi-threaded application, though, it initializes some internal
Packit df99a1
	  variables, requests data for the document and starts a new
Packit df99a1
	  {\em initializing} thread, which is responsible for determining the
Packit df99a1
	  document type and structure and completing the initialization
Packit df99a1
	  process. This additional complication is justified in the case of
Packit df99a1
	  the DjVu plugin because performing initialization requires data and
Packit df99a1
	  in the plugin the data can be supplied by the main thread only.
Packit df99a1
	  Thus, if the initialization was completed by the main thread, the
Packit df99a1
	  plugin would run out of data and block.
Packit df99a1
Packit df99a1
	  {\bf Stages of initialization}
Packit df99a1
	  Immediately after the #start_init()# function terminates, the
Packit df99a1
	  #DjVuDocument# object is ready for use. Its functionality will
Packit df99a1
	  not be complete (until the initializing thread finishes), but
Packit df99a1
	  the object is still very useful. Such functions as \Ref{get_page}()
Packit df99a1
	  or \Ref{get_djvu_file}() or \Ref{id_to_url}() may be called
Packit df99a1
	  before the initializing thread completes. This allows the DjVu
Packit df99a1
	  plugin start decoding as soon as possible without waiting for
Packit df99a1
	  all data to arrive.
Packit df99a1
Packit df99a1
	  To query the current stage of initialization you can use
Packit df99a1
	  \Ref{get_doc_flags}() function or listen to the
Packit df99a1
	  #notify_doc_flags_changed()# notifications distributed with the help
Packit df99a1
	  of \Ref{DjVuPortcaster}. To wait for the initialization to
Packit df99a1
	  complete use \Ref{wait_for_complete_init}(). To stop initialization
Packit df99a1
	  call \Ref{stop_init}().
Packit df99a1
Packit df99a1
	  {\bf Querying data}
Packit df99a1
	  The query for data is done using the communication mechanism
Packit df99a1
	  provided by \Ref{DjVuPort} and \Ref{DjVuPortcaster}. If #port#
Packit df99a1
	  is not #ZERO#, then the request for data will be forwarded to it.
Packit df99a1
	  If it {\bf is} #ZERO# then #DjVuDocument# will create an internal
Packit df99a1
	  instance of \Ref{DjVuSimplePort} and will use it to access local
Packit df99a1
	  files and report errors to #stderr#. In short, if the document
Packit df99a1
	  file is stored on the local hard disk, and you're OK about reporting
Packit df99a1
	  errors to #stderr#, you may pass #ZERO# pointer to \Ref{DjVuPort}
Packit df99a1
	  as #DjVuDocument# can take care of this situation by itself.
Packit df99a1
Packit df99a1
	  {\bf The URL}
Packit df99a1
	  Depending on the document type the #url# should point to:
Packit df99a1
	  \begin{itemize}
Packit df99a1
	     \item {\bf Old bundled} and {\bf New bundled} formats: to the
Packit df99a1
	           document itself.
Packit df99a1
	     \item {\bf Old indexed} format: to any page of the document.
Packit df99a1
	     \item {\bf New indirect} format: to the top-level file of the
Packit df99a1
	           document. If (like in the {\em old indexed} format) you
Packit df99a1
		   point the #url# to a page, the page {\em will} be decoded,
Packit df99a1
		   but it will {\em not} be recognized to be part of the
Packit df99a1
		   document.
Packit df99a1
	  \end{itemize}
Packit df99a1
Packit df99a1
	  @param url The URL pointing to the document. If the document is
Packit df99a1
	         in a {\em bundled} format then the URL should point to it.
Packit df99a1
		 If the document is in the {\em old indexed} format then
Packit df99a1
		 URL may point to any page of this document. For {\em new
Packit df99a1
		 indirect} format the URL should point to the top-level
Packit df99a1
		 file of the document.
Packit df99a1
	  @param port If not #ZERO#, all requests and notifications will
Packit df99a1
	         be sent to it. Otherwise #DjVuDocument# will create an internal
Packit df99a1
		 instance of \Ref{DjVuSimplePort} for these purposes.
Packit df99a1
		 It's OK to make it #ZERO# if you're writing a command line
Packit df99a1
		 tool, which should work with files on the hard disk only
Packit df99a1
		 because #DjVuDocument# can access such files itself.
Packit df99a1
	  @param cache It's used to cache decoded \Ref{DjVuFile}s and
Packit df99a1
	         is actually useful in the plugin only.  */
Packit df99a1
   void		start_init(const GURL & url, GP<DjVuPort> port=0,
Packit df99a1
			   DjVuFileCache * cache=0);
Packit df99a1
Packit df99a1
   /** This creates a DjVuDocument without initializing it. */
Packit df99a1
   static GP<DjVuDocument> create_noinit(void) {return new DjVuDocument;}
Packit df99a1
Packit df99a1
   /** Create a version of DjVuDocument which has finished initializing. */
Packit df99a1
   static GP<DjVuDocument> create_wait(
Packit df99a1
     const GURL &url, GP<DjVuPort> xport=0, DjVuFileCache * const xcache=0);
Packit df99a1
Packit df99a1
   /** Create a version of DjVuDocument which has begun initializing. */
Packit df99a1
   static GP<DjVuDocument> create(
Packit df99a1
     const GURL &url, GP<DjVuPort> xport=0, DjVuFileCache * const xcache=0);
Packit df99a1
Packit df99a1
   /** Create a version of DjVuDocument which has begun initializing. */
Packit df99a1
   static GP<DjVuDocument> create(
Packit df99a1
     GP<DataPool> pool, GP<DjVuPort> xport=0, DjVuFileCache * const xcache=0);
Packit df99a1
Packit df99a1
   /** Create a version of DjVuDocument which has begun initializing. */
Packit df99a1
   static GP<DjVuDocument> create(
Packit df99a1
     const GP<ByteStream> &bs, GP<DjVuPort> xport=0,
Packit df99a1
     DjVuFileCache * const xcache=0);
Packit df99a1
Packit df99a1
      /** Call this function when you don't need the #DjVuDocument# any more.
Packit df99a1
	  In a multi-threaded environment it will stop initialization
Packit df99a1
	  thread, if it is currently running. {\bf You will not be able
Packit df99a1
	  to start the initialization again. Thus, after calling this
Packit df99a1
          function the document should not be used any more}. */
Packit df99a1
   void		stop_init(void);
Packit df99a1
Packit df99a1
      /** Initializes the document.
Packit df99a1
Packit df99a1
	  Contrary to \Ref{start_init}(), which just starts the initialization
Packit df99a1
	  thread in a multi-threaded environment, this function does not
Packit df99a1
	  return until the initialization completes (either successfully or
Packit df99a1
	  not). Basically, it calls \Ref{start_init}() and then
Packit df99a1
	  \Ref{wait_for_complete_init}().
Packit df99a1
	  */
Packit df99a1
   void		init(const GURL & url, GP<DjVuPort> port=0,
Packit df99a1
		     DjVuFileCache * cache=0);
Packit df99a1
Packit df99a1
      /** Returns #TRUE# if the initialization thread finished (does not
Packit df99a1
	  matter successfully or not). As soon as it happens, the document
Packit df99a1
	  becomes completely initialized and its every function should work
Packit df99a1
	  properly. Please refer to the description of \Ref{init}() function
Packit df99a1
	  and of the #DjVuDocument# class to learn about the initializing
Packit df99a1
	  stages.
Packit df99a1
Packit df99a1
	  To wait for the initialization to complete use
Packit df99a1
	  \Ref{wait_for_complete_init}() function.
Packit df99a1
Packit df99a1
	  To query the initialization stage use \Ref{get_flags}() function.
Packit df99a1
Packit df99a1
	  To learn whether initialization was successful or not,
Packit df99a1
	  use \Ref{is_init_ok}() and \Ref{is_init_failed}().
Packit df99a1
Packit df99a1
	  {\bf Note:} In a single threaded application the initialization
Packit df99a1
	  completes before the \Ref{init}() function returns. */
Packit df99a1
   bool		is_init_complete(void) const;
Packit df99a1
Packit df99a1
      /** Returns #TRUE# is the initialization thread finished successfully.
Packit df99a1
Packit df99a1
	  See \Ref{is_init_complete}() and \Ref{wait_for_complete_init}()
Packit df99a1
	  for more details. */
Packit df99a1
   bool		is_init_ok(void) const;
Packit df99a1
      /** Forces compression with the next save_as function. */
Packit df99a1
   void		set_needs_compression(void);
Packit df99a1
      /** Returns #TRUE# if there are uncompressed pages in this document. */
Packit df99a1
   bool		needs_compression(void) const;
Packit df99a1
      /** Returns #TRUE# if this file must be renamed before saving. */
Packit df99a1
   bool		needs_rename(void) const;
Packit df99a1
      /** Returns #TRUE# if this file must be renamed before saving. */
Packit df99a1
   bool		can_compress(void) const;
Packit df99a1
Packit df99a1
      /** Returns #TRUE# is the initialization thread failed.
Packit df99a1
Packit df99a1
	  See \Ref{is_init_complete}() and \Ref{wait_for_complete_init}()
Packit df99a1
	  for more details. */
Packit df99a1
   bool		is_init_failed(void) const;
Packit df99a1
Packit df99a1
      /** If the document has already learnt its type, the function will
Packit df99a1
	  returns it: #DjVuDocument::OLD_BUNDLED# or
Packit df99a1
	  #DjVuDocument::OLD_INDEXED# or #DjVuDocument::SINGLE_PAGE# or
Packit df99a1
	  #DjVuDocument:BUNDLED# or #DjVuDocument::INDIRECT#. The first
Packit df99a1
	  two formats are obsolete. Otherwise (if the type is unknown yet),
Packit df99a1
	  #UNKNOWN_TYPE# will be returned.
Packit df99a1
Packit df99a1
	  {\bf Note:} To check the stage of the document initialization
Packit df99a1
	  use \Ref{get_flags}() or \Ref{is_init_complete}() functions. To
Packit df99a1
	  wait for the initialization to complete use \Ref{wait_for_complete_init}().
Packit df99a1
	  For single threaded applications the initialization completes
Packit df99a1
	  before the \Ref{init}() function returns. */
Packit df99a1
   int		get_doc_type(void) const;
Packit df99a1
Packit df99a1
      /** Returns the document flags. The flags describe the degree in which
Packit df99a1
	  the #DjVuDocument# object is initialized. Every time the flags
Packit df99a1
	  are changed, a #notify_doc_flags_changed()# notification is
Packit df99a1
	  distributed using the \Ref{DjVuPortcaster} communication
Packit df99a1
	  mechanism.
Packit df99a1
Packit df99a1
	  {\bf Note:} To wait for the initialization to complete use
Packit df99a1
	  \Ref{wait_for_complete_init}(). For single threaded applications
Packit df99a1
	  the initialization completes before the \Ref{init}() function
Packit df99a1
	  returns. */
Packit df99a1
   long		get_doc_flags(void) const;
Packit df99a1
Packit df99a1
      /** Returns #TRUE# if the document is in bundled format (either in
Packit df99a1
	  #DjVuDocument::OLD_BUNDLED# or #DjVuDocument::BUNDLED# formats). */
Packit df99a1
   bool		is_bundled(void) const;
Packit df99a1
Packit df99a1
      /// Returns the URL passed to the \Ref{init}() function
Packit df99a1
   GURL		get_init_url(void) const;
Packit df99a1
Packit df99a1
      /// Returns a listing of id's used by this document.
Packit df99a1
   GList<GUTF8String> get_id_list(void);
Packit df99a1
Packit df99a1
      /// Fill the id's into a GMap.
Packit df99a1
   void map_ids( GMap<GUTF8String,void *> &map);
Packit df99a1
Packit df99a1
      /** Returns data corresponding to the URL passed to the \Ref{init}()
Packit df99a1
	  function.
Packit df99a1
Packit df99a1
	  {\bf Note:} The pointer returned is guaranteed to be non-#ZERO#
Packit df99a1
	  only after the #DjVuDocument# learns its type (passes through
Packit df99a1
	  the first stage of initialization process). Please refer to
Packit df99a1
	  \Ref{init}() for details. */
Packit df99a1
   GP<DataPool>	get_init_data_pool(void) const;
Packit df99a1
Packit df99a1
      /** @name Accessing pages */
Packit df99a1
      //@{
Packit df99a1
      /** Returns the number of pages in the document. If there is still
Packit df99a1
	  insufficient information about the document structure (initialization
Packit df99a1
	  has not finished yet), #1# will be returned. Please refer to
Packit df99a1
          \Ref{init}() for details. */
Packit df99a1
   int		get_pages_num(void) const;
Packit df99a1
Packit df99a1
      /** Translates the page number to the full URL of the page. This URL
Packit df99a1
	  is "artificial" for the {\em bundled} formats and is obtained
Packit df99a1
	  by appending the page name to the document's URL honoring possible
Packit df99a1
	  #;# and #?# in it. Negative page number has a special meaning for
Packit df99a1
	  #OLD_INDEXED# documents: it points to the URL, which the
Packit df99a1
	  #DjVuDocument# has been initialized with. For other formats this
Packit df99a1
	  is the same as page #0#.
Packit df99a1
Packit df99a1
	  The function tries it best to map the page number to the URL.
Packit df99a1
	  Although, if the document structure has not been fully discovered
Packit df99a1
	  yet, an empty URL will be returned. Use \Ref{wait_for_complete_init}()
Packit df99a1
	  to wait until the document initialization completes. Refer to
Packit df99a1
	  \Ref{init}() for details.
Packit df99a1
Packit df99a1
	  Depending on the document format, the function assumes, that there
Packit df99a1
	  is enough information to complete the request when:
Packit df99a1
	  \begin{itemize}
Packit df99a1
	     \item #OLD_INDEXED#: If #page_num<0#, #DOC_TYPE_KNOWN# flag must
Packit df99a1
		   be set. Otherwise #DOC_NDIR_KNOWN# must be set.
Packit df99a1
	     \item #OLD_BUNDLED#: If #page_num=0#, #DOC_DIR_KNOWN# flag must
Packit df99a1
		   be set. Otherwise #DOC_NDIR_KNOWN# flag must be set.
Packit df99a1
	     \item #INDIRECT# and #BUNDLED#: #DOC_DIR_KNOWN# flag must be set.
Packit df99a1
	  \end{itemize} */
Packit df99a1
   GURL		page_to_url(int page_num) const;
Packit df99a1
   /// Tranlate the page number to id...
Packit df99a1
   GUTF8String page_to_id(int page_num) const
Packit df99a1
   { return url_to_id(page_to_url(page_num)); }
Packit df99a1
      /** Translates the page URL back to page number. Returns #-1# if the
Packit df99a1
	  page is not in the document or the document's structure
Packit df99a1
          has not been learnt yet.
Packit df99a1
Packit df99a1
	  Depending on the document format, the function starts working
Packit df99a1
	  properly as soon as:
Packit df99a1
	  \begin{itemize}
Packit df99a1
	     \item #OLD_INDEXED# and #OLD_BUNDLED# and #SINGLE_PAGE#:
Packit df99a1
	           #DOC_NDIR_KNOWN# is set
Packit df99a1
	     \item #INDIRECT# and #BUNDLED#: #DOC_DIR_KNOWN# is set.
Packit df99a1
	  \end{itemize} */
Packit df99a1
   int		url_to_page(const GURL & url) const;
Packit df99a1
   /// Map the specified url to it's id.
Packit df99a1
   GUTF8String  url_to_id(const GURL &url) const
Packit df99a1
   { return url.fname(); }
Packit df99a1
Packit df99a1
      /** Translates the textual ID to the complete URL if possible.
Packit df99a1
	  
Packit df99a1
	  Depending on the document format the translation is done in the
Packit df99a1
	  following way:
Packit df99a1
	  \begin{itemize}
Packit df99a1
	     \item For #BUNDLED# and #INDIRECT# documents the function
Packit df99a1
		   scans the \Ref{DjVmDir} (the document directory) and
Packit df99a1
		   matches the ID against:
Packit df99a1
		   \begin{enumerate}
Packit df99a1
		      \item File ID from the \Ref{DjVmDir}
Packit df99a1
		      \item File name from the \Ref{DjVmDir}
Packit df99a1
		      \item File title from the \Ref{DjVmDir}
Packit df99a1
		   \end{enumerate}
Packit df99a1
		   Then for #BUNDLED# document the URL is obtained by
Packit df99a1
		   appending the #name# of the found file to the document's
Packit df99a1
		   URL.
Packit df99a1
Packit df99a1
		   For #INDIRECT# documents the URL is obtained by
Packit df99a1
		   appending the #name# of the found file to the URL of
Packit df99a1
		   the directory containing the document.
Packit df99a1
	     \item For #OLD_BUNDLED# documents the function compares the ID
Packit df99a1
		   with internal name of every file inside the bundle and
Packit df99a1
		   composes an artificial URL by appending the file name to
Packit df99a1
		   the document's URL.
Packit df99a1
	     \item For #OLD_INDEXED# or #SINGLE_PAGE# documents the function
Packit df99a1
		   composes the URL by appending the ID to the URL of the
Packit df99a1
		   directory containing the document.
Packit df99a1
	  \end{itemize}
Packit df99a1
Packit df99a1
	  If information obtained by the initialization thread is not
Packit df99a1
	  sufficient yet, the #id_to_url()# may return an empty URL.
Packit df99a1
	  Depending on the document type, the information is sufficient when
Packit df99a1
	  \begin{itemize}
Packit df99a1
	     \item #BUNDLED# and #INDIRECT#: #DOC_DIR_KNOWN# flag is set.
Packit df99a1
	     \item #OLD_BUNDLED# and #OLD_INDEXED# and #SINGLE_PAGE#:
Packit df99a1
	           #DOC_TYPE_KNOWN# flag is set.
Packit df99a1
	  \end{itemize} */
Packit df99a1
   GURL		id_to_url(const GUTF8String &id) const;
Packit df99a1
   /// Find out which page this id is...
Packit df99a1
   int		id_to_page(const GUTF8String &id) const
Packit df99a1
   {  return url_to_page(id_to_url(id)); }
Packit df99a1
Packit df99a1
      /** Returns \Ref{GP} pointer to \Ref{DjVuImage} corresponding to page
Packit df99a1
          #page_num#. If caching is enabled, and there is a {\em fully decoded}
Packit df99a1
	  \Ref{DjVuFile} in the cache, the image will be reused and will
Packit df99a1
	  be returned fully decoded. Otherwise, if multi-threaded behavior
Packit df99a1
	  is allowed, and #sync# is set to #FALSE#, the decoding will be
Packit df99a1
	  started in a separate thread, which enables to do progressive
Packit df99a1
	  redisplay. Thus, in this case the image returned may be partially
Packit df99a1
	  decoded.
Packit df99a1
Packit df99a1
	  Negative #page_num# has a special meaning for the {\em old indexed}
Packit df99a1
	  multipage documents: the #DjVuDocument# will start decoding of the
Packit df99a1
	  URL with which it has been initialized. For other formats page
Packit df99a1
	  #-1# is the same as page #0#.
Packit df99a1
Packit df99a1
	  #DjVuDocument# can also connect the created page to the specified
Packit df99a1
	  #port# {\em before starting decoding}. This option will allow
Packit df99a1
	  the future owner of \Ref{DjVuImage} to receive all messages and
Packit df99a1
	  requests generated during its decoding.
Packit df99a1
Packit df99a1
	  If this function is called before the document's structure becomes
Packit df99a1
	  known (the initialization process completes), the \Ref{DjVuFile},
Packit df99a1
	  which the returned image will be attached to, will be assigned a
Packit df99a1
	  temporary artificial URL, which will be corrected as soon as enough
Packit df99a1
	  information becomes available. The trick prevents the main thread
Packit df99a1
	  from blocking and in some cases helps to start decoding earlier.
Packit df99a1
	  The URL is corrected and decoding will start as soon as
Packit df99a1
	  #DjVuDocument# passes some given stages of initialization and
Packit df99a1
	  \Ref{page_to_url}(), \Ref{id_to_url}() functions start working
Packit df99a1
	  properly. Please look through their description for details.
Packit df99a1
Packit df99a1
	  {\bf Note:} To wait for the initialization to complete use
Packit df99a1
	  \Ref{wait_for_complete_init}(). For single threaded applications
Packit df99a1
	  the initialization completes before the \Ref{init}() function
Packit df99a1
	  returns.
Packit df99a1
Packit df99a1
	  @param page_num Number of the page to be decoded
Packit df99a1
	  @param sync When set to #TRUE# the function will not return
Packit df99a1
	  	      until the page is completely decoded. Otherwise,
Packit df99a1
		      in a multi-threaded program, this function will
Packit df99a1
		      start decoding in a new thread and will return
Packit df99a1
		      a partially decoded image. Refer to
Packit df99a1
		      \Ref{DjVuImage::wait_for_complete_decode}() and
Packit df99a1
		      \Ref{DjVuFile::is_decode_ok}().
Packit df99a1
	  @param port A pointer to \Ref{DjVuPort}, that the created image
Packit df99a1
	  	      will be connected to. */
Packit df99a1
   GP<DjVuImage> get_page(int page_num, bool sync=true, DjVuPort * port=0) const;
Packit df99a1
   GP<DjVuImage> get_page(int page_num, bool sync=true, DjVuPort * port=0)
Packit df99a1
   { return const_cast<const DjVuDocument *>(this)->get_page(page_num,sync,port); }
Packit df99a1
Packit df99a1
      /** Returns \Ref{GP} pointer to \Ref{DjVuImage} corresponding to the
Packit df99a1
	  specified ID. This function behaves exactly as the #get_page()#
Packit df99a1
	  function above. The only thing worth mentioning here is how the #ID#
Packit df99a1
	  parameter is treated.
Packit df99a1
Packit df99a1
	  First of all the function checks, if the ID contains a number.
Packit df99a1
	  If so, it just calls the #get_page()# function above. If ID is
Packit df99a1
	  #ZERO# or just empty, page number #-1# is assumed. Otherwise
Packit df99a1
	  the ID is translated to the URL using \Ref{id_to_url}(). */
Packit df99a1
   GP<DjVuImage> get_page(const GUTF8String &id, bool sync=true, DjVuPort * port=0);
Packit df99a1
   
Packit df99a1
      /** Returns \Ref{DjVuFile} corresponding to the specified page.
Packit df99a1
	  Normally it translates the page number to the URL using
Packit df99a1
	  \Ref{page_to_url}() and then creates \Ref{DjVuFile} initializing
Packit df99a1
	  it with data from the URL.
Packit df99a1
Packit df99a1
	  The behavior becomes different, though in the case when the
Packit df99a1
	  document structure is unknown at the moment this function is called.
Packit df99a1
	  In this situations it invents a temporary URL, creates a
Packit df99a1
	  \Ref{DjVuFile}, initializes it with this URL and returns
Packit df99a1
	  immediately. The caller may start decoding the file right away
Packit df99a1
	  (if necessary). The decoding will block but will automatically
Packit df99a1
	  continue as soon as enough information is collected about the
Packit df99a1
	  document. This trick should be quite transparent to the user and
Packit df99a1
	  helps to prevent the main thread from blocking. The decoding will
Packit df99a1
	  unblock and this function will stop using this "trick" as soon
Packit df99a1
	  as #DjVuDocument# passes some given stages of initialization and
Packit df99a1
	  \Ref{page_to_url}(), \Ref{id_to_url}() functions start working
Packit df99a1
	  properly.
Packit df99a1
Packit df99a1
	  If #dont_create# is #FALSE# the function will return the file
Packit df99a1
	  only if it already exists.
Packit df99a1
Packit df99a1
	  {\bf Note:} To wait for the initialization to complete use
Packit df99a1
	  \Ref{wait_for_complete_init}(). For single threaded applications
Packit df99a1
	  the initialization completes before the \Ref{init}() function
Packit df99a1
	  returns. */
Packit df99a1
   GP<DjVuFile>	get_djvu_file(int page_num, bool dont_create=false) const;
Packit df99a1
   GP<DjVuFile> get_djvu_file(int page_num, bool dont_create=false)
Packit df99a1
   { return const_cast<const DjVuDocument *>(this)->get_djvu_file(page_num,dont_create); }
Packit df99a1
Packit df99a1
Packit df99a1
      /** Returns \Ref{DjVuFile} corresponding to the specified ID.
Packit df99a1
          This function behaves exactly as the #get_djvu_file()# function
Packit df99a1
	  above. The only thing worth mentioning here is how the #ID#
Packit df99a1
	  parameter is treated.
Packit df99a1
Packit df99a1
          First off, \Ref{id_to_url}() is called.  If not successfull,
Packit df99a1
	  the function checks, if the ID contains a number.
Packit df99a1
	  If so, it just calls the #get_djvu_file()# function above. If ID is
Packit df99a1
	  #ZERO# or just empty, page number #-1# is assumed.
Packit df99a1
Packit df99a1
	  If #dont_create# is #FALSE# the function will return the file
Packit df99a1
	  only if it already exists. */
Packit df99a1
   GP<DjVuFile>	get_djvu_file(const GUTF8String &id, bool dont_create=false);
Packit df99a1
   GP<DjVuFile>	get_djvu_file(const GURL &url, bool dont_create=false);
Packit df99a1
      /** Returns a \Ref{DataPool} containing one chunk #TH44# with
Packit df99a1
	  the encoded thumbnail for the specified page. The function
Packit df99a1
	  first looks for thumbnails enclosed into the document and if
Packit df99a1
	  it fails to find one, it decodes the required page and creates
Packit df99a1
	  the thumbnail on the fly (unless #dont_decode# is true).
Packit df99a1
Packit df99a1
	  {\bf Note:} It may happen that the returned \Ref{DataPool} will
Packit df99a1
	  not contain all the data you need. In this case you will need
Packit df99a1
	  to install a trigger into the \Ref{DataPool} to learn when the
Packit df99a1
	  data actually arrives. */
Packit df99a1
   virtual GP<DataPool> get_thumbnail(int page_num, bool dont_decode);
Packit df99a1
      /* Will return gamma correction, which was used when creating
Packit df99a1
	 thumbnail images. If you need other gamma correction, you will
Packit df99a1
	 need to correct the thumbnails again. */
Packit df99a1
   float	get_thumbnails_gamma(void) const;
Packit df99a1
      //@}
Packit df99a1
Packit df99a1
      /** Waits until the document initialization process finishes.
Packit df99a1
	  It can finish either successfully or not. Use \Ref{is_init_ok}()
Packit df99a1
	  and \Ref{is_init_failed}() to learn the result code.
Packit df99a1
	  
Packit df99a1
	  As described in \Ref{start_init}(), for multi-threaded applications the
Packit df99a1
	  initialization is carried out in parallel with the main thread.
Packit df99a1
	  This function blocks the calling thread until the initializing
Packit df99a1
	  thread reads enough data, receives information about the document
Packit df99a1
	  format and exits.  This function returns #true# if the
Packit df99a1
	  initialization is successful. You can use \Ref{get_flags}() or
Packit df99a1
	  \Ref{is_init_complete}() to check more precisely the degree of
Packit df99a1
	  initialization. Use \Ref{stop_init}() to interrupt initialization. */
Packit df99a1
   bool    	   wait_for_complete_init(void);
Packit df99a1
Packit df99a1
          /** Wait until we known the number of pages and return. */
Packit df99a1
   int wait_get_pages_num(void) const;
Packit df99a1
   
Packit df99a1
      /// Returns cache being used.
Packit df99a1
   DjVuFileCache * get_cache(void) const;
Packit df99a1
Packit df99a1
      /** @name Saving document to disk */
Packit df99a1
      //@{
Packit df99a1
      /** Returns pointer to the \Ref{DjVmDoc} class, which can save the
Packit df99a1
	  document contents on the hard disk in one of the two new formats:
Packit df99a1
	  {\em bundled} and {\em indirect}. You may also want to look
Packit df99a1
	  at \Ref{write}() and \Ref{expand}() if you are interested in
Packit df99a1
	  how to save the document.
Packit df99a1
Packit df99a1
	  {\bf Plugin Warning}. This function will read contents of the whole
Packit df99a1
	  document. Thus, if you call it from the main thread (the thread,
Packit df99a1
	  which transfers data from Netscape), the plugin will block. */
Packit df99a1
   GP<DjVmDoc>		get_djvm_doc(void);
Packit df99a1
      /** Saves the document in the {\em new bundled} format. All the data
Packit df99a1
	  is "bundled" into one file and this file is written into the
Packit df99a1
	  passed stream.
Packit df99a1
Packit df99a1
	  If #force_djvm# is #TRUE# then even one page documents will be
Packit df99a1
	  saved in the #DJVM BUNDLED# format (inside a #FORM:DJVM#);
Packit df99a1
Packit df99a1
	  {\bf Plugin Warning}. This function will read contents of the whole
Packit df99a1
	  document. Thus, if you call it from the main thread (the thread,
Packit df99a1
	  which transfers data from Netscape), the plugin will block. */
Packit df99a1
   virtual void write(const GP<ByteStream> &str, bool force_djvm=false);
Packit df99a1
     /** Always save as bundled, renaming any files conflicting with the
Packit df99a1
         the names in the supplied GMap. */
Packit df99a1
   virtual void write(const GP<ByteStream> &str,
Packit df99a1
     const GMap<GUTF8String,void *> &reserved);
Packit df99a1
      /** Saves the document in the {\em new indirect} format when every
Packit df99a1
	  page and component are stored in separate files. This format
Packit df99a1
	  is ideal for web publishing because it allows direct access to
Packit df99a1
	  any page and component. In addition to it, a top-level file
Packit df99a1
	  containing the list of all components will be created. To view
Packit df99a1
	  the document later in the plugin or in the viewer one should
Packit df99a1
	  load the top-level file.
Packit df99a1
Packit df99a1
	  {\bf Plugin Warning}. This function will read contents of the whole
Packit df99a1
	  document. Thus, if you call it from the main thread (the thread,
Packit df99a1
	  which transfers data from Netscape), the plugin will block.
Packit df99a1
	  
Packit df99a1
	  @param codebase - Name of the directory which the document should
Packit df99a1
	         be expanded into.
Packit df99a1
	  @param idx_name - Name of the top-level file containing the document
Packit df99a1
	         directory (basically, list of all files composing the document).
Packit df99a1
      */
Packit df99a1
   void			expand(const GURL &codebase, const GUTF8String &idx_name);
Packit df99a1
      /** This function can be used instead of \Ref{write}() and \Ref{expand}().
Packit df99a1
	  It allows to save the document either in the new #BUNDLED# format
Packit df99a1
	  or in the new #INDIRECT# format depending on the value of parameter
Packit df99a1
	  #bundled#.
Packit df99a1
Packit df99a1
	  Depending on the document's type, the meaning of #where# is:
Packit df99a1
	  \begin{itemize}
Packit df99a1
	     \item For #BUNDLED# documents this is the name of the file
Packit df99a1
	     \item For #INDIRECT# documents this is the name of top-level
Packit df99a1
	           index file. All document files will be saved into the
Packit df99a1
		   save directory where the index file will resize. */
Packit df99a1
   virtual void		save_as(const GURL &where, bool bundled=0);
Packit df99a1
      //@}
Packit df99a1
      /** Returns pointer to the internal directory of the document, if it
Packit df99a1
	  is in one of the new formats: #BUNDLED# or #INDIRECT#.
Packit df99a1
	  Otherwise (if the format of the input document is obsolete),
Packit df99a1
	  #ZERO# is returned.
Packit df99a1
Packit df99a1
	  #ZERO# will also be returned if the initializing thread has not
Packit df99a1
	  learnt enough information about the document (#DOC_DIR_KNOWN# has
Packit df99a1
	  not been set yet). Check \Ref{is_init_complete}() and \Ref{init}()
Packit df99a1
          for details. */
Packit df99a1
   GP<DjVmDir>		get_djvm_dir(void) const;
Packit df99a1
      /** Returns pointer to the document bookmarks.
Packit df99a1
          This applies to #BUNDLED# and #INDIRECT# documents.
Packit df99a1
Packit df99a1
	  #ZERO# will also be returned if the initializing thread has not
Packit df99a1
	  learnt enough information about the document (#DOC_DIR_KNOWN# has
Packit df99a1
	  not been set yet). Check \Ref{is_init_complete}() and \Ref{init}()
Packit df99a1
          for details. */
Packit df99a1
   GP<DjVmNav>		get_djvm_nav(void) const;
Packit df99a1
      /** Returns pointer to the internal directory of the document, if it
Packit df99a1
	  is in obsolete #OLD_BUNDLED# format.
Packit df99a1
Packit df99a1
	  #ZERO# will also be returned if the initializing thread has not
Packit df99a1
	  learnt enough information about the document (#DOC_DIR_KNOWN# has
Packit df99a1
	  not been set yet). Check \Ref{is_init_complete}() and \Ref{init}()
Packit df99a1
          for details. */
Packit df99a1
   GP<DjVmDir0>		get_djvm_dir0(void) const;
Packit df99a1
      /** Returns pointer to {\em navigation directory} of the document.
Packit df99a1
	  The navigation directory is a DjVu file containing only one
Packit df99a1
	  chunk #NDIR# inside a #FORM:DJVI# with the list of all
Packit df99a1
	  document pages. */
Packit df99a1
   GP<DjVuNavDir>	get_nav_dir(void) const;
Packit df99a1
Packit df99a1
   /// Create a complete DjVuXML file.
Packit df99a1
   void writeDjVuXML(const GP<ByteStream> &gstr_out,
Packit df99a1
                     int flags, int page = -1) const;
Packit df99a1
Packit df99a1
      /// Returns TRUE if #class_name# is #"DjVuDocument"# or #"DjVuPort"#
Packit df99a1
   virtual bool		inherits(const GUTF8String &class_name) const;
Packit df99a1
Packit df99a1
      /// Converts the specified id to a URL.
Packit df99a1
   virtual GURL		id_to_url(const DjVuPort * source, const GUTF8String &id;;
Packit df99a1
   virtual GP<DjVuFile>	id_to_file(const DjVuPort * source, const GUTF8String &id;;
Packit df99a1
   virtual GP<DataPool>	request_data(const DjVuPort * source, const GURL & url);
Packit df99a1
   virtual void		notify_file_flags_changed(const DjVuFile * source,
Packit df99a1
 			long set_mask, long clr_mask);
Packit df99a1
Packit df99a1
   virtual GList<GURL>	get_url_names(void);
Packit df99a1
   virtual void 	set_recover_errors(ErrorRecoveryAction=ABORT);
Packit df99a1
   virtual void 	set_verbose_eof(bool=true);
Packit df99a1
Packit df99a1
   static void set_compress_codec(
Packit df99a1
     void (*codec)(GP<ByteStream> &, const GURL &where, bool bundled));
Packit df99a1
Packit df99a1
   static void set_import_codec(
Packit df99a1
     void (*codec)(GP<DataPool> &,const GURL &url,bool &, bool &);;
Packit df99a1
Packit df99a1
protected:
Packit df99a1
   static void (*djvu_import_codec) (
Packit df99a1
     GP<DataPool> &pool, const GURL &url,bool &needs_compression, bool &needs_rename );
Packit df99a1
   static void (*djvu_compress_codec) (
Packit df99a1
     GP<ByteStream> &bs, const GURL &where, bool bundled);
Packit df99a1
   virtual GP<DjVuFile>	url_to_file(const GURL & url, bool dont_create=false) const;
Packit df99a1
   GURL			init_url;
Packit df99a1
   GP<DataPool>		init_data_pool;
Packit df99a1
   GP<DjVmDir>		djvm_dir;	// New-style DjVm directory
Packit df99a1
   GP<DjVmNav>          djvm_nav;
Packit df99a1
   int	doc_type;
Packit df99a1
   bool needs_compression_flag;
Packit df99a1
   bool can_compress_flag;
Packit df99a1
   bool needs_rename_flag;
Packit df99a1
Packit df99a1
   
Packit df99a1
Packit df99a1
   bool			has_url_names;
Packit df99a1
   GCriticalSection	url_names_lock;
Packit df99a1
   GList<GURL>	url_names;
Packit df99a1
   ErrorRecoveryAction	recover_errors;
Packit df99a1
   bool			verbose_eof;
Packit df99a1
public:
Packit df99a1
   class UnnamedFile; // This really should be protected ...
Packit df99a1
   class ThumbReq; // This really should be protected ...
Packit df99a1
protected:
Packit df99a1
   bool                 init_started;
Packit df99a1
   GSafeFlags		flags;
Packit df99a1
   GSafeFlags		init_thread_flags;
Packit df99a1
   DjVuFileCache	* cache;
Packit df99a1
   GP<DjVuSimplePort>	simple_port;
Packit df99a1
Packit df99a1
   GP<DjVmDir0>		djvm_dir0;	// Old-style DjVm directory
Packit df99a1
   GP<DjVuNavDir>	ndir;		// Old-style navigation directory
Packit df99a1
   GUTF8String		first_page_name;// For OLD_BUNDLED docs only
Packit df99a1
Packit df99a1
      // The following is used in init() and destructor to query NDIR
Packit df99a1
      // DO NOT USE FOR ANYTHING ELSE. THE FILE IS ZEROED IMMEDIATELY
Packit df99a1
      // AFTER IT'S NO LONGER NEEDED. If you don't zero it, ~DjVuDocument()
Packit df99a1
      // will kill it, which is a BAD thing if the file's already in cache.
Packit df99a1
   GP<DjVuFile>		ndir_file;
Packit df99a1
   
Packit df99a1
   GPList<UnnamedFile>	ufiles_list;
Packit df99a1
   GCriticalSection	ufiles_lock;
Packit df99a1
Packit df99a1
   GPList<ThumbReq>	threqs_list;
Packit df99a1
   GCriticalSection	threqs_lock;
Packit df99a1
Packit df99a1
   GP<DjVuDocument>	init_life_saver;
Packit df99a1
Packit df99a1
   static const float	thumb_gamma;
Packit df99a1
Packit df99a1
      // Reads document contents in another thread trying to determine
Packit df99a1
      // its type and structure
Packit df99a1
   GThread		init_thr;
Packit df99a1
   static void		static_init_thread(void *);
Packit df99a1
   void			init_thread(void);
Packit df99a1
Packit df99a1
   void                 check() const;
Packit df99a1
Packit df99a1
   void			process_threqs(void);
Packit df99a1
   GP<ThumbReq>		add_thumb_req(const GP<ThumbReq> & thumb_req);
Packit df99a1
      
Packit df99a1
   void			add_to_cache(const GP<DjVuFile> & f);
Packit df99a1
   void			check_unnamed_files(void);
Packit df99a1
   GUTF8String		get_int_prefix(void) const;
Packit df99a1
   void			set_file_aliases(const DjVuFile * file);
Packit df99a1
   GURL			invent_url(const GUTF8String &name) const;
Packit df99a1
};
Packit df99a1
Packit df99a1
class DjVuDocument::UnnamedFile : public GPEnabled
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
   enum { ID, PAGE_NUM };
Packit df99a1
   int		id_type;
Packit df99a1
   GUTF8String		id;
Packit df99a1
   int		page_num;
Packit df99a1
   GURL		url;
Packit df99a1
   GP<DjVuFile>	file;
Packit df99a1
   GP<DataPool>	data_pool;
Packit df99a1
protected:
Packit df99a1
   UnnamedFile(int xid_type, const GUTF8String &xid, int xpage_num, const GURL & xurl,
Packit df99a1
		  const GP<DjVuFile> & xfile) :
Packit df99a1
      id_type(xid_type), id(xid), page_num(xpage_num), url(xurl), file(xfile) {}
Packit df99a1
   friend class DjVuDocument;
Packit df99a1
};
Packit df99a1
Packit df99a1
class DjVuDocument::ThumbReq : public GPEnabled
Packit df99a1
{
Packit df99a1
public:
Packit df99a1
   int		page_num;
Packit df99a1
   GP<DataPool>	data_pool;
Packit df99a1
Packit df99a1
	 // Either of the next two blocks should present
Packit df99a1
   GP<DjVuFile>	image_file;
Packit df99a1
Packit df99a1
   int		thumb_chunk;
Packit df99a1
   GP<DjVuFile>	thumb_file;
Packit df99a1
protected:
Packit df99a1
   ThumbReq(int xpage_num, const GP<DataPool> & xdata_pool) :
Packit df99a1
      page_num(xpage_num), data_pool(xdata_pool) {}
Packit df99a1
   friend class DjVuDocument;
Packit df99a1
};
Packit df99a1
Packit df99a1
inline void
Packit df99a1
DjVuDocument::init(const GURL &url, GP<DjVuPort> port, DjVuFileCache *cache)
Packit df99a1
{
Packit df99a1
  start_init(url,port,cache);
Packit df99a1
  wait_for_complete_init();
Packit df99a1
}
Packit df99a1
Packit df99a1
inline GP<DjVuDocument>
Packit df99a1
DjVuDocument::create(
Packit df99a1
  const GURL &url, GP<DjVuPort> xport, DjVuFileCache * const xcache)
Packit df99a1
{
Packit df99a1
  DjVuDocument *doc=new DjVuDocument;
Packit df99a1
  GP<DjVuDocument> retval=doc;
Packit df99a1
  doc->start_init(url,xport,xcache);
Packit df99a1
  return retval;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuDocument::is_init_complete(void) const
Packit df99a1
{
Packit df99a1
   return (flags & (DOC_INIT_OK | DOC_INIT_FAILED))!=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuDocument::is_init_ok(void) const
Packit df99a1
{
Packit df99a1
   return (flags & DOC_INIT_OK)!=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
DjVuDocument::set_needs_compression(void)
Packit df99a1
{
Packit df99a1
   needs_compression_flag=true;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuDocument::needs_compression(void) const
Packit df99a1
{
Packit df99a1
   return needs_compression_flag;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuDocument::needs_rename(void) const
Packit df99a1
{
Packit df99a1
   return needs_rename_flag;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuDocument::can_compress(void) const
Packit df99a1
{
Packit df99a1
   return can_compress_flag;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuDocument::is_init_failed(void) const
Packit df99a1
{
Packit df99a1
   return (flags & DOC_INIT_FAILED)!=0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline int
Packit df99a1
DjVuDocument::get_doc_type(void) const { return doc_type; }
Packit df99a1
Packit df99a1
inline long
Packit df99a1
DjVuDocument::get_doc_flags(void) const { return flags; }
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuDocument::is_bundled(void) const
Packit df99a1
{
Packit df99a1
   return doc_type==BUNDLED || doc_type==OLD_BUNDLED;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline GURL
Packit df99a1
DjVuDocument::get_init_url(void) const { return init_url; }
Packit df99a1
Packit df99a1
inline GP<DataPool>
Packit df99a1
DjVuDocument::get_init_data_pool(void) const { return init_data_pool; }
Packit df99a1
Packit df99a1
inline bool
Packit df99a1
DjVuDocument::inherits(const GUTF8String &class_name) const
Packit df99a1
{
Packit df99a1
   return
Packit df99a1
      (GUTF8String("DjVuDocument") == class_name) ||
Packit df99a1
      DjVuPort::inherits(class_name);
Packit df99a1
//      !strcmp("DjVuDocument", class_name) ||
Packit df99a1
//      DjVuPort::inherits(class_name);
Packit df99a1
}
Packit df99a1
Packit df99a1
inline float
Packit df99a1
DjVuDocument::get_thumbnails_gamma(void) const
Packit df99a1
{
Packit df99a1
   return thumb_gamma;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline DjVuFileCache *
Packit df99a1
DjVuDocument::get_cache(void) const
Packit df99a1
{
Packit df99a1
   return cache;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline GP<DjVmDir>
Packit df99a1
DjVuDocument::get_djvm_dir(void) const
Packit df99a1
{
Packit df99a1
   if (doc_type==SINGLE_PAGE)
Packit df99a1
      G_THROW( ERR_MSG("DjVuDocument.no_dir") );
Packit df99a1
   if (doc_type!=BUNDLED && doc_type!=INDIRECT)
Packit df99a1
      G_THROW( ERR_MSG("DjVuDocument.obsolete") );
Packit df99a1
   return djvm_dir;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline GP<DjVmNav>
Packit df99a1
DjVuDocument::get_djvm_nav(void) const
Packit df99a1
{
Packit df99a1
  if (doc_type==BUNDLED || doc_type==INDIRECT)
Packit df99a1
    return djvm_nav;
Packit df99a1
  return 0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline GP<DjVmDir0>
Packit df99a1
DjVuDocument::get_djvm_dir0(void) const
Packit df99a1
{
Packit df99a1
   if (doc_type!=OLD_BUNDLED)
Packit df99a1
      G_THROW( ERR_MSG("DjVuDocument.old_bundle") );
Packit df99a1
   return djvm_dir0;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline GP<DjVuNavDir>
Packit df99a1
DjVuDocument::get_nav_dir(void) const
Packit df99a1
{
Packit df99a1
   return ndir;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
DjVuDocument::set_recover_errors(ErrorRecoveryAction recover)
Packit df99a1
{
Packit df99a1
  recover_errors=recover;
Packit df99a1
}
Packit df99a1
Packit df99a1
inline void
Packit df99a1
DjVuDocument::set_verbose_eof(bool verbose)
Packit df99a1
{
Packit df99a1
  verbose_eof=verbose;
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