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

Revision 10076, 10.1 kB (checked in by robert, 5 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 "readwrite.h"
[5453]24#include <osg/Endian>
[8]25
[10076]26
[8]27/*!
28 * \defgroup readwrite Portable Binary Input/Ouput
29 *
30 * \author J.E. Hoffmann <je-h@gmx.net>
31 */
32
[5453]33static bool s_requiresByteSwap = false;
34
35extern LIB3DSAPI void setByteOrder()
36{
37    s_requiresByteSwap = osg::getCpuByteOrder()==osg::BigEndian;
38}
39
40
41
[8]42/*!
43 * \ingroup readwrite
44 *
[151]45 * Read a byte from a file stream. 
[8]46 *
[151]47 * \param f  Input file stream.
[8]48 *
[151]49 * \return The byte read.
[8]50 */
51Lib3dsByte
[10076]52lib3ds_byte_read(iostream *strm)
[8]53{
[151]54  Lib3dsByte b;
[8]55
[10076]56  ASSERT(strm);
57  strm->read((char*)&b,1);
[151]58  return(b);
[8]59}
60
61
62/**
[151]63 * Read a word from a file stream in little endian format.   
[8]64 *
[151]65 * \param f  Input file stream.
[8]66 *
[151]67 * \return The word read.
[8]68 */
69Lib3dsWord
[10076]70lib3ds_word_read(iostream *strm)
[8]71{
[151]72  Lib3dsByte b[2];
73  Lib3dsWord w;
[8]74
[10076]75  ASSERT(strm); 
76  strm->read((char*)&b,2);
[151]77  w=((Lib3dsWord)b[1] << 8) |
78    ((Lib3dsWord)b[0]);
79  return(w);
[8]80}
81
82
83/*!
84 * \ingroup readwrite
85 *
[151]86 * Read a dword from file a stream in little endian format.   
[8]87 *
[151]88 * \param f  Input file stream.
[8]89 *
[151]90 * \return The dword read.
[8]91 */
92Lib3dsDword
[10076]93lib3ds_dword_read(iostream *strm)
[8]94{
[151]95  Lib3dsByte b[4];
96  Lib3dsDword d;       
97                         
[10076]98  ASSERT(strm); 
99  strm->read((char*)&b,4);
[151]100  d=((Lib3dsDword)b[3] << 24) |
101    ((Lib3dsDword)b[2] << 16) |
102    ((Lib3dsDword)b[1] << 8) |
103    ((Lib3dsDword)b[0]);
104  return(d);
[8]105}
106
107
108/*!
109 * \ingroup readwrite
110 *
[151]111 * Read a signed byte from a file stream.   
[8]112 *
[151]113 * \param f  Input file stream.
[8]114 *
[151]115 * \return The signed byte read.
[8]116 */
117Lib3dsIntb
[10076]118lib3ds_intb_read(iostream *strm)
[8]119{
[151]120  Lib3dsIntb b;
[8]121
[10076]122  ASSERT(strm); 
123  strm->read((char*)&b,1);
[151]124  return(b);
[8]125}
126
127
128/*!
129 * \ingroup readwrite
130 *
[151]131 * Read a signed word from a file stream in little endian format.   
[8]132 *
[151]133 * \param f  Input file stream.
[8]134 *
[151]135 * \return The signed word read.
[8]136 */
137Lib3dsIntw
[10076]138lib3ds_intw_read(iostream *strm)
[8]139{
[151]140  Lib3dsByte b[2];
[8]141
[10076]142  ASSERT(strm);
143  strm->read((char*)&b,2);
[5453]144
145  if (s_requiresByteSwap)
146  {
147    osg::swapBytes2((char*)b);
148  }
149
150  return (*((Lib3dsIntw*)b));
[8]151}
152
153
154/*!
155 * \ingroup readwrite
156 *
[151]157 * Read a signed dword a from file stream in little endian format.   
[8]158 *
[151]159 * \param f  Input file stream.
[8]160 *
[151]161 * \return The signed dword read.
[8]162 */
163Lib3dsIntd
[10076]164lib3ds_intd_read(iostream *strm)
[8]165{
[10076]166  Lib3dsByte b[4];     
[151]167                         
[10076]168  ASSERT(strm);
169  strm->read((char*)&b,4);
[5453]170
171  if (s_requiresByteSwap)
172  {
173    osg::swapBytes4((char*)b);
174  }
175
176  return (*((Lib3dsIntd*)b));
[10076]177
[8]178}
179
180
181/*!
182 * \ingroup readwrite
183 *
[151]184 * Read a float from a file stream in little endian format.   
[8]185 *
[151]186 * \param f  Input file stream.
[8]187 *
[151]188 * \return The float read.
[8]189 */
190Lib3dsFloat
[10076]191lib3ds_float_read(iostream *strm)
[8]192{
[151]193  Lib3dsByte b[4];
[8]194
[10076]195  ASSERT(strm);
196  b[0]=b[1]=b[2]=b[3]=0;
197  strm->read((char*)&b,4); 
[5453]198
199  if (s_requiresByteSwap)
200  {
201    osg::swapBytes4((char*)b);
202  }
203
204  return (*((Lib3dsFloat*)b));
[8]205}
206
207
208/*!
209 * \ingroup readwrite
210 * \ingroup vector
211 *
[151]212 * Read a vector from a file stream in little endian format.   
[8]213 *
[151]214 * \param v  The vector to store the data.
215 * \param f  Input file stream.
[8]216 *
[151]217 * \return The float read.
[8]218 */
219Lib3dsBool
[10076]220lib3ds_vector_read(Lib3dsVector v, iostream *strm)
[8]221{
[10076]222  v[0]=lib3ds_float_read(strm);
223  v[1]=lib3ds_float_read(strm);
224  v[2]=lib3ds_float_read(strm);
[8]225
[10076]226  if (strm->fail()) {
[151]227    return(LIB3DS_FALSE);
228  }
[10076]229
[5453]230  /*printf("lib3ds_vector_read %f %f %f\n",v[0],v[1],v[2]);*/
[10076]231
[151]232  return(LIB3DS_TRUE);
[8]233}
234
235
236/*!
237 * \ingroup readwrite
238 */
239Lib3dsBool
[10076]240lib3ds_rgb_read(Lib3dsRgb rgb, iostream *strm)
[8]241{
[10076]242  rgb[0]=lib3ds_float_read(strm);
243  rgb[1]=lib3ds_float_read(strm);
244  rgb[2]=lib3ds_float_read(strm);
[8]245
[10076]246  if (strm->fail()) {
[151]247    return(LIB3DS_FALSE);
248  }
[5453]249  /*printf("lib3ds_rgb_read %f %f %f\n",rgb[0],rgb[1],rgb[2]);*/
250
[151]251  return(LIB3DS_TRUE);
[8]252}
253
254
255/*!
256 * \ingroup readwrite
257 *
258 * Read a zero-terminated string from a file stream.
259 *
260 * \param s       The buffer to store the read string.
261 * \param buflen  Buffer length.
262 * \param f       The input file stream.
263 *
264 * \return        True on success, False otherwise.
265 */
266Lib3dsBool
[10076]267lib3ds_string_read(char *s, int buflen, iostream *strm)
[8]268{
[151]269  int k=0;
[10076]270  ASSERT(s);
271  s--;
272  do
273  {
274      s++;
275      k++;
276      strm->read(s,1);
277  } while ((*s!=0) && (k<buflen));
278
279  if (strm->fail()) {
[151]280    return(LIB3DS_FALSE);
281  }
282  return(LIB3DS_TRUE);
[8]283}
284
285/*!
286 * \ingroup readwrite
287 *
288 * Writes a byte into a file stream.
289 *
290 * \param b  The byte to write to the file stream.
291 * \param f  The input file stream.
292 *
293 * \return   True on success, False otherwise.
294 */
295Lib3dsBool
[10076]296lib3ds_byte_write(Lib3dsByte b, iostream *strm)
[8]297{
[10076]298  ASSERT(strm);
299  strm->write((char*)&b,1);
300  if (strm->fail()) {
[151]301    return(LIB3DS_FALSE);
302  }
303  return(LIB3DS_TRUE);
[8]304}
305
306
307/*!
308 * \ingroup readwrite
309 *
310 * Writes a word into a little endian file stream.
311 *
312 * \param w  The word to write to the file stream.
313 * \param f  The input file stream.
314 *
315 * \return   True on success, False otherwise.
316 */
317Lib3dsBool
[10076]318lib3ds_word_write(Lib3dsWord w, iostream *strm)
[8]319{
[151]320  Lib3dsByte b[2];
[8]321
[10076]322  ASSERT(strm);
[9571]323  b[1]=(Lib3dsByte)(((Lib3dsWord)w & 0xFF00) >> 8);
324  b[0]=(Lib3dsByte)((Lib3dsWord)w & 0x00FF);
[10076]325  strm->write((char*)b,2);
326  if (strm->fail()) {
[151]327    return(LIB3DS_FALSE);
328  }
329  return(LIB3DS_TRUE);
[8]330}
331
332
333/*!
334 * \ingroup readwrite
335 *
336 * Writes a dword into a little endian file stream.
337 *
338 * \param d  The dword to write to the file stream.
339 * \param f  The input file stream.
340 *
341 * \return   True on success, False otherwise.
342 */
343Lib3dsBool
[10076]344lib3ds_dword_write(Lib3dsDword d, iostream *strm)
[8]345{
[151]346  Lib3dsByte b[4];
[8]347
[10076]348  ASSERT(strm);
[151]349  b[3]=(Lib3dsByte)(((Lib3dsDword)d & 0xFF000000) >> 24);
350  b[2]=(Lib3dsByte)(((Lib3dsDword)d & 0x00FF0000) >> 16);
351  b[1]=(Lib3dsByte)(((Lib3dsDword)d & 0x0000FF00) >> 8);
352  b[0]=(Lib3dsByte)(((Lib3dsDword)d & 0x000000FF));
[10076]353
354  strm->write((char*)b,4);
355  if (strm->fail()) {
[151]356    return(LIB3DS_FALSE);
357  }
358  return(LIB3DS_TRUE);
[8]359}
360
361
362/*!
363 * \ingroup readwrite
364 *
365 * Writes a signed byte in a file stream.
366 *
367 * \param b  The signed byte to write to the file stream.
368 * \param f  The input file stream.
369 *
370 * \return   True on success, False otherwise.
371 */
372Lib3dsBool
[10076]373lib3ds_intb_write(Lib3dsIntb b, iostream *strm)
[8]374{
[10076]375  ASSERT(strm);
376  strm->write((char*)b,1);
377  if (strm->fail()) {
[151]378    return(LIB3DS_FALSE);
379  }
380  return(LIB3DS_TRUE);
[8]381}
382
383
384/*!
385 * \ingroup readwrite
386 *
387 * Writes a signed word into a little endian file stream.
388 *
389 * \param w  The signed word to write to the file stream.
390 * \param f  The input file stream.
391 *
392 * \return   True on success, False otherwise.
393 */
394Lib3dsBool
[10076]395lib3ds_intw_write(Lib3dsIntw w, iostream *strm)
[8]396{
[151]397  Lib3dsByte b[2];
[8]398
[10076]399  ASSERT(strm);
[9571]400  b[1]=(Lib3dsByte)(((Lib3dsWord)w & 0xFF00) >> 8);
401  b[0]=(Lib3dsByte)((Lib3dsWord)w & 0x00FF);
[10076]402
403  strm->write((char*)b,2);
404  if (strm->fail()) {
[151]405    return(LIB3DS_FALSE);
406  }
407  return(LIB3DS_TRUE);
[8]408}
409
410
411/*!
412 * \ingroup readwrite
413 *
414 * Writes a signed dword into a little endian file stream.
415 *
416 * \param d  The signed dword to write to the file stream.
417 * \param f  The input file stream.
418 *
419 * \return   True on success, False otherwise.
420 */
421Lib3dsBool
[10076]422lib3ds_intd_write(Lib3dsIntd d, iostream *strm)
[8]423{
[151]424  Lib3dsByte b[4];
[8]425
[10076]426  ASSERT(strm);
[151]427  b[3]=(Lib3dsByte)(((Lib3dsDword)d & 0xFF000000) >> 24);
428  b[2]=(Lib3dsByte)(((Lib3dsDword)d & 0x00FF0000) >> 16);
429  b[1]=(Lib3dsByte)(((Lib3dsDword)d & 0x0000FF00) >> 8);
430  b[0]=(Lib3dsByte)(((Lib3dsDword)d & 0x000000FF));
[10076]431
432  strm->write((char*)b,4);
433  if (strm->fail()) {
[151]434    return(LIB3DS_FALSE);
435  }
436  return(LIB3DS_TRUE);
[8]437}
438
439
440/*!
441 * \ingroup readwrite
442 *
443 * Writes a float into a little endian file stream.
444 *
445 * \param f  The float to write to the file stream.
446 * \param f  The input file stream.
447 *
448 * \return   True on success, False otherwise.
449 */
450Lib3dsBool
[10076]451lib3ds_float_write(Lib3dsFloat l, iostream *strm)
[8]452{
[10076]453  ASSERT(strm);
[9397]454
[151]455  Lib3dsByte b[4];
[9397]456  Lib3dsByte* ptr = (Lib3dsByte*) (&l);
[8]457
[9397]458  if (s_requiresByteSwap)
459  {
460      b[3] = *ptr++;
461      b[2] = *ptr++;
462      b[1] = *ptr++;
463      b[0] = *ptr++;
464  }
465  else
466  {
467      b[0] = *ptr++;
468      b[1] = *ptr++;
469      b[2] = *ptr++;
470      b[3] = *ptr++;
471  }
[10076]472
473  strm->write((char*)b,4);
474  if (strm->fail()) {
[151]475    return(LIB3DS_FALSE);
476  }
477  return(LIB3DS_TRUE);
[8]478}
479
480
481/*!
482 * \ingroup readwrite
483 * \ingroup vector
484 *
[151]485 * Writes a vector into a file stream in little endian format.   
[8]486 *
[151]487 * \param v  The vector to write to the file stream.
488 * \param f  Input file stream.
[8]489 */
490Lib3dsBool
[10076]491lib3ds_vector_write(Lib3dsVector v, iostream *strm)
[8]492{
[10076]493  if (!lib3ds_float_write(v[0], strm)) {
[151]494    return(LIB3DS_FALSE);
495  }
[10076]496  if (!lib3ds_float_write(v[1], strm)) {
[151]497    return(LIB3DS_FALSE);
498  }
[10076]499  if (!lib3ds_float_write(v[2], strm)) {
[151]500    return(LIB3DS_FALSE);
501  }
502  return(LIB3DS_TRUE);
[8]503}
504
505
506/*!
507 * \ingroup readwrite
508 */
509Lib3dsBool
[10076]510lib3ds_rgb_write(Lib3dsRgb rgb, iostream *strm)
[8]511{
[10076]512  if (!lib3ds_float_write(rgb[0], strm)) {
[151]513    return(LIB3DS_FALSE);
514  }
[10076]515  if (!lib3ds_float_write(rgb[1], strm)) {
[151]516    return(LIB3DS_FALSE);
517  }
[10076]518  if (!lib3ds_float_write(rgb[2], strm)) {
[151]519    return(LIB3DS_FALSE);
520  }
521  return(LIB3DS_TRUE);
[8]522}
523
524
525/*!
526 * \ingroup readwrite
527 *
528 * Writes a zero-terminated string into a file stream.
529 *
530 * \param f  The float to write to the file stream.
531 * \param f  The input file stream.
532 *
533 * \return   True on success, False otherwise.
534 */
535Lib3dsBool
[10076]536lib3ds_string_write(const char *s, iostream *strm)
[8]537{
[151]538  ASSERT(s);
[10076]539  ASSERT(strm);
540  do strm->write(s,1); while (*s++);
541  if (strm->fail()) {
[151]542    return(LIB3DS_FALSE);
543  }
544  return(LIB3DS_TRUE);
[8]545}
Note: See TracBrowser for help on using the browser.