1 | /////////////////////////////////////////////////////////////////////////// |
2 | // |
3 | // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas |
4 | // Digital Ltd. LLC |
5 | // |
6 | // All rights reserved. |
7 | // |
8 | // Redistribution and use in source and binary forms, with or without |
9 | // modification, are permitted provided that the following conditions are |
10 | // met: |
11 | // * Redistributions of source code must retain the above copyright |
12 | // notice, this list of conditions and the following disclaimer. |
13 | // * Redistributions in binary form must reproduce the above |
14 | // copyright notice, this list of conditions and the following disclaimer |
15 | // in the documentation and/or other materials provided with the |
16 | // distribution. |
17 | // * Neither the name of Industrial Light & Magic nor the names of |
18 | // its contributors may be used to endorse or promote products derived |
19 | // from this software without specific prior written permission. |
20 | // |
21 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
22 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
23 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
24 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
25 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
26 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
27 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
28 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
29 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
30 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
31 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
32 | // |
33 | /////////////////////////////////////////////////////////////////////////// |
34 | |
35 | |
36 | #ifndef INCLUDED_IMF_XDR_H |
37 | #define INCLUDED_IMF_XDR_H |
38 | |
39 | |
40 | //---------------------------------------------------------------------------- |
41 | // |
42 | // Xdr -- routines to convert data between the machine's native |
43 | // format and a machine-independent external data representation: |
44 | // |
45 | // write<R> (T &o, S v); converts a value, v, of type S |
46 | // into a machine-independent |
47 | // representation and stores the |
48 | // result in an output buffer, o. |
49 | // |
50 | // read<R> (T &i, S &v); reads the machine-independent |
51 | // representation of a value of type |
52 | // S from input buffer i, converts |
53 | // the value into the machine's native |
54 | // representation, and stores the result |
55 | // in v. |
56 | // |
57 | // size<S>(); returns the size, in bytes, of the |
58 | // machine-independent representation |
59 | // of an object of type S. |
60 | // |
61 | // The write() and read() routines are templates; data can be written |
62 | // to and read from any output or input buffer type T for which a helper |
63 | // class, R, exits. Class R must define a method to store a char array |
64 | // in a T, and a method to read a char array from a T: |
65 | // |
66 | // struct R |
67 | // { |
68 | // static void |
69 | // writeChars (T &o, const char c[/*n*/], int n) |
70 | // { |
71 | // ... // Write c[0], c[1] ... c[n-1] to output buffer o. |
72 | // } |
73 | // |
74 | // static void |
75 | // readChars (T &i, char c[/*n*/], int n) |
76 | // { |
77 | // ... // Read n characters from input buffer i |
78 | // // and copy them to c[0], c[1] ... c[n-1]. |
79 | // } |
80 | // }; |
81 | // |
82 | // Example - writing to and reading from iostreams: |
83 | // |
84 | // struct CharStreamIO |
85 | // { |
86 | // static void |
87 | // writeChars (ostream &os, const char c[], int n) |
88 | // { |
89 | // os.write (c, n); |
90 | // } |
91 | // |
92 | // static void |
93 | // readChars (istream &is, char c[], int n) |
94 | // { |
95 | // is.read (c, n); |
96 | // } |
97 | // }; |
98 | // |
99 | // ... |
100 | // |
101 | // Xdr::write<CharStreamIO> (os, 3); |
102 | // Xdr::write<CharStreamIO> (os, 5.0); |
103 | // |
104 | //---------------------------------------------------------------------------- |
105 | |
106 | #include "ImfInt64.h" |
107 | #include "IexMathExc.h" |
108 | #include "half.h" |
109 | #include <limits.h> |
110 | |
111 | #include "ImfNamespace.h" |
112 | |
113 | OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER |
114 | |
115 | namespace Xdr { |
116 | |
117 | |
118 | //------------------------------- |
119 | // Write data to an output stream |
120 | //------------------------------- |
121 | |
122 | template <class S, class T> |
123 | void |
124 | write (T &out, bool v); |
125 | |
126 | template <class S, class T> |
127 | void |
128 | write (T &out, char v); |
129 | |
130 | template <class S, class T> |
131 | void |
132 | write (T &out, signed char v); |
133 | |
134 | template <class S, class T> |
135 | void |
136 | write (T &out, unsigned char v); |
137 | |
138 | template <class S, class T> |
139 | void |
140 | write (T &out, signed short v); |
141 | |
142 | template <class S, class T> |
143 | void |
144 | write (T &out, unsigned short v); |
145 | |
146 | template <class S, class T> |
147 | void |
148 | write (T &out, signed int v); |
149 | |
150 | template <class S, class T> |
151 | void |
152 | write (T &out, unsigned int v); |
153 | |
154 | template <class S, class T> |
155 | void |
156 | write (T &out, signed long v); |
157 | |
158 | template <class S, class T> |
159 | void |
160 | write (T &out, unsigned long v); |
161 | |
162 | #if ULONG_MAX != 18446744073709551615LU |
163 | |
164 | template <class S, class T> |
165 | void |
166 | write (T &out, Int64 v); |
167 | |
168 | #endif |
169 | |
170 | template <class S, class T> |
171 | void |
172 | write (T &out, float v); |
173 | |
174 | template <class S, class T> |
175 | void |
176 | write (T &out, double v); |
177 | |
178 | template <class S, class T> |
179 | void |
180 | write (T &out, half v); |
181 | |
182 | template <class S, class T> |
183 | void |
184 | write (T &out, const char v[/*n*/], int n); // fixed-size char array |
185 | |
186 | template <class S, class T> |
187 | void |
188 | write (T &out, const char v[]); // zero-terminated string |
189 | |
190 | |
191 | //----------------------------------------- |
192 | // Append padding bytes to an output stream |
193 | //----------------------------------------- |
194 | |
195 | template <class S, class T> |
196 | void |
197 | pad (T &out, int n); // write n padding bytes |
198 | |
199 | |
200 | |
201 | //------------------------------- |
202 | // Read data from an input stream |
203 | //------------------------------- |
204 | |
205 | template <class S, class T> |
206 | void |
207 | read (T &in, bool &v); |
208 | |
209 | template <class S, class T> |
210 | void |
211 | read (T &in, char &v); |
212 | |
213 | template <class S, class T> |
214 | void |
215 | read (T &in, signed char &v); |
216 | |
217 | template <class S, class T> |
218 | void |
219 | read (T &in, unsigned char &v); |
220 | |
221 | template <class S, class T> |
222 | void |
223 | read (T &in, signed short &v); |
224 | |
225 | template <class S, class T> |
226 | void |
227 | read (T &in, unsigned short &v); |
228 | |
229 | template <class S, class T> |
230 | void |
231 | read (T &in, signed int &v); |
232 | |
233 | template <class S, class T> |
234 | void |
235 | read (T &in, unsigned int &v); |
236 | |
237 | template <class S, class T> |
238 | void |
239 | read (T &in, signed long &v); |
240 | |
241 | template <class S, class T> |
242 | void |
243 | read (T &in, unsigned long &v); |
244 | |
245 | #if ULONG_MAX != 18446744073709551615LU |
246 | |
247 | template <class S, class T> |
248 | void |
249 | read (T &in, Int64 &v); |
250 | |
251 | #endif |
252 | |
253 | template <class S, class T> |
254 | void |
255 | read (T &in, float &v); |
256 | |
257 | template <class S, class T> |
258 | void |
259 | read (T &in, double &v); |
260 | |
261 | template <class S, class T> |
262 | void |
263 | read (T &in, half &v); |
264 | |
265 | template <class S, class T> |
266 | void |
267 | read (T &in, char v[/*n*/], int n); // fixed-size char array |
268 | |
269 | template <class S, class T> |
270 | void |
271 | read (T &in, int n, char v[/*n*/]); // zero-terminated string |
272 | |
273 | |
274 | //------------------------------------------- |
275 | // Skip over padding bytes in an input stream |
276 | //------------------------------------------- |
277 | |
278 | template <class S, class T> |
279 | void |
280 | skip (T &in, int n); // skip n padding bytes |
281 | |
282 | |
283 | |
284 | //-------------------------------------- |
285 | // Size of the machine-independent |
286 | // representation of an object of type S |
287 | //-------------------------------------- |
288 | |
289 | template <class S> |
290 | int |
291 | size (); |
292 | |
293 | |
294 | //--------------- |
295 | // Implementation |
296 | //--------------- |
297 | |
298 | template <class S, class T> |
299 | inline void |
300 | writeSignedChars (T &out, const signed char c[], int n) |
301 | { |
302 | S::writeChars (out, (const char *) c, n); |
303 | } |
304 | |
305 | |
306 | template <class S, class T> |
307 | inline void |
308 | writeUnsignedChars (T &out, const unsigned char c[], int n) |
309 | { |
310 | S::writeChars (out, (const char *) c, n); |
311 | } |
312 | |
313 | |
314 | template <class S, class T> |
315 | inline void |
316 | readSignedChars (T &in, signed char c[], int n) |
317 | { |
318 | S::readChars (in, (char *) c, n); |
319 | } |
320 | |
321 | |
322 | template <class S, class T> |
323 | inline void |
324 | readUnsignedChars (T &in, unsigned char c[], int n) |
325 | { |
326 | S::readChars (in, (char *) c, n); |
327 | } |
328 | |
329 | |
330 | template <class S, class T> |
331 | inline void |
332 | write (T &out, bool v) |
333 | { |
334 | char c = !!v; |
335 | S::writeChars (out, &c, 1); |
336 | } |
337 | |
338 | |
339 | template <class S, class T> |
340 | inline void |
341 | write (T &out, char v) |
342 | { |
343 | S::writeChars (out, &v, 1); |
344 | } |
345 | |
346 | |
347 | template <class S, class T> |
348 | inline void |
349 | write (T &out, signed char v) |
350 | { |
351 | writeSignedChars<S> (out, &v, 1); |
352 | } |
353 | |
354 | |
355 | template <class S, class T> |
356 | inline void |
357 | write (T &out, unsigned char v) |
358 | { |
359 | writeUnsignedChars<S> (out, &v, 1); |
360 | } |
361 | |
362 | |
363 | template <class S, class T> |
364 | void |
365 | write (T &out, signed short v) |
366 | { |
367 | signed char b[2]; |
368 | |
369 | b[0] = (signed char) (v); |
370 | b[1] = (signed char) (v >> 8); |
371 | |
372 | writeSignedChars<S> (out, b, 2); |
373 | } |
374 | |
375 | |
376 | template <class S, class T> |
377 | void |
378 | write (T &out, unsigned short v) |
379 | { |
380 | unsigned char b[2]; |
381 | |
382 | b[0] = (unsigned char) (v); |
383 | b[1] = (unsigned char) (v >> 8); |
384 | |
385 | writeUnsignedChars<S> (out, b, 2); |
386 | } |
387 | |
388 | |
389 | template <class S, class T> |
390 | void |
391 | write (T &out, signed int v) |
392 | { |
393 | signed char b[4]; |
394 | |
395 | b[0] = (signed char) (v); |
396 | b[1] = (signed char) (v >> 8); |
397 | b[2] = (signed char) (v >> 16); |
398 | b[3] = (signed char) (v >> 24); |
399 | |
400 | writeSignedChars<S> (out, b, 4); |
401 | } |
402 | |
403 | |
404 | template <class S, class T> |
405 | void |
406 | write (T &out, unsigned int v) |
407 | { |
408 | unsigned char b[4]; |
409 | |
410 | b[0] = (unsigned char) (v); |
411 | b[1] = (unsigned char) (v >> 8); |
412 | b[2] = (unsigned char) (v >> 16); |
413 | b[3] = (unsigned char) (v >> 24); |
414 | |
415 | writeUnsignedChars<S> (out, b, 4); |
416 | } |
417 | |
418 | |
419 | template <class S, class T> |
420 | void |
421 | write (T &out, signed long v) |
422 | { |
423 | signed char b[8]; |
424 | |
425 | b[0] = (signed char) (v); |
426 | b[1] = (signed char) (v >> 8); |
427 | b[2] = (signed char) (v >> 16); |
428 | b[3] = (signed char) (v >> 24); |
429 | |
430 | #if LONG_MAX == 2147483647 |
431 | |
432 | if (v >= 0) |
433 | { |
434 | b[4] = 0; |
435 | b[5] = 0; |
436 | b[6] = 0; |
437 | b[7] = 0; |
438 | } |
439 | else |
440 | { |
441 | b[4] = ~0; |
442 | b[5] = ~0; |
443 | b[6] = ~0; |
444 | b[7] = ~0; |
445 | } |
446 | |
447 | #elif LONG_MAX == 9223372036854775807L |
448 | |
449 | b[4] = (signed char) (v >> 32); |
450 | b[5] = (signed char) (v >> 40); |
451 | b[6] = (signed char) (v >> 48); |
452 | b[7] = (signed char) (v >> 56); |
453 | |
454 | #else |
455 | |
456 | #error write<T> (T &out, signed long v) not implemented |
457 | |
458 | #endif |
459 | |
460 | writeSignedChars<S> (out, b, 8); |
461 | } |
462 | |
463 | |
464 | template <class S, class T> |
465 | void |
466 | write (T &out, unsigned long v) |
467 | { |
468 | unsigned char b[8]; |
469 | |
470 | b[0] = (unsigned char) (v); |
471 | b[1] = (unsigned char) (v >> 8); |
472 | b[2] = (unsigned char) (v >> 16); |
473 | b[3] = (unsigned char) (v >> 24); |
474 | |
475 | #if ULONG_MAX == 4294967295U |
476 | |
477 | b[4] = 0; |
478 | b[5] = 0; |
479 | b[6] = 0; |
480 | b[7] = 0; |
481 | |
482 | #elif ULONG_MAX == 18446744073709551615LU |
483 | |
484 | b[4] = (unsigned char) (v >> 32); |
485 | b[5] = (unsigned char) (v >> 40); |
486 | b[6] = (unsigned char) (v >> 48); |
487 | b[7] = (unsigned char) (v >> 56); |
488 | |
489 | #else |
490 | |
491 | #error write<T> (T &out, unsigned long v) not implemented |
492 | |
493 | #endif |
494 | |
495 | writeUnsignedChars<S> (out, b, 8); |
496 | } |
497 | |
498 | |
499 | #if ULONG_MAX != 18446744073709551615LU |
500 | |
501 | template <class S, class T> |
502 | void |
503 | write (T &out, Int64 v) |
504 | { |
505 | unsigned char b[8]; |
506 | |
507 | b[0] = (unsigned char) (v); |
508 | b[1] = (unsigned char) (v >> 8); |
509 | b[2] = (unsigned char) (v >> 16); |
510 | b[3] = (unsigned char) (v >> 24); |
511 | b[4] = (unsigned char) (v >> 32); |
512 | b[5] = (unsigned char) (v >> 40); |
513 | b[6] = (unsigned char) (v >> 48); |
514 | b[7] = (unsigned char) (v >> 56); |
515 | |
516 | writeUnsignedChars<S> (out, b, 8); |
517 | } |
518 | |
519 | #endif |
520 | |
521 | |
522 | template <class S, class T> |
523 | void |
524 | write (T &out, float v) |
525 | { |
526 | union {unsigned int i; float f;} u; |
527 | u.f = v; |
528 | |
529 | unsigned char b[4]; |
530 | |
531 | b[0] = (unsigned char) (u.i); |
532 | b[1] = (unsigned char) (u.i >> 8); |
533 | b[2] = (unsigned char) (u.i >> 16); |
534 | b[3] = (unsigned char) (u.i >> 24); |
535 | |
536 | writeUnsignedChars<S> (out, b, 4); |
537 | } |
538 | |
539 | |
540 | template <class S, class T> |
541 | void |
542 | write (T &out, double v) |
543 | { |
544 | union {Int64 i; double d;} u; |
545 | u.d = v; |
546 | |
547 | unsigned char b[8]; |
548 | |
549 | b[0] = (unsigned char) (u.i); |
550 | b[1] = (unsigned char) (u.i >> 8); |
551 | b[2] = (unsigned char) (u.i >> 16); |
552 | b[3] = (unsigned char) (u.i >> 24); |
553 | b[4] = (unsigned char) (u.i >> 32); |
554 | b[5] = (unsigned char) (u.i >> 40); |
555 | b[6] = (unsigned char) (u.i >> 48); |
556 | b[7] = (unsigned char) (u.i >> 56); |
557 | |
558 | writeUnsignedChars<S> (out, b, 8); |
559 | } |
560 | |
561 | |
562 | template <class S, class T> |
563 | inline void |
564 | write (T &out, half v) |
565 | { |
566 | unsigned char b[2]; |
567 | |
568 | b[0] = (unsigned char) (v.bits()); |
569 | b[1] = (unsigned char) (v.bits() >> 8); |
570 | |
571 | writeUnsignedChars<S> (out, b, 2); |
572 | } |
573 | |
574 | |
575 | template <class S, class T> |
576 | inline void |
577 | write (T &out, const char v[], int n) // fixed-size char array |
578 | { |
579 | S::writeChars (out, v, n); |
580 | } |
581 | |
582 | |
583 | template <class S, class T> |
584 | void |
585 | write (T &out, const char v[]) // zero-terminated string |
586 | { |
587 | while (*v) |
588 | { |
589 | S::writeChars (out, v, 1); |
590 | ++v; |
591 | } |
592 | |
593 | S::writeChars (out, v, 1); |
594 | } |
595 | |
596 | |
597 | template <class S, class T> |
598 | void |
599 | pad (T &out, int n) // add n padding bytes |
600 | { |
601 | for (int i = 0; i < n; i++) |
602 | { |
603 | const char c = 0; |
604 | S::writeChars (out, &c, 1); |
605 | } |
606 | } |
607 | |
608 | |
609 | template <class S, class T> |
610 | inline void |
611 | read (T &in, bool &v) |
612 | { |
613 | char c; |
614 | |
615 | S::readChars (in, &c, 1); |
616 | v = !!c; |
617 | } |
618 | |
619 | |
620 | template <class S, class T> |
621 | inline void |
622 | read (T &in, char &v) |
623 | { |
624 | S::readChars (in, &v, 1); |
625 | } |
626 | |
627 | |
628 | template <class S, class T> |
629 | inline void |
630 | read (T &in, signed char &v) |
631 | { |
632 | readSignedChars<S> (in, &v, 1); |
633 | } |
634 | |
635 | |
636 | template <class S, class T> |
637 | inline void |
638 | read (T &in, unsigned char &v) |
639 | { |
640 | readUnsignedChars<S> (in, &v, 1); |
641 | } |
642 | |
643 | |
644 | template <class S, class T> |
645 | void |
646 | read (T &in, signed short &v) |
647 | { |
648 | signed char b[2]; |
649 | |
650 | readSignedChars<S> (in, b, 2); |
651 | |
652 | v = (static_cast <unsigned char> (b[0]) & 0x00ff) | |
653 | (static_cast <unsigned char> (b[1]) << 8); |
654 | } |
655 | |
656 | |
657 | template <class S, class T> |
658 | void |
659 | read (T &in, unsigned short &v) |
660 | { |
661 | unsigned char b[2]; |
662 | |
663 | readUnsignedChars<S> (in, b, 2); |
664 | |
665 | v = (b[0] & 0x00ff) | |
666 | (b[1] << 8); |
667 | } |
668 | |
669 | |
670 | template <class S, class T> |
671 | void |
672 | read (T &in, signed int &v) |
673 | { |
674 | signed char b[4]; |
675 | |
676 | readSignedChars<S> (in, b, 4); |
677 | |
678 | v = (static_cast <unsigned char> (b[0]) & 0x000000ff) | |
679 | ((static_cast <unsigned char> (b[1]) << 8) & 0x0000ff00) | |
680 | ((static_cast <unsigned char> (b[2]) << 16) & 0x00ff0000) | |
681 | (static_cast <unsigned char> (b[3]) << 24); |
682 | } |
683 | |
684 | |
685 | template <class S, class T> |
686 | void |
687 | read (T &in, unsigned int &v) |
688 | { |
689 | unsigned char b[4]; |
690 | |
691 | readUnsignedChars<S> (in, b, 4); |
692 | |
693 | v = (b[0] & 0x000000ff) | |
694 | ((b[1] << 8) & 0x0000ff00) | |
695 | ((b[2] << 16) & 0x00ff0000) | |
696 | (b[3] << 24); |
697 | } |
698 | |
699 | |
700 | template <class S, class T> |
701 | void |
702 | read (T &in, signed long &v) |
703 | { |
704 | signed char b[8]; |
705 | |
706 | readSignedChars<S> (in, b, 8); |
707 | |
708 | #if LONG_MAX == 2147483647 |
709 | |
710 | v = (static_cast <unsigned long> (b[0]) & 0x000000ff) | |
711 | ((static_cast <unsigned long> (b[1]) << 8) & 0x0000ff00) | |
712 | ((static_cast <unsigned long> (b[2]) << 16) & 0x00ff0000) | |
713 | (static_cast <unsigned long> (b[3]) << 24); |
714 | |
715 | if (( b[4] || b[5] || b[6] || b[7]) && |
716 | (~b[4] || ~b[5] || ~b[6] || ~b[7])) |
717 | { |
718 | throw IEX_NAMESPACE::OverflowExc ("Long int overflow - read a large " |
719 | "64-bit integer in a 32-bit process." ); |
720 | } |
721 | |
722 | #elif LONG_MAX == 9223372036854775807L |
723 | |
724 | v = (static_cast <unsigned long> (b[0]) & 0x00000000000000ff) | |
725 | ((static_cast <unsigned long> (b[1]) << 8) & 0x000000000000ff00) | |
726 | ((static_cast <unsigned long> (b[2]) << 16) & 0x0000000000ff0000) | |
727 | ((static_cast <unsigned long> (b[3]) << 24) & 0x00000000ff000000) | |
728 | ((static_cast <unsigned long> (b[4]) << 32) & 0x000000ff00000000) | |
729 | ((static_cast <unsigned long> (b[5]) << 40) & 0x0000ff0000000000) | |
730 | ((static_cast <unsigned long> (b[6]) << 48) & 0x00ff000000000000) | |
731 | (static_cast <unsigned long> (b[7]) << 56); |
732 | |
733 | #else |
734 | |
735 | #error read<T> (T &in, signed long &v) not implemented |
736 | |
737 | #endif |
738 | } |
739 | |
740 | |
741 | template <class S, class T> |
742 | void |
743 | read (T &in, unsigned long &v) |
744 | { |
745 | unsigned char b[8]; |
746 | |
747 | readUnsignedChars<S> (in, b, 8); |
748 | |
749 | #if ULONG_MAX == 4294967295U |
750 | |
751 | v = (b[0] & 0x000000ff) | |
752 | ((b[1] << 8) & 0x0000ff00) | |
753 | ((b[2] << 16) & 0x00ff0000) | |
754 | (b[3] << 24); |
755 | |
756 | if (b[4] || b[5] || b[6] || b[7]) |
757 | { |
758 | throw IEX_NAMESPACE::OverflowExc ("Long int overflow - read a large " |
759 | "64-bit integer in a 32-bit process." ); |
760 | } |
761 | |
762 | #elif ULONG_MAX == 18446744073709551615LU |
763 | |
764 | v = ((unsigned long) b[0] & 0x00000000000000ff) | |
765 | (((unsigned long) b[1] << 8) & 0x000000000000ff00) | |
766 | (((unsigned long) b[2] << 16) & 0x0000000000ff0000) | |
767 | (((unsigned long) b[3] << 24) & 0x00000000ff000000) | |
768 | (((unsigned long) b[4] << 32) & 0x000000ff00000000) | |
769 | (((unsigned long) b[5] << 40) & 0x0000ff0000000000) | |
770 | (((unsigned long) b[6] << 48) & 0x00ff000000000000) | |
771 | ((unsigned long) b[7] << 56); |
772 | |
773 | #else |
774 | |
775 | #error read<T> (T &in, unsigned long &v) not implemented |
776 | |
777 | #endif |
778 | } |
779 | |
780 | |
781 | #if ULONG_MAX != 18446744073709551615LU |
782 | |
783 | template <class S, class T> |
784 | void |
785 | read (T &in, Int64 &v) |
786 | { |
787 | unsigned char b[8]; |
788 | |
789 | readUnsignedChars<S> (in, b, 8); |
790 | |
791 | v = ((Int64) b[0] & 0x00000000000000ffLL) | |
792 | (((Int64) b[1] << 8) & 0x000000000000ff00LL) | |
793 | (((Int64) b[2] << 16) & 0x0000000000ff0000LL) | |
794 | (((Int64) b[3] << 24) & 0x00000000ff000000LL) | |
795 | (((Int64) b[4] << 32) & 0x000000ff00000000LL) | |
796 | (((Int64) b[5] << 40) & 0x0000ff0000000000LL) | |
797 | (((Int64) b[6] << 48) & 0x00ff000000000000LL) | |
798 | ((Int64) b[7] << 56); |
799 | } |
800 | |
801 | #endif |
802 | |
803 | |
804 | template <class S, class T> |
805 | void |
806 | read (T &in, float &v) |
807 | { |
808 | unsigned char b[4]; |
809 | |
810 | readUnsignedChars<S> (in, b, 4); |
811 | |
812 | union {unsigned int i; float f;} u; |
813 | |
814 | u.i = (b[0] & 0x000000ff) | |
815 | ((b[1] << 8) & 0x0000ff00) | |
816 | ((b[2] << 16) & 0x00ff0000) | |
817 | (b[3] << 24); |
818 | |
819 | v = u.f; |
820 | } |
821 | |
822 | |
823 | template <class S, class T> |
824 | void |
825 | read (T &in, double &v) |
826 | { |
827 | unsigned char b[8]; |
828 | |
829 | readUnsignedChars<S> (in, b, 8); |
830 | |
831 | union {Int64 i; double d;} u; |
832 | |
833 | u.i = ((Int64) b[0] & 0x00000000000000ffULL) | |
834 | (((Int64) b[1] << 8) & 0x000000000000ff00ULL) | |
835 | (((Int64) b[2] << 16) & 0x0000000000ff0000ULL) | |
836 | (((Int64) b[3] << 24) & 0x00000000ff000000ULL) | |
837 | (((Int64) b[4] << 32) & 0x000000ff00000000ULL) | |
838 | (((Int64) b[5] << 40) & 0x0000ff0000000000ULL) | |
839 | (((Int64) b[6] << 48) & 0x00ff000000000000ULL) | |
840 | ((Int64) b[7] << 56); |
841 | |
842 | v = u.d; |
843 | } |
844 | |
845 | |
846 | template <class S, class T> |
847 | inline void |
848 | read (T &in, half &v) |
849 | { |
850 | unsigned char b[2]; |
851 | |
852 | readUnsignedChars<S> (in, b, 2); |
853 | |
854 | v.setBits ((b[0] & 0x00ff) | (b[1] << 8)); |
855 | } |
856 | |
857 | |
858 | template <class S, class T> |
859 | inline void |
860 | read (T &in, char v[], int n) // fixed-size char array |
861 | { |
862 | S::readChars (in, v, n); |
863 | } |
864 | |
865 | |
866 | template <class S, class T> |
867 | void |
868 | read (T &in, int n, char v[]) // zero-terminated string |
869 | { |
870 | while (n >= 0) |
871 | { |
872 | S::readChars (in, v, 1); |
873 | |
874 | if (*v == 0) |
875 | break; |
876 | |
877 | --n; |
878 | ++v; |
879 | } |
880 | } |
881 | |
882 | |
883 | template <class S, class T> |
884 | void |
885 | skip (T &in, int n) // skip n padding bytes |
886 | { |
887 | char c[1024]; |
888 | |
889 | while (n >= (int) sizeof (c)) |
890 | { |
891 | if (!S::readChars (in, c, sizeof (c))) |
892 | return; |
893 | |
894 | n -= sizeof (c); |
895 | } |
896 | |
897 | if (n >= 1) |
898 | S::readChars (in, c, n); |
899 | } |
900 | |
901 | |
902 | template <> inline int size <bool> () {return 1;} |
903 | template <> inline int size <char> () {return 1;} |
904 | template <> inline int size <signed char> () {return 1;} |
905 | template <> inline int size <unsigned char> () {return 1;} |
906 | template <> inline int size <signed short> () {return 2;} |
907 | template <> inline int size <unsigned short> () {return 2;} |
908 | template <> inline int size <signed int> () {return 4;} |
909 | template <> inline int size <unsigned int> () {return 4;} |
910 | template <> inline int size <signed long> () {return 8;} |
911 | template <> inline int size <unsigned long> () {return 8;} |
912 | template <> inline int size <unsigned long long> () {return 8;} |
913 | template <> inline int size <float> () {return 4;} |
914 | template <> inline int size <double> () {return 8;} |
915 | template <> inline int size <half> () {return 2;} |
916 | |
917 | |
918 | } // namespace Xdr |
919 | OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT |
920 | |
921 | |
922 | #if defined (OPENEXR_IMF_INTERNAL_NAMESPACE_AUTO_EXPOSE) |
923 | namespace Imf{using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;} |
924 | #endif |
925 | |
926 | |
927 | #endif |
928 | |