00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 #ifndef _DJVUDOCUMENT_H
00058 #define _DJVUDOCUMENT_H
00059 #ifdef HAVE_CONFIG_H
00060 #include "config.h"
00061 #endif
00062 #if NEED_GNUG_PRAGMAS
00063 # pragma interface
00064 #endif
00065 
00066 
00067 #include "DjVuPort.h"
00068 
00069 #ifdef HAVE_NAMESPACES
00070 namespace DJVU {
00071 # ifdef NOT_DEFINED // Just to fool emacs c++ mode
00072 }
00073 #endif
00074 #endif
00075 
00076 class DjVmDoc;
00077 class DjVmDir;
00078 class DjVmDir0;
00079 class DjVmNav;
00080 class DjVuImage;
00081 class DjVuFile;
00082 class DjVuFileCache;
00083 class DjVuNavDir;
00084 class ByteStream;
00085 
00097 
00214 class DjVuDocument : public DjVuPort
00215 {
00216 public:
00229    enum DOC_FLAGS { DOC_TYPE_KNOWN=1, DOC_DIR_KNOWN=2,
00230             DOC_NDIR_KNOWN=4, DOC_INIT_OK=8,
00231             DOC_INIT_FAILED=16 };
00250    enum DOC_TYPE { OLD_BUNDLED=1, OLD_INDEXED, BUNDLED, INDIRECT,
00251            SINGLE_PAGE, UNKNOWN_TYPE };
00252    enum THREAD_FLAGS { STARTED=1, FINISHED=2 };
00253 
00254 protected:
00258    DjVuDocument(void);
00259 public:
00260 
00262    virtual ~DjVuDocument(void);
00263 
00339    void     start_init(const GURL & url, GP<DjVuPort> port=0,
00340                DjVuFileCache * cache=0);
00341 
00343    static GP<DjVuDocument> create_noinit(void) {return new DjVuDocument;}
00344 
00346    static GP<DjVuDocument> create_wait(
00347      const GURL &url, GP<DjVuPort> xport=0, DjVuFileCache * const xcache=0);
00348 
00350    static GP<DjVuDocument> create(
00351      const GURL &url, GP<DjVuPort> xport=0, DjVuFileCache * const xcache=0);
00352 
00354    static GP<DjVuDocument> create(
00355      GP<DataPool> pool, GP<DjVuPort> xport=0, DjVuFileCache * const xcache=0);
00356 
00358    static GP<DjVuDocument> create(
00359      const GP<ByteStream> &bs, GP<DjVuPort> xport=0,
00360      DjVuFileCache * const xcache=0);
00361 
00367    void     stop_init(void);
00368 
00377    void     init(const GURL & url, GP<DjVuPort> port=0,
00378              DjVuFileCache * cache=0);
00379 
00397    bool     is_init_complete(void) const;
00398 
00403    bool     is_init_ok(void) const;
00405    void     set_needs_compression(void);
00407    bool     needs_compression(void) const;
00409    bool     needs_rename(void) const;
00411    bool     can_compress(void) const;
00412 
00417    bool     is_init_failed(void) const;
00418 
00431    int      get_doc_type(void) const;
00432 
00443    long     get_doc_flags(void) const;
00444 
00447    bool     is_bundled(void) const;
00448 
00450    GURL     get_init_url(void) const;
00451 
00453    GList<GUTF8String> get_id_list(void);
00454 
00456    void map_ids( GMap<GUTF8String,void *> &map);
00457 
00465    GP<DataPool> get_init_data_pool(void) const;
00466 
00473    int      get_pages_num(void) const;
00474 
00498    GURL     page_to_url(int page_num) const;
00500    GUTF8String page_to_id(int page_num) const
00501    { return url_to_id(page_to_url(page_num)); }
00513    int      url_to_page(const GURL & url) const;
00515    GUTF8String  url_to_id(const GURL &url) const
00516    { return url.fname(); }
00517 
00555    GURL     id_to_url(const GUTF8String &id) const;
00557    int      id_to_page(const GUTF8String &id) const
00558    {  return url_to_page(id_to_url(id)); }
00559 
00605    GP<DjVuImage> get_page(int page_num, bool sync=true, DjVuPort * port=0) const;
00606    GP<DjVuImage> get_page(int page_num, bool sync=true, DjVuPort * port=0)
00607    { return const_cast<const DjVuDocument *>(this)->get_page(page_num,sync,port); }
00608 
00618    GP<DjVuImage> get_page(const GUTF8String &id, bool sync=true, DjVuPort * port=0);
00619    
00646    GP<DjVuFile> get_djvu_file(int page_num, bool dont_create=false) const;
00647    GP<DjVuFile> get_djvu_file(int page_num, bool dont_create=false)
00648    { return const_cast<const DjVuDocument *>(this)->get_djvu_file(page_num,dont_create); }
00649 
00650 
00663    GP<DjVuFile> get_djvu_file(const GUTF8String &id, bool dont_create=false);
00664    GP<DjVuFile> get_djvu_file(const GURL &url, bool dont_create=false);
00675    virtual GP<DataPool> get_thumbnail(int page_num, bool dont_decode);
00676       
00677 
00678 
00679    float    get_thumbnails_gamma(void) const;
00681 
00694    bool        wait_for_complete_init(void);
00695 
00697    int wait_get_pages_num(void) const;
00698    
00700    DjVuFileCache * get_cache(void) const;
00701 
00713    GP<DjVmDoc>      get_djvm_doc(void);
00724    virtual void write(const GP<ByteStream> &str, bool force_djvm=false);
00727    virtual void write(const GP<ByteStream> &str,
00728      const GMap<GUTF8String,void *> &reserved);
00746    void         expand(const GURL &codebase, const GUTF8String &idx_name);
00758    virtual void     save_as(const GURL &where, const bool bundled=0);
00760 
00769    GP<DjVmDir>      get_djvm_dir(void) const;
00777    GP<DjVmNav>      get_djvm_nav(void) const;
00785    GP<DjVmDir0>     get_djvm_dir0(void) const;
00790    GP<DjVuNavDir>   get_nav_dir(void) const;
00791 
00793    void writeDjVuXML(const GP<ByteStream> &gstr_out,int flags) const;
00794 
00796    virtual bool     inherits(const GUTF8String &class_name) const;
00797 
00799    virtual GURL     id_to_url(const DjVuPort * source, const GUTF8String &id);
00800    virtual GP<DjVuFile> id_to_file(const DjVuPort * source, const GUTF8String &id);
00801    virtual GP<DataPool> request_data(const DjVuPort * source, const GURL & url);
00802    virtual void     notify_file_flags_changed(const DjVuFile * source,
00803             long set_mask, long clr_mask);
00804 
00805    virtual GList<GURL>  get_url_names(void);
00806    virtual void     set_recover_errors(ErrorRecoveryAction=ABORT);
00807    virtual void     set_verbose_eof(bool=true);
00808 
00809    static void set_compress_codec(
00810      void (*codec)(GP<ByteStream> &, const GURL &where, bool bundled));
00811 
00812    static void set_import_codec(
00813      void (*codec)(GP<DataPool> &,const GURL &url,bool &, bool &));
00814 
00815 protected:
00816    static void (*djvu_import_codec) (
00817      GP<DataPool> &pool, const GURL &url,bool &needs_compression, bool &needs_rename );
00818    static void (*djvu_compress_codec) (
00819      GP<ByteStream> &bs, const GURL &where, bool bundled);
00820    virtual GP<DjVuFile> url_to_file(const GURL & url, bool dont_create=false) const;
00821    GURL         init_url;
00822    GP<DataPool>     init_data_pool;
00823    GP<DjVmDir>      djvm_dir;   
00824    GP<DjVmNav>          djvm_nav;
00825    int  doc_type;
00826    bool needs_compression_flag;
00827    bool can_compress_flag;
00828    bool needs_rename_flag;
00829 
00830    
00831 
00832    bool         has_url_names;
00833    GCriticalSection url_names_lock;
00834    GList<GURL>  url_names;
00835    ErrorRecoveryAction  recover_errors;
00836    bool         verbose_eof;
00837 public:
00838    class UnnamedFile; 
00839    class ThumbReq; 
00840 protected:
00841    bool                 init_started;
00842    GSafeFlags       flags;
00843    GSafeFlags       init_thread_flags;
00844    DjVuFileCache    * cache;
00845    GP<DjVuSimplePort>   simple_port;
00846 
00847    GP<DjVmDir0>     djvm_dir0;  
00848    GP<DjVuNavDir>   ndir;       
00849    GUTF8String      first_page_name;
00850 
00851       
00852       
00853       
00854       
00855    GP<DjVuFile>     ndir_file;
00856    
00857    GPList<UnnamedFile>  ufiles_list;
00858    GCriticalSection ufiles_lock;
00859 
00860    GPList<ThumbReq> threqs_list;
00861    GCriticalSection threqs_lock;
00862 
00863    GP<DjVuDocument> init_life_saver;
00864 
00865    static const float   thumb_gamma;
00866 
00867       
00868       
00869    GThread      init_thr;
00870    static void      static_init_thread(void *);
00871    void         init_thread(void);
00872 
00873    void                 check() const;
00874 
00875    void         process_threqs(void);
00876    GP<ThumbReq>     add_thumb_req(const GP<ThumbReq> & thumb_req);
00877       
00878    void         add_to_cache(const GP<DjVuFile> & f);
00879    void         check_unnamed_files(void);
00880    GUTF8String      get_int_prefix(void) const;
00881    void         set_file_aliases(const DjVuFile * file);
00882    GURL         invent_url(const GUTF8String &name) const;
00883 };
00884 
00885 class DjVuDocument::UnnamedFile : public GPEnabled
00886 {
00887 public:
00888    enum { ID, PAGE_NUM };
00889    int      id_type;
00890    GUTF8String      id;
00891    int      page_num;
00892    GURL     url;
00893    GP<DjVuFile> file;
00894    GP<DataPool> data_pool;
00895 protected:
00896    UnnamedFile(int xid_type, const GUTF8String &xid, int xpage_num, const GURL & xurl,
00897           const GP<DjVuFile> & xfile) :
00898       id_type(xid_type), id(xid), page_num(xpage_num), url(xurl), file(xfile) {}
00899    friend class DjVuDocument;
00900 };
00901 
00902 class DjVuDocument::ThumbReq : public GPEnabled
00903 {
00904 public:
00905    int      page_num;
00906    GP<DataPool> data_pool;
00907 
00908      
00909    GP<DjVuFile> image_file;
00910 
00911    int      thumb_chunk;
00912    GP<DjVuFile> thumb_file;
00913 protected:
00914    ThumbReq(int xpage_num, const GP<DataPool> & xdata_pool) :
00915       page_num(xpage_num), data_pool(xdata_pool) {}
00916    friend class DjVuDocument;
00917 };
00918 
00919 inline void
00920 DjVuDocument::init(const GURL &url, GP<DjVuPort> port, DjVuFileCache *cache)
00921 {
00922   start_init(url,port,cache);
00923   wait_for_complete_init();
00924 }
00925 
00926 inline GP<DjVuDocument>
00927 DjVuDocument::create(
00928   const GURL &url, GP<DjVuPort> xport, DjVuFileCache * const xcache)
00929 {
00930   DjVuDocument *doc=new DjVuDocument;
00931   GP<DjVuDocument> retval=doc;
00932   doc->start_init(url,xport,xcache);
00933   return retval;
00934 }
00935 
00936 inline bool
00937 DjVuDocument::is_init_complete(void) const
00938 {
00939    return (flags & (DOC_INIT_OK | DOC_INIT_FAILED))!=0;
00940 }
00941 
00942 inline bool
00943 DjVuDocument::is_init_ok(void) const
00944 {
00945    return (flags & DOC_INIT_OK)!=0;
00946 }
00947 
00948 inline void
00949 DjVuDocument::set_needs_compression(void)
00950 {
00951    needs_compression_flag=true;
00952 }
00953 
00954 inline bool
00955 DjVuDocument::needs_compression(void) const
00956 {
00957    return needs_compression_flag;
00958 }
00959 
00960 inline bool
00961 DjVuDocument::needs_rename(void) const
00962 {
00963    return needs_rename_flag;
00964 }
00965 
00966 inline bool
00967 DjVuDocument::can_compress(void) const
00968 {
00969    return can_compress_flag;
00970 }
00971 
00972 inline bool
00973 DjVuDocument::is_init_failed(void) const
00974 {
00975    return (flags & DOC_INIT_FAILED)!=0;
00976 }
00977 
00978 inline int
00979 DjVuDocument::get_doc_type(void) const { return doc_type; }
00980 
00981 inline long
00982 DjVuDocument::get_doc_flags(void) const { return flags; }
00983 
00984 inline bool
00985 DjVuDocument::is_bundled(void) const
00986 {
00987    return doc_type==BUNDLED || doc_type==OLD_BUNDLED;
00988 }
00989 
00990 inline GURL
00991 DjVuDocument::get_init_url(void) const { return init_url; }
00992 
00993 inline GP<DataPool>
00994 DjVuDocument::get_init_data_pool(void) const { return init_data_pool; }
00995 
00996 inline bool
00997 DjVuDocument::inherits(const GUTF8String &class_name) const
00998 {
00999    return
01000       (GUTF8String("DjVuDocument") == class_name) ||
01001       DjVuPort::inherits(class_name);
01002 
01003 
01004 }
01005 
01006 inline float
01007 DjVuDocument::get_thumbnails_gamma(void) const
01008 {
01009    return thumb_gamma;
01010 }
01011 
01012 inline DjVuFileCache *
01013 DjVuDocument::get_cache(void) const
01014 {
01015    return cache;
01016 }
01017 
01018 inline GP<DjVmDir>
01019 DjVuDocument::get_djvm_dir(void) const
01020 {
01021    if (doc_type==SINGLE_PAGE)
01022       G_THROW( ERR_MSG("DjVuDocument.no_dir") );
01023    if (doc_type!=BUNDLED && doc_type!=INDIRECT)
01024       G_THROW( ERR_MSG("DjVuDocument.obsolete") );
01025    return djvm_dir;
01026 }
01027 
01028 inline GP<DjVmNav>
01029 DjVuDocument::get_djvm_nav(void) const
01030 {
01031   if (doc_type==BUNDLED || doc_type==INDIRECT)
01032     return djvm_nav;
01033   return 0;
01034 }
01035 
01036 inline GP<DjVmDir0>
01037 DjVuDocument::get_djvm_dir0(void) const
01038 {
01039    if (doc_type!=OLD_BUNDLED)
01040       G_THROW( ERR_MSG("DjVuDocument.old_bundle") );
01041    return djvm_dir0;
01042 }
01043 
01044 inline GP<DjVuNavDir>
01045 DjVuDocument::get_nav_dir(void) const
01046 {
01047    return ndir;
01048 }
01049 
01050 inline void
01051 DjVuDocument::set_recover_errors(ErrorRecoveryAction recover)
01052 {
01053   recover_errors=recover;
01054 }
01055 
01056 inline void
01057 DjVuDocument::set_verbose_eof(bool verbose)
01058 {
01059   verbose_eof=verbose;
01060 }
01061 
01063 
01064 
01065 #ifdef HAVE_NAMESPACES
01066 }
01067 # ifndef NOT_USING_DJVU_NAMESPACE
01068 using namespace DJVU;
01069 # endif
01070 #endif
01071 #endif