PageRenderTime 96ms CodeModel.GetById 25ms app.highlight 61ms RepoModel.GetById 2ms app.codeStats 0ms

/src/FreeImage/Source/OpenEXR/IlmImf/ImfXdr.h

https://bitbucket.org/cabalistic/ogredeps/
C++ Header | 916 lines | 576 code | 223 blank | 117 comment | 32 complexity | c0d4e4802b8c4e2ad476eea7bb680e3f MD5 | raw file
  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