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

Revision 10076, 5.4 kB (checked in by robert, 6 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
RevLine 
[8]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
[151]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
[8]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
[151]13 * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public 
[8]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
[1563]23#include "chunk.h"
24#include "readwrite.h"
25#include "chunktable.h"
[8]26#include <string.h>
[151]27#include <stdarg.h>
[8]28
[151]29
[8]30/*#define LIB3DS_CHUNK_DEBUG*/
31/*#define LIB3DS_CHUNK_WARNING*/
32
[151]33
[8]34/*!
35 * \defgroup chunk Chunk Handling
36 *
37 * \author J.E. Hoffmann <je-h@gmx.net>
38 */
39
[151]40
[8]41static Lib3dsBool enable_dump=LIB3DS_FALSE;
42static Lib3dsBool enable_unknown=LIB3DS_FALSE;
43static char lib3ds_chunk_level[128]="";
44
[151]45
[8]46static void
[576]47lib3ds_chunk_debug_enter(Lib3dsChunk *)
[8]48{
[151]49  strcat(lib3ds_chunk_level, "  ");
[8]50}
51
52
53static void
[576]54lib3ds_chunk_debug_leave(Lib3dsChunk *)
[8]55{
[151]56  lib3ds_chunk_level[strlen(lib3ds_chunk_level)-2]=0;
[8]57}
58
59
60static void
61lib3ds_chunk_debug_dump(Lib3dsChunk *c)
62{
[151]63  if (enable_dump) {
[5453]64    printf("%s%s (0x%X) size=%u\n",
[151]65      lib3ds_chunk_level,
66      lib3ds_chunk_name(c->chunk),
67      c->chunk,
68      c->size
69    );
70  }
[8]71}
72
73
74/*!
75 * \ingroup chunk
76 */
77void
78lib3ds_chunk_enable_dump(Lib3dsBool enable, Lib3dsBool unknown)
79{
[151]80  enable_dump=enable;
81  enable_unknown=unknown;
[8]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
[10076]96lib3ds_chunk_read(Lib3dsChunk *c, iostream *strm)
[8]97{
[151]98  ASSERT(c);
[10076]99  ASSERT(strm);
100  c->cur=strm->tellg();           
101  c->chunk=lib3ds_word_read(strm);
102  c->size=lib3ds_dword_read(strm);
[151]103  c->end=c->cur+c->size;
104  c->cur+=6;
[10076]105
106  if (strm->fail()||(c->size<6)) {   
[151]107    return(LIB3DS_FALSE);
108  }
109  return(LIB3DS_TRUE);
[8]110}
111
112
113/*!
114 * \ingroup chunk
115 */
116Lib3dsBool
[10076]117lib3ds_chunk_read_start(Lib3dsChunk *c, Lib3dsWord chunk, iostream *strm)
[8]118{
[151]119  ASSERT(c);
[10076]120  ASSERT(strm);
121  if (!lib3ds_chunk_read(c, strm)) {
[151]122    return(LIB3DS_FALSE);
123  }
124  lib3ds_chunk_debug_enter(c);
125  return((chunk==0) || (c->chunk==chunk));
[8]126}
127
128
129/*!
130 * \ingroup chunk
131 */
132void
[10076]133lib3ds_chunk_read_tell(Lib3dsChunk *c, iostream *strm)
[8]134{
[10076]135    c->cur=strm->tellg();
[8]136}
137
138
139/*!
140 * \ingroup chunk
141 */
142Lib3dsWord
[10076]143lib3ds_chunk_read_next(Lib3dsChunk *c, iostream *strm)
[8]144{
[151]145  Lib3dsChunk d;
[8]146
[151]147  if (c->cur>=c->end) {
148    ASSERT(c->cur==c->end);
149    return(0);
150  }
[8]151
[10076]152  strm->seekg((long)c->cur,ios_base::beg);
153  d.chunk=lib3ds_word_read(strm);
154  d.size=lib3ds_dword_read(strm);
[151]155  lib3ds_chunk_debug_dump(&d);
156  c->cur+=d.size;
157  return(d.chunk);
[8]158}
159
160
161/*!
162 * \ingroup chunk
163 */
164void
[10076]165lib3ds_chunk_read_reset(Lib3dsChunk *, iostream *strm)
166
167  strm->seekg(-6,ios_base::cur);
[8]168}
169
170
171/*!
172 * \ingroup chunk
173 */
174void
[10076]175lib3ds_chunk_read_end(Lib3dsChunk *c, iostream *strm)
[8]176{
[151]177  lib3ds_chunk_debug_leave(c);
[10076]178  strm->seekg(c->end,ios_base::beg);
[8]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
[10076]193lib3ds_chunk_write(Lib3dsChunk *c, iostream *strm)
[8]194{
[151]195  ASSERT(c);
[10076]196  if (!lib3ds_word_write(c->chunk, strm)) {
[151]197    LIB3DS_ERROR_LOG;
198    return(LIB3DS_FALSE);
199  }
[10076]200  if (!lib3ds_dword_write(c->size, strm)) {
[151]201    LIB3DS_ERROR_LOG;
202    return(LIB3DS_FALSE);
203  }
204  return(LIB3DS_TRUE);
[8]205}
206
207
208/*!
209 * \ingroup chunk
210 */
211Lib3dsBool
[10076]212lib3ds_chunk_write_start(Lib3dsChunk *c, iostream *strm)
[8]213{
[151]214  ASSERT(c);
215  c->size=0;
[10076]216  c->cur=strm->tellp();
217  if (!lib3ds_word_write(c->chunk, strm)) {
[151]218    return(LIB3DS_FALSE);
219  }
[10076]220  if (!lib3ds_dword_write(c->size, strm)) {
[151]221    return(LIB3DS_FALSE);
222  }
223  return(LIB3DS_TRUE);
[8]224}
225
226
227/*!
228 * \ingroup chunk
229 */
230Lib3dsBool
[10076]231lib3ds_chunk_write_end(Lib3dsChunk *c, iostream *strm)
[8]232{
[151]233  ASSERT(c);
[10076]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)) {
[151]237    LIB3DS_ERROR_LOG;
238    return(LIB3DS_FALSE);
239  }
[8]240
[151]241  c->cur+=c->size;
[10076]242  strm->seekp(c->cur, ios_base::beg);
243  if (strm->fail()) {
[151]244    LIB3DS_ERROR_LOG;
245    return(LIB3DS_FALSE);
246  }
247  return(LIB3DS_TRUE);
[8]248}
249
250
251/*!
252 * \ingroup chunk
253 */
254const char*
255lib3ds_chunk_name(Lib3dsWord chunk)
256{
[151]257  Lib3dsChunkTable *p;
[8]258
[151]259  for (p=lib3ds_chunk_table; p->name!=0; ++p) {
260    if (p->chunk==chunk) {
261      return(p->name);
[8]262    }
[151]263  }
264  return("***UNKNOWN***");
[8]265}
266
267
268/*!
269 * \ingroup chunk
270 */
271void
272lib3ds_chunk_unknown(Lib3dsWord chunk)
273{
[151]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  }
[8]281}
[151]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.