dropped all dependencies apart from SDL into the libs subdir
[summerhack] / libs / lib3ds / chunk.c
1 /*
2  * The 3D Studio File Format Library
3  * Copyright (C) 1996-2001 by J.E. Hoffmann <je-h@gmx.net>
4  * All rights reserved.
5  *
6  * This program is  free  software;  you can redistribute it and/or modify it
7  * under the terms of the  GNU Lesser General Public License  as published by 
8  * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
9  * your option) any later version.
10  *
11  * This  program  is  distributed in  the  hope that it will  be useful,  but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13  * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
14  * License for more details.
15  *
16  * You should  have received  a copy of the GNU Lesser General Public License
17  * along with  this program;  if not, write to the  Free Software Foundation,
18  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  * $Id: chunk.c,v 1.14 2001/07/07 19:05:30 jeh Exp $
21  */
22 #define LIB3DS_EXPORT
23 #include <lib3ds/chunk.h>
24 #include <lib3ds/io.h>
25 #include <lib3ds/chunktable.h>
26 #include <string.h>
27 #include <stdarg.h>
28
29
30 /*#define LIB3DS_CHUNK_DEBUG*/
31 /*#define LIB3DS_CHUNK_WARNING*/
32
33
34 /*!
35  * \defgroup chunk Chunk Handling
36  *
37  * \author J.E. Hoffmann <je-h@gmx.net>
38  */
39
40
41 static Lib3dsBool enable_dump=LIB3DS_FALSE;
42 static Lib3dsBool enable_unknown=LIB3DS_FALSE;
43 static char lib3ds_chunk_level[128]="";
44
45
46 static void
47 lib3ds_chunk_debug_enter(Lib3dsChunk *c)
48 {
49   strcat(lib3ds_chunk_level, "  ");
50 }
51
52
53 static void
54 lib3ds_chunk_debug_leave(Lib3dsChunk *c)
55 {
56   lib3ds_chunk_level[strlen(lib3ds_chunk_level)-2]=0;
57 }
58
59
60 static void
61 lib3ds_chunk_debug_dump(Lib3dsChunk *c)
62 {
63   if (enable_dump) {
64     printf("%s%s (0x%X) size=%lu\n",
65       lib3ds_chunk_level,
66       lib3ds_chunk_name(c->chunk),
67       c->chunk,
68       c->size
69     );
70   }
71 }
72
73
74 /*!
75  * \ingroup chunk
76  */
77 void
78 lib3ds_chunk_enable_dump(Lib3dsBool enable, Lib3dsBool unknown)
79 {
80   enable_dump=enable;
81   enable_unknown=unknown;
82 }
83
84
85 /*!
86  * \ingroup chunk
87  *
88  * Reads a 3d-Studio chunk header from a little endian file stream.
89  *
90  * \param c  The chunk to store the data.
91  * \param f  The file stream.
92  *
93  * \return   True on success, False otherwise.
94  */
95 Lib3dsBool
96 lib3ds_chunk_read(Lib3dsChunk *c, Lib3dsIo *io)
97 {
98   ASSERT(c);
99   ASSERT(io);
100   c->cur=lib3ds_io_tell(io);
101   c->chunk=lib3ds_io_read_word(io);
102   c->size=lib3ds_io_read_dword(io);
103   c->end=c->cur+c->size;
104   c->cur+=6;
105   if (lib3ds_io_error(io) || (c->size<6)) {
106     return(LIB3DS_FALSE);
107   }
108   return(LIB3DS_TRUE);
109   
110 }
111
112
113 /*!
114  * \ingroup chunk
115  */
116 Lib3dsBool
117 lib3ds_chunk_read_start(Lib3dsChunk *c, Lib3dsWord chunk, Lib3dsIo *io)
118 {
119   ASSERT(c);
120   ASSERT(io);
121   if (!lib3ds_chunk_read(c, io)) {
122     return(LIB3DS_FALSE);
123   }
124   lib3ds_chunk_debug_enter(c);
125   return((chunk==0) || (c->chunk==chunk));
126 }
127
128
129 /*!
130  * \ingroup chunk
131  */
132 void
133 lib3ds_chunk_read_tell(Lib3dsChunk *c, Lib3dsIo *io)
134 {
135   c->cur=lib3ds_io_tell(io);
136 }
137
138
139 /*!
140  * \ingroup chunk
141  */
142 Lib3dsWord
143 lib3ds_chunk_read_next(Lib3dsChunk *c, Lib3dsIo *io)
144 {
145   Lib3dsChunk d;
146
147   if (c->cur>=c->end) {
148     ASSERT(c->cur==c->end);
149     return(0);
150   }
151
152   lib3ds_io_seek(io, (long)c->cur, LIB3DS_SEEK_SET);
153   d.chunk=lib3ds_io_read_word(io);
154   d.size=lib3ds_io_read_dword(io);
155   lib3ds_chunk_debug_dump(&d);
156   c->cur+=d.size;
157   return(d.chunk);
158 }
159
160
161 /*!
162  * \ingroup chunk
163  */
164 void
165 lib3ds_chunk_read_reset(Lib3dsChunk *c, Lib3dsIo *io)
166 {
167   lib3ds_io_seek(io, -6, LIB3DS_SEEK_CUR);
168 }
169
170
171 /*!
172  * \ingroup chunk
173  */
174 void
175 lib3ds_chunk_read_end(Lib3dsChunk *c, Lib3dsIo *io)
176 {
177   lib3ds_chunk_debug_leave(c);
178   lib3ds_io_seek(io, c->end, LIB3DS_SEEK_SET);
179 }
180
181
182 /*!
183  * \ingroup chunk
184  *
185  * Writes a 3d-Studio chunk header into a little endian file stream.
186  *
187  * \param c  The chunk to be written.
188  * \param f  The file stream.
189  *
190  * \return   True on success, False otherwise.
191  */
192 Lib3dsBool
193 lib3ds_chunk_write(Lib3dsChunk *c, Lib3dsIo *io)
194 {
195   ASSERT(c);
196   if (!lib3ds_io_write_word(io, c->chunk)) {
197     LIB3DS_ERROR_LOG;
198     return(LIB3DS_FALSE);
199   }
200   if (!lib3ds_io_write_dword(io, c->size)) {
201     LIB3DS_ERROR_LOG;
202     return(LIB3DS_FALSE);
203   }
204   return(LIB3DS_TRUE);
205 }
206
207
208 /*!
209  * \ingroup chunk
210  */
211 Lib3dsBool
212 lib3ds_chunk_write_start(Lib3dsChunk *c, Lib3dsIo *io)
213 {
214   ASSERT(c);
215   c->size=0;
216   c->cur=lib3ds_io_tell(io);
217   if (!lib3ds_io_write_word(io, c->chunk)) {
218     return(LIB3DS_FALSE);
219   }
220   if (!lib3ds_io_write_dword(io, c->size)) {
221     return(LIB3DS_FALSE);
222   }
223   return(LIB3DS_TRUE);
224 }
225
226
227 /*!
228  * \ingroup chunk
229  */
230 Lib3dsBool
231 lib3ds_chunk_write_end(Lib3dsChunk *c, Lib3dsIo *io)
232 {
233   ASSERT(c);
234   c->size=lib3ds_io_tell(io) - c->cur;
235   lib3ds_io_seek(io, c->cur+2, LIB3DS_SEEK_SET);
236   if (!lib3ds_io_write_dword(io, c->size)) {
237     LIB3DS_ERROR_LOG;
238     return(LIB3DS_FALSE);
239   }
240
241   c->cur+=c->size;
242   lib3ds_io_seek(io, c->cur, LIB3DS_SEEK_SET);
243   if (lib3ds_io_error(io)) {
244     LIB3DS_ERROR_LOG;
245     return(LIB3DS_FALSE);
246   }
247   return(LIB3DS_TRUE);
248 }
249
250
251 /*!
252  * \ingroup chunk
253  */
254 const char*
255 lib3ds_chunk_name(Lib3dsWord chunk)
256 {
257   Lib3dsChunkTable *p;
258
259   for (p=lib3ds_chunk_table; p->name!=0; ++p) {
260     if (p->chunk==chunk) {
261       return(p->name);
262     }
263   }
264   return("***UNKNOWN***");
265 }
266
267
268 /*!
269  * \ingroup chunk
270  */
271 void
272 lib3ds_chunk_unknown(Lib3dsWord chunk)
273 {
274   if (enable_unknown) {
275     printf("%s***WARNING*** Unknown Chunk: %s (0x%X)\n",
276       lib3ds_chunk_level,
277       lib3ds_chunk_name(chunk),
278       chunk
279     );
280   }
281 }
282
283
284 /*!
285  * \ingroup chunk
286  */
287 void 
288 lib3ds_chunk_dump_info(const char *format, ...)
289 {
290   if (enable_dump) {
291     char s[1024];
292     va_list marker;
293
294     va_start(marker, format);
295     vsprintf(s, format, marker);
296     va_end(marker);
297
298     printf("%s%s\n", lib3ds_chunk_level, s);
299   }
300 }
301
302
303
304
305
306
307