]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - libs/picomodel/lwo/lwio.c
transfer from internal tree r5311 branches/1.4-gpl
[xonotic/netradiant.git] / libs / picomodel / lwo / lwio.c
1 /*\r
2 ======================================================================\r
3 lwio.c\r
4 \r
5 Functions for reading basic LWO2 data types.\r
6 \r
7 Ernie Wright  17 Sep 00\r
8 ====================================================================== */\r
9 \r
10 #include "../picointernal.h"\r
11 #include "lwo2.h"\r
12 \r
13 \r
14 /*\r
15 ======================================================================\r
16 flen\r
17 \r
18 This accumulates a count of the number of bytes read.  Callers can set\r
19 it at the beginning of a sequence of reads and then retrieve it to get\r
20 the number of bytes actually read.  If one of the I/O functions fails,\r
21 flen is set to an error code, after which the I/O functions ignore\r
22 read requests until flen is reset.\r
23 ====================================================================== */\r
24 \r
25 #define INT_MIN     (-2147483647 - 1) /* minimum (signed) int value */\r
26 #define FLEN_ERROR INT_MIN\r
27 \r
28 static int flen;\r
29 \r
30 void set_flen( int i ) { flen = i; }\r
31 \r
32 int get_flen( void ) { return flen; }\r
33 \r
34 \r
35 #ifdef _WIN32\r
36 /*\r
37 =====================================================================\r
38 revbytes()\r
39 \r
40 Reverses byte order in place.\r
41 \r
42 INPUTS\r
43    bp       bytes to reverse\r
44    elsize   size of the underlying data type\r
45    elcount  number of elements to swap\r
46 \r
47 RESULTS\r
48    Reverses the byte order in each of elcount elements.\r
49 \r
50 This only needs to be defined on little-endian platforms, most\r
51 notably Windows.  lwo2.h replaces this with a #define on big-endian\r
52 platforms.\r
53 ===================================================================== */\r
54 \r
55 void revbytes( void *bp, int elsize, int elcount )\r
56 {\r
57    register unsigned char *p, *q;\r
58 \r
59    p = ( unsigned char * ) bp;\r
60 \r
61    if ( elsize == 2 ) {\r
62       q = p + 1;\r
63       while ( elcount-- ) {\r
64          *p ^= *q;\r
65          *q ^= *p;\r
66          *p ^= *q;\r
67          p += 2;\r
68          q += 2;\r
69       }\r
70       return;\r
71    }\r
72 \r
73    while ( elcount-- ) {\r
74       q = p + elsize - 1;\r
75       while ( p < q ) {\r
76          *p ^= *q;\r
77          *q ^= *p;\r
78          *p ^= *q;\r
79          ++p;\r
80          --q;\r
81       }\r
82       p += elsize >> 1;\r
83    }\r
84 }\r
85 #endif\r
86 \r
87 \r
88 void *getbytes( picoMemStream_t *fp, int size )\r
89 {\r
90    void *data;\r
91 \r
92    if ( flen == FLEN_ERROR ) return NULL;\r
93    if ( size < 0 ) {\r
94       flen = FLEN_ERROR;\r
95       return NULL;\r
96    }\r
97    data = _pico_alloc( size );\r
98    if ( !data ) {\r
99       flen = FLEN_ERROR;\r
100       return NULL;\r
101    }\r
102    if ( 1 != _pico_memstream_read( fp, data, size )) {\r
103       flen = FLEN_ERROR;\r
104       _pico_free( data );\r
105       return NULL;\r
106    }\r
107 \r
108    flen += size;\r
109    return data;\r
110 }\r
111 \r
112 \r
113 void skipbytes( picoMemStream_t *fp, int n )\r
114 {\r
115    if ( flen == FLEN_ERROR ) return;\r
116    if ( _pico_memstream_seek( fp, n, PICO_SEEK_CUR ))\r
117       flen = FLEN_ERROR;\r
118    else\r
119       flen += n;\r
120 }\r
121 \r
122 \r
123 int getI1( picoMemStream_t *fp )\r
124 {\r
125    int i;\r
126 \r
127    if ( flen == FLEN_ERROR ) return 0;\r
128    i = _pico_memstream_getc( fp );\r
129    if ( i < 0 ) {\r
130       flen = FLEN_ERROR;\r
131       return 0;\r
132    }\r
133    if ( i > 127 ) i -= 256;\r
134    flen += 1;\r
135    return i;\r
136 }\r
137 \r
138 \r
139 short getI2( picoMemStream_t *fp )\r
140 {\r
141    short i;\r
142 \r
143    if ( flen == FLEN_ERROR ) return 0;\r
144    if ( 1 != _pico_memstream_read( fp, &i, 2 )) {\r
145       flen = FLEN_ERROR;\r
146       return 0;\r
147    }\r
148    revbytes( &i, 2, 1 );\r
149    flen += 2;\r
150    return i;\r
151 }\r
152 \r
153 \r
154 int getI4( picoMemStream_t *fp )\r
155 {\r
156    int i;\r
157 \r
158    if ( flen == FLEN_ERROR ) return 0;\r
159    if ( 1 != _pico_memstream_read( fp, &i, 4 )) {\r
160       flen = FLEN_ERROR;\r
161       return 0;\r
162    }\r
163    revbytes( &i, 4, 1 );\r
164    flen += 4;\r
165    return i;\r
166 }\r
167 \r
168 \r
169 unsigned char getU1( picoMemStream_t *fp )\r
170 {\r
171    int i;\r
172 \r
173    if ( flen == FLEN_ERROR ) return 0;\r
174    i = _pico_memstream_getc( fp );\r
175    if ( i < 0 ) {\r
176       flen = FLEN_ERROR;\r
177       return 0;\r
178    }\r
179    flen += 1;\r
180    return i;\r
181 }\r
182 \r
183 \r
184 unsigned short getU2( picoMemStream_t *fp )\r
185 {\r
186    unsigned short i;\r
187 \r
188    if ( flen == FLEN_ERROR ) return 0;\r
189    if ( 1 != _pico_memstream_read( fp, &i, 2 )) {\r
190       flen = FLEN_ERROR;\r
191       return 0;\r
192    }\r
193    revbytes( &i, 2, 1 );\r
194    flen += 2;\r
195    return i;\r
196 }\r
197 \r
198 \r
199 unsigned int getU4( picoMemStream_t *fp )\r
200 {\r
201    unsigned int i;\r
202 \r
203    if ( flen == FLEN_ERROR ) return 0;\r
204    if ( 1 != _pico_memstream_read( fp, &i, 4 )) {\r
205       flen = FLEN_ERROR;\r
206       return 0;\r
207    }\r
208    revbytes( &i, 4, 1 );\r
209    flen += 4;\r
210    return i;\r
211 }\r
212 \r
213 \r
214 int getVX( picoMemStream_t *fp )\r
215 {\r
216    int i, c;\r
217 \r
218    if ( flen == FLEN_ERROR ) return 0;\r
219 \r
220    c = _pico_memstream_getc( fp );\r
221    if ( c != 0xFF ) {\r
222       i = c << 8;\r
223       c = _pico_memstream_getc( fp );\r
224       i |= c;\r
225       flen += 2;\r
226    }\r
227    else {\r
228       c = _pico_memstream_getc( fp );\r
229       i = c << 16;\r
230       c = _pico_memstream_getc( fp );\r
231       i |= c << 8;\r
232       c = _pico_memstream_getc( fp );\r
233       i |= c;\r
234       flen += 4;\r
235    }\r
236 \r
237    if ( _pico_memstream_error( fp )) {\r
238       flen = FLEN_ERROR;\r
239       return 0;\r
240    }\r
241    return i;\r
242 }\r
243 \r
244 \r
245 float getF4( picoMemStream_t *fp )\r
246 {\r
247    float f;\r
248 \r
249    if ( flen == FLEN_ERROR ) return 0.0f;\r
250    if ( 1 != _pico_memstream_read( fp, &f, 4 )) {\r
251       flen = FLEN_ERROR;\r
252       return 0.0f;\r
253    }\r
254    revbytes( &f, 4, 1 );\r
255    flen += 4;\r
256    return f;\r
257 }\r
258 \r
259 \r
260 char *getS0( picoMemStream_t *fp )\r
261 {\r
262    char *s;\r
263    int i, c, len, pos;\r
264 \r
265    if ( flen == FLEN_ERROR ) return NULL;\r
266 \r
267    pos = _pico_memstream_tell( fp );\r
268    for ( i = 1; ; i++ ) {\r
269       c = _pico_memstream_getc( fp );\r
270       if ( c <= 0 ) break;\r
271    }\r
272    if ( c < 0 ) {\r
273       flen = FLEN_ERROR;\r
274       return NULL;\r
275    }\r
276 \r
277    if ( i == 1 ) {\r
278       if ( _pico_memstream_seek( fp, pos + 2, PICO_SEEK_SET ))\r
279          flen = FLEN_ERROR;\r
280       else\r
281          flen += 2;\r
282       return NULL;\r
283    }\r
284 \r
285    len = i + ( i & 1 );\r
286    s = _pico_alloc( len );\r
287    if ( !s ) {\r
288       flen = FLEN_ERROR;\r
289       return NULL;\r
290    }\r
291 \r
292    if ( _pico_memstream_seek( fp, pos, PICO_SEEK_SET )) {\r
293       flen = FLEN_ERROR;\r
294       return NULL;\r
295    }\r
296    if ( 1 != _pico_memstream_read( fp, s, len )) {\r
297       flen = FLEN_ERROR;\r
298       return NULL;\r
299    }\r
300 \r
301    flen += len;\r
302    return s;\r
303 }\r
304 \r
305 \r
306 int sgetI1( unsigned char **bp )\r
307 {\r
308    int i;\r
309 \r
310    if ( flen == FLEN_ERROR ) return 0;\r
311    i = **bp;\r
312    if ( i > 127 ) i -= 256;\r
313    flen += 1;\r
314    *bp++;\r
315    return i;\r
316 }\r
317 \r
318 \r
319 short sgetI2( unsigned char **bp )\r
320 {\r
321    short i;\r
322 \r
323    if ( flen == FLEN_ERROR ) return 0;\r
324    memcpy( &i, *bp, 2 );\r
325    revbytes( &i, 2, 1 );\r
326    flen += 2;\r
327    *bp += 2;\r
328    return i;\r
329 }\r
330 \r
331 \r
332 int sgetI4( unsigned char **bp )\r
333 {\r
334    int i;\r
335 \r
336    if ( flen == FLEN_ERROR ) return 0;\r
337    memcpy( &i, *bp, 4 );\r
338    revbytes( &i, 4, 1 );\r
339    flen += 4;\r
340    *bp += 4;\r
341    return i;\r
342 }\r
343 \r
344 \r
345 unsigned char sgetU1( unsigned char **bp )\r
346 {\r
347    unsigned char c;\r
348 \r
349    if ( flen == FLEN_ERROR ) return 0;\r
350    c = **bp;\r
351    flen += 1;\r
352    *bp++;\r
353    return c;\r
354 }\r
355 \r
356 \r
357 unsigned short sgetU2( unsigned char **bp )\r
358 {\r
359    unsigned char *buf = *bp;\r
360    unsigned short i;\r
361 \r
362    if ( flen == FLEN_ERROR ) return 0;\r
363    i = ( buf[ 0 ] << 8 ) | buf[ 1 ];\r
364    flen += 2;\r
365    *bp += 2;\r
366    return i;\r
367 }\r
368 \r
369 \r
370 unsigned int sgetU4( unsigned char **bp )\r
371 {\r
372    unsigned int i;\r
373 \r
374    if ( flen == FLEN_ERROR ) return 0;\r
375    memcpy( &i, *bp, 4 );\r
376    revbytes( &i, 4, 1 );\r
377    flen += 4;\r
378    *bp += 4;\r
379    return i;\r
380 }\r
381 \r
382 \r
383 int sgetVX( unsigned char **bp )\r
384 {\r
385    unsigned char *buf = *bp;\r
386    int i;\r
387 \r
388    if ( flen == FLEN_ERROR ) return 0;\r
389 \r
390    if ( buf[ 0 ] != 0xFF ) {\r
391       i = buf[ 0 ] << 8 | buf[ 1 ];\r
392       flen += 2;\r
393       *bp += 2;\r
394    }\r
395    else {\r
396       i = ( buf[ 1 ] << 16 ) | ( buf[ 2 ] << 8 ) | buf[ 3 ];\r
397       flen += 4;\r
398       *bp += 4;\r
399    }\r
400    return i;\r
401 }\r
402 \r
403 \r
404 float sgetF4( unsigned char **bp )\r
405 {\r
406    float f;\r
407 \r
408    if ( flen == FLEN_ERROR ) return 0.0f;\r
409    memcpy( &f, *bp, 4 );\r
410    revbytes( &f, 4, 1 );\r
411    flen += 4;\r
412    *bp += 4;\r
413    return f;\r
414 }\r
415 \r
416 \r
417 char *sgetS0( unsigned char **bp )\r
418 {\r
419    char *s;\r
420    unsigned char *buf = *bp;\r
421    int len;\r
422 \r
423    if ( flen == FLEN_ERROR ) return NULL;\r
424 \r
425    len = strlen( buf ) + 1;\r
426    if ( len == 1 ) {\r
427       flen += 2;\r
428       *bp += 2;\r
429       return NULL;\r
430    }\r
431    len += len & 1;\r
432    s = _pico_alloc( len );\r
433    if ( !s ) {\r
434       flen = FLEN_ERROR;\r
435       return NULL;\r
436    }\r
437 \r
438    memcpy( s, buf, len );\r
439    flen += len;\r
440    *bp += len;\r
441    return s;\r
442 }\r