magic/calma/CalmaRdio.c

627 lines
14 KiB
C
Raw Normal View History

/*
* CalmaReadio.c --
*
* Input of Calma GDS-II stream format.
* Low-level input.
*
* *********************************************************************
* * Copyright (C) 1985, 1990 Regents of the University of California. *
* * Permission to use, copy, modify, and distribute this *
* * software and its documentation for any purpose and without *
* * fee is hereby granted, provided that the above copyright *
* * notice appear in all copies. The University of California *
* * makes no representations about the suitability of this *
* * software for any purpose. It is provided "as is" without *
* * express or implied warranty. Export of this software outside *
* * of the United States of America may require an export license. *
* *********************************************************************
*/
#ifndef lint
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 $";
#endif /* not lint */
#include <stdio.h>
#include <sys/types.h>
#include <time.h>
#include <netinet/in.h>
#include "utils/magic.h"
#include "utils/geometry.h"
#include "tiles/tile.h"
#include "utils/utils.h"
#include "utils/hash.h"
#include "database/database.h"
#include "database/databaseInt.h"
#include "utils/malloc.h"
#include "utils/tech.h"
#include "cif/cif.h"
#include "cif/CIFint.h"
#include "cif/CIFread.h"
#include "utils/signals.h"
#include "windows/windows.h"
#include "dbwind/dbwind.h"
#include "utils/styles.h"
#include "textio/textio.h"
#include "calma/calmaInt.h"
/* C99 compat */
#include "calma/calma.h"
/* Forward declarations */
bool calmaReadR8();
bool calmaSkipBytes();
/*
* ----------------------------------------------------------------------------
*
* calmaReadTransform --
*
* Read a CALMA_STRANS, CALMA_MAG, CALMA_ANGLE sequence and construct
* the corresponding geometric transform.
*
* Results:
* TRUE normally, FALSE on EOF or fatal syntax error.
*
* Side effects:
* Consumes input.
* Modifies the Transform pointed to by 'ptrans'.
*
* ----------------------------------------------------------------------------
*/
bool
calmaReadTransform(ptrans, name)
Transform *ptrans; /* Fill in this transform */
char *name; /* Name of subcell (for errors) */
{
int nbytes, rtype, flags, angle;
double dangle;
double dmag;
Transform t;
/* Default is the identity transform */
*ptrans = GeoIdentityTransform;
/* Is there any transform at all? */
READRH(nbytes, rtype);
if (nbytes < 0) return (FALSE);
if (rtype != CALMA_STRANS)
{
UNREADRH(nbytes, rtype);
return (TRUE);
}
if (nbytes != 6)
{
(void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH);
return (FALSE);
}
READI2(flags);
/* Look for magnification and angle */
READRH(nbytes, rtype);
if (nbytes < 0) return (FALSE);
if (rtype == CALMA_MAG)
{
if (nbytes != CALMAHEADERLENGTH + 8)
{
(void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH);
return (FALSE);
}
if (!calmaReadR8(&dmag)) return (FALSE);
if (dmag != (double)((int)(dmag + 0.5)))
{
CalmaReadError("Non-integer magnification (%g) in transform\n", dmag);
CalmaReadError("Rounding to %d.\n", (int)(dmag + 0.5));
}
GeoScaleTrans(ptrans, (int)(dmag + 0.5), &t);
*ptrans = t;
}
else UNREADRH(nbytes, rtype);
READRH(nbytes, rtype);
if (nbytes < 0) return (FALSE);
dangle = 0.0;
if (rtype == CALMA_ANGLE)
{
if (nbytes != CALMAHEADERLENGTH + 8)
{
(void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH);
return (FALSE);
}
if (!calmaReadR8(&dangle)) return (FALSE);
}
else UNREADRH(nbytes, rtype);
/* Make sure the angle is Manhattan */
angle = (int) dangle;
while (angle < 0) angle += 360;
while (angle > 360) angle -= 360;
switch (angle)
{
case 360:
angle = 0;
break;
case 0: case 90: case 180: case 270:
break;
default:
CalmaReadError("Non-Manhattan angle (%d) in transform\n", angle);
if (angle < 45) angle = 0;
else if (angle < 135) angle = 90;
else if (angle < 225) angle = 180;
else if (angle < 315) angle = 270;
else angle = 0;
CalmaReadError(" Rounding to %d degrees.\n", angle);
}
/*
* Construct the transform.
* Magic angles are clockwise; Calma angles are counterclockwise.
*/
if (flags & CALMA_STRANS_UPSIDEDOWN)
{
GeoTransTrans(ptrans, &GeoUpsideDownTransform, &t);
*ptrans = t;
}
switch (angle)
{
case 90:
GeoTransTrans(ptrans, &Geo270Transform, &t);
*ptrans = t;
break;
case 180:
GeoTransTrans(ptrans, &Geo180Transform, &t);
*ptrans = t;
break;
case 270:
GeoTransTrans(ptrans, &Geo90Transform, &t);
*ptrans = t;
break;
}
return (TRUE);
}
/*
* ----------------------------------------------------------------------------
*
* calmaReadI2Record --
*
* Read a record that should contain a two-byte integer.
*
* Results:
* TRUE on success, FALSE if the record type we read is not
* what we're expecting, or if it is of the wrong size.
*
* Side effects:
* Consumes input.
* Stores the result value in *pvalue (note that this is a normal
* int, even though we're reading only 16 bits from the input).
*
* ----------------------------------------------------------------------------
*/
bool
calmaReadI2Record(type, pvalue)
int type; /* Type of record expected */
int *pvalue; /* Store value here */
{
int nbytes, rtype, n;
READRH(nbytes, rtype);
if (nbytes < 0)
goto eof;
if (type != rtype)
{
calmaUnexpected(type, rtype);
return (FALSE);
}
/* Read the value */
READI2(n);
if (FEOF(calmaInputFile)) goto eof;
*pvalue = n;
return (TRUE);
eof:
CalmaReadError("Unexpected EOF.\n");
return (FALSE);
}
/*
* ----------------------------------------------------------------------------
*
* calmaReadI4Record --
*
* Read a record that should contain a four-byte integer.
*
* Results:
* TRUE on success, FALSE if the record type we read is not
* what we're expecting, or if it is of the wrong size.
*
* Side effects:
* Consumes input.
* Stores the result value in *pvalue.
*
* ----------------------------------------------------------------------------
*/
bool
calmaReadI4Record(type, pvalue)
int type; /* Type of record expected */
int *pvalue; /* Store value here */
{
int nbytes, rtype, n;
READRH(nbytes, rtype);
if (nbytes < 0)
goto eof;
if (type != rtype)
{
calmaUnexpected(type, rtype);
return (FALSE);
}
/* Read the value */
READI4(n);
if (FEOF(calmaInputFile)) goto eof;
*pvalue = n;
return (TRUE);
eof:
CalmaReadError("Unexpected EOF.\n");
return (FALSE);
}
/*
* ----------------------------------------------------------------------------
*
* calmaReadStampRecord --
*
* Read a record that contains a pair of timestamps for creation and
* modification dates.
*
* Results:
* TRUE on success, FALSE if the record type we read is not
* what we're expecting.
*
* Side effects:
* Consumes input.
* Translates the creation timestamp from GDS format to a standard
* UNIX (time.h) timestamp (seconds since the epoch).
* Stores the result in the integer pointed to by 'stampptr'.
*
* ----------------------------------------------------------------------------
*/
bool
calmaReadStampRecord(type, stampptr)
int type;
int *stampptr;
{
int nbytes, rtype;
struct tm gds_timestamp;
READRH(nbytes, rtype);
if (nbytes < 0)
goto eof;
if (type != rtype)
{
calmaUnexpected(type, rtype);
return (FALSE);
}
nbytes -= CALMAHEADERLENGTH;
if (nbytes != 24)
{
/* Not dealing with any timestamp that is not in I2 format */
calmaSkipBytes(nbytes);
if (stampptr) *stampptr = 0;
CalmaReadError("Unknown timestamp format; setting timestamp to zero.\n");
return TRUE;
}
gds_timestamp.tm_wday = 0; /* Not used by mktime() */
gds_timestamp.tm_yday = 0; /* Not used by mktime() */
gds_timestamp.tm_isdst = -1;
READI2(gds_timestamp.tm_year);
READI2(gds_timestamp.tm_mon);
READI2(gds_timestamp.tm_mday);
READI2(gds_timestamp.tm_hour);
READI2(gds_timestamp.tm_min);
READI2(gds_timestamp.tm_sec);
/* GDS timestamps differ from UNIX time structure only by a */
/* difference of 1 in the month count. */
gds_timestamp.tm_mon--;
/* Skip the modification date timestamp */
(void) calmaSkipBytes(nbytes - 12);
if (stampptr) *stampptr = (int)mktime(&gds_timestamp);
return (TRUE);
eof:
CalmaReadError("Unexpected EOF.\n");
return (FALSE);
}
/*
* ----------------------------------------------------------------------------
*
* calmaReadStringRecord --
*
* Read a record that should contain an ASCII string.
*
* Results:
* TRUE on success, FALSE if the record type we read is not
* what we're expecting.
*
* Side effects:
* Consumes input.
* Allocates memory for string str (must be freed by the caller)
* Stores the result in the string pointed to by 'str'.
*
* ----------------------------------------------------------------------------
*/
bool
calmaReadStringRecord(type, str)
int type;
char **str;
{
int nbytes, rtype;
READRH(nbytes, rtype);
if (nbytes < 0)
goto eof;
if (type != rtype)
{
calmaUnexpected(type, rtype);
return (FALSE);
}
nbytes -= CALMAHEADERLENGTH;
*str = (char *) mallocMagic(nbytes + 1);
if (FREAD(*str, sizeof (char), nbytes, calmaInputFile) != nbytes)
goto eof;
*(*str + nbytes) = '\0';
return (TRUE);
eof:
CalmaReadError("Unexpected EOF.\n");
return (FALSE);
}
/*
* ----------------------------------------------------------------------------
*
* calmaReadR8 --
*
* Read a single 8-byte real number in Calma stream format.
* Convert to internal double-precision format and store in
* the double pointed to by 'pd'.
*
* Results:
* TRUE on success, FALSE if EOF is encountered.
*
* Side effects:
* Consumes input.
* Stores the result in the *pd.
*
* ----------------------------------------------------------------------------
*/
bool
calmaReadR8(pd)
double *pd; /* Store result in *pd */
{
int i, exponent;
unsigned char dchars[8];
double mantissa, d;
bool isneg;
if (FREAD((char *) dchars, sizeof (char), sizeof dchars,
calmaInputFile) != sizeof dchars)
return (FALSE);
/* Extract the sign and exponent */
exponent = dchars[0];
35 x warning: suggest parentheses around assignment used as truth value PlowRules1.c:439:9: warning: suggest parentheses around assignment used as truth value PlowTech.c:645:17: warning: suggest parentheses around assignment used as truth value PlowTech.c:652:17: warning: suggest parentheses around assignment used as truth value PlowTech.c:1019:17: warning: suggest parentheses around assignment used as truth value ResReadSim.c:270:13: warning: suggest parentheses around assignment used as truth value ResReadSim.c:871:9: warning: suggest parentheses around assignment used as truth value ResRex.c:1840:17: warning: suggest parentheses around assignment used as truth value getrect.c:72:9: warning: suggest parentheses around assignment used as truth value getrect.c:79:9: warning: suggest parentheses around assignment used as truth value getrect.c:86:9: warning: suggest parentheses around assignment used as truth value getrect.c:93:9: warning: suggest parentheses around assignment used as truth value hash.c:732:16: warning: suggest parentheses around assignment used as truth value heap.c:328:17: warning: suggest parentheses around assignment used as truth value heap.c:344:17: warning: suggest parentheses around assignment used as truth value netlist.c:323:17: warning: suggest parentheses around assignment used as truth value niceabort.c:121:9: warning: suggest parentheses around assignment used as truth value path.c:1102:12: warning: suggest parentheses around assignment used as truth value pathvisit.c:245:13: warning: suggest parentheses around assignment used as truth value pathvisit.c:295:17: warning: suggest parentheses around assignment used as truth value tech.c:656:17: warning: suggest parentheses around assignment used as truth value ext2spice.c:1591:16: warning: suggest parentheses around assignment used as truth value ext2spice.c:1622:16: warning: suggest parentheses around assignment used as truth value ext2spice.c:1813:12: warning: suggest parentheses around assignment used as truth value ext2spice.c:1862:12: warning: suggest parentheses around assignment used as truth value ext2spice.c:3808:16: warning: suggest parentheses around assignment used as truth value CalmaRdio.c:437:9: warning: suggest parentheses around assignment used as truth value CalmaWrite.c:396:9: warning: suggest parentheses around assignment used as truth value CalmaWrite.c:1772:29: warning: suggest parentheses around assignment used as truth value CalmaWriteZ.c:372:9: warning: suggest parentheses around assignment used as truth value CalmaWriteZ.c:1608:29: warning: suggest parentheses around assignment used as truth value CIFrdtech.c:209:9: warning: suggest parentheses around assignment used as truth value CIFrdtech.c:214:9: warning: suggest parentheses around assignment used as truth value CIFrdtech.c:220:9: warning: suggest parentheses around assignment used as truth value CIFrdtech.c:226:9: warning: suggest parentheses around assignment used as truth value CIFrdutils.c:1258:12: warning: suggest parentheses around assignment used as truth value GCC14 -Wall cleanup series [-Wparentheses]
2024-10-04 18:21:15 +02:00
if ((isneg = (exponent & 0x80)))
exponent &= ~0x80;
exponent -= 64;
/* Construct the mantissa */
mantissa = 0.0;
for (i = 7; i > 0; i--)
{
mantissa += dchars[i];
mantissa /= 256.0;
}
/* Now raise the mantissa to the exponent */
d = mantissa;
if (exponent > 0)
{
while (exponent-- > 0)
d *= 16.0;
}
else if (exponent < 0)
{
while (exponent++ < 0)
d /= 16.0;
}
/* Make it negative if necessary */
if (isneg)
d = -d;
*pd = d;
return (TRUE);
}
/*
* ----------------------------------------------------------------------------
*
* calmaSkipSet --
*
* Skip all records falling in a specified set of types.
* Leave the input stream positioned to the start of the first
* record not in the specified set.
*
* The array pointed to by 'skipwhat' contains the record types
* of all records to be skipped, terminated with -1.
*
* Results:
* None.
*
* Side effects:
* Consumes input.
*
* ----------------------------------------------------------------------------
*/
void
calmaSkipSet(skipwhat)
int *skipwhat;
{
int *skipp;
int nbytes, rtype;
for (;;)
{
READRH(nbytes, rtype);
if (nbytes < 0)
return;
for (skipp = skipwhat; *skipp >= 0; skipp++)
if (*skipp == rtype)
goto skipit;
UNREADRH(nbytes, rtype);
break;
skipit:
(void) calmaSkipBytes(nbytes - CALMAHEADERLENGTH);
}
}
/*
* ----------------------------------------------------------------------------
*
* calmaSkipExact --
*
* Skip a single stream record, which must be of the type 'type'.
* Leave the input positioned to the start of the record following
* this one. Complain if the record is not the one expected.
*
* Results:
* TRUE if successful, FALSE if we encountered an error and
* the caller should abort.
*
* Side effects:
* Consumes input.
*
* ----------------------------------------------------------------------------
*/
bool
calmaSkipExact(type)
int type;
{
int nbytes, rtype;
/* Eat up the record header */
READRH(nbytes, rtype);
if (nbytes < 0)
goto eof;
/* Skip remainder of record */
if (!calmaSkipBytes(nbytes - CALMAHEADERLENGTH))
goto eof;
if (rtype != type)
{
calmaUnexpected(type, rtype);
return (FALSE);
}
return (TRUE);
eof:
CalmaReadError("Unexpected EOF.\n");
return (FALSE);
}
/*
* ----------------------------------------------------------------------------
*
* calmaSkipTo --
*
* Skip to a record of a particular type. Leaves the input stream
* positioned AFTER the record whose type is given by 'what'.
*
* Results:
* TRUE if we found this record, FALSE if EOF was encountered.
*
* Side effects:
* Consumes input.
*
* ----------------------------------------------------------------------------
*/
bool
calmaSkipTo(what)
int what;
{
int nbytes, rtype;
do
{
READRH(nbytes, rtype);
if (nbytes < 0)
return (FALSE);
calmaSkipBytes(nbytes - CALMAHEADERLENGTH);
} while (rtype != what);
return (TRUE);
}
/*
* ----------------------------------------------------------------------------
*
* calmaSkipBytes --
*
* Skip 'nbytes' bytes from the input.
* WARNING: this procedure doesn't know about input saved via UNREADRH(),
* so if the caller wants this input to be discarded, it must call READRH()
* itself.
*
* Results:
* TRUE if successful, FALSE if EOF was encountered.
*
* Side effects:
* Consumes nbytes of input.
*
* ----------------------------------------------------------------------------
*/
bool
calmaSkipBytes(nbytes)
int nbytes; /* Skip this many bytes */
{
while (nbytes-- > 0)
if (FGETC(calmaInputFile) < 0)
return (FALSE);
return (TRUE);
}