source: NonGTP/OpenEXR/include/IlmImf/ImfXdr.h @ 855

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