Debug messages for code blocks.
[scummvm-innocent.git] / common / iff_container.h
blobebcf9ba80329cdc003020db8f19841837c35e4ef
1 /* ScummVM - Graphic Adventure Engine
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * $URL$
22 * $Id$
25 #ifndef COMMON_IFF_CONTAINER_H
26 #define COMMON_IFF_CONTAINER_H
28 #include "common/scummsys.h"
29 #include "common/endian.h"
30 #include "common/func.h"
31 #include "common/stream.h"
32 #include "common/util.h"
34 namespace Common {
36 typedef uint32 IFF_ID;
38 #define ID_FORM MKID_BE('FORM')
39 /* EA IFF 85 group identifier */
40 #define ID_CAT MKID_BE('CAT ')
41 /* EA IFF 85 group identifier */
42 #define ID_LIST MKID_BE('LIST')
43 /* EA IFF 85 group identifier */
44 #define ID_PROP MKID_BE('PROP')
45 /* EA IFF 85 group identifier */
46 #define ID_END MKID_BE('END ')
47 /* unofficial END-of-FORM identifier (see Amiga RKM Devices Ed.3
48 page 376) */
49 #define ID_ILBM MKID_BE('ILBM')
50 /* EA IFF 85 raster bitmap form */
51 #define ID_DEEP MKID_BE('DEEP')
52 /* Chunky pixel image files (Used in TV Paint) */
53 #define ID_RGB8 MKID_BE('RGB8')
54 /* RGB image forms, Turbo Silver (Impulse) */
55 #define ID_RGBN MKID_BE('RGBN')
56 /* RGB image forms, Turbo Silver (Impulse) */
57 #define ID_PBM MKID_BE('PBM ')
58 /* 256-color chunky format (DPaint 2 ?) */
59 #define ID_ACBM MKID_BE('ACBM')
60 /* Amiga Contiguous Bitmap (AmigaBasic) */
61 #define ID_8SVX MKID_BE('8SVX')
62 /* Amiga 8 bits voice */
64 /* generic */
66 #define ID_FVER MKID_BE('FVER')
67 /* AmigaOS version string */
68 #define ID_JUNK MKID_BE('JUNK')
69 /* always ignore this chunk */
70 #define ID_ANNO MKID_BE('ANNO')
71 /* EA IFF 85 Generic Annotation chunk */
72 #define ID_AUTH MKID_BE('AUTH')
73 /* EA IFF 85 Generic Author chunk */
74 #define ID_CHRS MKID_BE('CHRS')
75 /* EA IFF 85 Generic character string chunk */
76 #define ID_NAME MKID_BE('NAME')
77 /* EA IFF 85 Generic Name of art, music, etc. chunk */
78 #define ID_TEXT MKID_BE('TEXT')
79 /* EA IFF 85 Generic unformatted ASCII text chunk */
80 #define ID_copy MKID_BE('(c) ')
81 /* EA IFF 85 Generic Copyright text chunk */
83 /* ILBM chunks */
85 #define ID_BMHD MKID_BE('BMHD')
86 /* ILBM BitmapHeader */
87 #define ID_CMAP MKID_BE('CMAP')
88 /* ILBM 8bit RGB colormap */
89 #define ID_GRAB MKID_BE('GRAB')
90 /* ILBM "hotspot" coordiantes */
91 #define ID_DEST MKID_BE('DEST')
92 /* ILBM destination image info */
93 #define ID_SPRT MKID_BE('SPRT')
94 /* ILBM sprite identifier */
95 #define ID_CAMG MKID_BE('CAMG')
96 /* Amiga viewportmodes */
97 #define ID_BODY MKID_BE('BODY')
98 /* ILBM image data */
99 #define ID_CRNG MKID_BE('CRNG')
100 /* color cycling */
101 #define ID_CCRT MKID_BE('CCRT')
102 /* color cycling */
103 #define ID_CLUT MKID_BE('CLUT')
104 /* Color Lookup Table chunk */
105 #define ID_DPI MKID_BE('DPI ')
106 /* Dots per inch chunk */
107 #define ID_DPPV MKID_BE('DPPV')
108 /* DPaint perspective chunk (EA) */
109 #define ID_DRNG MKID_BE('DRNG')
110 /* DPaint IV enhanced color cycle chunk (EA) */
111 #define ID_EPSF MKID_BE('EPSF')
112 /* Encapsulated Postscript chunk */
113 #define ID_CMYK MKID_BE('CMYK')
114 /* Cyan, Magenta, Yellow, & Black color map (Soft-Logik) */
115 #define ID_CNAM MKID_BE('CNAM')
116 /* Color naming chunk (Soft-Logik) */
117 #define ID_PCHG MKID_BE('PCHG')
118 /* Line by line palette control information (Sebastiano Vigna) */
119 #define ID_PRVW MKID_BE('PRVW')
120 /* A mini duplicate ILBM used for preview (Gary Bonham) */
121 #define ID_XBMI MKID_BE('XBMI')
122 /* eXtended BitMap Information (Soft-Logik) */
123 #define ID_CTBL MKID_BE('CTBL')
124 /* Newtek Dynamic Ham color chunk */
125 #define ID_DYCP MKID_BE('DYCP')
126 /* Newtek Dynamic Ham chunk */
127 #define ID_SHAM MKID_BE('SHAM')
128 /* Sliced HAM color chunk */
129 #define ID_ABIT MKID_BE('ABIT')
130 /* ACBM body chunk */
131 #define ID_DCOL MKID_BE('DCOL')
132 /* unofficial direct color */
133 #define ID_DPPS MKID_BE('DPPS')
134 /* ? */
135 #define ID_TINY MKID_BE('TINY')
136 /* ? */
137 #define ID_DPPV MKID_BE('DPPV')
138 /* ? */
140 /* 8SVX chunks */
142 #define ID_VHDR MKID_BE('VHDR')
143 /* 8SVX Voice8Header */
146 char * ID2string(Common::IFF_ID id);
150 * Represents a IFF chunk available to client code.
152 * Client code must *not* deallocate _stream when done.
154 struct IFFChunk {
155 Common::IFF_ID _type;
156 uint32 _size;
157 Common::ReadStream *_stream;
159 IFFChunk(Common::IFF_ID type, uint32 size, Common::ReadStream *stream) : _type(type), _size(size), _stream(stream) {
160 assert(_stream);
165 * Parser for IFF containers.
167 class IFFParser {
170 * This private class implements IFF chunk navigation.
172 class IFFChunkNav : public Common::ReadStream {
173 protected:
174 Common::ReadStream *_input;
175 uint32 _bytesRead;
176 public:
177 Common::IFF_ID id;
178 uint32 size;
180 IFFChunkNav() : _input(0) {
182 void setInputStream(Common::ReadStream *input) {
183 _input = input;
184 size = _bytesRead = 0;
186 void incBytesRead(uint32 inc) {
187 _bytesRead += inc;
188 if (_bytesRead > size) {
189 error("Chunk overread");
192 void readHeader() {
193 id = _input->readUint32BE();
194 size = _input->readUint32BE();
195 _bytesRead = 0;
197 bool hasReadAll() const {
198 return (size - _bytesRead) == 0;
200 void feed() {
201 if (size % 2) {
202 size++;
204 while (!hasReadAll()) {
205 readByte();
208 // Common::ReadStream implementation
209 bool eos() const { return _input->eos(); }
210 bool err() const { return _input->err(); }
211 void clearErr() { _input->clearErr(); }
213 uint32 read(void *dataPtr, uint32 dataSize) {
214 incBytesRead(dataSize);
215 return _input->read(dataPtr, dataSize);
219 protected:
220 IFFChunkNav _formChunk; //!< The root chunk of the file.
221 IFFChunkNav _chunk; //!< The current chunk.
223 uint32 _formSize;
224 Common::IFF_ID _formType;
226 Common::ReadStream *_stream;
227 bool _disposeStream;
229 void setInputStream(Common::ReadStream *stream) {
230 assert(stream);
231 _formChunk.setInputStream(stream);
232 _chunk.setInputStream(stream);
234 _formChunk.readHeader();
235 if (_formChunk.id != ID_FORM) {
236 error("IFFParser input is not a FORM type IFF file");
238 _formSize = _formChunk.size;
239 _formType = _formChunk.readUint32BE();
242 public:
243 IFFParser(Common::ReadStream *stream, bool disposeStream = false) : _stream(stream), _disposeStream(disposeStream) {
244 setInputStream(stream);
246 ~IFFParser() {
247 if (_disposeStream) {
248 delete _stream;
250 _stream = 0;
254 * Returns the IFF FORM type.
255 * @return the IFF FORM type of the stream, or 0 if FORM header is not found.
257 Common::IFF_ID getFORMType() const;
260 * Returns the size of the data.
261 * @return the size of the data in file, or -1 if FORM header is not found.
263 uint32 getFORMSize() const;
266 * Callback type for the parser.
268 typedef Common::Functor1< IFFChunk&, bool > IFFCallback;
271 * Parse the IFF container, invoking the callback on each chunk encountered.
272 * The callback can interrupt the parsing by returning 'true'.
274 void parse(IFFCallback &callback) {
275 bool stop;
276 do {
277 _chunk.feed();
278 _formChunk.incBytesRead(_chunk.size);
280 if (_formChunk.hasReadAll()) {
281 break;
284 _formChunk.incBytesRead(8);
285 _chunk.readHeader();
287 // invoke the callback
288 Common::SubReadStream stream(&_chunk, _chunk.size);
289 IFFChunk chunk(_chunk.id, _chunk.size, &stream);
290 stop = callback(chunk);
292 // eats up all the remaining data in the chunk
293 while (!stream.eos()) {
294 stream.readByte();
297 } while (!stop);
302 } // namespace Common
304 #endif