root/OpenSceneGraph/trunk/src/osgPlugins/3ds/lib3ds/lib3ds_io.c @ 11173

Revision 11173, 11.7 kB (checked in by robert, 5 years ago)

Fixed usage of osg::swapBytes to properly pass in pointer to data that needs swapping.

RevLine 
[10853]1/*
2    Copyright (C) 1996-2008 by Jan Eric Kyprianidis <www.kyprianidis.com>
3    All rights reserved.
4   
5    This program is free  software: you can redistribute it and/or modify
6    it under the terms of the GNU Lesser General Public License as published
7    by the Free Software Foundation, either version 2.1 of the License, or
8    (at your option) any later version.
9
10    Thisprogram  is  distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13    GNU Lesser General Public License for more details.
14   
15    You should  have received a copy of the GNU Lesser General Public License
16    along with  this program; If not, see <http://www.gnu.org/licenses/>.
17*/
18#include "lib3ds_impl.h"
19
20/* --- Code for OpenSceneGraph --- */
21#include "lib3ds.h"             // For setByteOrder()
22#include <osg/Endian>
23
24static bool s_requiresByteSwap = false;
25extern LIB3DSAPI void setByteOrder()
26{
27    s_requiresByteSwap = osg::getCpuByteOrder()==osg::BigEndian;
28}
29/* --- (end) Code for OpenSceneGraph --- */
30
31typedef union {
32    uint32_t dword_value;
33    float float_value;
34} Lib3dsDwordFloat;
35
36
37void
38lib3ds_io_setup(Lib3dsIo *io) {
39    assert(io);
40    io->impl = calloc(sizeof(Lib3dsIoImpl), 1);
41}
42
43
44void
45lib3ds_io_cleanup(Lib3dsIo *io) {
46    Lib3dsIoImpl *impl;
47    assert(io);
48    impl = (Lib3dsIoImpl*)io->impl;
49    if (impl->tmp_mem) {
50        free(impl->tmp_mem);
51        impl->tmp_mem = NULL;
52    }
53    if (impl->tmp_node) {
54        lib3ds_node_free(impl->tmp_node);
55        impl->tmp_node = NULL;
56    }
57    free(impl);
58}
59
60
61long
62lib3ds_io_seek(Lib3dsIo *io, long offset, Lib3dsIoSeek origin) {
63    assert(io);
64    if (!io || !io->seek_func) {
65        return 0;
66    }
67    return (*io->seek_func)(io->self, offset, origin);
68}
69
70
71long
72lib3ds_io_tell(Lib3dsIo *io) {
73    assert(io);
74    if (!io || !io->tell_func) {
75        return 0;
76    }
77    return (*io->tell_func)(io->self);
78}
79
80
81size_t
82lib3ds_io_read(Lib3dsIo *io, void *buffer, size_t size) {
83    assert(io);
84    if (!io || !io->read_func) {
85        return 0;
86    }
87    return (*io->read_func)(io->self, buffer, size);
88}
89
90
91size_t
92lib3ds_io_write(Lib3dsIo *io, const void *buffer, size_t size) {
93    assert(io);
94    if (!io || !io->write_func) {
95        return 0;
96    }
97    return (*io->write_func)(io->self, buffer, size);
98}
99
100
101static void 
102lib3ds_io_log_str(Lib3dsIo *io, Lib3dsLogLevel level, const char *str) {
103    if (!io || !io->log_func)
104        return;
105    (*io->log_func)(io->self, level, ((Lib3dsIoImpl*)io->impl)->log_indent, str);
106}
107
108
109void 
110lib3ds_io_log(Lib3dsIo *io, Lib3dsLogLevel level, const char *format, ...) {
111    va_list args;
112    /* FIXME */ char str[1024];
113
114    assert(io);
115    if (!io || !io->log_func)
116        return;
117
118    va_start(args, format);
119    /* FIXME: */ vsprintf(str, format, args);
120    lib3ds_io_log_str(io, level, str);
121
122    if (level == LIB3DS_LOG_ERROR) {
123        longjmp(((Lib3dsIoImpl*)io->impl)->jmpbuf, 1);
124    }
125}
126
127
128void 
129lib3ds_io_log_indent(Lib3dsIo *io, int indent) {
130    assert(io);
131    if (!io)
132        return;
133    ((Lib3dsIoImpl*)io->impl)->log_indent += indent;
134}
135
136
137void 
138lib3ds_io_read_error(Lib3dsIo *io) {
139    lib3ds_io_log(io, LIB3DS_LOG_ERROR, "Reading from input stream failed.");
140}
141
142
143void 
144lib3ds_io_write_error(Lib3dsIo *io) {
145    lib3ds_io_log(io, LIB3DS_LOG_ERROR, "Writing to output stream failed.");
146}
147
148
149/*!
150 * Read a byte from a file stream.
151 */
152uint8_t
153lib3ds_io_read_byte(Lib3dsIo *io) {
154    uint8_t b;
155
156    assert(io);
157    lib3ds_io_read(io, &b, 1);
158    return(b);
159}
160
161
162/**
163 * Read a word from a file stream in little endian format.
164 */
165uint16_t
166lib3ds_io_read_word(Lib3dsIo *io) {
167    uint8_t b[2];
168    uint16_t w;
169
170    assert(io);
171    lib3ds_io_read(io, b, 2);
172    w = ((uint16_t)b[1] << 8) |
173        ((uint16_t)b[0]);
[11173]174    /* --- Code for OpenSceneGraph --- */
[10853]175    if (s_requiresByteSwap)
176    {
[11173]177        osg::swapBytes2((char*)&w);
[10853]178    }
[11173]179    /* --- (end) Code for OpenSceneGraph --- */
180    return(w);
[10853]181}
182
183
184/*!
185 * Read a dword from file a stream in little endian format.
186 */
187uint32_t
188lib3ds_io_read_dword(Lib3dsIo *io) {
189    uint8_t b[4];
190    uint32_t d;
191
192    assert(io);
193    lib3ds_io_read(io, b, 4);
194    d = ((uint32_t)b[3] << 24) |
195        ((uint32_t)b[2] << 16) |
196        ((uint32_t)b[1] << 8) |
197        ((uint32_t)b[0]);
[11173]198    /* --- Code for OpenSceneGraph --- */
[10853]199    if (s_requiresByteSwap)
200    {
[11173]201        osg::swapBytes4((char*)&d);
[10853]202    }
[11173]203    /* --- (end) Code for OpenSceneGraph --- */
[10853]204    return(d);
205}
206
207
208/*!
209 * Read a signed byte from a file stream.
210 */
211int8_t
212lib3ds_io_read_intb(Lib3dsIo *io) {
213    int8_t b;
214
215    assert(io);
216    lib3ds_io_read(io, &b, 1);
217    return(b);
218}
219
220
221/*!
222 * Read a signed word from a file stream in little endian format.
223 */
224int16_t
225lib3ds_io_read_intw(Lib3dsIo *io) {
226    uint8_t b[2];
227    uint16_t w;
228
229    assert(io);
230    lib3ds_io_read(io, b, 2);
231    w = ((uint16_t)b[1] << 8) |
232        ((uint16_t)b[0]);
[11173]233    /* --- Code for OpenSceneGraph --- */
[10853]234    if (s_requiresByteSwap)
235    {
[11173]236        osg::swapBytes2((char*)&w);
[10853]237    }
[11173]238    /* --- (end) Code for OpenSceneGraph --- */
239    return((int16_t)w);
[10853]240}
241
242
243/*!
244 * Read a signed dword a from file stream in little endian format.
245 */
246int32_t
247lib3ds_io_read_intd(Lib3dsIo *io) {
248    uint8_t b[4];
249    uint32_t d;
250
251    assert(io);
252    lib3ds_io_read(io, b, 4);
253    d = ((uint32_t)b[3] << 24) |
254        ((uint32_t)b[2] << 16) |
255        ((uint32_t)b[1] << 8) |
256        ((uint32_t)b[0]);
[11173]257    /* --- Code for OpenSceneGraph --- */
[10853]258    if (s_requiresByteSwap)
259    {
[11173]260        osg::swapBytes4((char*)&d);
[10853]261    }
[11173]262    /* --- (end) Code for OpenSceneGraph --- */
[10853]263    return((int32_t)d);
264}
265
266
267/*!
268 * Read a float from a file stream in little endian format.
269 */
270float
271lib3ds_io_read_float(Lib3dsIo *io) {
272    uint8_t b[4];
273    Lib3dsDwordFloat d;
274
275    assert(io);
276    lib3ds_io_read(io, b, 4);
277    d.dword_value = ((uint32_t)b[3] << 24) |
278                    ((uint32_t)b[2] << 16) |
279                    ((uint32_t)b[1] << 8) |
280                    ((uint32_t)b[0]);
[11173]281    /* --- Code for OpenSceneGraph --- */
[10853]282    if (s_requiresByteSwap)
283    {
[11173]284        osg::swapBytes4((char*)&(d.dword_value));
[10853]285    }
[11173]286    /* --- (end) Code for OpenSceneGraph --- */
287    return d.float_value;
[10853]288}
289
290
291/*!
292 * Read a vector from a file stream in little endian format.
293 *
294 * \param io IO input handle.
295 * \param v  The vector to store the data.
296 */
297void
298lib3ds_io_read_vector(Lib3dsIo *io, float v[3]) {
299    assert(io);
300    v[0] = lib3ds_io_read_float(io);
301    v[1] = lib3ds_io_read_float(io);
302    v[2] = lib3ds_io_read_float(io);
303}
304
305
306void
307lib3ds_io_read_rgb(Lib3dsIo *io, float rgb[3]) {
308    assert(io);
309    rgb[0] = lib3ds_io_read_float(io);
310    rgb[1] = lib3ds_io_read_float(io);
311    rgb[2] = lib3ds_io_read_float(io);
312}
313
314
315/*!
316 * Read a zero-terminated string from a file stream.
317 *
318 * \param io      IO input handle.
319 * \param s       The buffer to store the read string.
320 * \param buflen  Buffer length.
321 *
322 * \return        True on success, False otherwise.
323 */
324void
325lib3ds_io_read_string(Lib3dsIo *io, char *s, int buflen) {
326    char c;
327    int k = 0;
328
329    assert(io);
330    for (;;) {
331        if (lib3ds_io_read(io, &c, 1) != 1) {
332            lib3ds_io_read_error(io);
333        }
334        *s++ = c;
335        if (!c) {
336            break;
337        }
338        ++k;
339        if (k >= buflen) {
340            lib3ds_io_log(io, LIB3DS_LOG_ERROR, "Invalid string in input stream.");
341        }
342    }
343}
344
345
346/*!
347 * Writes a byte into a file stream.
348 */
349void
350lib3ds_io_write_byte(Lib3dsIo *io, uint8_t b) {
351    assert(io);
352    if (lib3ds_io_write(io, &b, 1) != 1) {
353        lib3ds_io_write_error(io);
354    }
355}
356
357
358/*!
359 * Writes a word into a little endian file stream.
360 */
361void
362lib3ds_io_write_word(Lib3dsIo *io, uint16_t w) {
[11173]363    /* --- Code for OpenSceneGraph --- */
[10853]364    if (s_requiresByteSwap)
365    {
[11173]366            osg::swapBytes2((char*)&w);
[10853]367    }
[11173]368    /* --- (end) Code for OpenSceneGraph --- */
[10853]369
[11173]370    uint8_t b[2];
[10853]371
372    assert(io);
373    b[1] = ((uint16_t)w & 0xFF00) >> 8;
374    b[0] = ((uint16_t)w & 0x00FF);
375    if (lib3ds_io_write(io, b, 2) != 2) {
376        lib3ds_io_write_error(io);
377    }
378}
379
380
381/*!
382 * Writes a dword into a little endian file stream.
383 */
384void
385lib3ds_io_write_dword(Lib3dsIo *io, uint32_t d) {
[11173]386    /* --- Code for OpenSceneGraph --- */
[10853]387    if (s_requiresByteSwap)
388    {
[11173]389        osg::swapBytes4((char*)&d);
[10853]390    }
[11173]391    /* --- (end) Code for OpenSceneGraph --- */
[10853]392    uint8_t b[4];
393
394    assert(io);
395    b[3] = (uint8_t)(((uint32_t)d & 0xFF000000) >> 24);
396    b[2] = (uint8_t)(((uint32_t)d & 0x00FF0000) >> 16);
397    b[1] = (uint8_t)(((uint32_t)d & 0x0000FF00) >> 8);
398    b[0] = (uint8_t)(((uint32_t)d & 0x000000FF));
399    if (lib3ds_io_write(io, b, 4) != 4) {
400        lib3ds_io_write_error(io);
401    }
402}
403
404
405/*!
406 * Writes a signed byte in a file stream.
407 */
408void
409lib3ds_io_write_intb(Lib3dsIo *io, int8_t b) {
410    assert(io);
411    if (lib3ds_io_write(io, &b, 1) != 1) {
412        lib3ds_io_write_error(io);
413    }
414}
415
416
417/*!
418 * Writes a signed word into a little endian file stream.
419 */
420void
421lib3ds_io_write_intw(Lib3dsIo *io, int16_t w) {
[11173]422    /* --- Code for OpenSceneGraph --- */
[10853]423    if (s_requiresByteSwap)
424    {
[11173]425        osg::swapBytes2((char*)&w);
[10853]426    }
[11173]427    /* --- (end) Code for OpenSceneGraph --- */
[10853]428    uint8_t b[2];
429
430    assert(io);
431    b[1] = ((uint16_t)w & 0xFF00) >> 8;
432    b[0] = ((uint16_t)w & 0x00FF);
433    if (lib3ds_io_write(io, b, 2) != 2) {
434        lib3ds_io_write_error(io);
435    }
436}
437
438
439/*!
440 * Writes a signed dword into a little endian file stream.
441 */
442void
443lib3ds_io_write_intd(Lib3dsIo *io, int32_t d) {
[11173]444    /* --- Code for OpenSceneGraph --- */
[10853]445    if (s_requiresByteSwap)
446    {
[11173]447        osg::swapBytes4((char*)&d);
[10853]448    }
[11173]449    /* --- (end) Code for OpenSceneGraph --- */
[10853]450    uint8_t b[4];
451
452    assert(io);
453    b[3] = (uint8_t)(((uint32_t)d & 0xFF000000) >> 24);
454    b[2] = (uint8_t)(((uint32_t)d & 0x00FF0000) >> 16);
455    b[1] = (uint8_t)(((uint32_t)d & 0x0000FF00) >> 8);
456    b[0] = (uint8_t)(((uint32_t)d & 0x000000FF));
457    if (lib3ds_io_write(io, b, 4) != 4) {
458        lib3ds_io_write_error(io);
459    }
460}
461
462
463/*!
464 * Writes a float into a little endian file stream.
465 */
466void
467lib3ds_io_write_float(Lib3dsIo *io, float l) {
468        uint8_t b[4];
469    Lib3dsDwordFloat d;
470
471    assert(io);
472    d.float_value = l;
[11173]473    /* --- Code for OpenSceneGraph --- */
[10853]474    if (s_requiresByteSwap)
475    {
[11173]476        osg::swapBytes4((char*)&d.dword_value);
[10853]477    }
[11173]478    /* --- (end) Code for OpenSceneGraph --- */
[10853]479    b[3] = (uint8_t)(((uint32_t)d.dword_value & 0xFF000000) >> 24);
480    b[2] = (uint8_t)(((uint32_t)d.dword_value & 0x00FF0000) >> 16);
481    b[1] = (uint8_t)(((uint32_t)d.dword_value & 0x0000FF00) >> 8);
482    b[0] = (uint8_t)(((uint32_t)d.dword_value & 0x000000FF));
483    if (lib3ds_io_write(io, b, 4) != 4) {
484        lib3ds_io_write_error(io);
485    }
486}
487
488
489/*!
490 * Writes a vector into a file stream in little endian format.
491 */
492void
493lib3ds_io_write_vector(Lib3dsIo *io, float v[3]) {
494    int i;
495    for (i = 0; i < 3; ++i) {
496        lib3ds_io_write_float(io, v[i]);
497    }
498}
499
500
501void
502lib3ds_io_write_rgb(Lib3dsIo *io, float rgb[3]) {
503    int i;
504    for (i = 0; i < 3; ++i) {
505        lib3ds_io_write_float(io, rgb[i]);
506    }
507}
508
509
510/*!
511 * Writes a zero-terminated string into a file stream.
512 */
513void
514lib3ds_io_write_string(Lib3dsIo *io, const char *s) {
515    size_t len;
516    assert(io && s);
517    len = strlen(s);
518    if (lib3ds_io_write(io, s, len + 1) != len +1) {
519        lib3ds_io_write_error(io);
520    }
521}
Note: See TracBrowser for help on using the browser.