cvtvax.h
来自「Machine Vision (美)Wesley E.Snyder著 光盘中的」· C头文件 代码 · 共 385 行 · 第 1/2 页
H
385 行
/*
PURPOSE -- Data Conversion MACROS for the ifs libary, VAX
RESTRICTIONS --
VAX version = assume "machine data" in the VAX format
Controlled by #define M2E (defined = Machine To External),
defaulting to E2M (External to Machine)
Macro invocation:
CVTxxx_yyy (ibyte, obyte, nbyte )
xxx - External data type: ( EEE, VAX, BYT )
yyy - Element type: ( SHRT, LONG, REAL, DBLE )
ibyte - input buffer char* pointer, not incremented.
obyte - output buffer char* pointer, not incremented.
nbyte - input bytes long int byte count
Conversions can be done in place.
Byte ordering assumptions:
Bit number: 31 24 23 16 15 08 07 00
VAX byte order: n+3 n+2 n+1 n+0
68020 byte order: n+0 n+1 n+2 n+3
80386 byte order: n+3 n+2 n+1 n+0
(bytes assumed to use the same most significant bit, this
will NOT be the case for IBM-360 data)
Note: The SEDEEE means MC68020 IEEE external data
The SED386 means I-80386 IEEE external data
The SEDBYT means "byte" = no conversion
The SEDVAX just dumps out data in VAX format
*/
/*
INTeger VAX to 68020 IEEE to VAX conversions
Only byte swap is necessary.
For the VAX, this code is bi-directional (same for M2E and E2M)
*/
#define CVTEEE_SHORT( ibyte, obyte, nbyte ) \
{ short *ip, *op, *last = (short*) (ibyte + nbyte); \
op = ( short *) obyte; \
ip = ( short *) ibyte; \
while ( ip < last ) \
{ *op++ = ifs_swap_half(*ip); ip++; }; \
}
#define CVT386_SHORT( ibyte, obyte, nbyte ) \
{ memcpy (obyte,ibyte,nbyte); }
#define CVTVAX_SHORT( ibyte, obyte, nbyte ) \
{ memcpy (obyte,ibyte,nbyte); }
#define CVTBYT_SHORT( ibyte, obyte, nbyte ) \
{ memcpy (obyte,ibyte,nbyte); }
#define CVTEEE_LONG( ibyte, obyte, nbyte ) \
{ long *ip, *op, *last = (long*) (ibyte + nbyte); \
op = ( long *) obyte; \
ip = ( long *) ibyte; \
while ( ip < last ) \
{ *op++ = ifs_swap_word(*ip); ip++; }; \
}
#define CVT386_LONG( ibyte, obyte, nbyte ) \
{ memcpy (obyte,ibyte,nbyte); }
#define CVTVAX_LONG( ibyte, obyte, nbyte ) \
{ memcpy (obyte,ibyte,nbyte); }
#define CVTBYT_LONG( ibyte, obyte, nbyte ) \
{ memcpy (obyte,ibyte,nbyte); }
/*
R E A L (FLOAT) FORMAT CONVERSIONS
IEEE Float format, normalized, "hidden" highest order mantissa bit,
2 based exponent biassed +127:
IEEE
------------------------------
|S|expone| mantissa |
------------------------------
31 30 23 22 0
(1) (8) (23)
DEC VAX Double format, normalized, "hidden" highest order mantissa bit,
2 based exponent biased +129 (128+1 for a hidden bit)
DEC VAX
------------------------------
| mantissa |S|expone|manti|
------------------------------
31 16 14 7 6 0
(low 16) (8) (hi 7)
For DEC->IEEE: subtract DEC base(129), add IEEE base(127) => exp -=2
For IEEE->DEC: subtract IEEE base(127), add DEC base(129) => exp +=2
On potential over/under flow, we force max.number resp. zero.
In both direcions we assume user's buffer is properly alligned.
*/
#ifdef M2E
/*
FLOAT VAX to 68020 IEEE conversion
VAX F longword is moved to local "eee0" longword store.
Exponent is adjusted to IEEE notation maintaining VAX byte order,
Bytes are swapped into output buffer in desired IEEE order, thus
we swap bytes in a word only.
*/
#define CVTEEE_REAL( ibyte, obyte, nbyte ) \
{ long *last = (long*) (ibyte + nbyte); long *vax0,*op; \
vax0 = (long*) ibyte; op = (long*) obyte; \
while ( vax0 < last ) \
{ long eee0, exp; /* Working IEEE */\
if ( *vax0 ) /* nonzero data */ \
{ exp = *vax0 & 0x00007F80; /* extract expon.*/ \
if(exp < 0x00000100) /* exp underflow?*/ \
eee0 = 0x00000000; /* = force zero */ \
else /* blank exponent*/ \
eee0 =(*vax0&0xFFFF807F)|(exp-0x100); /* or exp -=2*/ \
} \
else \
eee0 = 0; \
*op++ = ifs_swap_bytes(eee0); /* SWAP bytes */\
vax0++;
}; \
}
#else /*E2M*/
/*
FLOAT 68020 IEEE to VAX conversion
Bytes are swapped to build VAX F format (with an IEEE exponent),
Exponent is adjusted to VAX base limiting underflow.
*/
#define CVTEEE_REAL( ibyte, obyte, nbyte ) \
{ long *last = (long*) (ibyte + nbyte); long *ip, *vax0; \
ip = (long*) ibyte; /* input pointer */ \
vax0 = (long*) obyte; /* output FLOAT */ \
while ( ip < last ) \
{ long exp; \
*vax0 = ifs_swap_bytes(*ip); /* SWAP bytes */ \
if( *vax0 ) /* nonzero data */ \
{ exp = *vax0 & 0x00007F80; /* separate exp */ \
*vax0 = *vax0 & 0xFFFF807F; /* remove expon. */ \
if(exp > 0x00007E80) /* exp overflow? */ \
*vax0 |= 0xFFFF7FFF; /* = force max */ \
else /* (signed) */ \
*vax0 |= (exp + 0x00000100); /* exp +=2 */ \
} \
if (*vax0 == 0x00008000 ) *vax0 = 0; /* neg ZERO? */ \
vax0++; ip++; /* next longs */ \
}; \
}
#endif
#ifdef M2E
/*
FLOAT VAX to I-80386 IEEE conversion
VAX F longword is moved to local "eee0" longword store.
Exponent is adjusted to IEEE notation maintaining VAX byte order,
Words are swapped into output buffer in desired 386 IEEE order
(here we swap words only).
*/
#define CVT386_REAL( ibyte, obyte, nbyte ) \
{ long *last = (long*) (ibyte + nbyte); long *vax0, *op; \
op = (long*) obyte; /* output as long*/ \
vax0 = (long*) ibyte; \
while ( vax0 < last ) \
{ long eee0, exp; \
if ( *vax0 ) /* nonzero data */ \
{ exp = *vax0 & 0x00007F80; /* extract expon.*/ \
if(exp < 0x00000100) /* exp underflow?*/ \
eee0 = 0x00000000; /* = force zero */ \
else /* blank exponent*/ \
eee0 =(*vax0&0xFFFF807F)|(exp-0x100); /* or exp -=2*/ \
} \
else \
eee0 = 0; \
*op++ = ifs_swap_32(eee0); \
vax0++; \
}; \
}
#else /*E2M*/
/*
FLOAT I-80386 IEEE to VAX conversion
Bytes are moved to build VAX F format (with an IEEE exponent),
Exponent is adjusted to VAX base limiting underflow.
*/
#define CVT386_REAL( ibyte, obyte, nbyte ) \
{ long *last = (long*)(ibyte + nbyte); long *vax0, *ip; \
vax0 = (long*) obyte; ip = ( long*) ibyte; \
while ( ip < last ) \
{ unsigned long exp; \
*vax0 = ifs_swap_32(*ip); /* SWAP words */ \
ip++; /* next long */ \
if( *vax0 ) /* nonzero data */ \
{ exp = *vax0 & 0x00007F80; /* separate exp */ \
*vax0 = *vax0 & 0xFFFF807F; /* remove expon. */ \
if(exp > 0x00007E80) /* exp overflow? */ \
*vax0 = 0xFFFF7FFF; /* = force max */ \
else /* (signed) */ \
*vax0 |= (exp + 0x00000100); /* exp +=2 */ \
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?