HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ImfXdr.h
Go to the documentation of this file.
1 //
2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright (c) Contributors to the OpenEXR Project.
4 //
5 
6 #ifndef INCLUDED_IMF_XDR_H
7 #define INCLUDED_IMF_XDR_H
8 
9 
10 //----------------------------------------------------------------------------
11 //
12 // Xdr -- routines to convert data between the machine's native
13 // format and a machine-independent external data representation:
14 //
15 // write<R> (T &o, S v); converts a value, v, of type S
16 // into a machine-independent
17 // representation and stores the
18 // result in an output buffer, o.
19 //
20 // read<R> (T &i, S &v); reads the machine-independent
21 // representation of a value of type
22 // S from input buffer i, converts
23 // the value into the machine's native
24 // representation, and stores the result
25 // in v.
26 //
27 // size<S>(); returns the size, in bytes, of the
28 // machine-independent representation
29 // of an object of type S.
30 //
31 // The write() and read() routines are templates; data can be written
32 // to and read from any output or input buffer type T for which a helper
33 // class, R, exits. Class R must define a method to store a char array
34 // in a T, and a method to read a char array from a T:
35 //
36 // struct R
37 // {
38 // static void
39 // writeChars (T &o, const char c[/*n*/], int n)
40 // {
41 // ... // Write c[0], c[1] ... c[n-1] to output buffer o.
42 // }
43 //
44 // static void
45 // readChars (T &i, char c[/*n*/], int n)
46 // {
47 // ... // Read n characters from input buffer i
48 // // and copy them to c[0], c[1] ... c[n-1].
49 // }
50 // };
51 //
52 // Example - writing to and reading from iostreams:
53 //
54 // struct CharStreamIO
55 // {
56 // static void
57 // writeChars (ostream &os, const char c[], int n)
58 // {
59 // os.write (c, n);
60 // }
61 //
62 // static void
63 // readChars (istream &is, char c[], int n)
64 // {
65 // is.read (c, n);
66 // }
67 // };
68 //
69 // ...
70 //
71 // Xdr::write<CharStreamIO> (os, 3);
72 // Xdr::write<CharStreamIO> (os, 5.0);
73 //
74 //----------------------------------------------------------------------------
75 
76 #include "ImfNamespace.h"
77 
78 #include "IexMathExc.h"
79 #include <half.h>
80 #include <limits.h>
81 #include <cstdint>
82 
84 
85 namespace Xdr {
86 
87 
88 //-------------------------------
89 // Write data to an output stream
90 //-------------------------------
91 
92 template <class S, class T>
93 void
94 write (T &out, bool v);
95 
96 template <class S, class T>
97 void
98 write (T &out, char v);
99 
100 template <class S, class T>
101 void
102 write (T &out, signed char v);
103 
104 template <class S, class T>
105 void
106 write (T &out, unsigned char v);
107 
108 template <class S, class T>
109 void
110 write (T &out, signed short v);
111 
112 template <class S, class T>
113 void
114 write (T &out, unsigned short v);
115 
116 template <class S, class T>
117 void
118 write (T &out, signed int v);
119 
120 template <class S, class T>
121 void
122 write (T &out, unsigned int v);
123 
124 template <class S, class T>
125 void
126 write (T &out, int64_t v);
127 
128 template <class S, class T>
129 void
130 write (T &out, uint64_t v);
131 
132 
133 template <class S, class T>
134 void
135 write (T &out, float v);
136 
137 template <class S, class T>
138 void
139 write (T &out, double v);
140 
141 template <class S, class T>
142 void
143 write (T &out, half v);
144 
145 template <class S, class T>
146 void
147 write (T &out, const char v[/*n*/], int n); // fixed-size char array
148 
149 template <class S, class T>
150 void
151 write (T &out, const char v[]); // zero-terminated string
152 
153 
154 //-----------------------------------------
155 // Append padding bytes to an output stream
156 //-----------------------------------------
157 
158 template <class S, class T>
159 void
160 pad (T &out, int n); // write n padding bytes
161 
162 
163 
164 //-------------------------------
165 // Read data from an input stream
166 //-------------------------------
167 
168 template <class S, class T>
169 void
170 read (T &in, bool &v);
171 
172 template <class S, class T>
173 void
174 read (T &in, char &v);
175 
176 template <class S, class T>
177 void
178 read (T &in, signed char &v);
179 
180 template <class S, class T>
181 void
182 read (T &in, unsigned char &v);
183 
184 template <class S, class T>
185 void
186 read (T &in, signed short &v);
187 
188 template <class S, class T>
189 void
190 read (T &in, unsigned short &v);
191 
192 template <class S, class T>
193 void
194 read (T &in, signed int &v);
195 
196 template <class S, class T>
197 void
198 read (T &in, unsigned int &v);
199 
200 template <class S, class T>
201 void
202 read (T &in, int64_t &v);
203 
204 template <class S, class T>
205 void
206 read (T &in, uint64_t &v);
207 
208 template <class S, class T>
209 void
210 read (T &in, float &v);
211 
212 template <class S, class T>
213 void
214 read (T &in, double &v);
215 
216 template <class S, class T>
217 void
218 read (T &in, half &v);
219 
220 template <class S, class T>
221 void
222 read (T &in, char v[/*n*/], int n); // fixed-size char array
223 
224 template <class S, class T>
225 void
226 read (T &in, int n, char v[/*n*/]); // zero-terminated string
227 
228 
229 //-------------------------------------------
230 // Skip over padding bytes in an input stream
231 //-------------------------------------------
232 
233 template <class S, class T>
234 void
235 skip (T &in, int n); // skip n padding bytes
236 
237 
238 
239 //--------------------------------------
240 // Size of the machine-independent
241 // representation of an object of type S
242 //--------------------------------------
243 
244 template <class S>
245 int
246 size ();
247 
248 
249 //---------------
250 // Implementation
251 //---------------
252 
253 template <class S, class T>
254 inline void
255 writeSignedChars (T &out, const signed char c[], int n)
256 {
257  S::writeChars (out, (const char *) c, n);
258 }
259 
260 
261 template <class S, class T>
262 inline void
263 writeUnsignedChars (T &out, const unsigned char c[], int n)
264 {
265  S::writeChars (out, (const char *) c, n);
266 }
267 
268 
269 template <class S, class T>
270 inline void
271 readSignedChars (T &in, signed char c[], int n)
272 {
273  S::readChars (in, (char *) c, n);
274 }
275 
276 
277 template <class S, class T>
278 inline void
279 readUnsignedChars (T &in, unsigned char c[], int n)
280 {
281  S::readChars (in, (char *) c, n);
282 }
283 
284 
285 template <class S, class T>
286 inline void
287 write (T &out, bool v)
288 {
289  char c = !!v;
290  S::writeChars (out, &c, 1);
291 }
292 
293 
294 template <class S, class T>
295 inline void
296 write (T &out, char v)
297 {
298  S::writeChars (out, &v, 1);
299 }
300 
301 
302 template <class S, class T>
303 inline void
304 write (T &out, signed char v)
305 {
306  writeSignedChars<S> (out, &v, 1);
307 }
308 
309 
310 template <class S, class T>
311 inline void
312 write (T &out, unsigned char v)
313 {
314  writeUnsignedChars<S> (out, &v, 1);
315 }
316 
317 
318 template <class S, class T>
319 void
320 write (T &out, signed short v)
321 {
322  signed char b[2];
323 
324  b[0] = (signed char) (v);
325  b[1] = (signed char) (v >> 8);
326 
327  writeSignedChars<S> (out, b, 2);
328 }
329 
330 
331 template <class S, class T>
332 void
333 write (T &out, unsigned short v)
334 {
335  unsigned char b[2];
336 
337  b[0] = (unsigned char) (v);
338  b[1] = (unsigned char) (v >> 8);
339 
340  writeUnsignedChars<S> (out, b, 2);
341 }
342 
343 
344 template <class S, class T>
345 void
346 write (T &out, signed int v)
347 {
348  signed char b[4];
349 
350  b[0] = (signed char) (v);
351  b[1] = (signed char) (v >> 8);
352  b[2] = (signed char) (v >> 16);
353  b[3] = (signed char) (v >> 24);
354 
355  writeSignedChars<S> (out, b, 4);
356 }
357 
358 
359 template <class S, class T>
360 void
361 write (T &out, unsigned int v)
362 {
363  unsigned char b[4];
364 
365  b[0] = (unsigned char) (v);
366  b[1] = (unsigned char) (v >> 8);
367  b[2] = (unsigned char) (v >> 16);
368  b[3] = (unsigned char) (v >> 24);
369 
370  writeUnsignedChars<S> (out, b, 4);
371 }
372 
373 
374 template <class S, class T>
375 void
376 write (T &out, int64_t v)
377 {
378  signed char b[8];
379 
380  b[0] = (signed char) (v);
381  b[1] = (signed char) (v >> 8);
382  b[2] = (signed char) (v >> 16);
383  b[3] = (signed char) (v >> 24);
384  b[4] = (signed char) (v >> 32);
385  b[5] = (signed char) (v >> 40);
386  b[6] = (signed char) (v >> 48);
387  b[7] = (signed char) (v >> 56);
388 
389  writeSignedChars<S> (out, b, 8);
390 }
391 
392 template <class S, class T>
393 void
394 write (T &out, uint64_t v)
395 {
396  unsigned char b[8];
397 
398  b[0] = (unsigned char) (v);
399  b[1] = (unsigned char) (v >> 8);
400  b[2] = (unsigned char) (v >> 16);
401  b[3] = (unsigned char) (v >> 24);
402  b[4] = (unsigned char) (v >> 32);
403  b[5] = (unsigned char) (v >> 40);
404  b[6] = (unsigned char) (v >> 48);
405  b[7] = (unsigned char) (v >> 56);
406 
407  writeUnsignedChars<S> (out, b, 8);
408 }
409 
410 
411 
412 
413 template <class S, class T>
414 void
415 write (T &out, float v)
416 {
417  union {unsigned int i; float f;} u;
418  u.f = v;
419 
420  unsigned char b[4];
421 
422  b[0] = (unsigned char) (u.i);
423  b[1] = (unsigned char) (u.i >> 8);
424  b[2] = (unsigned char) (u.i >> 16);
425  b[3] = (unsigned char) (u.i >> 24);
426 
427  writeUnsignedChars<S> (out, b, 4);
428 }
429 
430 
431 template <class S, class T>
432 void
433 write (T &out, double v)
434 {
435  union {uint64_t i; double d;} u;
436  u.d = v;
437 
438  unsigned char b[8];
439 
440  b[0] = (unsigned char) (u.i);
441  b[1] = (unsigned char) (u.i >> 8);
442  b[2] = (unsigned char) (u.i >> 16);
443  b[3] = (unsigned char) (u.i >> 24);
444  b[4] = (unsigned char) (u.i >> 32);
445  b[5] = (unsigned char) (u.i >> 40);
446  b[6] = (unsigned char) (u.i >> 48);
447  b[7] = (unsigned char) (u.i >> 56);
448 
449  writeUnsignedChars<S> (out, b, 8);
450 }
451 
452 
453 template <class S, class T>
454 inline void
455 write (T &out, half v)
456 {
457  unsigned char b[2];
458 
459  b[0] = (unsigned char) (v.bits());
460  b[1] = (unsigned char) (v.bits() >> 8);
461 
462  writeUnsignedChars<S> (out, b, 2);
463 }
464 
465 
466 template <class S, class T>
467 inline void
468 write (T &out, const char v[], int n) // fixed-size char array
469 {
470  S::writeChars (out, v, n);
471 }
472 
473 
474 template <class S, class T>
475 void
476 write (T &out, const char v[]) // zero-terminated string
477 {
478  while (*v)
479  {
480  S::writeChars (out, v, 1);
481  ++v;
482  }
483 
484  S::writeChars (out, v, 1);
485 }
486 
487 
488 template <class S, class T>
489 void
490 pad (T &out, int n) // add n padding bytes
491 {
492  for (int i = 0; i < n; i++)
493  {
494  const char c = 0;
495  S::writeChars (out, &c, 1);
496  }
497 }
498 
499 
500 template <class S, class T>
501 inline void
502 read (T &in, bool &v)
503 {
504  char c;
505 
506  S::readChars (in, &c, 1);
507  v = !!c;
508 }
509 
510 
511 template <class S, class T>
512 inline void
513 read (T &in, char &v)
514 {
515  S::readChars (in, &v, 1);
516 }
517 
518 
519 template <class S, class T>
520 inline void
521 read (T &in, signed char &v)
522 {
523  readSignedChars<S> (in, &v, 1);
524 }
525 
526 
527 template <class S, class T>
528 inline void
529 read (T &in, unsigned char &v)
530 {
531  readUnsignedChars<S> (in, &v, 1);
532 }
533 
534 
535 template <class S, class T>
536 void
537 read (T &in, signed short &v)
538 {
539  signed char b[2];
540 
541  readSignedChars<S> (in, b, 2);
542 
543  v = (static_cast <unsigned char> (b[0]) & 0x00ff) |
544  (static_cast <unsigned char> (b[1]) << 8);
545 }
546 
547 
548 template <class S, class T>
549 void
550 read (T &in, unsigned short &v)
551 {
552  unsigned char b[2];
553 
554  readUnsignedChars<S> (in, b, 2);
555 
556  v = (b[0] & 0x00ff) |
557  (b[1] << 8);
558 }
559 
560 
561 template <class S, class T>
562 void
563 read (T &in, signed int &v)
564 {
565  signed char b[4];
566 
567  readSignedChars<S> (in, b, 4);
568 
569  v = (static_cast <unsigned char> (b[0]) & 0x000000ff) |
570  ((static_cast <unsigned char> (b[1]) << 8) & 0x0000ff00) |
571  ((static_cast <unsigned char> (b[2]) << 16) & 0x00ff0000) |
572  (static_cast <unsigned char> (b[3]) << 24);
573 }
574 
575 
576 template <class S, class T>
577 void
578 read (T &in, unsigned int &v)
579 {
580  unsigned char b[4];
581 
582  readUnsignedChars<S> (in, b, 4);
583 
584  v = (b[0] & 0x000000ff) |
585  ((b[1] << 8) & 0x0000ff00) |
586  ((b[2] << 16) & 0x00ff0000) |
587  (b[3] << 24);
588 }
589 
590 
591 template <class S, class T>
592 void
593 read (T &in, int64_t &v)
594 {
595  signed char b[8];
596 
597  readSignedChars<S> (in, b, 8);
598 
599  v = (static_cast <int64_t> (b[0]) & 0x00000000000000ff) |
600  ((static_cast <int64_t> (b[1]) << 8) & 0x000000000000ff00) |
601  ((static_cast <int64_t> (b[2]) << 16) & 0x0000000000ff0000) |
602  ((static_cast <int64_t> (b[3]) << 24) & 0x00000000ff000000) |
603  ((static_cast <int64_t> (b[4]) << 32) & 0x000000ff00000000) |
604  ((static_cast <int64_t> (b[5]) << 40) & 0x0000ff0000000000) |
605  ((static_cast <int64_t> (b[6]) << 48) & 0x00ff000000000000) |
606  (static_cast <int64_t> (b[7]) << 56);
607 
608 }
609 
610 
611 template <class S, class T>
612 void
613 read (T &in, uint64_t &v)
614 {
615  unsigned char b[8];
616 
617  readUnsignedChars<S> (in, b, 8);
618 
619  v = ((uint64_t) b[0] & 0x00000000000000ffLL) |
620  (((uint64_t) b[1] << 8) & 0x000000000000ff00LL) |
621  (((uint64_t) b[2] << 16) & 0x0000000000ff0000LL) |
622  (((uint64_t) b[3] << 24) & 0x00000000ff000000LL) |
623  (((uint64_t) b[4] << 32) & 0x000000ff00000000LL) |
624  (((uint64_t) b[5] << 40) & 0x0000ff0000000000LL) |
625  (((uint64_t) b[6] << 48) & 0x00ff000000000000LL) |
626  ((uint64_t) b[7] << 56);
627 }
628 
629 
630 template <class S, class T>
631 void
632 read (T &in, float &v)
633 {
634  unsigned char b[4];
635 
636  readUnsignedChars<S> (in, b, 4);
637 
638  union {unsigned int i; float f;} u;
639 
640  u.i = (b[0] & 0x000000ff) |
641  ((b[1] << 8) & 0x0000ff00) |
642  ((b[2] << 16) & 0x00ff0000) |
643  (b[3] << 24);
644 
645  v = u.f;
646 }
647 
648 
649 template <class S, class T>
650 void
651 read (T &in, double &v)
652 {
653  unsigned char b[8];
654 
655  readUnsignedChars<S> (in, b, 8);
656 
657  union {uint64_t i; double d;} u;
658 
659  u.i = ((uint64_t) b[0] & 0x00000000000000ffULL) |
660  (((uint64_t) b[1] << 8) & 0x000000000000ff00ULL) |
661  (((uint64_t) b[2] << 16) & 0x0000000000ff0000ULL) |
662  (((uint64_t) b[3] << 24) & 0x00000000ff000000ULL) |
663  (((uint64_t) b[4] << 32) & 0x000000ff00000000ULL) |
664  (((uint64_t) b[5] << 40) & 0x0000ff0000000000ULL) |
665  (((uint64_t) b[6] << 48) & 0x00ff000000000000ULL) |
666  ((uint64_t) b[7] << 56);
667 
668  v = u.d;
669 }
670 
671 
672 template <class S, class T>
673 inline void
674 read (T &in, half &v)
675 {
676  unsigned char b[2];
677 
678  readUnsignedChars<S> (in, b, 2);
679 
680  v.setBits ((b[0] & 0x00ff) | (b[1] << 8));
681 }
682 
683 
684 template <class S, class T>
685 inline void
686 read (T &in, char v[], int n) // fixed-size char array
687 {
688  S::readChars (in, v, n);
689 }
690 
691 
692 template <class S, class T>
693 void
694 read (T &in, int n, char v[]) // zero-terminated string
695 {
696  while (n >= 0)
697  {
698  S::readChars (in, v, 1);
699 
700  if (*v == 0)
701  break;
702 
703  --n;
704  ++v;
705  }
706 }
707 
708 
709 template <class S, class T>
710 void
711 skip (T &in, int n) // skip n padding bytes
712 {
713  char c[1024];
714 
715  while (n >= (int) sizeof (c))
716  {
717  if (!S::readChars (in, c, sizeof (c)))
718  return;
719 
720  n -= sizeof (c);
721  }
722 
723  if (n >= 1)
724  S::readChars (in, c, n);
725 }
726 
727 
728 template <> inline int size <bool> () {return 1;}
729 template <> inline int size <char> () {return 1;}
730 template <> inline int size <signed char> () {return 1;}
731 template <> inline int size <unsigned char> () {return 1;}
732 template <> inline int size <signed short> () {return 2;}
733 template <> inline int size <unsigned short> () {return 2;}
734 template <> inline int size <signed int> () {return 4;}
735 template <> inline int size <unsigned int> () {return 4;}
736 template <> inline int size <signed long> () {return 8;}
737 template <> inline int size <unsigned long> () {return 8;}
738 template <> inline int size <unsigned long long> () {return 8;}
739 template <> inline int size <float> () {return 4;}
740 template <> inline int size <double> () {return 8;}
741 template <> inline int size <half> () {return 2;}
742 
743 
744 } // namespace Xdr
746 
747 
748 #if defined (OPENEXR_IMF_INTERNAL_NAMESPACE_AUTO_EXPOSE)
749 namespace Imf{using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;}
750 #endif
751 
752 
753 #endif
#define OPENEXR_IMF_INTERNAL_NAMESPACE
Definition: OpenEXRConfig.h:29
int size()
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
Definition: ImfNamespace.h:80
void writeUnsignedChars(T &out, const unsigned char c[], int n)
Definition: ImfXdr.h:263
imath_half_bits_t half
if we're in a C-only context, alias the half bits type to half
Definition: half.h:266
void skip(T &in, int n)
Definition: ImfXdr.h:711
const GLdouble * v
Definition: glcorearb.h:837
void readUnsignedChars(T &in, unsigned char c[], int n)
Definition: ImfXdr.h:279
void read(T &in, bool &v)
Definition: ImfXdr.h:502
void pad(T &out, int n)
Definition: ImfXdr.h:490
GLdouble n
Definition: glcorearb.h:2008
GLfloat f
Definition: glcorearb.h:1926
void writeSignedChars(T &out, const signed char c[], int n)
Definition: ImfXdr.h:255
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLsizeiptr size
Definition: glcorearb.h:664
#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
Definition: ImfNamespace.h:79
void readSignedChars(T &in, signed char c[], int n)
Definition: ImfXdr.h:271
void write(T &out, bool v)
Definition: ImfXdr.h:287