C:/jkyprian/devel/lib3ds/lib3ds/chunk.c

00001 /*
00002  * The 3D Studio File Format Library
00003  * Copyright (C) 1996-2007 by Jan Eric Kyprianidis <www.kyprianidis.com>
00004  * All rights reserved.
00005  *
00006  * This program is  free  software;  you can redistribute it and/or modify it
00007  * under the terms of the  GNU Lesser General Public License  as published by 
00008  * the  Free Software Foundation;  either version 2.1 of the License,  or (at 
00009  * your option) any later version.
00010  *
00011  * This  program  is  distributed in  the  hope that it will  be useful,  but
00012  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
00013  * or  FITNESS FOR A  PARTICULAR PURPOSE.  See the  GNU Lesser General Public  
00014  * License for more details.
00015  *
00016  * You should  have received  a copy of the GNU Lesser General Public License
00017  * along with  this program;  if not, write to the  Free Software Foundation,
00018  * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  *
00020  * $Id: chunk.c,v 1.18 2007/06/20 17:04:08 jeh Exp $
00021  */
00022 #include <lib3ds/chunk.h>
00023 #include <lib3ds/io.h>
00024 #include <lib3ds/chunktable.h>
00025 #include <string.h>
00026 #include <stdarg.h>
00027 
00028 
00029 /*#define LIB3DS_CHUNK_DEBUG*/
00030 /*#define LIB3DS_CHUNK_WARNING*/
00031 
00032 
00038 static Lib3dsBool enable_dump=LIB3DS_FALSE;
00039 static Lib3dsBool enable_unknown=LIB3DS_FALSE;
00040 static char lib3ds_chunk_level[128]="";
00041 
00042 
00043 static void
00044 lib3ds_chunk_debug_enter(Lib3dsChunk *c)
00045 {
00046   strcat(lib3ds_chunk_level, "  ");
00047 }
00048 
00049 
00050 static void
00051 lib3ds_chunk_debug_leave(Lib3dsChunk *c)
00052 {
00053   lib3ds_chunk_level[strlen(lib3ds_chunk_level)-2]=0;
00054 }
00055 
00056 
00057 static void
00058 lib3ds_chunk_debug_dump(Lib3dsChunk *c)
00059 {
00060   if (enable_dump) {
00061     printf("%s%s (0x%X) size=%lu\n",
00062       lib3ds_chunk_level,
00063       lib3ds_chunk_name(c->chunk),
00064       c->chunk,
00065       c->size
00066     );
00067   }
00068 }
00069 
00070 
00074 void
00075 lib3ds_chunk_enable_dump(Lib3dsBool enable, Lib3dsBool unknown)
00076 {
00077   enable_dump=enable;
00078   enable_unknown=unknown;
00079 }
00080 
00081 
00092 Lib3dsBool
00093 lib3ds_chunk_read(Lib3dsChunk *c, Lib3dsIo *io)
00094 {
00095   ASSERT(c);
00096   ASSERT(io);
00097   c->cur=lib3ds_io_tell(io);
00098   c->chunk=lib3ds_io_read_word(io);
00099   c->size=lib3ds_io_read_dword(io);
00100   c->end=c->cur+c->size;
00101   c->cur+=6;
00102   if (lib3ds_io_error(io) || (c->size<6)) {
00103     return(LIB3DS_FALSE);
00104   }
00105   return(LIB3DS_TRUE);
00106   
00107 }
00108 
00109 
00113 Lib3dsBool
00114 lib3ds_chunk_read_start(Lib3dsChunk *c, Lib3dsWord chunk, Lib3dsIo *io)
00115 {
00116   ASSERT(c);
00117   ASSERT(io);
00118   if (!lib3ds_chunk_read(c, io)) {
00119     return(LIB3DS_FALSE);
00120   }
00121   lib3ds_chunk_debug_enter(c);
00122   return((chunk==0) || (c->chunk==chunk));
00123 }
00124 
00125 
00129 void
00130 lib3ds_chunk_read_tell(Lib3dsChunk *c, Lib3dsIo *io)
00131 {
00132   c->cur=lib3ds_io_tell(io);
00133 }
00134 
00135 
00139 Lib3dsWord
00140 lib3ds_chunk_read_next(Lib3dsChunk *c, Lib3dsIo *io)
00141 {
00142   Lib3dsChunk d;
00143 
00144   if (c->cur>=c->end) {
00145     ASSERT(c->cur==c->end);
00146     return(0);
00147   }
00148 
00149   lib3ds_io_seek(io, (long)c->cur, LIB3DS_SEEK_SET);
00150   d.chunk=lib3ds_io_read_word(io);
00151   d.size=lib3ds_io_read_dword(io);
00152   lib3ds_chunk_debug_dump(&d);
00153   c->cur+=d.size;
00154   return(d.chunk);
00155 }
00156 
00157 
00161 void
00162 lib3ds_chunk_read_reset(Lib3dsChunk *c, Lib3dsIo *io)
00163 {
00164   lib3ds_io_seek(io, -6, LIB3DS_SEEK_CUR);
00165 }
00166 
00167 
00171 void
00172 lib3ds_chunk_read_end(Lib3dsChunk *c, Lib3dsIo *io)
00173 {
00174   lib3ds_chunk_debug_leave(c);
00175   lib3ds_io_seek(io, c->end, LIB3DS_SEEK_SET);
00176 }
00177 
00178 
00189 Lib3dsBool
00190 lib3ds_chunk_write(Lib3dsChunk *c, Lib3dsIo *io)
00191 {
00192   ASSERT(c);
00193   if (!lib3ds_io_write_word(io, c->chunk)) {
00194     LIB3DS_ERROR_LOG;
00195     return(LIB3DS_FALSE);
00196   }
00197   if (!lib3ds_io_write_dword(io, c->size)) {
00198     LIB3DS_ERROR_LOG;
00199     return(LIB3DS_FALSE);
00200   }
00201   return(LIB3DS_TRUE);
00202 }
00203 
00204 
00208 Lib3dsBool
00209 lib3ds_chunk_write_start(Lib3dsChunk *c, Lib3dsIo *io)
00210 {
00211   ASSERT(c);
00212   c->size=0;
00213   c->cur=lib3ds_io_tell(io);
00214   if (!lib3ds_io_write_word(io, c->chunk)) {
00215     return(LIB3DS_FALSE);
00216   }
00217   if (!lib3ds_io_write_dword(io, c->size)) {
00218     return(LIB3DS_FALSE);
00219   }
00220   return(LIB3DS_TRUE);
00221 }
00222 
00223 
00227 Lib3dsBool
00228 lib3ds_chunk_write_end(Lib3dsChunk *c, Lib3dsIo *io)
00229 {
00230   ASSERT(c);
00231   c->size=lib3ds_io_tell(io) - c->cur;
00232   lib3ds_io_seek(io, c->cur+2, LIB3DS_SEEK_SET);
00233   if (!lib3ds_io_write_dword(io, c->size)) {
00234     LIB3DS_ERROR_LOG;
00235     return(LIB3DS_FALSE);
00236   }
00237 
00238   c->cur+=c->size;
00239   lib3ds_io_seek(io, c->cur, LIB3DS_SEEK_SET);
00240   if (lib3ds_io_error(io)) {
00241     LIB3DS_ERROR_LOG;
00242     return(LIB3DS_FALSE);
00243   }
00244   return(LIB3DS_TRUE);
00245 }
00246 
00247 
00251 Lib3dsBool
00252 lib3ds_chunk_write_switch(Lib3dsWord chunk, Lib3dsIo *io)
00253 {
00254   Lib3dsChunk c;
00255   c.chunk=chunk;
00256   c.size=6;
00257   return lib3ds_chunk_write(&c,io);
00258 }
00259 
00260 
00264 const char*
00265 lib3ds_chunk_name(Lib3dsWord chunk)
00266 {
00267   Lib3dsChunkTable *p;
00268 
00269   for (p=lib3ds_chunk_table; p->name!=0; ++p) {
00270     if (p->chunk==chunk) {
00271       return(p->name);
00272     }
00273   }
00274   return("***UNKNOWN***");
00275 }
00276 
00277 
00281 void
00282 lib3ds_chunk_unknown(Lib3dsWord chunk)
00283 {
00284   if (enable_unknown) {
00285     printf("%s***WARNING*** Unknown Chunk: %s (0x%X)\n",
00286       lib3ds_chunk_level,
00287       lib3ds_chunk_name(chunk),
00288       chunk
00289     );
00290   }
00291 }
00292 
00293 
00297 void 
00298 lib3ds_chunk_dump_info(const char *format, ...)
00299 {
00300   if (enable_dump) {
00301     char s[1024];
00302     va_list marker;
00303 
00304     va_start(marker, format);
00305     vsprintf(s, format, marker);
00306     va_end(marker);
00307 
00308     printf("%s%s\n", lib3ds_chunk_level, s);
00309   }
00310 }
00311 
00312 
00313 
00314 
00315 
00316 
00317 

Hosted by
SourceForge.net Logo
Generated at Wed Jun 20 18:51:36 2007 by Doxygen 1.5.2