@@ -1377,68 +1377,116 @@ static int slicelength( int start, int stop, int step ) {
13771377 return (stop - start - 1 ) / step + 1 ;
13781378}
13791379
1380- static int32_t bswap_header_word (int32_t f , int word_size ) {
1381- if (word_size == 4 )
1382- return bswap32 (f );
1380+ static int bswap_header_word ( segy_field_data * fd ) {
1381+ uint8_t datatype = entry_type_to_datatype_map [fd -> entry_type ];
1382+ switch ( datatype ) {
1383+ case SEGY_SIGNED_INTEGER_8_BYTE :
1384+ fd -> value .i64 = bswap64 ( fd -> value .i64 );
1385+ return SEGY_OK ;
13831386
1384- /*
1385- * The casts are here are necessary
1386- *
1387- * First, it must be converted to a *signed* short (to preserve negative
1388- * numbers). The narrowing is safe because the source is 2 bytes anyway.
1389- *
1390- * The behaviour when this is implicitly wrong was discovered in [1].
1391- *
1392- * Then, it must be byteswapped with bswap16. When using the shifts is
1393- * probably fine as the types are also cast in the macro and are
1394- * compatible, but the builtins have this signature [2]:
1395- *
1396- * uint16_t __builtin_bswap16 (uint16_t x)
1397- *
1398- * which means that if the value is *negative* it will be interpreted as
1399- * unsigned and very much positive. When it is then implicitly converted
1400- * in the return type it is widened, and int32 can fit uint16 maximum just
1401- * fine.
1402- *
1403- * [1] https://github.com/equinor/segyio/issues/368
1404- * [2] http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
1405- */
1406- return (int16_t ) bswap16 ((int16_t ) f );
1387+ case SEGY_SIGNED_INTEGER_4_BYTE :
1388+ fd -> value .i32 = bswap32 ( fd -> value .i32 );
1389+ return SEGY_OK ;
1390+
1391+ case SEGY_SIGNED_SHORT_2_BYTE :
1392+ fd -> value .i16 = bswap16 ( fd -> value .i16 );
1393+ return SEGY_OK ;
1394+
1395+ case SEGY_UNSIGNED_INTEGER_8_BYTE :
1396+ fd -> value .u64 = bswap64 ( fd -> value .u64 );
1397+ return SEGY_OK ;
1398+
1399+ case SEGY_UNSIGNED_INTEGER_4_BYTE :
1400+ fd -> value .u32 = bswap32 ( fd -> value .u32 );
1401+ return SEGY_OK ;
1402+
1403+ case SEGY_UNSIGNED_SHORT_2_BYTE :
1404+ fd -> value .u16 = bswap16 ( fd -> value .u16 );
1405+ return SEGY_OK ;
1406+
1407+ case SEGY_UNSIGNED_CHAR_1_BYTE :
1408+ case SEGY_SIGNED_CHAR_1_BYTE :
1409+ return SEGY_OK ;
1410+ default :
1411+ return SEGY_INVALID_FIELD_DATATYPE ;
1412+ }
14071413}
14081414
14091415int segy_field_forall ( segy_datasource * ds ,
14101416 int field ,
14111417 int start ,
14121418 int stop ,
14131419 int step ,
1414- int * buf ,
1420+ void * buffer ,
14151421 long trace0 ,
14161422 int trace_bsize ) {
14171423 int err ;
1424+ char * buf = (char * )buffer ;
1425+
14181426 // do a dummy-read of a zero-init'd buffer to check args
1419- int32_t f ;
1420- char header [ SEGY_TRACE_HEADER_SIZE ] = { 0 };
1421- err = segy_get_tracefield_int ( header , field , & f );
1427+ segy_field_data fd ;
1428+ char header [SEGY_TRACE_HEADER_SIZE ] = { 0 };
1429+
1430+ const segy_entry_definition * offset_map =
1431+ ds -> traceheader_mapping_standard .offset_to_entry_definition ;
1432+ err = segy_get_tracefield ( header , offset_map , field , & fd );
14221433 if ( err != SEGY_OK ) return SEGY_INVALID_ARGS ;
14231434
14241435 int slicelen = slicelength ( start , stop , step );
1436+ int elemsize = segy_formatsize ( entry_type_to_datatype_map [fd .entry_type ] );
14251437
14261438 const int zfield = field - 1 ;
1427- for ( int i = start ; slicelen > 0 ; i += step , ++ buf , -- slicelen ) {
1428- err = segy_seek ( ds , i , trace0 + zfield , trace_bsize );
1439+ for ( int i = start ; slicelen > 0 ; i += step , buf += elemsize , -- slicelen ) {
1440+ int offset = trace0 + zfield ;
1441+ err = segy_seek ( ds , i , offset , trace_bsize );
14291442 if ( err != SEGY_OK ) return err ;
1430- err = ds -> read ( ds , header + zfield , sizeof ( uint32_t ) );
1443+ err = ds -> read ( ds , header + zfield , elemsize );
14311444 if ( err != 0 ) return SEGY_DS_READ_ERROR ;
14321445
1433- // note: for the moment function still works only on ints
1434- err = segy_get_tracefield_int ( header , field , & f );
1446+ err = segy_get_tracefield ( header , offset_map , field , & fd );
14351447 if ( err != 0 ) return err ;
1436- const uint8_t entry_type = traceheader_default_map [zfield ].entry_type ;
1437- const uint8_t datatype = entry_type_to_datatype_map [entry_type ];
1438- if ( ds -> metadata .endianness == SEGY_LSB ) {
1439- f = bswap_header_word ( f , segy_formatsize ( datatype ) );
1448+
1449+ if ( ds -> metadata .endianness == SEGY_LSB ) {
1450+ err = bswap_header_word ( & fd );
1451+ if ( err != SEGY_OK ) return err ;
1452+ }
1453+
1454+ switch ( entry_type_to_datatype_map [fd .entry_type ] ) {
1455+ case SEGY_SIGNED_INTEGER_8_BYTE :
1456+ memcpy ( buf , & fd .value .i64 , elemsize );
1457+ break ;
1458+
1459+ case SEGY_SIGNED_INTEGER_4_BYTE :
1460+ memcpy ( buf , & fd .value .i32 , elemsize );
1461+ break ;
1462+
1463+ case SEGY_SIGNED_SHORT_2_BYTE :
1464+ memcpy ( buf , & fd .value .i16 , elemsize );
1465+ break ;
1466+
1467+ case SEGY_SIGNED_CHAR_1_BYTE :
1468+ memcpy ( buf , & fd .value .i8 , elemsize );
1469+ break ;
1470+
1471+ case SEGY_UNSIGNED_INTEGER_8_BYTE :
1472+ memcpy ( buf , & fd .value .u64 , elemsize );
1473+ break ;
1474+
1475+ case SEGY_UNSIGNED_INTEGER_4_BYTE :
1476+ memcpy ( buf , & fd .value .u32 , elemsize );
1477+ break ;
1478+
1479+ case SEGY_UNSIGNED_SHORT_2_BYTE :
1480+ memcpy ( buf , & fd .value .u16 , elemsize );
1481+ break ;
1482+
1483+ case SEGY_UNSIGNED_CHAR_1_BYTE :
1484+ memcpy ( buf , & fd .value .u8 , elemsize );
1485+ break ;
1486+
1487+ default :
1488+ return SEGY_INVALID_FIELD_DATATYPE ;
14401489 }
1441- * buf = f ;
14421490 }
14431491
14441492 return SEGY_OK ;
@@ -2117,7 +2165,7 @@ static int segy_line_indices( segy_datasource* ds,
21172165 int traceno ,
21182166 int stride ,
21192167 int num_indices ,
2120- int * buf ,
2168+ void * buf ,
21212169 long trace0 ,
21222170 int trace_bsize ) {
21232171 return segy_field_forall ( ds ,
@@ -2281,7 +2329,7 @@ int segy_inline_indices( segy_datasource* ds,
22812329 int inline_count ,
22822330 int crossline_count ,
22832331 int offsets ,
2284- int * buf ,
2332+ void * buf ,
22852333 long trace0 ,
22862334 int trace_bsize ) {
22872335
@@ -2303,7 +2351,7 @@ int segy_crossline_indices( segy_datasource* ds,
23032351 int inline_count ,
23042352 int crossline_count ,
23052353 int offsets ,
2306- int * buf ,
2354+ void * buf ,
23072355 long trace0 ,
23082356 int trace_bsize ) {
23092357
0 commit comments