source: trunk/libdjvu/GIFFManager.h @ 76

Last change on this file since 76 was 17, checked in by Eugene Romanenko, 16 years ago

update makefiles, remove absolute paths, update djvulibre to version 3.5.17

File size: 15.8 KB
Line 
1//C-  -*- C++ -*-
2//C- -------------------------------------------------------------------
3//C- DjVuLibre-3.5
4//C- Copyright (c) 2002  Leon Bottou and Yann Le Cun.
5//C- Copyright (c) 2001  AT&T
6//C-
7//C- This software is subject to, and may be distributed under, the
8//C- GNU General Public License, Version 2. The license should have
9//C- accompanied the software or you may obtain a copy of the license
10//C- from the Free Software Foundation at http://www.fsf.org .
11//C-
12//C- This program is distributed in the hope that it will be useful,
13//C- but WITHOUT ANY WARRANTY; without even the implied warranty of
14//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15//C- GNU General Public License for more details.
16//C-
17//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library
18//C- distributed by Lizardtech Software.  On July 19th 2002, Lizardtech
19//C- Software authorized us to replace the original DjVu(r) Reference
20//C- Library notice by the following text (see doc/lizard2002.djvu):
21//C-
22//C-  ------------------------------------------------------------------
23//C- | DjVu (r) Reference Library (v. 3.5)
24//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved.
25//C- | The DjVu Reference Library is protected by U.S. Pat. No.
26//C- | 6,058,214 and patents pending.
27//C- |
28//C- | This software is subject to, and may be distributed under, the
29//C- | GNU General Public License, Version 2. The license should have
30//C- | accompanied the software or you may obtain a copy of the license
31//C- | from the Free Software Foundation at http://www.fsf.org .
32//C- |
33//C- | The computer code originally released by LizardTech under this
34//C- | license and unmodified by other parties is deemed "the LIZARDTECH
35//C- | ORIGINAL CODE."  Subject to any third party intellectual property
36//C- | claims, LizardTech grants recipient a worldwide, royalty-free,
37//C- | non-exclusive license to make, use, sell, or otherwise dispose of
38//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the
39//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU
40//C- | General Public License.   This grant only confers the right to
41//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to
42//C- | the extent such infringement is reasonably necessary to enable
43//C- | recipient to make, have made, practice, sell, or otherwise dispose
44//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to
45//C- | any greater extent that may be necessary to utilize further
46//C- | modifications or combinations.
47//C- |
48//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY
49//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
50//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF
51//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
52//C- +------------------------------------------------------------------
53//
54// $Id: GIFFManager.h,v 1.8 2003/11/07 22:08:21 leonb Exp $
55// $Name:  $
56
57#ifndef _GIFFMANAGER_H
58#define _GIFFMANAGER_H
59#ifdef HAVE_CONFIG_H
60#include "config.h"
61#endif
62#if NEED_GNUG_PRAGMAS
63# pragma interface
64#endif
65
66
67#include "IFFByteStream.h"
68#include "GContainer.h"
69#include "Arrays.h"
70#include "GSmartPointer.h"
71#include "GString.h"
72
73#ifdef HAVE_NAMESPACES
74namespace DJVU {
75# ifdef NOT_DEFINED // Just to fool emacs c++ mode
76}
77#endif
78#endif
79
80
81/** @name GIFFManager.h
82
83    Files #"GIFFManager.h"# and #"GIFFManager.cpp"# define more convenient
84    interface to IFF files. You may want to use the {\Ref GIFFManager} class
85    instead of coping with {\Ref IFFByteStream} especially when you have to
86    insert or move chunks, which is a kind of tricky with sequential access
87    provided by {\Ref IFFByteStream}.
88
89    You will mostly deal with {\Ref GIFFManager} class, but sometimes you may
90    want to use {\Ref GIFFChunk}s as well thus bypassing {\Ref GIFFManager}'s
91    interface and working with the chunks hierarchy yourself.
92   
93    Interface to IFF files.
94    @author
95    Andrei Erofeev <eaf@geocities.com> -- Initial implementation.
96    @version
97    #$Id: GIFFManager.h,v 1.8 2003/11/07 22:08:21 leonb Exp $# */
98
99/** #GIFFChunk# is the base class for other IFF chunks understood by
100    {\Ref GIFFManager}. It provides some basic interface, and is not supposed
101    to be used on its own. */
102
103class GIFFChunk : public GPEnabled
104{
105protected:
106   GIFFChunk(void);
107   GIFFChunk(const GUTF8String &name);
108   GIFFChunk(const GUTF8String &name, const TArray<char> & data);
109public:
110      /// Default creator.
111   static GP<GIFFChunk> create(void) {return new GIFFChunk();}
112
113      /** Creates the chunk with the given name. The {\em name} may not
114          contain dots colons or brackets */
115   static GP<GIFFChunk> create(const GUTF8String &name)
116   {return new GIFFChunk(name);}
117
118      /** Creates the {\em plain chunk} containing raw data */
119   static GP<GIFFChunk> create(const GUTF8String &name, const TArray<char> & data)
120   { return new GIFFChunk(name,data); }
121
122      /// Destructor
123   virtual ~GIFFChunk(void);
124
125      /// Returns the name of the chunk (without possible #FORM:# or similar prefixes)
126   GUTF8String  get_name(void) const;
127      /// Returns full chunk name, with possible container specification
128   GUTF8String  get_full_name(void) const;
129      /// Returns the chunk type, like #CAT# for chunk #CAT:DJVU#
130   GUTF8String  get_type(void) const;
131      /// Returns TRUE if the chunk may contain other chunks or FALSE otherwise
132   bool         is_container(void) const;
133      /** Sets the chunk name. The {\em name} may not contain dots or brackets,
134          but {\bf may} contain colons. */
135   void         set_name(GUTF8String name);
136      /** Parses the {\em name} probably containing colon and compares it
137          with its own name returning TRUE if they are the same */
138   bool         check_name(GUTF8String name);
139
140      /** Adds the {\em chunk} to the chunks list at position {\em order}.
141          Set {\em order} to #-1# to append the chunk to the list.
142          {\bf Note!} By adding chunk #PROP# you will convert this chunk
143          to type #LIST# {\em automatically}. */
144   void         add_chunk(const GP<GIFFChunk> & chunk, int order=-1);
145      /** Removes the chunk with given {\em name}. The {\em name} may not
146          contain dots, but MAY contain colons and brackets (the latter -
147          for specifying the chunk number) */
148   void         del_chunk(const GUTF8String &name);
149      /** Returns the chunk with given {\em name}. The {\em name} may not
150          contain dots, but MAY contain colons and brackets (the latter -
151          for specifying the chunk number). If {\em position} is not zero
152          then the chunk position in its parent will be put into #*position# */
153   GP<GIFFChunk>get_chunk(const GUTF8String &name, int * position=0);
154      /** Returns the number of chunks with given {\em name}. The {\em name}
155          may not contain dots and brackets. If {\em name} is ZERO, the
156          total number of chunks will be returned. */
157   int          get_chunks_number(const GUTF8String &name);
158   int          get_chunks_number(void);
159      /** Returns the data array for plain chunks */
160   TArray<char> get_data(void) const;
161   
162      /** Saves the chunk into the {\Ref IFFByteStream}.
163          Set {\em use_trick} to #1# if this is a top-level chunk */
164   void         save(IFFByteStream & istr, bool use_trick=0);
165private:
166   char                 name[5];
167   GUTF8String          type;
168   GPList<GIFFChunk>    chunks;
169   TArray<char>         data;
170   static GUTF8String decode_name(const GUTF8String &name, int &number);
171};
172
173inline GUTF8String
174GIFFChunk::get_name(void) const { return GUTF8String(name, 4); }
175
176inline GUTF8String
177GIFFChunk::get_type(void) const { return type; };
178
179inline GUTF8String
180GIFFChunk::get_full_name(void) const { return get_type()+":"+get_name(); };
181
182inline bool
183GIFFChunk::is_container(void) const { return type.length()!=0; };
184
185inline TArray<char>
186GIFFChunk::get_data(void) const { return data; };
187
188inline
189GIFFChunk::GIFFChunk(void) { name[0]=0; }
190
191inline
192GIFFChunk::GIFFChunk(const GUTF8String &name) { set_name(name); }
193
194inline
195GIFFChunk::GIFFChunk(const GUTF8String &name, const TArray<char> & data_in) :
196      data(data_in)
197{
198   set_name(name);
199}
200
201//************************************************************************
202
203/** Intuitive interface to IFF files.
204
205    It's too terrible to keep reading/writing IFF files chunk after chunk
206    using {\Ref IFFByteStream}s. This class allows you to operate with chunks
207    as with structures or arrays without even caring about the byte streams.
208
209    Some of the examples are below:
210    \begin{verbatim}
211       GP<GIFFChunk> chunk;
212       chunk=manager1.get_chunk("BG44[2]");
213       manager2.add_chunk(".FORM:DJVU.BG44[-1]", chunk);
214    \end{verbatim}
215
216    {\bf Chunk name}
217    \begin{itemize}
218       \item Every chunk name may contain optional prefix #FORM:#, #LIST:#,
219             #PROP:# or #CAT:#. If the prefix is omitted and the chunk happens
220             to contain other chunks, #FORM:# will be assumed.
221       \item Every chunk name may be {\em short} or {\em complete}.
222             {\em short} chunk names may not contain dots as they're a
223             subchunks names with respect to a given chunk.
224             {\em complete} chunk names may contain dots. But there may be
225             or may not be the {\em leading dot} in the name. If the
226             {\em leading dot} is present, then the name is assumed to contain
227             the name of the top-level chunk as well. Otherwise it's treated
228             {\em with respect} to the top-level chunk. You may want to use
229             the leading dot only when you add a chunk to an empty document,
230             since a command like #manager.addChunk(".FORM:DJVU.BG44", chunk)#
231             will create the top level chunk of the requested type (#FORM:DJVU#)
232             and will add chunk #BG44# to it {\em automatically}.
233       \item You may use {\em brackets} in the name to specify the chunk's
234             position. The meaning of the number inside the brackets depends
235             on the function you call. In most of the cases this is the number
236             of the chunk with the given name in the parent chunk. But sometimes
237             (as in #addChunk(name, buffer, length)#) the brackets at the
238             end of the #name# actually specify the {\em position} of the
239             chunk in the parent. For example, to insert #INCL# chunk into
240             #DJVU# form at position #1# (make it the second) you may want to
241             use #manager.addChunk(".DJVU.INCL[1]", data, size)#. At the same
242             time, to get 2-nd chunk with name #BG44# from form #DJVU# you
243             should do smth like #chunk=manager.getChunk("BG44[1]")#. Note, that
244             here the manager will search for chunk #BG44# in form #DJVU# and
245             will take the second {\em found} one.
246    \end{itemize} */
247
248class GIFFManager : public GPEnabled
249{
250protected:
251   GIFFManager(void);
252   void init(void);
253   void init(const GUTF8String &name);
254public:
255      /// Default creator.
256   static GP<GIFFManager> create(void);
257
258      /** Creates the {\Ref GIFFManager} and assigns name {\em name} to
259          the top-level chunk. you may use chunk type names (before colon)
260          to set the top-level chunk type, or omit it to work with #FORM# */
261   static GP<GIFFManager> create(const GUTF8String &name);
262
263      /// Virtual destructor.
264   virtual ~GIFFManager(void);
265
266      /// Sets the name of the top level chunk to {\em name}
267   void         set_name(const GUTF8String &name);
268      /** Adds the chunk {\em chunk} to chunk with name {\em parent_name} at
269          position {\em pos}. {\em parent_name} may contain dots, brackets
270          and colons. All missing chunks in the chain will be created.
271
272          {\bf Examples:}
273          \begin{verbatim}
274             ;; To set the top-level chunk to 'ch'
275             m.addChunk(".", ch);
276             ;; To add 'ch' to the top-level chunk "DJVU" creating it if necessary
277             m.addChunk(".DJVU", ch);
278             ;; Same as above regardless of top-level chunk name
279             m.addChunk("", ch);
280             ;; To add 'ch' to 2nd FORM DJVU in top-level form DJVM
281             m.addChunk(".FORM:DJVM.FORM:DJVU[1]", ch);
282             ;; Same thing regardless of the top-level chunk name
283             m.addChunk("FORM:DJVU[1]", ch);
284          \end{verbatim} */
285   void         add_chunk(GUTF8String parent_name, const GP<GIFFChunk> & chunk, int pos=-1);
286      /** If {\em name}={\em name1}.{\em name2} where {\em name2} doesn't
287          contain dots, then #addChunk()# will create plain chunk with
288          name {\em name2} with data {\em buffer} of size {\em length} and
289          will add it to chunk {\em name1} in the same way as
290          #addChunk(name, chunk, pos)# function would do it. The #pos# in
291          this case is either #-1# (append) or is extracted from between
292          brackets if the {\em name} ends with them.
293         
294          {\bf Examples:}
295          \begin{verbatim}
296             ;; To insert INCL chunk at position 2 (make it 3rd)
297             m.addChunk("INCL[2]", data, length);
298             ;; To append chunk BG44 to 2nd DjVu file inside DjVm archive:
299             m.addChunk(".DJVM.DJVU[1].BG44", data, length);
300          \end{verbatim} */
301   void         add_chunk(GUTF8String name, const TArray<char> & data);
302      /** Will remove chunk with name {\em name}. You may use dots, colons
303          and brackets to specify the chunk uniquely.
304
305          {\bf Examples:}
306          \begin{verbatim}
307             ;; To remove 2nd DjVu document from DjVm archive use
308             m.delChunk(".DJVM.DJVU[1]");
309             ;; Same thing without top-level chunk name specification
310             m.delChunk("DJVU[1]");
311             ;; Same thing for the first DJVU chunk
312             m.delChunk("DJVU");
313          \end{verbatim}
314      */
315   void         del_chunk(GUTF8String name);
316   void         del_chunk(void);
317      /** Will return the number of chunks with given name. The {\em name} may
318          not end with brackets, but may contain them inside. It may also
319          contain dots and colons. If {\em name} is ZERO, the total number
320          of chunks will be returned.
321
322          {\bf Examples:}
323          \begin{verbatim}
324             ;; To get the number of DJVU forms inside DjVm document
325             m.getChunksNumber(".DJVM.DJVU");
326             ;; Same thing without top-level chunk name specification
327             m.getChunksNumber("DJVU");
328          \end{verbatim}
329      */
330   int          get_chunks_number(const GUTF8String &name);
331   int          get_chunks_number(void);
332
333      /** Returns the chunk with name {\em name}. The {\em name} may contain dots
334          colons and slashes. If {\em position} is not zero, #*position# will
335          be assigned the position of the found chunk in the parent chunk.
336
337          {\bf Examples:}
338          \begin{verbatim}
339             ;; To get the directory chunk of DjVm document
340             m.getChunk(".DJVM.DIR0");
341             ;; To get chunk corresponding to 2nd DJVU form
342             m.getChunk(".DJVU[1]");
343          \end{verbatim} */
344   GP<GIFFChunk>get_chunk(GUTF8String name, int * position=0);
345
346      /** Loads the composite {\em chunk}'s contents from stream {\em istr}. */
347   void         load_chunk(IFFByteStream & istr, GP<GIFFChunk> chunk);
348      /** Loads the file contents from stream {\em str} */
349   void         load_file(GP<ByteStream> str);
350      /** Loads the file contents from the data array {\em data} */
351   void         load_file(const TArray<char> & data);
352      /** Saves all the chunks into stream {\em str} */
353   void         save_file(GP<ByteStream> str);
354      /** Saves all the chunks into the data array {\em data} */
355   void         save_file(TArray<char> & data);
356
357private:
358   GP<GIFFChunk>        top_level;
359
360   static const char *  check_leading_dot(const GUTF8String &name);
361private: //dummy methods
362   static void save_file(ByteStream *);
363   static void load_file(ByteStream *);
364};
365
366inline void
367GIFFManager::set_name(const GUTF8String &name)
368{
369   top_level->set_name(name);
370}
371
372inline
373GIFFManager::GIFFManager(void) {}
374
375inline  void
376GIFFManager::init(void)
377{
378  top_level=GIFFChunk::create();
379}
380
381inline  void
382GIFFManager::init(const GUTF8String &name)
383{
384  top_level=GIFFChunk::create(name);
385}
386
387
388#ifdef HAVE_NAMESPACES
389}
390# ifndef NOT_USING_DJVU_NAMESPACE
391using namespace DJVU;
392# endif
393#endif
394#endif
Note: See TracBrowser for help on using the repository browser.