[segyio] 99/376: Remove undefined pointer casts
Jørgen Kvalsvik
jokva-guest at moszumanska.debian.org
Wed Sep 20 08:04:15 UTC 2017
This is an automated email from the git hooks/post-receive script.
jokva-guest pushed a commit to branch debian
in repository segyio.
commit a936695b2a20f5be70b838f9fd2f972b6e13df7d
Author: Jørgen Kvalsvik <jokva at statoil.com>
Date: Mon Nov 7 16:06:39 2016 +0100
Remove undefined pointer casts
Restrict aliasing slightly and remove a source of undefined behaviour by
casting float pointers to uint32_t. Reimplements the ieee<->ibm
functions to work on one float at the time without triggering undefined
behaviour.
---
python/segyio/_segyio.c | 6 +-
src/segyio/segy.c | 178 +++++++++++++++++++++++++-----------------------
src/segyio/segy.h | 4 +-
src/segyio/util.h | 4 +-
tests/test_utils.c | 6 +-
5 files changed, 102 insertions(+), 96 deletions(-)
diff --git a/python/segyio/_segyio.c b/python/segyio/_segyio.c
index 36be7e5..3d2ecc4 100644
--- a/python/segyio/_segyio.c
+++ b/python/segyio/_segyio.c
@@ -755,11 +755,11 @@ static PyObject *py_read_trace(PyObject *self, PyObject *args) {
}
int error = 0;
- char* buf = buffer.buf;
+ float* buf = buffer.buf;
Py_ssize_t i;
- for( i = 0; error == 0 && i < length; ++i, buf += trace_bsize ) {
- error = segy_readtrace(p_FILE, start + (i * step), (float*)buf, trace0, trace_bsize);
+ for( i = 0; error == 0 && i < length; ++i, buf += samples ) {
+ error = segy_readtrace(p_FILE, start + (i * step), buf, trace0, trace_bsize);
}
int conv_error = segy_to_native(format, length * samples, buffer.buf);
diff --git a/src/segyio/segy.c b/src/segyio/segy.c
index cb8dda6..6814770 100644
--- a/src/segyio/segy.c
+++ b/src/segyio/segy.c
@@ -65,94 +65,92 @@ void ascii2ebcdic( const char* ascii, char* ebcdic ) {
*ebcdic = '\0';
}
-void ibm2ieee(void* to, const void* from, int len) {
- register unsigned fr; /* fraction */
+void ibm2ieee( void* to, const void* from ) {
+ uint32_t fr; /* fraction */
register int exp; /* exponent */
- register int sgn; /* sign */
-
- for (; len-- > 0; to = (char*) to + 4, from = (const char*) from + 4) {
- /* split into sign, exponent, and fraction */
- fr = ntohl(*(const int32_t*) from); /* pick up value */
- sgn = fr >> 31; /* save sign */
- fr <<= 1; /* shift sign out */
- exp = fr >> 25; /* save exponent */
- fr <<= 7; /* shift exponent out */
-
- if (fr == 0) { /* short-circuit for zero */
- exp = 0;
- goto done;
- }
+ uint32_t sgn; /* sign */
+
+ memcpy( &fr, from, sizeof( uint32_t ) );
+ /* split into sign, exponent, and fraction */
+ fr = ntohl( fr ); /* pick up value */
+ sgn = fr >> 31; /* save sign */
+ fr <<= 1; /* shift sign out */
+ exp = fr >> 25; /* save exponent */
+ fr <<= 7; /* shift exponent out */
+
+ if (fr == 0) { /* short-circuit for zero */
+ exp = 0;
+ goto done;
+ }
- /* adjust exponent from base 16 offset 64 radix point before first digit
- * to base 2 offset 127 radix point after first digit
- * (exp - 64) * 4 + 127 - 1 == exp * 4 - 256 + 126 == (exp << 2) - 130 */
- exp = (exp << 2) - 130;
+ /* adjust exponent from base 16 offset 64 radix point before first digit
+ * to base 2 offset 127 radix point after first digit
+ * (exp - 64) * 4 + 127 - 1 == exp * 4 - 256 + 126 == (exp << 2) - 130 */
+ exp = (exp << 2) - 130;
- /* (re)normalize */
- while (fr < 0x80000000) { /* 3 times max for normalized input */
- --exp;
- fr <<= 1;
- }
+ /* (re)normalize */
+ while (fr < 0x80000000) { /* 3 times max for normalized input */
+ --exp;
+ fr <<= 1;
+ }
- if (exp <= 0) { /* underflow */
- if (exp < -24) /* complete underflow - return properly signed zero */
- fr = 0;
- else /* partial underflow - return denormalized number */
- fr >>= -exp;
- exp = 0;
- } else if (exp >= 255) { /* overflow - return infinity */
+ if (exp <= 0) { /* underflow */
+ if (exp < -24) /* complete underflow - return properly signed zero */
fr = 0;
- exp = 255;
- } else { /* just a plain old number - remove the assumed high bit */
- fr <<= 1;
- }
-
- done:
- /* put the pieces back together and return it */
- *(unsigned*) to = (fr >> 9) | (exp << 23) | (sgn << 31);
+ else /* partial underflow - return denormalized number */
+ fr >>= -exp;
+ exp = 0;
+ } else if (exp >= 255) { /* overflow - return infinity */
+ fr = 0;
+ exp = 255;
+ } else { /* just a plain old number - remove the assumed high bit */
+ fr <<= 1;
}
+
+done:
+ /* put the pieces back together and return it */
+ fr = (fr >> 9) | (exp << 23) | (sgn << 31);
+ memcpy( to, &fr, sizeof( uint32_t ) );
}
-void ieee2ibm(void* to, const void* from, int len) {
- register unsigned fr; /* fraction */
+void ieee2ibm( void* to, const void* from ) {
+ uint32_t fr; /* fraction */
register int exp; /* exponent */
- register int sgn; /* sign */
-
- for (; len-- > 0; to = (char*) to + 4, from = (const char*) from + 4) {
- /* split into sign, exponent, and fraction */
- fr = *(const unsigned*) from; /* pick up value */
- sgn = fr >> 31; /* save sign */
- fr <<= 1; /* shift sign out */
- exp = fr >> 24; /* save exponent */
- fr <<= 8; /* shift exponent out */
-
- if (exp == 255) { /* infinity (or NAN) - map to largest */
- fr = 0xffffff00;
- exp = 0x7f;
- goto done;
- }
- else if (exp > 0) /* add assumed digit */
- fr = (fr >> 1) | 0x80000000;
- else if (fr == 0) /* short-circuit for zero */
- goto done;
-
- /* adjust exponent from base 2 offset 127 radix point after first digit
- * to base 16 offset 64 radix point before first digit */
- exp += 130;
- fr >>= -exp & 3;
- exp = (exp + 3) >> 2;
-
- /* (re)normalize */
- while (fr < 0x10000000) { /* never executed for normalized input */
- --exp;
- fr <<= 4;
- }
-
- done:
- /* put the pieces back together and return it */
- fr = (fr >> 8) | (exp << 24) | (sgn << 31);
- *(unsigned*) to = htonl(fr);
+ uint32_t sgn; /* sign */
+
+ /* split into sign, exponent, and fraction */
+ memcpy( &fr, from, sizeof( uint32_t ) ); /* pick up value */
+ sgn = fr >> 31; /* save sign */
+ fr <<= 1; /* shift sign out */
+ exp = fr >> 24; /* save exponent */
+ fr <<= 8; /* shift exponent out */
+
+ if (exp == 255) { /* infinity (or NAN) - map to largest */
+ fr = 0xffffff00;
+ exp = 0x7f;
+ goto done;
}
+ else if (exp > 0) /* add assumed digit */
+ fr = (fr >> 1) | 0x80000000;
+ else if (fr == 0) /* short-circuit for zero */
+ goto done;
+
+ /* adjust exponent from base 2 offset 127 radix point after first digit
+ * to base 16 offset 64 radix point before first digit */
+ exp += 130;
+ fr >>= -exp & 3;
+ exp = (exp + 3) >> 2;
+
+ /* (re)normalize */
+ while (fr < 0x10000000) { /* never executed for normalized input */
+ --exp;
+ fr <<= 4;
+ }
+
+done:
+ /* put the pieces back together and return it */
+ fr = htonl( (fr >> 8) | (exp << 24) | (sgn << 31) );
+ memcpy( to, &fr, sizeof( uint32_t ) );
}
/* Lookup table for field sizes. All values not explicitly set are 0 */
@@ -888,41 +886,49 @@ int segy_writetrace( FILE* fp,
}
int segy_to_native( int format,
- unsigned int size,
+ int size,
float* buf ) {
assert( sizeof( float ) == sizeof( uint32_t ) );
+ uint32_t u;
if( format == IEEE_FLOAT_4_BYTE ) {
- uint32_t u;
while( size-- ) {
memcpy( &u, buf, sizeof( float ) );
u = ntohl( u );
memcpy( buf++, &u, sizeof( float ) );
}
}
- else
- ibm2ieee( buf, buf, size );
+ else {
+ while( size-- ) {
+ ibm2ieee( &u, buf );
+ memcpy( buf++, &u, sizeof( float ) );
+ }
+ }
return SEGY_OK;
}
int segy_from_native( int format,
- unsigned int size,
+ int size,
float* buf ) {
assert( sizeof( float ) == sizeof( uint32_t ) );
+ uint32_t u;
if( format == IEEE_FLOAT_4_BYTE ) {
- uint32_t u;
while( size-- ) {
memcpy( &u, buf, sizeof( float ) );
u = htonl( u );
memcpy( buf++, &u, sizeof( float ) );
}
}
- else
- ieee2ibm( buf, buf, size );
+ else {
+ while( size-- ) {
+ ieee2ibm( &u, buf );
+ memcpy( buf++, &u, sizeof( float ) );
+ }
+ }
return SEGY_OK;
}
diff --git a/src/segyio/segy.h b/src/segyio/segy.h
index c9b0baf..3d9a444 100644
--- a/src/segyio/segy.h
+++ b/src/segyio/segy.h
@@ -114,11 +114,11 @@ int segy_writetrace( FILE*,
/* convert to/from native float from segy formats (likely IBM or IEEE) */
int segy_to_native( int format,
- unsigned int size,
+ int size,
float* buf );
int segy_from_native( int format,
- unsigned int size,
+ int size,
float* buf );
int segy_read_line( FILE* fp,
diff --git a/src/segyio/util.h b/src/segyio/util.h
index 6292e85..b39e49a 100644
--- a/src/segyio/util.h
+++ b/src/segyio/util.h
@@ -10,8 +10,8 @@
void ebcdic2ascii( const char* ebcdic, char* ascii );
void ascii2ebcdic( const char* ascii, char* ebcdic );
-void ibm2ieee(void* to, const void* from, int len);
-void ieee2ibm(void* to, const void* from, int len);
+void ibm2ieee(void* to, const void* from);
+void ieee2ibm(void* to, const void* from);
int segy_seek( FILE*, unsigned int, long, unsigned int );
#endif //SEGYIO_UTILS_H
diff --git a/tests/test_utils.c b/tests/test_utils.c
index ab67663..f1b942c 100644
--- a/tests/test_utils.c
+++ b/tests/test_utils.c
@@ -57,9 +57,9 @@ static void check(float f1, double * epsm) {
unsigned ibm1, ibm2;
frexp(f1, &exp);
- ieee2ibm(&ibm1, &f1, 1);
- ibm2ieee(&f2, &ibm1, 1);
- ieee2ibm(&ibm2, &f2, 1);
+ ieee2ibm(&ibm1, &f1);
+ ibm2ieee(&f2, &ibm1);
+ ieee2ibm(&ibm2, &f2);
assertTrue(memcmp(&ibm1, &ibm2, sizeof ibm1) == 0, "The content of two memory areas were not identical!");
//printf("Error: %08x <=> %08x\n", *(unsigned*) &ibm1, *(unsigned*) &ibm2);
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/segyio.git
More information about the debian-science-commits
mailing list