1 /*
2 * CalmaReadio.c --
3 *
4 * Input of Calma GDS-II stream format.
5 * Low-level input.
6 *
7 * *********************************************************************
8 * * Copyright (C) 1985, 1990 Regents of the University of California. *
9 * * Permission to use, copy, modify, and distribute this *
10 * * software and its documentation for any purpose and without *
11 * * fee is hereby granted, provided that the above copyright *
12 * * notice appear in all copies. The University of California *
13 * * makes no representations about the suitability of this *
14 * * software for any purpose. It is provided "as is" without *
15 * * express or implied warranty. Export of this software outside *
16 * * of the United States of America may require an export license. *
17 * *********************************************************************
18 */
19
20 #ifndef lint
21 static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/calma/CalmaRdio.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
22 #endif /* not lint */
23
24 #include <stdio.h>
25 #include <sys/types.h>
26
27 #include <netinet/in.h>
28
29 #include "utils/magic.h"
30 #include "utils/geometry.h"
31 #include "tiles/tile.h"
32 #include "utils/utils.h"
33 #include "utils/hash.h"
34 #include "database/database.h"
35 #include "database/databaseInt.h"
36 #include "utils/malloc.h"
37 #include "utils/tech.h"
38 #include "cif/cif.h"
39 #include "cif/CIFint.h"
40 #include "cif/CIFread.h"
41 #include "utils/signals.h"
42 #include "windows/windows.h"
43 #include "dbwind/dbwind.h"
44 #include "utils/styles.h"
45 #include "textio/textio.h"
46 #include "calma/calmaInt.h"
47
48 /* Forward declarations */
49 bool calmaReadR8();
50 bool calmaSkipBytes();
51
52
53 /*
54 * ----------------------------------------------------------------------------
55 *
56 * calmaReadTransform --
57 *
58 * Read a CALMA_STRANS, CALMA_MAG, CALMA_ANGLE sequence and construct
59 * the corresponding geometric transform.
60 *
61 * Results:
62 * TRUE normally, FALSE on EOF or fatal syntax error.
63 *
64 * Side effects:
65 * Consumes input.
66 * Modifies the Transform pointed to by 'ptrans'.
67 *
68 * ----------------------------------------------------------------------------
69 */
70
71 bool
calmaReadTransform(ptrans,name)72 calmaReadTransform(ptrans, name)
73 Transform *ptrans; /* Fill in this transform */
74 char *name; /* Name of subcell (for errors) */
75 {
76 int nbytes, rtype, flags, angle;
77 double dangle;
78 double dmag;
79 Transform t;
80
81 /* Default is the identity transform */
82 *ptrans = GeoIdentityTransform;
83
84 /* Is there any transform at all? */
85 READRH(nbytes, rtype);
86 if (nbytes < 0) return (FALSE);
87 if (rtype != CALMA_STRANS)
88 {
89 UNREADRH(nbytes, rtype);
90 return (TRUE);
91 }
92 if (nbytes != 6)
93 {
94 (void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH);
95 return (FALSE);
96 }
97 READI2(flags);
98
99 /* Look for magnification and angle */
100 READRH(nbytes, rtype);
101 if (nbytes < 0) return (FALSE);
102 if (rtype == CALMA_MAG)
103 {
104 if (nbytes != CALMAHEADERLENGTH + 8)
105 {
106 (void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH);
107 return (FALSE);
108 }
109 if (!calmaReadR8(&dmag)) return (FALSE);
110
111 if (dmag != (double)((int)(dmag + 0.5)))
112 {
113 CalmaReadError("Non-integer magnification (%g) in transform\n", dmag);
114 CalmaReadError("Rounding to %d.\n", (int)(dmag + 0.5));
115 }
116 GeoScaleTrans(ptrans, (int)(dmag + 0.5), &t);
117 *ptrans = t;
118 }
119 else UNREADRH(nbytes, rtype);
120
121 READRH(nbytes, rtype);
122 if (nbytes < 0) return (FALSE);
123 dangle = 0.0;
124 if (rtype == CALMA_ANGLE)
125 {
126 if (nbytes != CALMAHEADERLENGTH + 8)
127 {
128 (void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH);
129 return (FALSE);
130 }
131 if (!calmaReadR8(&dangle)) return (FALSE);
132 }
133 else UNREADRH(nbytes, rtype);
134
135 /* Make sure the angle is Manhattan */
136 angle = (int) dangle;
137 while (angle < 0) angle += 360;
138 while (angle > 360) angle -= 360;
139 switch (angle)
140 {
141 case 360:
142 angle = 0;
143 break;
144 case 0: case 90: case 180: case 270:
145 break;
146 default:
147 CalmaReadError("Non-Manhattan angle (%d) in transform\n", angle);
148 if (angle < 45) angle = 0;
149 else if (angle < 135) angle = 90;
150 else if (angle < 225) angle = 180;
151 else if (angle < 315) angle = 270;
152 else angle = 0;
153 CalmaReadError(" Rounding to %d degrees.\n", angle);
154 }
155
156 /*
157 * Construct the transform.
158 * Magic angles are clockwise; Calma angles are counterclockwise.
159 */
160 if (flags & CALMA_STRANS_UPSIDEDOWN)
161 {
162 GeoTransTrans(ptrans, &GeoUpsideDownTransform, &t);
163 *ptrans = t;
164 }
165 switch (angle)
166 {
167 case 90:
168 GeoTransTrans(ptrans, &Geo270Transform, &t);
169 *ptrans = t;
170 break;
171 case 180:
172 GeoTransTrans(ptrans, &Geo180Transform, &t);
173 *ptrans = t;
174 break;
175 case 270:
176 GeoTransTrans(ptrans, &Geo90Transform, &t);
177 *ptrans = t;
178 break;
179 }
180
181 return (TRUE);
182 }
183
184 /*
185 * ----------------------------------------------------------------------------
186 *
187 * calmaReadI2Record --
188 *
189 * Read a record that should contain a two-byte integer.
190 *
191 * Results:
192 * TRUE on success, FALSE if the record type we read is not
193 * what we're expecting, or if it is of the wrong size.
194 *
195 * Side effects:
196 * Consumes input.
197 * Stores the result value in *pvalue (note that this is a normal
198 * int, even though we're reading only 16 bits from the input).
199 *
200 * ----------------------------------------------------------------------------
201 */
202
203 bool
calmaReadI2Record(type,pvalue)204 calmaReadI2Record(type, pvalue)
205 int type; /* Type of record expected */
206 int *pvalue; /* Store value here */
207 {
208 int nbytes, rtype, n;
209
210 READRH(nbytes, rtype);
211 if (nbytes < 0)
212 goto eof;
213 if (type != rtype)
214 {
215 calmaUnexpected(type, rtype);
216 return (FALSE);
217 }
218
219 /* Read the value */
220 READI2(n);
221 if (feof(calmaInputFile)) goto eof;
222 *pvalue = n;
223 return (TRUE);
224
225 eof:
226 CalmaReadError("Unexpected EOF.\n");
227 return (FALSE);
228 }
229
230 /*
231 * ----------------------------------------------------------------------------
232 *
233 * calmaReadI4Record --
234 *
235 * Read a record that should contain a four-byte integer.
236 *
237 * Results:
238 * TRUE on success, FALSE if the record type we read is not
239 * what we're expecting, or if it is of the wrong size.
240 *
241 * Side effects:
242 * Consumes input.
243 * Stores the result value in *pvalue.
244 *
245 * ----------------------------------------------------------------------------
246 */
247
248 bool
calmaReadI4Record(type,pvalue)249 calmaReadI4Record(type, pvalue)
250 int type; /* Type of record expected */
251 int *pvalue; /* Store value here */
252 {
253 int nbytes, rtype, n;
254
255 READRH(nbytes, rtype);
256 if (nbytes < 0)
257 goto eof;
258 if (type != rtype)
259 {
260 calmaUnexpected(type, rtype);
261 return (FALSE);
262 }
263
264 /* Read the value */
265 READI4(n);
266 if (feof(calmaInputFile)) goto eof;
267 *pvalue = n;
268 return (TRUE);
269
270 eof:
271 CalmaReadError("Unexpected EOF.\n");
272 return (FALSE);
273 }
274
275 /*
276 * ----------------------------------------------------------------------------
277 *
278 * calmaReadStringRecord --
279 *
280 * Read a record that should contain an ASCII string.
281 *
282 * Results:
283 * TRUE on success, FALSE if the record type we read is not
284 * what we're expecting.
285 *
286 * Side effects:
287 * Consumes input.
288 * Allocates memory for string str (must be freed by the caller)
289 * Stores the result in the string pointed to by 'str'.
290 *
291 * ----------------------------------------------------------------------------
292 */
293
294 bool
calmaReadStringRecord(type,str)295 calmaReadStringRecord(type, str)
296 int type;
297 char **str;
298 {
299 int nbytes, rtype;
300
301 READRH(nbytes, rtype);
302 if (nbytes < 0)
303 goto eof;
304
305 if (type != rtype)
306 {
307 calmaUnexpected(type, rtype);
308 return (FALSE);
309 }
310
311 nbytes -= CALMAHEADERLENGTH;
312 *str = (char *) mallocMagic(nbytes + 1);
313 if (fread(*str, sizeof (char), nbytes, calmaInputFile) != nbytes)
314 goto eof;
315
316 *(*str + nbytes) = '\0';
317 return (TRUE);
318
319 eof:
320 CalmaReadError("Unexpected EOF.\n");
321 return (FALSE);
322 }
323
324 /*
325 * ----------------------------------------------------------------------------
326 *
327 * calmaReadR8 --
328 *
329 * Read a single 8-byte real number in Calma stream format.
330 * Convert to internal double-precision format and store in
331 * the double pointed to by 'pd'.
332 *
333 * Results:
334 * TRUE on success, FALSE if EOF is encountered.
335 *
336 * Side effects:
337 * Consumes input.
338 * Stores the result in the *pd.
339 *
340 * ----------------------------------------------------------------------------
341 */
342
343 bool
calmaReadR8(pd)344 calmaReadR8(pd)
345 double *pd; /* Store result in *pd */
346 {
347 int i, exponent;
348 unsigned char dchars[8];
349 double mantissa, d;
350 bool isneg;
351
352 if (fread((char *) dchars, sizeof (char), sizeof dchars,
353 calmaInputFile) != sizeof dchars)
354 return (FALSE);
355
356 /* Extract the sign and exponent */
357 exponent = dchars[0];
358 if (isneg = (exponent & 0x80))
359 exponent &= ~0x80;
360 exponent -= 64;
361
362 /* Construct the mantissa */
363 mantissa = 0.0;
364 for (i = 7; i > 0; i--)
365 {
366 mantissa += dchars[i];
367 mantissa /= 256.0;
368 }
369
370 /* Now raise the mantissa to the exponent */
371 d = mantissa;
372 if (exponent > 0)
373 {
374 while (exponent-- > 0)
375 d *= 16.0;
376 }
377 else if (exponent < 0)
378 {
379 while (exponent++ < 0)
380 d /= 16.0;
381 }
382
383 /* Make it negative if necessary */
384 if (isneg)
385 d = -d;
386
387 *pd = d;
388 return (TRUE);
389 }
390
391 /*
392 * ----------------------------------------------------------------------------
393 *
394 * calmaSkipSet --
395 *
396 * Skip all records falling in a specified set of types.
397 * Leave the input stream positioned to the start of the first
398 * record not in the specified set.
399 *
400 * The array pointed to by 'skipwhat' contains the record types
401 * of all records to be skipped, terminated with -1.
402 *
403 * Results:
404 * None.
405 *
406 * Side effects:
407 * Consumes input.
408 *
409 * ----------------------------------------------------------------------------
410 */
411
412 void
calmaSkipSet(skipwhat)413 calmaSkipSet(skipwhat)
414 int *skipwhat;
415 {
416 int *skipp;
417 int nbytes, rtype;
418
419 for (;;)
420 {
421 READRH(nbytes, rtype);
422 if (nbytes < 0)
423 return;
424
425 for (skipp = skipwhat; *skipp >= 0; skipp++)
426 if (*skipp == rtype)
427 goto skipit;
428
429 UNREADRH(nbytes, rtype);
430 break;
431
432 skipit:
433 (void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH);
434 }
435 }
436
437 /*
438 * ----------------------------------------------------------------------------
439 *
440 * calmaSkipExact --
441 *
442 * Skip a single stream record, which must be of the type 'type'.
443 * Leave the input positioned to the start of the record following
444 * this one. Complain if the record is not the one expected.
445 *
446 * Results:
447 * TRUE if successful, FALSE if we encountered an error and
448 * the caller should abort.
449 *
450 * Side effects:
451 * Consumes input.
452 *
453 * ----------------------------------------------------------------------------
454 */
455
456 bool
calmaSkipExact(type)457 calmaSkipExact(type)
458 int type;
459 {
460 int nbytes, rtype;
461
462 /* Eat up the record header */
463 READRH(nbytes, rtype);
464
465 if (nbytes < 0)
466 goto eof;
467
468 /* Skip remainder of record */
469 if (!calmaSkipBytes(nbytes - CALMAHEADERLENGTH))
470 goto eof;
471
472 if (rtype != type)
473 {
474 calmaUnexpected(type, rtype);
475 return (FALSE);
476 }
477
478 return (TRUE);
479
480 eof:
481 CalmaReadError("Unexpected EOF.\n");
482 return (FALSE);
483 }
484
485 /*
486 * ----------------------------------------------------------------------------
487 *
488 * calmaSkipTo --
489 *
490 * Skip to a record of a particular type. Leaves the input stream
491 * positioned AFTER the record whose type is given by 'what'.
492 *
493 * Results:
494 * TRUE if we found this record, FALSE if EOF was encountered.
495 *
496 * Side effects:
497 * Consumes input.
498 *
499 * ----------------------------------------------------------------------------
500 */
501
502 bool
calmaSkipTo(what)503 calmaSkipTo(what)
504 int what;
505 {
506 int nbytes, rtype;
507
508 do
509 {
510 READRH(nbytes, rtype);
511 if (nbytes < 0)
512 return (FALSE);
513 calmaSkipBytes(nbytes - CALMAHEADERLENGTH);
514 } while (rtype != what);
515
516 return (TRUE);
517 }
518
519 /*
520 * ----------------------------------------------------------------------------
521 *
522 * calmaSkipBytes --
523 *
524 * Skip 'nbytes' bytes from the input.
525 * WARNING: this procedure doesn't know about input saved via UNREADRH(),
526 * so if the caller wants this input to be discarded, it must call READRH()
527 * itself.
528 *
529 * Results:
530 * TRUE if successful, FALSE if EOF was encountered.
531 *
532 * Side effects:
533 * Consumes nbytes of input.
534 *
535 * ----------------------------------------------------------------------------
536 */
537
538 bool
calmaSkipBytes(nbytes)539 calmaSkipBytes(nbytes)
540 int nbytes; /* Skip this many bytes */
541 {
542 while (nbytes-- > 0)
543 if (getc(calmaInputFile) < 0)
544 return (FALSE);
545
546 return (TRUE);
547 }
548