1 | #include <stdio.h> |
---|
2 | |
---|
3 | #define BYTE2(a) ((a & 0xff00) >> 8) + ((a & 0x00ff) << 8) |
---|
4 | #define BYTE4(a) ((a & 0xff000000)>>24) + ((a & 0x00ff0000)>> 8) \ |
---|
5 | +((a & 0x0000ff00)<< 8) + ((a & 0x000000ff)<<24) |
---|
6 | |
---|
7 | /* |
---|
8 | * Operate on the premise that: short = 2 bytes |
---|
9 | * int = 4 bytes |
---|
10 | * float = 4 bytes |
---|
11 | */ |
---|
12 | int fgetshort(FILE *fp, short *outval, int byteorder) { |
---|
13 | short val; |
---|
14 | |
---|
15 | if (feof(fp)) return -1; |
---|
16 | fread(&val,sizeof(short),1,fp); |
---|
17 | if (byteorder) val = BYTE2(val); |
---|
18 | *outval=val; |
---|
19 | return 0; |
---|
20 | } |
---|
21 | |
---|
22 | int fputshort(FILE *fp, short *outval, int byteorder) { |
---|
23 | short val; |
---|
24 | val = *outval; |
---|
25 | if (byteorder) val = BYTE2(val); |
---|
26 | fwrite(&val,sizeof(short),1,fp); |
---|
27 | return 0; |
---|
28 | } |
---|
29 | |
---|
30 | |
---|
31 | |
---|
32 | int fgetint(FILE *fp, int *outval, int byteorder) { |
---|
33 | int val; |
---|
34 | |
---|
35 | if (feof(fp)) return -1; |
---|
36 | fread(&val,sizeof(int),1,fp); |
---|
37 | if (byteorder) val = BYTE4(val); |
---|
38 | *outval = val; |
---|
39 | return 0; |
---|
40 | } |
---|
41 | |
---|
42 | int fputint(FILE *fp, int *outval, int byteorder) { |
---|
43 | int val; |
---|
44 | val = *outval; |
---|
45 | if (byteorder) val = BYTE4(val); |
---|
46 | fwrite(&val,sizeof(int),1,fp); |
---|
47 | return 0; |
---|
48 | } |
---|
49 | |
---|
50 | int fgetbool(FILE *fp, int *outval, int byteorder) { |
---|
51 | int val; |
---|
52 | |
---|
53 | if (feof(fp)) return -1; |
---|
54 | fread(&val,sizeof(int),1,fp); |
---|
55 | if (byteorder) val = BYTE4(val); |
---|
56 | *outval = val; |
---|
57 | return 0; |
---|
58 | } |
---|
59 | |
---|
60 | int fputbool(FILE *fp, int *outval, int byteorder) { |
---|
61 | int val; |
---|
62 | val = *outval; |
---|
63 | if (byteorder) val = BYTE4(val); |
---|
64 | fwrite(&val,sizeof(int),1,fp); |
---|
65 | return 0; |
---|
66 | } |
---|
67 | |
---|
68 | int fgetstring(FILE *fp, char *string, int stringlen) { |
---|
69 | if (feof(fp)) return -1; |
---|
70 | fread(string,stringlen * sizeof(char),1,fp); |
---|
71 | string[stringlen] = 0; |
---|
72 | return 0; |
---|
73 | } |
---|
74 | |
---|
75 | int fputstring(FILE *fp, char *string, int stringlen) { |
---|
76 | int retn; |
---|
77 | |
---|
78 | retn = fwrite(string,1,stringlen,fp); |
---|
79 | if (retn <= 0) return -1; |
---|
80 | return 0; |
---|
81 | } |
---|
82 | |
---|
83 | void |
---|
84 | pbin(int val, int len, char * trailer){ |
---|
85 | int j,bit; |
---|
86 | printf("-->"); |
---|
87 | for(j=len;j>0;j--){ |
---|
88 | bit = ((val & (0x00000001 << (j-1))) ? 1 : 0); |
---|
89 | if (!(j%4)) printf(" "); |
---|
90 | printf("%d",bit); |
---|
91 | } |
---|
92 | printf("%s",trailer); |
---|
93 | } |
---|
94 | |
---|
95 | |
---|
96 | /* |
---|
97 | * GetVaxFloat |
---|
98 | * |
---|
99 | * Convert a VMS 4 byte F-float number to a IEEE 754 single precision floating |
---|
100 | * point number. The method is as follows: detect invalid numbers and zero; |
---|
101 | * for all other values subtract 2 from exponent (VAX uses excess-128 and |
---|
102 | * mantissa of the form 0.(1)fffff..., whereas IEEE uses excess-127 and |
---|
103 | * (1).fffffff..., where parentheses mean the implied MSB. |
---|
104 | * The bit layout is: VMS format IEEE format |
---|
105 | * ffffffffffffffffseeeeeeeefffffff seeeeeeeefffffffffffffffffffffff |
---|
106 | * |
---|
107 | * Based on the function ftoi() by Przemek Klosowski at NIST |
---|
108 | */ |
---|
109 | |
---|
110 | int |
---|
111 | GetVaxFloat(FILE *fp, float *flt, int byteorder) { |
---|
112 | register unsigned int sign, exp; |
---|
113 | union intflo { |
---|
114 | int intnum; |
---|
115 | float fltnum; |
---|
116 | } val; |
---|
117 | |
---|
118 | if (feof(fp)) return -1; |
---|
119 | *flt = 0; |
---|
120 | fread(&val.intnum,sizeof(int),1,fp); |
---|
121 | if (byteorder) { |
---|
122 | val.intnum = BYTE4(val.intnum); |
---|
123 | } |
---|
124 | |
---|
125 | sign = (val.intnum & 0x00008000); |
---|
126 | exp = (val.intnum & 0x00007f80); |
---|
127 | |
---|
128 | if ( ! exp ) {/* zero if sign==0 or else VAX Invalid number */ |
---|
129 | /* that is what DEC ftoi() does */ |
---|
130 | /* Integer zero is also floating zero, all ones is a NaN */ |
---|
131 | val.intnum = sign? 0xffffffff : 0; |
---|
132 | *flt = val.fltnum; |
---|
133 | return 0; |
---|
134 | } else { |
---|
135 | if (exp <= 0x100) { /* IEEE exp 0 is underflow; could try but won't */ |
---|
136 | // return -1; |
---|
137 | } |
---|
138 | exp -= 0x100; /* decrease exponent by 2 */ |
---|
139 | exp &= 0x00007f80; /* kill any borrow beyond exp field */ |
---|
140 | /* put back sign, exp and mantissa; swap halves. >> must be logical shift*/ |
---|
141 | //printf("float(V): "); pbin(val.intnum,32,"\n"); |
---|
142 | val.intnum = ((exp | sign | (val.intnum & 0x0000007f)) << 16) | |
---|
143 | ((val.intnum & 0xffff0000) >> 16); |
---|
144 | // printf("float(I): ");pbin(val.intnum,32," ");printf("%f\n",val.fltnum); |
---|
145 | *flt = val.fltnum; |
---|
146 | return 0; |
---|
147 | } |
---|
148 | } |
---|
149 | |
---|
150 | int |
---|
151 | PutVaxFloat(FILE *fp, float *flt, int byteorder) { |
---|
152 | register unsigned int sign, exp, bits; |
---|
153 | union intflo { |
---|
154 | int intnum; |
---|
155 | float fltnum; |
---|
156 | } val; |
---|
157 | |
---|
158 | val.fltnum = *flt; |
---|
159 | |
---|
160 | sign = (val.intnum & 0x80000000)>>16; |
---|
161 | exp = (val.intnum & 0x7f800000)>>16; |
---|
162 | bits = (val.intnum & 0x007fffff); |
---|
163 | // if (*flt != 0) { |
---|
164 | // printf("float(I):"); pbin(val.intnum,32," "); printf("%f\n",*flt); |
---|
165 | // } |
---|
166 | |
---|
167 | |
---|
168 | /* Recompose image of floating point number */ |
---|
169 | exp += 0x100; |
---|
170 | |
---|
171 | val.intnum = (sign | exp | ((bits & 0x00ff0000) >> 16) | |
---|
172 | ((bits & 0x0000ffff) << 16)); |
---|
173 | |
---|
174 | // if (*flt != 0) { |
---|
175 | // printf("float(V):"); pbin(val.intnum,32,"\n"); |
---|
176 | // } |
---|
177 | fwrite(&val.intnum,sizeof(int),1,fp); |
---|
178 | return 0; |
---|
179 | } |
---|
180 | |
---|
181 | int fgetfloat(FILE *fp, float * outval, int byteorder) { |
---|
182 | float val; |
---|
183 | |
---|
184 | if (GetVaxFloat(fp, &val, byteorder)) return -1; |
---|
185 | *outval = val; |
---|
186 | return 0; |
---|
187 | } |
---|
188 | |
---|
189 | int fputfloat(FILE *fp, float * outval, int byteorder) { |
---|
190 | return PutVaxFloat(fp, outval, byteorder); |
---|
191 | } |
---|