root/OpenSceneGraph/trunk/src/osgPlugins/3ds/chunk.cpp @ 10076

Revision 10076, 5.4 kB (checked in by robert, 4 years ago)

From Neil Hughes, converted across to use istream for reading data from file to enable reading .3ds files over http (use OSG's libcurl plugin).

From Robert Osfield, ammendments of the above to better support reading of files from local directories.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
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$
21 */
22#define LIB3DS_EXPORT
23#include "chunk.h"
24#include "readwrite.h"
25#include "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
41static Lib3dsBool enable_dump=LIB3DS_FALSE;
42static Lib3dsBool enable_unknown=LIB3DS_FALSE;
43static char lib3ds_chunk_level[128]="";
44
45
46static void
47lib3ds_chunk_debug_enter(Lib3dsChunk *)
48{
49  strcat(lib3ds_chunk_level, "  ");
50}
51
52
53static void
54lib3ds_chunk_debug_leave(Lib3dsChunk *)
55{
56  lib3ds_chunk_level[strlen(lib3ds_chunk_level)-2]=0;
57}
58
59
60static void
61lib3ds_chunk_debug_dump(Lib3dsChunk *c)
62{
63  if (enable_dump) {
64    printf("%s%s (0x%X) size=%u\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 */
77void
78lib3ds_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 */
95Lib3dsBool
96lib3ds_chunk_read(Lib3dsChunk *c, iostream *strm)
97{
98  ASSERT(c);
99  ASSERT(strm);
100  c->cur=strm->tellg();           
101  c->chunk=lib3ds_word_read(strm);
102  c->size=lib3ds_dword_read(strm);
103  c->end=c->cur+c->size;
104  c->cur+=6;
105
106  if (strm->fail()||(c->size<6)) {   
107    return(LIB3DS_FALSE);
108  }
109  return(LIB3DS_TRUE);
110}
111
112
113/*!
114 * \ingroup chunk
115 */
116Lib3dsBool
117lib3ds_chunk_read_start(Lib3dsChunk *c, Lib3dsWord chunk, iostream *strm)
118{
119  ASSERT(c);
120  ASSERT(strm);
121  if (!lib3ds_chunk_read(c, strm)) {
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 */
132void
133lib3ds_chunk_read_tell(Lib3dsChunk *c, iostream *strm)
134{
135    c->cur=strm->tellg();
136}
137
138
139/*!
140 * \ingroup chunk
141 */
142Lib3dsWord
143lib3ds_chunk_read_next(Lib3dsChunk *c, iostream *strm)
144{
145  Lib3dsChunk d;
146
147  if (c->cur>=c->end) {
148    ASSERT(c->cur==c->end);
149    return(0);
150  }
151
152  strm->seekg((long)c->cur,ios_base::beg);
153  d.chunk=lib3ds_word_read(strm);
154  d.size=lib3ds_dword_read(strm);
155  lib3ds_chunk_debug_dump(&d);
156  c->cur+=d.size;
157  return(d.chunk);
158}
159
160
161/*!
162 * \ingroup chunk
163 */
164void
165lib3ds_chunk_read_reset(Lib3dsChunk *, iostream *strm)
166
167  strm->seekg(-6,ios_base::cur);
168}
169
170
171/*!
172 * \ingroup chunk
173 */
174void
175lib3ds_chunk_read_end(Lib3dsChunk *c, iostream *strm)
176{
177  lib3ds_chunk_debug_leave(c);
178  strm->seekg(c->end,ios_base::beg);
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 */
192Lib3dsBool
193lib3ds_chunk_write(Lib3dsChunk *c, iostream *strm)
194{
195  ASSERT(c);
196  if (!lib3ds_word_write(c->chunk, strm)) {
197    LIB3DS_ERROR_LOG;
198    return(LIB3DS_FALSE);
199  }
200  if (!lib3ds_dword_write(c->size, strm)) {
201    LIB3DS_ERROR_LOG;
202    return(LIB3DS_FALSE);
203  }
204  return(LIB3DS_TRUE);
205}
206
207
208/*!
209 * \ingroup chunk
210 */
211Lib3dsBool
212lib3ds_chunk_write_start(Lib3dsChunk *c, iostream *strm)
213{
214  ASSERT(c);
215  c->size=0;
216  c->cur=strm->tellp();
217  if (!lib3ds_word_write(c->chunk, strm)) {
218    return(LIB3DS_FALSE);
219  }
220  if (!lib3ds_dword_write(c->size, strm)) {
221    return(LIB3DS_FALSE);
222  }
223  return(LIB3DS_TRUE);
224}
225
226
227/*!
228 * \ingroup chunk
229 */
230Lib3dsBool
231lib3ds_chunk_write_end(Lib3dsChunk *c, iostream *strm)
232{
233  ASSERT(c);
234  c->size=(Lib3dsDword)(strm->tellp()) - c->cur;
235  strm->seekp(c->cur+2,ios_base::beg); 
236  if (!lib3ds_dword_write(c->size, strm)) {
237    LIB3DS_ERROR_LOG;
238    return(LIB3DS_FALSE);
239  }
240
241  c->cur+=c->size;
242  strm->seekp(c->cur, ios_base::beg);
243  if (strm->fail()) {
244    LIB3DS_ERROR_LOG;
245    return(LIB3DS_FALSE);
246  }
247  return(LIB3DS_TRUE);
248}
249
250
251/*!
252 * \ingroup chunk
253 */
254const char*
255lib3ds_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 */
271void
272lib3ds_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 */
287void 
288lib3ds_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
Note: See TracBrowser for help on using the browser.