Philippe 23/02/2016: lfi2cdf: modif for JPHEXT/=1
[MNH-git_open_source-lfs.git] / lib / vis5d / src / binio.c
1 /* Vis5D version 5.1 */
2
3 /*
4 Vis5D system for visualizing five dimensional gridded data sets
5 Copyright (C) 1990 - 1997 Bill Hibbard, Johan Kellum, Brian Paul,
6 Dave Santek, and Andre Battaiola.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 1, or (at your option)
11 any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 /*
24  * Functions to do binary I/O of floats, ints.
25  *
26  * >>>> These functions are built on top of Unix I/O functions, not stdio! <<<<
27  *
28  * The file format is assumed to be BIG-ENDIAN.
29  * If this code is compiled with -DLITTLE and executes on a little endian
30  * CPU then byte-swapping will be done.
31  *
32  * If an ANSI compiler is used prototypes and ANSI function declarations
33  * are used.  Otherwise use K&R conventions.
34  *
35  * If we're running on a CRAY (8-byte ints and floats), conversions will
36  * be done as needed.
37  */
38
39
40 /*
41  * Updates:
42  *
43  * April 13, 1995, brianp
44  *   added cray_to_ieee and iee_to_cray array conversion functions.
45  *   fixed potential cray bug in write_float4_array function.
46  *
47  */
48
49
50
51 #include <stdio.h>
52 #include <stdlib.h>
53 #include <unistd.h>
54 #ifdef _CRAY
55 #  include <string.h>
56 #endif
57 #include "binio.h"
58
59
60
61
62 /**********************************************************************/
63 /******                     Byte Flipping                         *****/
64 /**********************************************************************/
65
66
67 #define FLIP4( n )  (  (n & 0xff000000) >> 24     \
68                      | (n & 0x00ff0000) >> 8      \
69                      | (n & 0x0000ff00) << 8      \
70                      | (n & 0x000000ff) << 24  )
71
72
73 #define FLIP2( n )  (((unsigned short) (n & 0xff00)) >> 8  |  (n & 0x00ff) << 8)
74
75
76
77 /*
78  * Flip the order of the 4 bytes in an array of 4-byte words.
79  */
80 void flip4( const unsigned int *src, unsigned int *dest, int n )
81 {
82    int i;
83
84    for (i=0;i<n;i++) {
85       unsigned int tmp = src[i];
86       dest[i] = FLIP4( tmp );
87    }
88 }
89
90
91
92 /*
93  * Flip the order of the 2 bytes in an array of 2-byte words.
94  */
95 void flip2( const unsigned short *src, unsigned short *dest, int n )
96 {
97    int i;
98
99    for (i=0;i<n;i++) {
100       unsigned short tmp = src[i];
101       dest[i] = FLIP2( tmp );
102    }
103 }
104
105
106 #ifdef _CRAY
107 /*****************************************************************************
108 *
109 * The following source code is in the public domain.
110 * Specifically, we give to the public domain all rights for future licensing
111 * of the source code, all resale rights, and all publishing rights.
112 *
113 * We ask, but do not require, that the following message be included in all
114 * derived works:
115 *
116 * Portions developed at the National Center for Supercomputing Applications at
117 * the University of Illinois at Urbana-Champaign.
118 *
119 * THE UNIVERSITY OF ILLINOIS GIVES NO WARRANTY, EXPRESSED OR IMPLIED, FOR THE
120 * SOFTWARE AND/OR DOCUMENTATION PROVIDED, INCLUDING, WITHOUT LIMITATION,
121 * WARRANTY OF MERCHANTABILITY AND WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE
122 *
123 ****************************************************************************/
124
125 /** THESE ROUTINES MUST BE COMPILED ON THE CRAY ONLY SINCE THEY **/
126 /** REQUIRE 8-BYTES PER C-TYPE LONG                             **/
127
128 /* Cray to IEEE single precision */
129 static void c_to_if( long *t, const long *f)
130 {
131     if (*f != 0){
132         *t = (((*f & 0x8000000000000000) |      /* sign bit */
133                  ((((*f & 0x7fff000000000000) >> 48)-16258) << 55)) + /* exp */
134                  (((*f & 0x00007fffff000000) +
135                     ((*f & 0x0000000000800000) << 1)) << 8));  /* mantissa */
136     }
137     else *t = *f;
138 }
139
140
141 #define C_TO_IF( T, F )                                                 \
142         if (F != 0) {                                                   \
143                 T = (((F & 0x8000000000000000) |                        \
144                 ((((F & 0x7fff000000000000) >> 48)-16258) << 55)) +     \
145                 (((F & 0x00007fffff000000) +                            \
146                 ((F & 0x0000000000800000) << 1)) << 8));                \
147         }                                                               \
148         else {                                                          \
149                 T = F;                                                  \
150         }
151
152
153
154 /* IEEE single precison to Cray */
155 static void if_to_c( long *t, const long *f)
156 {
157     if (*f != 0) {
158         *t = (((*f & 0x8000000000000000) |
159                 ((*f & 0x7f80000000000000) >> 7) +
160                 (16258 << 48)) |
161                 (((*f & 0x007fffff00000000) >> 8) | (0x0000800000000000)));
162         if ((*f << 1) == 0) *t = 0;
163     }
164     else *t = *f;
165 }
166
167 /* T and F must be longs! */
168 #define IF_TO_C( T, F )                                                 \
169         if (F != 0) {                                                   \
170                 T = (((F & 0x8000000000000000) |                        \
171                 ((F & 0x7f80000000000000) >> 7) +                       \
172                 (16258 << 48)) |                                        \
173                 (((F & 0x007fffff00000000) >> 8) | (0x0000800000000000)));  \
174                 if ((F << 1) == 0) T = 0;                               \
175         }                                                               \
176         else {                                                          \
177                 T = F;                                                  \
178         }
179
180
181
182
183 /*
184  * Convert an array of Cray 8-byte floats to an array of IEEE 4-byte floats.
185  */
186 void cray_to_ieee_array( long *dest, const float *source, int n )
187 {
188    long *dst;
189    const long *src;
190    long tmp1, tmp2;
191    int i;
192
193    dst = dest;
194    src = (const long *) source;
195
196    for (i=0;i<n;i+=2) {       /* add 1 in case n is odd */
197       c_to_if( &tmp1, &src[i] );
198       c_to_if( &tmp2, &src[i+1] );
199       *dst = (tmp1 & 0xffffffff00000000) | (tmp2 >> 32);
200       dst++;
201    }
202 }
203
204
205
206 /*
207  * Convert an array of IEEE 4-byte floats to an array of 8-byte Cray floats.
208  */
209 void ieee_to_cray_array( float *dest, const long *source, int n )
210 {
211    long *dst;
212    const long *src;
213    int i;
214    long ieee;
215
216    src = source;
217    dst = (long *) dest;
218
219    for (i=0;i<n;i++) {
220       /* most significant 4-bytes of ieee contain bit pattern to convert */
221       if ((i&1)==0) {
222          /* get upper half */
223          ieee = src[i/2] & 0xffffffff00000000;
224       }
225       else {
226          /* get lower half */
227          ieee = src[i/2] << 32;
228       }
229       if_to_c( dst, &ieee );
230       dst++;
231    }
232 }
233
234
235 #endif /*_CRAY*/
236
237
238
239 /**********************************************************************/
240 /*****                     Read Functions                         *****/
241 /**********************************************************************/
242
243
244 /*
245  * Read a block of bytes.
246  *  Input:  f - the file descriptor to read from.
247  *         b - address of buffer to read into.
248  *         n - number of bytes to read.
249  * Return:  number of bytes read, 0 if error.
250  */
251 int read_bytes( int f, void *b, int n )
252 {
253    return read( f, b, n );
254 }
255
256
257
258 /*
259  * Read an array of 2-byte integers.
260  * Input:  f - file descriptor
261  *         iarray - address to put integers
262  *         n - number of integers to read.
263  * Return:  number of integers read.
264  */
265 int read_int2_array( int f, short *iarray, int n )
266 {
267 #ifdef _CRAY
268    int i;
269    signed char *buffer;
270    int nread;
271    buffer = (signed char *) malloc( n * 2 );
272    if (!buffer)  return 0;
273    nread = read( f, buffer, n*2 );
274    if (nread<=0)  return 0;
275    nread /= 2;
276    for (i=0;i<nread;i++) {
277       /* don't forget about sign extension! */
278       iarray[i] = (buffer[i*2] * 256) | buffer[i*2+1];
279    }
280    free( buffer );
281    return nread;
282 #else
283    int nread = read( f, iarray, n*2 );
284    if (nread<=0)
285       return 0;
286 #ifdef LITTLE
287    flip2( (const unsigned short *) iarray, (unsigned short *) iarray, nread/2);
288 #endif
289    return nread/2;
290 #endif
291 }
292
293
294
295 /*
296  * Read an array of unsigned 2-byte integers.
297  * Input:  f - file descriptor
298  *         iarray - address to put integers
299  *         n - number of integers to read.
300  * Return:  number of integers read.
301  */
302 int read_uint2_array( int f, unsigned short *iarray, int n )
303 {
304 #ifdef _CRAY
305    int i;
306    unsigned char *buffer;
307    int nread;
308    buffer = (unsigned char *) malloc( n * 2 );
309    if (!buffer)  return 0;
310    nread = read( f, buffer, n*2 );
311    if (nread<=0)  return 0;
312    nread /= 2;
313    for (i=0;i<nread;i++) {
314       iarray[i] = (buffer[i*2] << 8) | buffer[i*2+1];
315    }
316    free( buffer );
317    return nread;
318 #else
319    int nread = read( f, iarray, n*2 );
320    if (nread<=0)
321       return 0;
322 #ifdef LITTLE
323    flip2( iarray, iarray, nread/2 );
324 #endif
325    return nread/2;
326 #endif
327 }
328
329
330
331 /*
332  * Read a 4-byte integer.
333  * Input:  f - the file descriptor to read from
334  *         i - pointer to integer to put result into.
335  * Return:  1 = ok, 0 = error
336  */
337 int read_int4( int f, int *i )
338 {
339 #ifdef LITTLE
340    /* read big endian and convert to little endian */
341    unsigned int n;
342    if (read( f, &n, 4 )==4) {
343       *i = FLIP4( n );
344       return 1;
345    }
346    else {
347       return 0;
348    }
349 #else
350    if (read( f, i, 4 )==4) {
351 #  ifdef _CRAY
352       *i = *i >> 32;
353 #  endif
354       return 1;
355    }
356    else {
357       return 0;
358    }
359 #endif
360 }
361
362
363
364 /*
365  * Read an array of 4-byte integers.
366  * Input:  f - file descriptor
367  *         iarray - address to put integers
368  *         n - number of integers to read.
369  * Return:  number of integers read.
370  */
371 int read_int4_array( int f, int *iarray, int n )
372 {
373 #ifdef _CRAY
374    int j, nread;
375    int *buffer;
376
377    buffer = (int *) malloc( (n+1)*4 );
378    if (!buffer)
379       return 0;
380    nread = read( f, buffer, 4*n );
381    if (nread<=0) {
382       return 0;
383    }
384    nread /= 4;
385
386    for (j=0;j<nread;j++) {
387       if ((j&1)==0) {
388          iarray[j] = buffer[j/2] >> 32;
389       }
390       else {
391          iarray[j] = buffer[j/2] & 0xffffffff;
392       }
393    }
394    free( buffer );
395    return nread;
396 #else
397    int nread = read( f, iarray, 4*n );
398    if (nread<=0)
399      return 0;
400 #  ifdef LITTLE
401       flip4( (const unsigned int *) iarray, (unsigned int *) iarray, nread/4 );
402 #  endif
403    return nread/4;
404 #endif
405 }
406
407
408
409 /*
410  * Read a 4-byte IEEE float.
411  * Input:  f - the file descriptor to read from.
412  *         x - pointer to float to put result into.
413  * Return:  1 = ok, 0 = error
414  */
415 int read_float4( int f, float *x )
416 {
417 #ifdef _CRAY
418    long buffer = 0;
419
420    if ( read( f, &buffer, 4 )==4 ) {
421       /* convert IEEE float (buffer) to Cray float (x) */
422       if_to_c( (long *) x, &buffer );
423       return 1;
424     }
425     return 0;
426 #else
427 #  ifdef LITTLE
428       unsigned int n, *iptr;
429       if (read( f, &n, 4 )==4) {
430          iptr = (unsigned int *) x;
431          *iptr = FLIP4( n );
432          return 1;
433       }
434       else {
435          return 0;
436       }
437 #  else
438       if (read( f, x, 4 )==4) {
439          return 1;
440       }
441       else {
442          return 0;
443       }
444 #  endif
445 #endif
446 }
447
448
449
450 /*
451  * Read an array of 4-byte IEEE floats.
452  * Input:  f - file descriptor
453  *         x - address to put floats
454  *         n - number of floats to read.
455  * Return:  number of floats read.
456  */
457 int read_float4_array( int f, float *x, int n )
458 {
459 #ifdef _CRAY
460    /* read IEEE floats into buffer, then convert to Cray format */
461    long *buffer;
462    int i, nread;
463
464    buffer = (long *) malloc( (n+1) * 4 );
465    if (!buffer) return 0;
466    nread = read( f, buffer, n*4 );
467    if (nread<=0)  return 0;
468    nread /= 4;
469    ieee_to_cray_array( x, buffer, nread );
470    free( buffer );
471    return nread;
472 #else
473    int nread = read( f, x, 4*n );
474    if (nread<=0)
475       return 0;
476 #ifdef LITTLE
477    flip4( (const unsigned int *) x, (unsigned int*) x, nread/4 );
478 #endif
479    return nread/4;
480 #endif
481 }
482
483
484
485 /*
486  * Read a block of memory.
487  * Input:  f - file descriptor
488  *         data - address of first byte
489  *         elements - number of elements to read
490  *         elsize - size of each element to read (1, 2 or 4)
491  * Return: number of elements written
492  */
493 int read_block( int f, void *data, int elements, int elsize )
494 {
495    if (elsize==1) {
496       return read( f, data, elements );
497    }
498    else if (elsize==2) {
499 #ifdef LITTLE
500       int n;
501       n = read( f, data, elements*2 ) / 2;
502       if (n==elements) {
503          flip2( (const unsigned short *) data, (unsigned short *) data,
504                 elements );
505       }
506       return n;
507 #else
508       return read( f, data, elements*2 ) / 2;
509 #endif
510    }
511    else if (elsize==4) {
512 #ifdef LITTLE
513       int n;
514       n = read( f, data, elements*4 ) / 4;
515       if (n==elements) {
516          flip4( (const unsigned int *) data, (unsigned int *) data, elements );
517       }
518       return n;
519 #else
520       return read( f, data, elements*4 ) / 4;
521 #endif
522    }
523    else {
524       printf("Fatal error in read_block(): bad elsize (%d)\n", elsize );
525       abort();
526    }
527    return 0;
528 }
529
530
531
532
533 /**********************************************************************/
534 /*****                         Write Functions                    *****/
535 /**********************************************************************/
536
537
538
539 /*
540  * Write a block of bytes.
541  * Input:  f - the file descriptor to write to.
542  *         b - address of buffer to write.
543  *         n - number of bytes to write.
544  * Return:  number of bytes written, 0 if error.
545  */
546 int write_bytes( int f, const void *b, int n )
547 {
548    return write( f, b, n );
549 }
550
551
552
553
554 /*
555  * Write an array of 2-byte integers.
556  * Input:  f - file descriptor
557  *         iarray - address to put integers
558  *         n - number of integers to write.
559  * Return:  number of integers written
560  */
561 int write_int2_array( int f, const short *iarray, int n )
562 {
563 #ifdef _CRAY
564    printf("write_int2_array not implemented!\n");
565    exit(1);
566 #else
567    int nwritten;
568 #ifdef LITTLE
569    flip2( (const unsigned short *) iarray, (unsigned short *) iarray, n );
570 #endif
571    nwritten = write( f, iarray, 2*n );
572 #ifdef LITTLE
573    flip2( (const unsigned short *) iarray, (unsigned short *) iarray, n );
574 #endif
575    if (nwritten<=0)
576       return 0;
577    return nwritten/2;
578 #endif
579 }
580
581
582
583 /*
584  * Write an array of 2-byte unsigned integers.
585  * Input:  f - file descriptor
586  *         iarray - address to put integers
587  *         n - number of integers to write.
588  * Return:  number of integers written
589  */
590 int write_uint2_array( int f, const unsigned short *iarray, int n )
591 {
592 #ifdef _CRAY
593    int i, nwritten;
594    unsigned char *buffer;
595    buffer = (unsigned char *) malloc( 2*n );
596    if (!buffer)  return 0;
597    for (i=0;i<n;i++) {
598       buffer[i*2] = (iarray[i] >> 8) & 0xff;
599       buffer[i*2+1] = iarray[i] & 0xff;
600    }
601    nwritten = write( f, buffer, 2*n );
602    free( buffer );
603    if (nwritten<=0)
604       return 0;
605    else
606       return nwritten/2;
607 #else
608    int nwritten;
609 #ifdef LITTLE
610    flip2( iarray, (unsigned short *) iarray, n );
611 #endif
612    nwritten = write( f, iarray, 2*n );
613 #ifdef LITTLE
614    flip2( iarray, (unsigned short *) iarray, n );
615 #endif
616    if (nwritten<=0)
617       return 0;
618    else
619       return nwritten/2;
620 #endif
621 }
622
623
624
625 /*
626  * Write a 4-byte integer.
627  *Input:  f - the file descriptor
628  *         i - the integer
629  * Return:  1 = ok, 0 = error
630  */
631 int write_int4( int f, int i )
632 {
633 #ifdef _CRAY
634    i = i << 32;
635    return write( f, &i, 4 ) > 0;
636 #else
637 #  ifdef LITTLE
638      i = FLIP4( i );
639 #  endif
640    return write( f, &i, 4 ) > 0;
641 #endif
642 }
643
644
645
646 /*
647  * Write an array of 4-byte integers.
648  * Input:  f - the file descriptor
649  *         i - the array of ints
650  *           n - the number of ints in array
651  *  Return:  number of integers written.
652  */
653 int write_int4_array( int f, const int *i, int n )
654 {
655 #ifdef _CRAY
656    int j, nwritten;
657    char *buf, *b, *ptr;
658
659    b = buf = (char *) malloc( n*4 + 8 );
660    if (!b)
661       return 0;
662    ptr = (char *) i;
663    for (j=0;j<n;j++) {
664       ptr += 4;      /* skip upper 4 bytes */
665       *b++ = *ptr++;
666       *b++ = *ptr++;
667       *b++ = *ptr++;
668       *b++ = *ptr++;
669    }
670    nwritten = write( f, buf, 4*n );
671    free( buf );
672    if (nwritten<=0)
673       return 0;
674    else
675       return nwritten / 4;
676 #else
677 #  ifdef LITTLE
678       int nwritten;
679       flip4( (const unsigned int *) i, (unsigned int *) i, n );
680       nwritten = write( f, i, 4*n );
681       flip4( (const unsigned int *) i, (unsigned int *) i, n );
682       if (nwritten<=0)
683          return 0;
684       else
685         return nwritten / 4;
686 #  else
687       return write( f, i, 4*n ) / 4;
688 #  endif
689 #endif
690 }
691
692
693
694 /*
695  * Write a 4-byte IEEE float.
696  * Input:  f - the file descriptor
697  *         x - the float
698  * Return:  1 = ok, 0 = error
699  */
700 int write_float4( int f, float x )
701 {
702 #ifdef _CRAY
703    char buffer[8];
704    c_to_if( (long *) buffer, (const long *) &x );
705    return write( f, buffer, 4 ) > 0;
706 #else
707 #  ifdef LITTLE
708       float y;
709       unsigned int *iptr = (unsigned int *) &y, temp;
710       y = (float) x;
711       temp = FLIP4( *iptr );
712       return write( f, &temp, 4 ) > 0;
713 #  else
714       float y;
715       y = (float) x;
716       return write( f, &y, 4 ) > 0;
717 #  endif
718 #endif
719 }
720
721
722
723 /*
724  * Write an array of 4-byte IEEE floating point numbers.
725  * Input:  f - the file descriptor
726  *         x - the array of floats
727  *         n - number of floats in array
728  * Return:  number of float written.
729  */
730 int write_float4_array( int f, const float *x, int n )
731 {
732 #ifdef _CRAY
733    /* convert cray floats to IEEE and put into buffer */
734    int nwritten;
735    long *buffer;
736    buffer = (long *) malloc( n*4 + 8 );
737    if (!buffer)
738       return 0;
739    cray_to_ieee_array( buffer, x, n );
740    nwritten = write( f, buffer, 4*n );
741    free( buffer );
742    if (nwritten<=0)
743       return 0;
744    else
745       return nwritten / 4;
746 #else
747 #  ifdef LITTLE
748       int nwritten;
749       flip4( (const unsigned int *) x, (unsigned int *) x, n );
750       nwritten = write( f, x, 4*n );
751       flip4( (const unsigned int *) x, (unsigned int *) x, n );
752       if (nwritten<=0)
753          return 0;
754       else 
755          return nwritten / 4;
756 #  else
757       return write( f, x, 4*n ) / 4;
758 #  endif
759 #endif
760 }
761
762
763
764 /*
765  * Write a block of memory.
766  * Input:  f - file descriptor
767  *         data - address of first byte
768  *         elements - number of elements to write
769  *         elsize - size of each element to write (1, 2 or 4)
770  * Return: number of elements written
771  */
772 int write_block( int f, const void *data, int elements, int elsize )
773 {
774    if (elsize==1) {
775       return write( f, data, elements );
776    }
777    else if (elsize==2) {
778 #ifdef LITTLE
779       int n;
780       flip2( (const unsigned short *) data, (unsigned short *) data, elements);
781       n = write( f, data, elements*2 ) / 2;
782       flip2( (const unsigned short *) data, (unsigned short *) data, elements);
783       return n;
784 #else
785       return write( f, data, elements*2 ) / 2;
786 #endif
787    }
788    else if (elsize==4) {
789 #ifdef LITTLE
790       int n;
791       flip4( (const unsigned int *) data, (unsigned int *) data, elements );
792       n = write( f, data, elements*4 ) / 4;
793       flip4( (const unsigned int *) data, (unsigned int *) data, elements );
794       return n;
795 #else
796       return write( f, data, elements*4 ) / 4;
797 #endif
798    }
799    else {
800       printf("Fatal error in write_block(): bad elsize (%d)\n", elsize );
801       abort();
802    }
803    return 0;
804 }