From 82ef4376e76733330951be97ae40d38ceecd47fd Mon Sep 17 00:00:00 2001 From: Alena Chaikouskaya Date: Fri, 4 Jul 2025 18:48:28 +0200 Subject: [PATCH 01/10] Remove int-[type] specific get-set field functions Specialized versions are not needed for the moment and we should be fine with more general functions. Partly reverses commits "Introduce segy_get_field_[type]" / "Introduce segy_set_field_[type]" to make tests to use just int. For current code it is safe because in current tests/internal functions all values are 4 bytes or less and there are no 4-bytes unsigned integers in current headers. General segy_get/set_field_int integer specialization is left as is for now as it is heavily used internally in segy.c code. We should aim to reconsider this before 2.0 release as otherwise it would become a permanent part of the C interface. General int specialization is mostly used in functions dealing with fields important for segy layout. These functions would require logic update as those fields have overriding "extended" field. For those general segy_get_field/segy_set_field would be used and it might present an opportunity to get rid of "int" specialization there completely. Why we might want to get rid of general segy_get/set_field_int integer specialization: - more general segy_get_field/segy_set_field function is available - having two ways in the interface to do the same thing is confusing - general "int" version might be dangerous in library source code as we now want to be very careful with types of fields we read. Now it exists purely for developer's convenience due to segyio 1.0 having only int fields. We should aim to use segy_get_field/segy_set_field where it ok to do so. Then we can decide whether it could be removed from the interface completely. Note that specialization would still be heavily used in tests/matlab/applications, but if we manage to get rid of it in the main code, it could become tests-only helper. --- applications/segyinfo.c | 16 ++-- applications/segyio-cath.c | 4 +- applications/segyio-crop.c | 26 +++--- lib/include/segyio/segy.h | 16 +--- lib/src/segy.c | 170 +++++-------------------------------- lib/src/segy.def | 7 -- lib/test/segy.cpp | 62 +++++++------- mex/segy_get_traces_mex.c | 4 +- 8 files changed, 78 insertions(+), 227 deletions(-) diff --git a/applications/segyinfo.c b/applications/segyinfo.c index 360aa4c1..538842a1 100644 --- a/applications/segyinfo.c +++ b/applications/segyinfo.c @@ -8,10 +8,10 @@ static void printSegyTraceInfo( const char* buf ) { int cdp, tsf, xl, il; - segy_get_field_i32( buf, SEGY_TR_ENSEMBLE, &cdp ); - segy_get_field_i32( buf, SEGY_TR_SEQ_FILE, &tsf ); - segy_get_field_i32( buf, SEGY_TR_CROSSLINE, &xl ); - segy_get_field_i32( buf, SEGY_TR_INLINE, &il ); + segy_get_field_int( buf, SEGY_TR_ENSEMBLE, &cdp ); + segy_get_field_int( buf, SEGY_TR_SEQ_FILE, &tsf ); + segy_get_field_int( buf, SEGY_TR_CROSSLINE, &xl ); + segy_get_field_int( buf, SEGY_TR_INLINE, &il ); printf("cdp: %d\n", cdp ); printf("TraceSequenceFile: %d\n", tsf ); @@ -55,8 +55,8 @@ int main(int argc, char* argv[]) { const int samples = segy_samples( header ); const long trace0 = segy_trace0( header ); const int trace_bsize = segy_trace_bsize( samples ); - int16_t extended_headers; - err = segy_get_field_i16( header, SEGY_BIN_EXT_HEADERS, &extended_headers ); + int extended_headers; + err = segy_get_field_int( header, SEGY_BIN_EXT_HEADERS, &extended_headers ); if( err != 0 ) { perror( "Can't read 'extended headers' field from binary header" ); @@ -113,8 +113,8 @@ int main(int argc, char* argv[]) { exit( err ); } - int16_t sample_count; - err = segy_get_field_i16( traceh, SEGY_TR_SAMPLE_COUNT, &sample_count ); + int sample_count; + err = segy_get_field_int( traceh, SEGY_TR_SAMPLE_COUNT, &sample_count ); if( err != 0 ) { fprintf( stderr, "Invalid trace header field: %d\n", SEGY_TR_SAMPLE_COUNT ); diff --git a/applications/segyio-cath.c b/applications/segyio-cath.c index fa1cc2c6..b2bf7cce 100644 --- a/applications/segyio-cath.c +++ b/applications/segyio-cath.c @@ -34,8 +34,8 @@ static int ext_headers( segy_file* fp ) { if( err ) return -1; - int16_t ext; - err = segy_get_field_i16( binary, SEGY_BIN_EXT_HEADERS, &ext ); + int ext; + err = segy_get_field_int( binary, SEGY_BIN_EXT_HEADERS, &ext ); if( err ) return -2; return ext; } diff --git a/applications/segyio-crop.c b/applications/segyio-crop.c index 0e2d798d..13357e40 100644 --- a/applications/segyio-crop.c +++ b/applications/segyio-crop.c @@ -51,10 +51,10 @@ static struct delay delay_recording_time( const char* trheader, int dt, int samples ) { - int16_t t0; - segy_get_field_i16( trheader, SEGY_TR_DELAY_REC_TIME, &t0 ); - int16_t trdt; - segy_get_field_i16( trheader, SEGY_TR_SAMPLE_INTER, &trdt ); + int t0; + segy_get_field_int( trheader, SEGY_TR_DELAY_REC_TIME, &t0 ); + int trdt; + segy_get_field_int( trheader, SEGY_TR_SAMPLE_INTER, &trdt ); if( trdt ) dt = trdt; /* @@ -408,8 +408,8 @@ int main( int argc, char** argv ) { if( sz != 1 ) exit( errmsg2( errno, "Unable to write binary header", strerror( errno ) ) ); - int16_t ext_headers; - int err = segy_get_field_i16(binheader, SEGY_BIN_EXT_HEADERS, &ext_headers); + int ext_headers; + int err = segy_get_field_int(binheader, SEGY_BIN_EXT_HEADERS, &ext_headers); if( err != SEGY_OK ) exit( errmsg( -1, "Malformed binary header" ) ); for( int i = 0; i < ext_headers; ++i ) { @@ -424,10 +424,10 @@ int main( int argc, char** argv ) { } if( verbosity > 2 ) puts( "Computing samples-per-trace" ); - int16_t bindt; - segy_get_field_i16( binheader, SEGY_BIN_INTERVAL, &bindt ); - uint16_t src_samples; - err = segy_get_field_u16( binheader, SEGY_BIN_SAMPLES, &src_samples ); + int bindt; + segy_get_field_int( binheader, SEGY_BIN_INTERVAL, &bindt ); + int src_samples; + err = segy_get_field_int( binheader, SEGY_BIN_SAMPLES, &src_samples ); if( err != SEGY_OK ) exit( errmsg( -2, "Could not determine samples per trace" ) ); @@ -514,9 +514,9 @@ int main( int argc, char** argv ) { bindt, src_samples ); - segy_set_field_u16( trheader, SEGY_TR_SAMPLE_COUNT, d.len ); - segy_set_field_i16( trheader, SEGY_TR_DELAY_REC_TIME, d.delay ); - segy_set_field_u16( binheader, SEGY_BIN_SAMPLES, d.len ); + segy_set_field_int( trheader, SEGY_TR_SAMPLE_COUNT, d.len ); + segy_set_field_int( trheader, SEGY_TR_DELAY_REC_TIME, d.delay ); + segy_set_field_int( binheader, SEGY_BIN_SAMPLES, d.len ); if( verbosity > 2 ) printf( "Copying trace %lld\n", traces ); sz = fwrite( trheader, TRHSIZE, 1, dst ); diff --git a/lib/include/segyio/segy.h b/lib/include/segyio/segy.h index 9c06b797..5584961a 100644 --- a/lib/include/segyio/segy.h +++ b/lib/include/segyio/segy.h @@ -204,23 +204,13 @@ int segy_set_endianness( segy_datasource*, int opt ); */ int segy_init_field_data(int field, segy_field_data* fd); -int segy_get_field_u8( const char* header, int field, uint8_t* val ); -int segy_get_field_u16( const char* header, int field, uint16_t* val ); -int segy_get_field_u64( const char* header, int field, uint64_t* val ); -int segy_get_field_i16( const char* header, int field, int16_t* val ); -int segy_get_field_i32( const char* header, int field, int32_t* val ); -int segy_get_field_f64( const char* header, int field, double* val ); -int segy_get_field_int( const char* header, int field, int* f ); segy_field_data segy_get_field( const char* header, int field); +int segy_set_field( char* header, segy_field_data* fd ); + int segy_field_data_to_int( const segy_field_data* fd, int* val ); -int segy_set_field_i16( char* header, const int field, const int16_t val ); -int segy_set_field_i32( char* header, const int field, const int32_t val ); -int segy_set_field_u16( char* header, const int field, const uint16_t val ); -int segy_set_field_u64( char* header, const int field, const uint64_t val ); -int segy_set_field_f64( char* header, const int field, const double val ); +int segy_get_field_int( const char* header, int field, int* f ); int segy_set_field_int( char* header, const int field, const int val ); -int segy_set_field( char* header, segy_field_data* fd ); int segy_field_forall( segy_datasource*, int field, diff --git a/lib/src/segy.c b/lib/src/segy.c index 2520381b..5518b8c6 100644 --- a/lib/src/segy.c +++ b/lib/src/segy.c @@ -916,78 +916,6 @@ int segy_init_field_data(int field, segy_field_data* fd) { return SEGY_OK; } -int segy_get_field_u8( const char* header, int field, uint8_t* val ) { - segy_field_data fd; - int err = segy_init_field_data( field, &fd ); - if ( err != SEGY_OK ) return err; - err = get_field( header, &fd ); - if( err != SEGY_OK ) return err; - if ( fd.datatype != SEGY_UNSIGNED_CHAR_1_BYTE ) - return SEGY_INVALID_FIELD_DATATYPE; - *val = fd.value.u8; - return SEGY_OK; -} - -int segy_get_field_u16( const char* header, int field, uint16_t* val ) { - segy_field_data fd; - int err = segy_init_field_data( field, &fd ); - if ( err != SEGY_OK ) return err; - err = get_field( header, &fd ); - if( err != SEGY_OK ) return err; - if ( fd.datatype != SEGY_UNSIGNED_SHORT_2_BYTE ) - return SEGY_INVALID_FIELD_DATATYPE; - *val = fd.value.u16; - return SEGY_OK; -} - -int segy_get_field_u64( const char* header, int field, uint64_t* val ) { - segy_field_data fd; - int err = segy_init_field_data( field, &fd ); - if ( err != SEGY_OK ) return err; - err = get_field( header, &fd ); - if( err != SEGY_OK ) return err; - if ( fd.datatype != SEGY_UNSIGNED_INTEGER_8_BYTE ) - return SEGY_INVALID_FIELD_DATATYPE; - *val = fd.value.u64; - return SEGY_OK; -} - -int segy_get_field_i16( const char* header, int field, int16_t* val ) { - segy_field_data fd; - int err = segy_init_field_data( field, &fd ); - if ( err != SEGY_OK ) return err; - err = get_field( header, &fd ); - if( err != SEGY_OK ) return err; - if ( fd.datatype != SEGY_SIGNED_SHORT_2_BYTE ) - return SEGY_INVALID_FIELD_DATATYPE; - *val = fd.value.i16; - return SEGY_OK; -} - -int segy_get_field_i32( const char* header, int field, int32_t* val ) { - segy_field_data fd; - int err = segy_init_field_data( field, &fd ); - if ( err != SEGY_OK ) return err; - err = get_field( header, &fd ); - if( err != SEGY_OK ) return err; - if ( fd.datatype != SEGY_SIGNED_INTEGER_4_BYTE ) - return SEGY_INVALID_FIELD_DATATYPE; - *val = fd.value.i32; - return SEGY_OK; -} - -int segy_get_field_f64( const char* header, int field, double* val ) { - segy_field_data fd; - int err = segy_init_field_data( field, &fd ); - if ( err != SEGY_OK ) return err; - err = get_field( header, &fd ); - if( err != SEGY_OK ) return err; - if ( fd.datatype != SEGY_IEEE_FLOAT_8_BYTE ) - return SEGY_INVALID_FIELD_DATATYPE; - *val = fd.value.f64; - return SEGY_OK; -} - int segy_get_field_int( const char* header, int field, int* val ) { segy_field_data fd; int err = segy_init_field_data( field, &fd ); @@ -1098,66 +1026,6 @@ static int fd_set_int( segy_field_data* fd, int val ) { } } -int segy_set_field_i16( char* header, const int field, const int16_t val ) { - segy_field_data fd; - int err = segy_init_field_data( field, &fd ); - if ( err != SEGY_OK ) return err; - - if ( fd.datatype != SEGY_SIGNED_SHORT_2_BYTE ) - return SEGY_INVALID_FIELD_DATATYPE; - - fd.value.i16 = val; - return set_field( header, &fd ); -} - -int segy_set_field_i32( char* header, const int field, const int32_t val ) { - segy_field_data fd; - int err = segy_init_field_data( field, &fd ); - if ( err != SEGY_OK ) return err; - - if ( fd.datatype != SEGY_SIGNED_INTEGER_4_BYTE ) - return SEGY_INVALID_FIELD_DATATYPE; - - fd.value.i32 = val; - return set_field( header, &fd ); -} - -int segy_set_field_u16( char* header, const int field, const uint16_t val ) { - segy_field_data fd; - int err = segy_init_field_data( field, &fd ); - if ( err != SEGY_OK ) return err; - - if ( fd.datatype != SEGY_UNSIGNED_SHORT_2_BYTE ) - return SEGY_INVALID_FIELD_DATATYPE; - - fd.value.u16 = val; - return set_field( header, &fd ); -} - -int segy_set_field_u64( char* header, const int field, const uint64_t val ) { - segy_field_data fd; - int err = segy_init_field_data( field, &fd ); - if ( err != SEGY_OK ) return err; - - if ( fd.datatype != SEGY_UNSIGNED_INTEGER_8_BYTE ) - return SEGY_INVALID_FIELD_DATATYPE; - - fd.value.u64 = val; - return set_field( header, &fd ); -} - -int segy_set_field_f64( char* header, const int field, const double val ) { - segy_field_data fd; - int err = segy_init_field_data( field, &fd ); - if ( err != SEGY_OK ) return err; - - if ( fd.datatype != SEGY_IEEE_FLOAT_8_BYTE ) - return SEGY_INVALID_FIELD_DATATYPE; - - fd.value.f64 = val; - return set_field( header, &fd ); -} - int segy_set_field_int( char* header, const int field, const int val ) { segy_field_data fd; @@ -1345,8 +1213,8 @@ int segy_write_binheader( segy_datasource* ds, const char* buf ) { } int segy_format( const char* binheader ) { - int16_t format = 0; - segy_get_field_i16( binheader, SEGY_BIN_FORMAT, &format ); + int format = 0; + segy_get_field_int( binheader, SEGY_BIN_FORMAT, &format ); return format; } @@ -1372,12 +1240,12 @@ int segy_set_endianness( segy_datasource* ds, int endianness) { } int segy_samples( const char* binheader ) { - uint16_t samples = 0; - segy_get_field_u16( binheader, SEGY_BIN_SAMPLES, &samples ); + int samples = 0; + segy_get_field_int( binheader, SEGY_BIN_SAMPLES, &samples ); samples = (int32_t)((uint16_t)samples); - int32_t ext_samples = 0; - segy_get_field_i32(binheader, SEGY_BIN_EXT_SAMPLES, &ext_samples); + int ext_samples = 0; + segy_get_field_int(binheader, SEGY_BIN_EXT_SAMPLES, &ext_samples); if (samples == 0 && ext_samples > 0) return ext_samples; @@ -1393,8 +1261,8 @@ int segy_samples( const char* binheader ) { * used, the revision flag is also appropriately set to >= 2. Negative * values are ignored, as it's likely just noise. */ - uint8_t revision = 0; - segy_get_field_u8(binheader, SEGY_BIN_SEGY_REVISION, &revision); + int revision = 0; + segy_get_field_int(binheader, SEGY_BIN_SEGY_REVISION, &revision); if (revision >= 2 && ext_samples > 0) return ext_samples; @@ -1413,8 +1281,8 @@ int segy_trsize( int format, int samples ) { } long segy_trace0( const char* binheader ) { - int16_t extra_headers = 0; - segy_get_field_i16( binheader, SEGY_BIN_EXT_HEADERS, &extra_headers ); + int extra_headers = 0; + segy_get_field_int( binheader, SEGY_BIN_EXT_HEADERS, &extra_headers ); return SEGY_TEXT_HEADER_SIZE + SEGY_BINARY_HEADER_SIZE + SEGY_TEXT_HEADER_SIZE * extra_headers; @@ -1621,11 +1489,11 @@ int segy_sample_interval( segy_datasource* ds, float fallback, float* dt ) { return err; } - int16_t bindt = 0; - int16_t trdt = 0; + int bindt = 0; + int trdt = 0; - segy_get_field_i16( bin_header, SEGY_BIN_INTERVAL, &bindt ); - segy_get_field_i16( trace_header, SEGY_TR_SAMPLE_INTER, &trdt ); + segy_get_field_int( bin_header, SEGY_BIN_INTERVAL, &bindt ); + segy_get_field_int( trace_header, SEGY_TR_SAMPLE_INTER, &trdt ); float binary_header_dt = (float) bindt; float trace_header_dt = (float) trdt; @@ -2672,18 +2540,18 @@ static int scaled_cdp( segy_datasource* ds, float* cdpy, long trace0, int trace_bsize ) { - int32_t x, y; - int16_t scalar; + int x, y; + int scalar; char trheader[ SEGY_TRACE_HEADER_SIZE ]; int err = segy_traceheader( ds, traceno, trheader, trace0, trace_bsize ); if( err != 0 ) return err; - err = segy_get_field_i32( trheader, SEGY_TR_CDP_X, &x ); + err = segy_get_field_int( trheader, SEGY_TR_CDP_X, &x ); if( err != 0 ) return err; - err = segy_get_field_i32( trheader, SEGY_TR_CDP_Y, &y ); + err = segy_get_field_int( trheader, SEGY_TR_CDP_Y, &y ); if( err != 0 ) return err; - err = segy_get_field_i16( trheader, SEGY_TR_SOURCE_GROUP_SCALAR, &scalar ); + err = segy_get_field_int( trheader, SEGY_TR_SOURCE_GROUP_SCALAR, &scalar ); if( err != 0 ) return err; float scale = (float) scalar; diff --git a/lib/src/segy.def b/lib/src/segy.def index 7527e123..6c9b23eb 100644 --- a/lib/src/segy.def +++ b/lib/src/segy.def @@ -12,14 +12,7 @@ segy_sample_interval segy_format segy_set_format segy_set_endianness -segy_get_field_u8 -segy_get_field_u16 -segy_get_field_i16 -segy_get_field_i32 segy_get_field_int -segy_set_field_u16 -segy_set_field_i16 -segy_set_field_i32 segy_set_field_int segy_field_forall segy_trace_bsize diff --git a/lib/test/segy.cpp b/lib/test/segy.cpp index 7fde357b..5288bc9c 100644 --- a/lib/test/segy.cpp +++ b/lib/test/segy.cpp @@ -274,8 +274,8 @@ TEST_CASE_METHOD( smallbin, "use bin-interval when trace-interval is zero", "[c.segy]" ) { - std::int16_t hdt = arbitrary_int(); - segy_get_field_i16( bin, SEGY_BIN_INTERVAL, &hdt ); + int hdt = arbitrary_int(); + segy_get_field_int( bin, SEGY_BIN_INTERVAL, &hdt ); REQUIRE( hdt == 4000 ); float dt = arbitrary_float(); @@ -411,8 +411,8 @@ TEST_CASE_METHOD( smallheader, "valid trace-header fields can be read", "[c.segy]" ) { - int32_t ilno; - Err err = segy_get_field_i32( header, SEGY_TR_INLINE, &ilno ); + int ilno; + Err err = segy_get_field_int( header, SEGY_TR_INLINE, &ilno ); CHECK( success( err ) ); CHECK( ilno == 1 ); } @@ -420,9 +420,9 @@ TEST_CASE_METHOD( smallheader, TEST_CASE_METHOD( smallheader, "zero header field is an argument error", "[c.segy]" ) { - const int32_t input_value = arbitrary_int(); + const int input_value = arbitrary_int(); auto value = input_value; - Err err = segy_get_field_i32( header, 0, &value ); + Err err = segy_get_field_int( header, 0, &value ); CHECK( err == Err::field() ); CHECK( value == input_value ); @@ -431,9 +431,9 @@ TEST_CASE_METHOD( smallheader, TEST_CASE_METHOD( smallheader, "negative header field is an argument error", "[c.segy]" ) { - const int32_t input_value = arbitrary_int(); + const int input_value = arbitrary_int(); auto value = input_value; - Err err = segy_get_field_i32( header, -1, &value ); + Err err = segy_get_field_int( header, -1, &value ); CHECK( err == Err::field() ); CHECK( value == input_value ); @@ -442,9 +442,9 @@ TEST_CASE_METHOD( smallheader, TEST_CASE_METHOD( smallheader, "unaligned header field is an argument error", "[c.segy]" ) { - const int32_t input_value = arbitrary_int(); + const int input_value = arbitrary_int(); auto value = input_value; - Err err = segy_get_field_i32( header, SEGY_TR_INLINE + 1, &value ); + Err err = segy_get_field_int( header, SEGY_TR_INLINE + 1, &value ); CHECK( err == Err::field() ); CHECK( value == input_value ); @@ -1291,7 +1291,7 @@ TEST_CASE( "setting unaligned header-field fails", char header[ SEGY_TRACE_HEADER_SIZE ]; const int32_t v = arbitrary_int(); - Err err = segy_set_field_i32( header, SEGY_TR_INLINE + 1, v ); + Err err = segy_set_field_int( header, SEGY_TR_INLINE + 1, v ); CHECK( err == Err::field() ); } @@ -1309,7 +1309,7 @@ TEST_CASE( "setting too large header-field fails", char header[ SEGY_TRACE_HEADER_SIZE ]; const int32_t v = arbitrary_int(); - Err err = segy_set_field_i32( header, SEGY_TRACE_HEADER_SIZE + 10, v ); + Err err = segy_set_field_int( header, SEGY_TRACE_HEADER_SIZE + 10, v ); CHECK( err == Err::field() ); } @@ -1319,12 +1319,12 @@ TEST_CASE( "setting correct header fields succeeds", const int32_t input = 1; const int field = SEGY_TR_INLINE; - Err err = segy_set_field_i32( header, field, input ); + Err err = segy_set_field_int( header, field, input ); CHECK( success( err ) ); int32_t output; - err = segy_get_field_i32( header, field, &output ); + err = segy_get_field_int( header, field, &output ); CHECK( success( err ) ); CHECK( output == input ); @@ -1342,17 +1342,17 @@ SCENARIO( "modifying trace header", "[c.segy]" ) { WHEN( "writing iline no" ) { char header[ SEGY_TRACE_HEADER_SIZE ] = {}; - Err err = segy_set_field_i32( header, SEGY_TR_INLINE, 2 ); + Err err = segy_set_field_int( header, SEGY_TR_INLINE, 2 ); CHECK( err == Err::ok() ); - err = segy_set_field_i16( header, SEGY_TR_SOURCE_GROUP_SCALAR, -100 ); + err = segy_set_field_int( header, SEGY_TR_SOURCE_GROUP_SCALAR, -100 ); CHECK( err == Err::ok() ); THEN( "the header buffer is updated") { int ilno = 0; - int16_t scale = 0; - err = segy_get_field_i32( header, SEGY_TR_INLINE, &ilno ); + int scale = 0; + err = segy_get_field_int( header, SEGY_TR_INLINE, &ilno ); CHECK( err == Err::ok() ); - err = segy_get_field_i16( header, SEGY_TR_SOURCE_GROUP_SCALAR, &scale ); + err = segy_get_field_int( header, SEGY_TR_SOURCE_GROUP_SCALAR, &scale ); CHECK( err == Err::ok() ); CHECK( ilno == 2 ); @@ -1379,12 +1379,12 @@ SCENARIO( "modifying trace header", "[c.segy]" ) { THEN( "changes are observable on disk" ) { char fresh[ SEGY_TRACE_HEADER_SIZE ] = {}; int ilno = 0; - int16_t scale = 0; + int scale = 0; err = segy_traceheader( fp, 5, fresh, trace0, trace_bsize ); CHECK( err == Err::ok() ); - err = segy_get_field_i32( fresh, SEGY_TR_INLINE, &ilno ); + err = segy_get_field_int( fresh, SEGY_TR_INLINE, &ilno ); CHECK( err == Err::ok() ); - err = segy_get_field_i16( fresh, SEGY_TR_SOURCE_GROUP_SCALAR, &scale ); + err = segy_get_field_int( fresh, SEGY_TR_SOURCE_GROUP_SCALAR, &scale ); CHECK( err == Err::ok() ); CHECK( ilno == 2 ); @@ -1858,7 +1858,7 @@ SCENARIO( "reading a 2-byte int file", "[c.segy][2-byte]" ) { CHECK( err == Err::ok() ); int ilno = 0; - err = segy_get_field_i32( buf, SEGY_TR_INLINE, &ilno ); + err = segy_get_field_int( buf, SEGY_TR_INLINE, &ilno ); CHECK( err == Err::ok() ); CHECK( ilno == 111 ); } @@ -1869,7 +1869,7 @@ SCENARIO( "reading a 2-byte int file", "[c.segy][2-byte]" ) { CHECK( err == Err::field() ); CHECK( x == -1 ); - err = segy_get_field_i32( buf, SEGY_TR_INLINE + 1, &x ); + err = segy_get_field_int( buf, SEGY_TR_INLINE + 1, &x ); CHECK( err == Err::field() ); CHECK( x == -1 ); } @@ -2010,14 +2010,14 @@ TEST_CASE("1-byte header words are correctly read", "[c.segy]") { header[300] = 0x01; header[301] = 0x02; - std::uint8_t one; - std::uint8_t two; + int one; + int two; - Err err = segy_get_field_u8(header.data(), SEGY_BIN_SEGY_REVISION, &one); + Err err = segy_get_field_int(header.data(), SEGY_BIN_SEGY_REVISION, &one); CHECK(err == Err::ok()); CHECK(one == 0x01); - err = segy_get_field_u8(header.data(), SEGY_BIN_SEGY_REVISION_MINOR, &two); + err = segy_get_field_int(header.data(), SEGY_BIN_SEGY_REVISION_MINOR, &two); CHECK(err == Err::ok()); CHECK(two == 0x02); } @@ -2053,8 +2053,8 @@ TEST_CASE("segy_get_field reads values correctly", "[c.segy]" ) { header[SEGY_TR_TRACE_ID-1] = b1; header[SEGY_TR_TRACE_ID-0] = b0; - int16_t read_value; - Err err = segy_get_field_i16( header, SEGY_TR_TRACE_ID, &read_value ); + int read_value; + Err err = segy_get_field_int( header, SEGY_TR_TRACE_ID, &read_value ); CHECK( success( err ) ); CHECK( read_value == value ); } @@ -2066,7 +2066,7 @@ TEST_CASE("segy_set_field write values correctly", "[c.segy]" ) { SECTION("test edge cases int16") { int16_t value = GENERATE(0, 1, -1, 0x0102, 0x0201, -32767, -32766); - Err err = segy_set_field_i16( header, SEGY_TR_TRACE_ID, value ); + Err err = segy_set_field_int( header, SEGY_TR_TRACE_ID, value ); CHECK( err == Err::ok() ); uint8_t b0 = header[SEGY_TR_TRACE_ID-0]; diff --git a/mex/segy_get_traces_mex.c b/mex/segy_get_traces_mex.c index 78ced546..cd2a9642 100644 --- a/mex/segy_get_traces_mex.c +++ b/mex/segy_get_traces_mex.c @@ -63,8 +63,8 @@ void mexFunction(int nlhs, mxArray *plhs[], segy_to_native( fmt.format, bufsize, mxGetData( plhs[ 0 ] ) ); - int16_t interval; - segy_get_field_i16( binary, SEGY_BIN_INTERVAL, &interval ); + int interval; + segy_get_field_int( binary, SEGY_BIN_INTERVAL, &interval ); plhs[ 1 ] = mxCreateDoubleScalar( interval ); plhs[ 2 ] = mxCreateDoubleScalar( fmt.format ); From a19565cdde193717e3e70c2886536bbf92539f17 Mon Sep 17 00:00:00 2001 From: Alena Chaikouskaya Date: Thu, 24 Jul 2025 20:29:03 +0200 Subject: [PATCH 02/10] Remove segy_field_data_to_int Function is exposed in the header only for "application", which are supposed to be test-only applications. We should avoid having test-only functions in the interface. --- applications/segyio-catb.c | 75 ++++++++++++++++++++++++-------------- lib/include/segyio/segy.h | 2 - lib/src/segy.c | 6 +-- 3 files changed, 50 insertions(+), 33 deletions(-) diff --git a/applications/segyio-catb.c b/applications/segyio-catb.c index 2f477e2a..bfc03051 100644 --- a/applications/segyio-catb.c +++ b/applications/segyio-catb.c @@ -77,6 +77,14 @@ typedef struct { const char* description; } binary_field_type; +static void u64_to_buf(char *buf, size_t buflen, unsigned long long int value) { + snprintf(buf, buflen, "%llu", value); +} + +static void i64_to_buf(char *buf, size_t buflen, long long int value) { + snprintf(buf, buflen, "%lld", value); +} + int main( int argc, char** argv ){ if( argc == 1 ){ @@ -154,36 +162,47 @@ int main( int argc, char** argv ){ segy_field_data fd = segy_get_field( binheader, field_data[c].offset ); if ( fd.error ) return errmsg( fd.error, "Unable to read field" ); - int byte_offset = (field_data[c].offset - SEGY_TEXT_HEADER_SIZE); - const char* short_name = field_data[c].short_name; - const char* description = field_data[c].description; - - if( fd.datatype == SEGY_UNSIGNED_INTEGER_8_BYTE ) { - unsigned long long int field = fd.value.u64; - if( opts.nonzero && field == 0) continue; - if( opts.description ) - printf( "%s\t%llu\t%d\t%s\n", short_name, field, byte_offset, description ); - else - printf( "%-10s\t%llu\n", short_name, field ); + bool value_is_zero = false; + char value_str[40]; // should be enough for all strings + + switch( fd.datatype ) { + case SEGY_UNSIGNED_INTEGER_8_BYTE: { + u64_to_buf( value_str, sizeof( value_str ), fd.value.u64 ); + } break; + case SEGY_UNSIGNED_SHORT_2_BYTE: { + u64_to_buf( value_str, sizeof( value_str ), fd.value.u16 ); + } break; + case SEGY_UNSIGNED_CHAR_1_BYTE: { + u64_to_buf( value_str, sizeof( value_str ), fd.value.u8 ); + } break; + case SEGY_SIGNED_INTEGER_4_BYTE: { + i64_to_buf( value_str, sizeof( value_str ), fd.value.i32 ); + } break; + case SEGY_SIGNED_SHORT_2_BYTE: { + i64_to_buf( value_str, sizeof( value_str ), fd.value.i16 ); + } break; + case SEGY_IEEE_FLOAT_8_BYTE: { + double value = fd.value.f64; + value_is_zero = (value == 0.0); + snprintf( value_str, sizeof( value_str ), "%f", value ); + } break; + default: { + return errmsg( -1, "Unhandled field format" ); + } } - else if( fd.datatype == SEGY_IEEE_FLOAT_8_BYTE ) { - double field = fd.value.f64; - if( opts.nonzero && field == 0.0) continue; - if( opts.description ) - printf( "%s\t%f\t%d\t%s\n", short_name, field, byte_offset, description ); - else - printf( "%-10s\t%f\n", short_name, field ); + + if (strcmp( value_str, "0" ) == 0) { + value_is_zero = true; } - else { - int field; - err = segy_field_data_to_int( &fd, &field ); - if( err ) return errmsg( err, "Unable to convert segy_field_data to int32" ); - - if( opts.nonzero && field == 0) continue; - if( opts.description ) - printf( "%s\t%d\t%d\t%s\n", short_name, field, byte_offset, description ); - else - printf( "%-10s\t%d\n", short_name, field ); + + if( opts.nonzero && value_is_zero ) continue; + if( opts.description ) { + int byte_offset = (field_data[c].offset - SEGY_TEXT_HEADER_SIZE); + const char* short_name = field_data[c].short_name; + const char* description = field_data[c].description; + printf( "%s\t%s\t%d\t%s\n", short_name, value_str, byte_offset, description ); + } else { + printf( "%-10s\t%s\n", field_data[c].short_name, value_str ); } } segy_close( fp ); diff --git a/lib/include/segyio/segy.h b/lib/include/segyio/segy.h index 5584961a..baea9ab9 100644 --- a/lib/include/segyio/segy.h +++ b/lib/include/segyio/segy.h @@ -207,8 +207,6 @@ int segy_init_field_data(int field, segy_field_data* fd); segy_field_data segy_get_field( const char* header, int field); int segy_set_field( char* header, segy_field_data* fd ); -int segy_field_data_to_int( const segy_field_data* fd, int* val ); - int segy_get_field_int( const char* header, int field, int* f ); int segy_set_field_int( char* header, const int field, const int val ); diff --git a/lib/src/segy.c b/lib/src/segy.c index 5518b8c6..3cfc5267 100644 --- a/lib/src/segy.c +++ b/lib/src/segy.c @@ -870,7 +870,7 @@ static int get_field( const char* header, segy_field_data* fd) { } } -int segy_field_data_to_int( const segy_field_data* fd, int* val ) { +static int fd_get_int( const segy_field_data* fd, int* val ) { switch( fd->datatype ) { case SEGY_SIGNED_INTEGER_4_BYTE: @@ -922,7 +922,7 @@ int segy_get_field_int( const char* header, int field, int* val ) { if ( err != SEGY_OK ) return err; err = get_field( header, &fd ); if( err != SEGY_OK ) return err; - return segy_field_data_to_int( &fd, val ); + return fd_get_int( &fd, val ); } segy_field_data segy_get_field( const char* header, int field) { @@ -1118,7 +1118,7 @@ int segy_field_forall( segy_datasource* ds, if ( err != SEGY_OK ) return err; err = get_field( header, &fd ); if( err != 0 ) return err; - err = segy_field_data_to_int( &fd, &f ); + err = fd_get_int( &fd, &f ); if( err != 0 ) return err; if (ds->lsb) f = bswap_header_word(f, formatsize( fd.datatype )); *buf = f; From e49f3a581c56e56e42e90c1342d5af9f96a888be Mon Sep 17 00:00:00 2001 From: Alena Chaikouskaya Date: Thu, 17 Jul 2025 18:24:23 +0200 Subject: [PATCH 03/10] Move some functions to better places --- lib/src/segy.c | 65 +++++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 33 deletions(-) diff --git a/lib/src/segy.c b/lib/src/segy.c index 3cfc5267..08353b35 100644 --- a/lib/src/segy.c +++ b/lib/src/segy.c @@ -815,6 +815,24 @@ int segy_close( segy_datasource* ds ) { return SEGY_OK; } +int segy_init_field_data( int field, segy_field_data* fd ) { + if( field > 0 && field < SEGY_TRACE_HEADER_SIZE ) { + fd->field_index = field; + fd->field_offset = 0; + fd->datatype = tr_field_type[fd->field_index]; + } else if( field > SEGY_TEXT_HEADER_SIZE && field < SEGY_TEXT_HEADER_SIZE + SEGY_BINARY_HEADER_SIZE ) { + fd->field_index = field - SEGY_TEXT_HEADER_SIZE; + fd->field_offset = SEGY_TEXT_HEADER_SIZE; + fd->datatype = bin_field_type[fd->field_index]; + } else { + return SEGY_INVALID_FIELD; + } + + if( fd->datatype == SEGY_UNDEFINED_FIELD ) + return SEGY_INVALID_FIELD; + return SEGY_OK; +} + static int get_field( const char* header, segy_field_data* fd) { uint64_t val; @@ -898,41 +916,23 @@ static int fd_get_int( const segy_field_data* fd, int* val ) { } } -int segy_init_field_data(int field, segy_field_data* fd) { - if ( field > 0 && field < SEGY_TRACE_HEADER_SIZE ) { - fd->field_index = field; - fd->field_offset = 0; - fd->datatype = tr_field_type[ fd->field_index ]; - } - else if ( field > SEGY_TEXT_HEADER_SIZE && field < SEGY_TEXT_HEADER_SIZE + SEGY_BINARY_HEADER_SIZE ) { - fd->field_index = field - SEGY_TEXT_HEADER_SIZE; - fd->field_offset = SEGY_TEXT_HEADER_SIZE; - fd->datatype = bin_field_type[ fd->field_index ]; - } - else - return SEGY_INVALID_FIELD; - if ( fd->datatype == SEGY_UNDEFINED_FIELD ) - return SEGY_INVALID_FIELD; - return SEGY_OK; +segy_field_data segy_get_field( const char* header, int field) { + segy_field_data fd; + fd.error = segy_init_field_data( field, &fd ); + if ( fd.error != SEGY_OK ) return fd; + fd.error = get_field( header, &fd ); + return fd; } int segy_get_field_int( const char* header, int field, int* val ) { segy_field_data fd; int err = segy_init_field_data( field, &fd ); - if ( err != SEGY_OK ) return err; + if( err != SEGY_OK ) return err; err = get_field( header, &fd ); if( err != SEGY_OK ) return err; return fd_get_int( &fd, val ); } -segy_field_data segy_get_field( const char* header, int field) { - segy_field_data fd; - fd.error = segy_init_field_data( field, &fd ); - if ( fd.error != SEGY_OK ) return fd; - fd.error = get_field( header, &fd ); - return fd; -} - static int set_field( char* header, const segy_field_data* fd ) { @@ -1026,23 +1026,22 @@ static int fd_set_int( segy_field_data* fd, int val ) { } } -int segy_set_field_int( char* header, const int field, const int val ) { +int segy_set_field( char* header, segy_field_data* fd ) { + fd->error = set_field( header, fd ); + return fd->error; +} +int segy_set_field_int( char* header, const int field, const int val ) { segy_field_data fd; int err = segy_init_field_data( field, &fd ); - if ( err != SEGY_OK ) return err; + if( err != SEGY_OK ) return err; err = fd_set_int( &fd, val ); - if ( err != SEGY_OK ) return err; + if( err != SEGY_OK ) return err; return set_field( header, &fd ); } -int segy_set_field( char* header, segy_field_data* fd ) { - fd->error = set_field( header, fd ); - return fd->error; -} - static int slicelength( int start, int stop, int step ) { if( step == 0 ) return 0; From bbb0c1b032384de8c43e8cc18bf95a063dcd3b33 Mon Sep 17 00:00:00 2001 From: Alena Chaikouskaya Date: Thu, 24 Jul 2025 20:12:02 +0200 Subject: [PATCH 04/10] Reuse general field get/set in their int versions --- lib/src/segy.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/lib/src/segy.c b/lib/src/segy.c index 08353b35..42e316a5 100644 --- a/lib/src/segy.c +++ b/lib/src/segy.c @@ -925,11 +925,8 @@ segy_field_data segy_get_field( const char* header, int field) { } int segy_get_field_int( const char* header, int field, int* val ) { - segy_field_data fd; - int err = segy_init_field_data( field, &fd ); - if( err != SEGY_OK ) return err; - err = get_field( header, &fd ); - if( err != SEGY_OK ) return err; + segy_field_data fd = segy_get_field(header, field); + if ( fd.error != SEGY_OK ) return fd.error; return fd_get_int( &fd, val ); } @@ -1039,7 +1036,7 @@ int segy_set_field_int( char* header, const int field, const int val ) { err = fd_set_int( &fd, val ); if( err != SEGY_OK ) return err; - return set_field( header, &fd ); + return segy_set_field( header, &fd ); } static int slicelength( int start, int stop, int step ) { From e17c97a3cde896f0568511870606a5687eaef04c Mon Sep 17 00:00:00 2001 From: Alena Chaikouskaya Date: Thu, 24 Jul 2025 20:30:40 +0200 Subject: [PATCH 05/10] Unify segy_get/set_field and get/set_field segy_get_field now requires segy_field_data passed as argument, instead of creating and returning it on its own. Given that library has been available for a long time and there exist C-library users only, consistency in the return functions is highly desirable. Only few functions that can't fail return value instead of error code. From the presence of .error member we know that segy_get_field can fail, so it makes sense for it to return the error code. That also allows us to have consistency between all get-set methods. --- applications/segyio-catb.c | 7 +++++-- lib/include/segyio/segy.h | 2 +- lib/src/segy.c | 29 ++++++++--------------------- python/segyio/segyio.cpp | 11 ++++++++--- 4 files changed, 22 insertions(+), 27 deletions(-) diff --git a/applications/segyio-catb.c b/applications/segyio-catb.c index bfc03051..0a9ee7bb 100644 --- a/applications/segyio-catb.c +++ b/applications/segyio-catb.c @@ -159,8 +159,11 @@ int main( int argc, char** argv ){ int nr_fields = sizeof(field_data)/sizeof(binary_field_type); for( int c = 0; c < nr_fields; ++c ){ - segy_field_data fd = segy_get_field( binheader, field_data[c].offset ); - if ( fd.error ) return errmsg( fd.error, "Unable to read field" ); + segy_field_data fd; + int err = segy_init_field_data( field_data[c].offset, &fd ); + if( err ) return errmsg(err, "Unable to initialize field"); + err = segy_get_field( binheader, &fd ); + if ( err ) return errmsg( err, "Unable to read field" ); bool value_is_zero = false; char value_str[40]; // should be enough for all strings diff --git a/lib/include/segyio/segy.h b/lib/include/segyio/segy.h index baea9ab9..583918a3 100644 --- a/lib/include/segyio/segy.h +++ b/lib/include/segyio/segy.h @@ -204,7 +204,7 @@ int segy_set_endianness( segy_datasource*, int opt ); */ int segy_init_field_data(int field, segy_field_data* fd); -segy_field_data segy_get_field( const char* header, int field); +int segy_get_field( const char* header, segy_field_data* fd ); int segy_set_field( char* header, segy_field_data* fd ); int segy_get_field_int( const char* header, int field, int* f ); diff --git a/lib/src/segy.c b/lib/src/segy.c index 42e316a5..77892acd 100644 --- a/lib/src/segy.c +++ b/lib/src/segy.c @@ -833,8 +833,7 @@ int segy_init_field_data( int field, segy_field_data* fd ) { return SEGY_OK; } -static int get_field( const char* header, segy_field_data* fd) { - +int segy_get_field( const char* header, segy_field_data* fd ) { uint64_t val; switch ( fd->datatype ) { @@ -916,23 +915,17 @@ static int fd_get_int( const segy_field_data* fd, int* val ) { } } -segy_field_data segy_get_field( const char* header, int field) { +int segy_get_field_int( const char* header, int field, int* val ) { segy_field_data fd; - fd.error = segy_init_field_data( field, &fd ); - if ( fd.error != SEGY_OK ) return fd; - fd.error = get_field( header, &fd ); - return fd; -} + int err = segy_init_field_data( field, &fd ); + if( err != SEGY_OK ) return err; -int segy_get_field_int( const char* header, int field, int* val ) { - segy_field_data fd = segy_get_field(header, field); - if ( fd.error != SEGY_OK ) return fd.error; + err = segy_get_field(header, &fd); + if ( err != SEGY_OK ) return err; return fd_get_int( &fd, val ); } -static int set_field( char* header, - const segy_field_data* fd ) { - +int segy_set_field( char* header, segy_field_data* fd ) { segy_field_value fv = fd->value; uint64_t val; switch ( fd->datatype ) { @@ -987,7 +980,6 @@ static int set_field( char* header, } } - static int fd_set_int( segy_field_data* fd, int val ) { switch( fd->datatype ) { case SEGY_SIGNED_INTEGER_4_BYTE: @@ -1023,11 +1015,6 @@ static int fd_set_int( segy_field_data* fd, int val ) { } } -int segy_set_field( char* header, segy_field_data* fd ) { - fd->error = set_field( header, fd ); - return fd->error; -} - int segy_set_field_int( char* header, const int field, const int val ) { segy_field_data fd; int err = segy_init_field_data( field, &fd ); @@ -1112,7 +1099,7 @@ int segy_field_forall( segy_datasource* ds, segy_field_data fd; err = segy_init_field_data(field, &fd); if ( err != SEGY_OK ) return err; - err = get_field( header, &fd ); + err = segy_get_field( header, &fd ); if( err != 0 ) return err; err = fd_get_int( &fd, &f ); if( err != 0 ) return err; diff --git a/python/segyio/segyio.cpp b/python/segyio/segyio.cpp index 5668cee8..8ce3b9b8 100644 --- a/python/segyio/segyio.cpp +++ b/python/segyio/segyio.cpp @@ -1696,9 +1696,14 @@ PyObject* getfield( PyObject*, PyObject *args ) { buffer.len() != SEGY_TRACE_HEADER_SIZE ) return BufferError( "buffer too small" ); - segy_field_data fd = segy_get_field( buffer.buf< const char >(), field ); - if( fd.error != SEGY_OK ) - return KeyError( "Got error code %d when requesting field %d", fd.error, field ); + segy_field_data fd; + int err = segy_init_field_data( field, &fd ); + if( err != SEGY_OK ) + return KeyError( "Failed to initialize field %d got error %d", field, err ); + + err = segy_get_field( buffer.buf< const char >(), &fd ); + if( err != SEGY_OK ) + return KeyError( "Got error code %d when requesting field %d", err, field ); switch ( fd.datatype ) { From 3f3061fed4f6a75e0ca6a1f65dab45d30360d0f6 Mon Sep 17 00:00:00 2001 From: Alena Chaikouskaya Date: Fri, 25 Jul 2025 15:08:41 +0200 Subject: [PATCH 06/10] Directly pass field argument to segy_get/set_field --- applications/segyio-catb.c | 4 +-- lib/include/segyio/segy.h | 4 +-- lib/src/segy.c | 63 +++++++++++++++++++++----------------- python/segyio/segyio.cpp | 8 ++--- 4 files changed, 40 insertions(+), 39 deletions(-) diff --git a/applications/segyio-catb.c b/applications/segyio-catb.c index 0a9ee7bb..8c38a908 100644 --- a/applications/segyio-catb.c +++ b/applications/segyio-catb.c @@ -160,9 +160,7 @@ int main( int argc, char** argv ){ int nr_fields = sizeof(field_data)/sizeof(binary_field_type); for( int c = 0; c < nr_fields; ++c ){ segy_field_data fd; - int err = segy_init_field_data( field_data[c].offset, &fd ); - if( err ) return errmsg(err, "Unable to initialize field"); - err = segy_get_field( binheader, &fd ); + err = segy_get_field( binheader, field_data[c].offset, &fd ); if ( err ) return errmsg( err, "Unable to read field" ); bool value_is_zero = false; diff --git a/lib/include/segyio/segy.h b/lib/include/segyio/segy.h index 583918a3..43082528 100644 --- a/lib/include/segyio/segy.h +++ b/lib/include/segyio/segy.h @@ -204,8 +204,8 @@ int segy_set_endianness( segy_datasource*, int opt ); */ int segy_init_field_data(int field, segy_field_data* fd); -int segy_get_field( const char* header, segy_field_data* fd ); -int segy_set_field( char* header, segy_field_data* fd ); +int segy_get_field( const char* header, int field, segy_field_data* fd ); +int segy_set_field( char* header, int field, segy_field_data* fd ); int segy_get_field_int( const char* header, int field, int* f ); int segy_set_field_int( char* header, const int field, const int val ); diff --git a/lib/src/segy.c b/lib/src/segy.c index 77892acd..0c0f3314 100644 --- a/lib/src/segy.c +++ b/lib/src/segy.c @@ -833,50 +833,57 @@ int segy_init_field_data( int field, segy_field_data* fd ) { return SEGY_OK; } -int segy_get_field( const char* header, segy_field_data* fd ) { +int segy_get_field( const char* header, int field, segy_field_data* fd ) { + int err = segy_init_field_data( field, fd ); + if( err != SEGY_OK ) return err; + + int offset = field - 1; + if (offset >= SEGY_TEXT_HEADER_SIZE) { + offset -= SEGY_TEXT_HEADER_SIZE; + } uint64_t val; switch ( fd->datatype ) { case SEGY_SIGNED_INTEGER_8_BYTE: - memcpy( &(fd->value.i64), header + (fd->field_index -1), formatsize( fd->datatype ) ); + memcpy( &(fd->value.i64), header + offset, formatsize( fd->datatype ) ); fd->value.i64 = be64toh( fd->value.i64 ); return SEGY_OK; case SEGY_SIGNED_INTEGER_4_BYTE: - memcpy( &(fd->value.i32), header + (fd->field_index -1), formatsize( fd->datatype ) ); + memcpy( &(fd->value.i32), header + offset, formatsize( fd->datatype ) ); fd->value.i32 = be32toh( fd->value.i32 ); return SEGY_OK; case SEGY_SIGNED_SHORT_2_BYTE: - memcpy( &(fd->value.i16), header + (fd->field_index -1), formatsize( fd->datatype ) ); + memcpy( &(fd->value.i16), header + offset, formatsize( fd->datatype ) ); fd->value.i16 = be16toh( fd->value.i16 ); return SEGY_OK; case SEGY_SIGNED_CHAR_1_BYTE: - memcpy( &(fd->value.i8), header + (fd->field_index -1), formatsize( fd->datatype ) ); + memcpy( &(fd->value.i8), header + offset, formatsize( fd->datatype ) ); return SEGY_OK; case SEGY_UNSIGNED_INTEGER_8_BYTE: - memcpy( &(fd->value.u64), header + (fd->field_index -1), formatsize( fd->datatype ) ); + memcpy( &(fd->value.u64), header + offset, formatsize( fd->datatype ) ); fd->value.u64 = be64toh( fd->value.u64 ); return SEGY_OK; case SEGY_UNSIGNED_INTEGER_4_BYTE: - memcpy( &(fd->value.u32), header + (fd->field_index -1), formatsize( fd->datatype ) ); + memcpy( &(fd->value.u32), header + offset, formatsize( fd->datatype ) ); fd->value.u32 = be32toh( fd->value.u32 ); return SEGY_OK; case SEGY_UNSIGNED_SHORT_2_BYTE: - memcpy( &(fd->value.u16), header + (fd->field_index -1), formatsize( fd->datatype ) ); + memcpy( &(fd->value.u16), header + offset, formatsize( fd->datatype ) ); fd->value.u16 = be16toh( fd->value.u16 ); return SEGY_OK; case SEGY_UNSIGNED_CHAR_1_BYTE: - memcpy( &(fd->value.u8), header + (fd->field_index -1), formatsize( fd->datatype ) ); + memcpy( &(fd->value.u8), header + offset, formatsize( fd->datatype ) ); return SEGY_OK; case SEGY_IEEE_FLOAT_8_BYTE: - memcpy( &(fd->value.f64), header + (fd->field_index -1), formatsize( fd->datatype ) ); + memcpy( &(fd->value.f64), header + offset, formatsize( fd->datatype ) ); memcpy( &val, &(fd->value.f64), sizeof( uint64_t ) ); val = be64toh( val ); memcpy( &(fd->value.f64), &val, sizeof( uint64_t ) ); @@ -917,62 +924,64 @@ static int fd_get_int( const segy_field_data* fd, int* val ) { int segy_get_field_int( const char* header, int field, int* val ) { segy_field_data fd; - int err = segy_init_field_data( field, &fd ); - if( err != SEGY_OK ) return err; - - err = segy_get_field(header, &fd); + int err = segy_get_field(header, field, &fd); if ( err != SEGY_OK ) return err; return fd_get_int( &fd, val ); } -int segy_set_field( char* header, segy_field_data* fd ) { +int segy_set_field( char* header, int field, segy_field_data* fd ) { + int offset = field - 1; + if (offset >= SEGY_TEXT_HEADER_SIZE) { + offset -= SEGY_TEXT_HEADER_SIZE; + } + segy_field_value fv = fd->value; uint64_t val; switch ( fd->datatype ) { case SEGY_SIGNED_INTEGER_8_BYTE: fv.i64 = htobe64( fv.i64 ); - memcpy( header + (fd->field_index - 1), &(fv.i64), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.i64), formatsize( fd->datatype )); return SEGY_OK; case SEGY_SIGNED_INTEGER_4_BYTE: fv.i32 = htobe32( fv.i32 ); - memcpy( header + (fd->field_index - 1), &(fv.i32), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.i32), formatsize( fd->datatype )); return SEGY_OK; case SEGY_SIGNED_SHORT_2_BYTE: fv.i16 = htobe16( fv.i16 ); - memcpy( header + (fd->field_index - 1), &(fv.i16), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.i16), formatsize( fd->datatype )); return SEGY_OK; case SEGY_SIGNED_CHAR_1_BYTE: - memcpy( header + (fd->field_index - 1), &(fv.i8), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.i8), formatsize( fd->datatype )); return SEGY_OK; case SEGY_UNSIGNED_INTEGER_8_BYTE: fv.u64 = htobe64( fv.u64 ); - memcpy( header + (fd->field_index - 1), &(fv.u64), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.u64), formatsize( fd->datatype )); return SEGY_OK; case SEGY_UNSIGNED_INTEGER_4_BYTE: fv.u32 = htobe32( fv.u32 ); - memcpy( header + (fd->field_index - 1), &(fv.u32), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.u32), formatsize( fd->datatype )); return SEGY_OK; case SEGY_UNSIGNED_SHORT_2_BYTE: fv.u16 = htobe16( fv.u16 ); - memcpy( header + (fd->field_index - 1), &(fv.u16), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.u16), formatsize( fd->datatype )); return SEGY_OK; case SEGY_UNSIGNED_CHAR_1_BYTE: - memcpy( header + (fd->field_index - 1), &(fv.u8), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.u8), formatsize( fd->datatype )); return SEGY_OK; case SEGY_IEEE_FLOAT_8_BYTE: memcpy( &val, &(fv.f64), sizeof( uint64_t ) ); val = htobe64( val ); memcpy( &(fv.f64), &val, sizeof( uint64_t ) ); - memcpy( header + (fd->field_index - 1), &(fv.f64), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.f64), formatsize( fd->datatype )); return SEGY_OK; default: @@ -1023,7 +1032,7 @@ int segy_set_field_int( char* header, const int field, const int val ) { err = fd_set_int( &fd, val ); if( err != SEGY_OK ) return err; - return segy_set_field( header, &fd ); + return segy_set_field( header, field, &fd ); } static int slicelength( int start, int stop, int step ) { @@ -1097,9 +1106,7 @@ int segy_field_forall( segy_datasource* ds, if( err != 0 ) return SEGY_DS_READ_ERROR; segy_field_data fd; - err = segy_init_field_data(field, &fd); - if ( err != SEGY_OK ) return err; - err = segy_get_field( header, &fd ); + err = segy_get_field( header, field, &fd ); if( err != 0 ) return err; err = fd_get_int( &fd, &f ); if( err != 0 ) return err; diff --git a/python/segyio/segyio.cpp b/python/segyio/segyio.cpp index 8ce3b9b8..484cec16 100644 --- a/python/segyio/segyio.cpp +++ b/python/segyio/segyio.cpp @@ -1697,11 +1697,7 @@ PyObject* getfield( PyObject*, PyObject *args ) { return BufferError( "buffer too small" ); segy_field_data fd; - int err = segy_init_field_data( field, &fd ); - if( err != SEGY_OK ) - return KeyError( "Failed to initialize field %d got error %d", field, err ); - - err = segy_get_field( buffer.buf< const char >(), &fd ); + int err = segy_get_field( buffer.buf< const char >(), field, &fd ); if( err != SEGY_OK ) return KeyError( "Got error code %d when requesting field %d", err, field ); @@ -1853,7 +1849,7 @@ PyObject* putfield( PyObject*, PyObject *args ) { return KeyError( "Field %d has unknown datatype %d", field, fd.datatype ); } - err = segy_set_field( buffer.buf< char >(), &fd ); + err = segy_set_field( buffer.buf< char >(), field, &fd ); switch( err ) { case SEGY_OK: From cd6242602f706531a598195c2bd63d4eab38edc7 Mon Sep 17 00:00:00 2001 From: Alena Chaikouskaya Date: Fri, 25 Jul 2025 17:02:11 +0200 Subject: [PATCH 07/10] Remove unused members from segy_field_data --- lib/include/segyio/segy.h | 3 --- lib/src/segy.c | 8 ++------ 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/lib/include/segyio/segy.h b/lib/include/segyio/segy.h index 43082528..b101a477 100644 --- a/lib/include/segyio/segy.h +++ b/lib/include/segyio/segy.h @@ -132,9 +132,6 @@ typedef union { typedef struct { segy_field_value value; uint8_t datatype; - int32_t field_index; - int32_t field_offset; - int32_t error; } segy_field_data; segy_file* segy_open( const char* path, const char* mode ); diff --git a/lib/src/segy.c b/lib/src/segy.c index 0c0f3314..c97c7e53 100644 --- a/lib/src/segy.c +++ b/lib/src/segy.c @@ -817,13 +817,9 @@ int segy_close( segy_datasource* ds ) { int segy_init_field_data( int field, segy_field_data* fd ) { if( field > 0 && field < SEGY_TRACE_HEADER_SIZE ) { - fd->field_index = field; - fd->field_offset = 0; - fd->datatype = tr_field_type[fd->field_index]; + fd->datatype = tr_field_type[field]; } else if( field > SEGY_TEXT_HEADER_SIZE && field < SEGY_TEXT_HEADER_SIZE + SEGY_BINARY_HEADER_SIZE ) { - fd->field_index = field - SEGY_TEXT_HEADER_SIZE; - fd->field_offset = SEGY_TEXT_HEADER_SIZE; - fd->datatype = bin_field_type[fd->field_index]; + fd->datatype = bin_field_type[field - SEGY_TEXT_HEADER_SIZE]; } else { return SEGY_INVALID_FIELD; } From b9e3f3d17107b3758d9a894f7bd8359b756154ad Mon Sep 17 00:00:00 2001 From: Alena Chaikouskaya Date: Fri, 25 Jul 2025 18:00:14 +0200 Subject: [PATCH 08/10] Turn segy_init_field_data into segy_field_datatype "Init" became impractical as the only thing that it inits now is the datatype. Solution could be simplified even more if we in future decide to make binary header-fields not 3200, but 0 based. Then "segy_field_datatype" might disappear altogether. --- lib/include/segyio/segy.h | 12 ++++-------- lib/src/segy.c | 27 +++++++++++---------------- python/segyio/segyio.cpp | 7 ++----- 3 files changed, 17 insertions(+), 29 deletions(-) diff --git a/lib/include/segyio/segy.h b/lib/include/segyio/segy.h index b101a477..d179b54c 100644 --- a/lib/include/segyio/segy.h +++ b/lib/include/segyio/segy.h @@ -191,15 +191,11 @@ int segy_set_format( segy_datasource*, int format ); */ int segy_set_endianness( segy_datasource*, int opt ); -/* Initialize the segy_field_data structure using the field number - * - * If the field number is greater than SEGY_TEXT_HEADER_SIZE [3200] - * the field is assumed to be a binary header field. - * Binary header field: field_index = (field number)-3200, field_offset = 3200 - * Trace header field : field_index = field number, field_offset = 0 - * Tables tr_field_type and bin_field_type are used to set the datatype. +/* Gets field datatype from field id. Depending on field value, binary or trace + * mapping table would be used. + * The int returned is the field datatype, not an error code. */ -int segy_init_field_data(int field, segy_field_data* fd); +int segy_field_datatype( int field ); int segy_get_field( const char* header, int field, segy_field_data* fd ); int segy_set_field( char* header, int field, segy_field_data* fd ); diff --git a/lib/src/segy.c b/lib/src/segy.c index c97c7e53..f48fd750 100644 --- a/lib/src/segy.c +++ b/lib/src/segy.c @@ -815,29 +815,24 @@ int segy_close( segy_datasource* ds ) { return SEGY_OK; } -int segy_init_field_data( int field, segy_field_data* fd ) { +int segy_field_datatype( int field ) { if( field > 0 && field < SEGY_TRACE_HEADER_SIZE ) { - fd->datatype = tr_field_type[field]; + return tr_field_type[field]; } else if( field > SEGY_TEXT_HEADER_SIZE && field < SEGY_TEXT_HEADER_SIZE + SEGY_BINARY_HEADER_SIZE ) { - fd->datatype = bin_field_type[field - SEGY_TEXT_HEADER_SIZE]; + return bin_field_type[field - SEGY_TEXT_HEADER_SIZE]; } else { - return SEGY_INVALID_FIELD; + return SEGY_UNDEFINED_FIELD; } - - if( fd->datatype == SEGY_UNDEFINED_FIELD ) - return SEGY_INVALID_FIELD; - return SEGY_OK; } int segy_get_field( const char* header, int field, segy_field_data* fd ) { - int err = segy_init_field_data( field, fd ); - if( err != SEGY_OK ) return err; - int offset = field - 1; if (offset >= SEGY_TEXT_HEADER_SIZE) { offset -= SEGY_TEXT_HEADER_SIZE; } uint64_t val; + + fd->datatype = segy_field_datatype( field ); switch ( fd->datatype ) { case SEGY_SIGNED_INTEGER_8_BYTE: @@ -886,7 +881,7 @@ int segy_get_field( const char* header, int field, segy_field_data* fd ) { return SEGY_OK; default: - return SEGY_INVALID_FIELD_DATATYPE; + return SEGY_INVALID_FIELD; } } @@ -981,7 +976,7 @@ int segy_set_field( char* header, int field, segy_field_data* fd ) { return SEGY_OK; default: - return SEGY_INVALID_FIELD_DATATYPE; + return SEGY_INVALID_FIELD; } } @@ -1022,10 +1017,10 @@ static int fd_set_int( segy_field_data* fd, int val ) { int segy_set_field_int( char* header, const int field, const int val ) { segy_field_data fd; - int err = segy_init_field_data( field, &fd ); - if( err != SEGY_OK ) return err; + fd.datatype = segy_field_datatype( field ); + if ( fd.datatype == SEGY_UNDEFINED_FIELD ) return SEGY_INVALID_FIELD; - err = fd_set_int( &fd, val ); + int err = fd_set_int( &fd, val ); if( err != SEGY_OK ) return err; return segy_set_field( header, field, &fd ); diff --git a/python/segyio/segyio.cpp b/python/segyio/segyio.cpp index 484cec16..2105764e 100644 --- a/python/segyio/segyio.cpp +++ b/python/segyio/segyio.cpp @@ -1746,10 +1746,7 @@ PyObject* putfield( PyObject*, PyObject *args ) { int field = (int)PyLong_AsLong(field_arg); segy_field_data fd; - int err = segy_init_field_data(field, &fd); - - if( err != SEGY_OK ) - return KeyError( "Failed to initialize field %d got error %d", field, err ); + fd.datatype = segy_field_datatype(field); switch ( fd.datatype ) { case SEGY_UNSIGNED_INTEGER_8_BYTE: @@ -1849,7 +1846,7 @@ PyObject* putfield( PyObject*, PyObject *args ) { return KeyError( "Field %d has unknown datatype %d", field, fd.datatype ); } - err = segy_set_field( buffer.buf< char >(), field, &fd ); + int err = segy_set_field( buffer.buf< char >(), field, &fd ); switch( err ) { case SEGY_OK: From 033b287e85c429206c9464b635f0dad83b8b9425 Mon Sep 17 00:00:00 2001 From: Alena Chaikouskaya Date: Fri, 25 Jul 2025 20:24:13 +0200 Subject: [PATCH 09/10] Check datatype match inside segy_set_field .datatype field is kind of pointless at the moment. - In C we can't easily force someone to set datatype the same moment when .value is set. So nothing prevents us from setting value to i16 and datatype to u32. - In theory we can simply pass segy_field_value as an argument instead of passing full segy_field_data. However it doesn't fit into the spirit of function, as without knowing .datatype we can't interpret value on its own and are forced to do it according to the field mapping table instead of the actual datatype. The best option seems to force .datatype being set by checking that it corresponds to the datatype retrieved from field mapping. Additionally fd doesn't have to be a pointer. We should treat that value as any other local primitive as it is not that big in size. --- lib/include/segyio/segy.h | 2 +- lib/src/segy.c | 32 +++++++++++++++++++------------- lib/src/segy.def | 2 ++ lib/test/segy.cpp | 32 +++++++++++++++++++++++--------- python/segyio/segyio.cpp | 2 +- 5 files changed, 46 insertions(+), 24 deletions(-) diff --git a/lib/include/segyio/segy.h b/lib/include/segyio/segy.h index d179b54c..1dcd571b 100644 --- a/lib/include/segyio/segy.h +++ b/lib/include/segyio/segy.h @@ -198,7 +198,7 @@ int segy_set_endianness( segy_datasource*, int opt ); int segy_field_datatype( int field ); int segy_get_field( const char* header, int field, segy_field_data* fd ); -int segy_set_field( char* header, int field, segy_field_data* fd ); +int segy_set_field( char* header, int field, segy_field_data fd ); int segy_get_field_int( const char* header, int field, int* f ); int segy_set_field_int( char* header, const int field, const int val ); diff --git a/lib/src/segy.c b/lib/src/segy.c index f48fd750..7014c7f0 100644 --- a/lib/src/segy.c +++ b/lib/src/segy.c @@ -920,59 +920,65 @@ int segy_get_field_int( const char* header, int field, int* val ) { return fd_get_int( &fd, val ); } -int segy_set_field( char* header, int field, segy_field_data* fd ) { +int segy_set_field( char* header, int field, segy_field_data fd ) { int offset = field - 1; if (offset >= SEGY_TEXT_HEADER_SIZE) { offset -= SEGY_TEXT_HEADER_SIZE; } - segy_field_value fv = fd->value; + segy_field_value fv = fd.value; uint64_t val; - switch ( fd->datatype ) { + + uint8_t datatype = segy_field_datatype( field ); + if (fd.datatype != datatype) { + return SEGY_INVALID_FIELD_DATATYPE; + } + + switch ( fd.datatype ) { case SEGY_SIGNED_INTEGER_8_BYTE: fv.i64 = htobe64( fv.i64 ); - memcpy( header + offset, &(fv.i64), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.i64), formatsize( fd.datatype )); return SEGY_OK; case SEGY_SIGNED_INTEGER_4_BYTE: fv.i32 = htobe32( fv.i32 ); - memcpy( header + offset, &(fv.i32), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.i32), formatsize( fd.datatype )); return SEGY_OK; case SEGY_SIGNED_SHORT_2_BYTE: fv.i16 = htobe16( fv.i16 ); - memcpy( header + offset, &(fv.i16), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.i16), formatsize( fd.datatype )); return SEGY_OK; case SEGY_SIGNED_CHAR_1_BYTE: - memcpy( header + offset, &(fv.i8), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.i8), formatsize( fd.datatype )); return SEGY_OK; case SEGY_UNSIGNED_INTEGER_8_BYTE: fv.u64 = htobe64( fv.u64 ); - memcpy( header + offset, &(fv.u64), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.u64), formatsize( fd.datatype )); return SEGY_OK; case SEGY_UNSIGNED_INTEGER_4_BYTE: fv.u32 = htobe32( fv.u32 ); - memcpy( header + offset, &(fv.u32), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.u32), formatsize( fd.datatype )); return SEGY_OK; case SEGY_UNSIGNED_SHORT_2_BYTE: fv.u16 = htobe16( fv.u16 ); - memcpy( header + offset, &(fv.u16), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.u16), formatsize( fd.datatype )); return SEGY_OK; case SEGY_UNSIGNED_CHAR_1_BYTE: - memcpy( header + offset, &(fv.u8), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.u8), formatsize( fd.datatype )); return SEGY_OK; case SEGY_IEEE_FLOAT_8_BYTE: memcpy( &val, &(fv.f64), sizeof( uint64_t ) ); val = htobe64( val ); memcpy( &(fv.f64), &val, sizeof( uint64_t ) ); - memcpy( header + offset, &(fv.f64), formatsize( fd->datatype )); + memcpy( header + offset, &(fv.f64), formatsize( fd.datatype )); return SEGY_OK; default: @@ -1023,7 +1029,7 @@ int segy_set_field_int( char* header, const int field, const int val ) { int err = fd_set_int( &fd, val ); if( err != SEGY_OK ) return err; - return segy_set_field( header, field, &fd ); + return segy_set_field( header, field, fd ); } static int slicelength( int start, int stop, int step ) { diff --git a/lib/src/segy.def b/lib/src/segy.def index 6c9b23eb..34bf7762 100644 --- a/lib/src/segy.def +++ b/lib/src/segy.def @@ -12,6 +12,8 @@ segy_sample_interval segy_format segy_set_format segy_set_endianness +segy_get_field +segy_set_field segy_get_field_int segy_set_field_int segy_field_forall diff --git a/lib/test/segy.cpp b/lib/test/segy.cpp index 5288bc9c..09caf7ee 100644 --- a/lib/test/segy.cpp +++ b/lib/test/segy.cpp @@ -69,10 +69,11 @@ struct Err { bool operator == ( Err other ) const { return this->err == other.err; } bool operator != ( Err other ) const { return !(*this == other); } - static Err ok() { return SEGY_OK; } - static Err args() { return SEGY_INVALID_ARGS; } - static Err field() { return SEGY_INVALID_FIELD; } - static Err value() { return SEGY_INVALID_FIELD_VALUE; } + static Err ok() { return SEGY_OK; } + static Err args() { return SEGY_INVALID_ARGS; } + static Err field() { return SEGY_INVALID_FIELD; } + static Err value() { return SEGY_INVALID_FIELD_VALUE; } + static Err datatype() { return SEGY_INVALID_FIELD_DATATYPE; } int err; }; @@ -2053,10 +2054,11 @@ TEST_CASE("segy_get_field reads values correctly", "[c.segy]" ) { header[SEGY_TR_TRACE_ID-1] = b1; header[SEGY_TR_TRACE_ID-0] = b0; - int read_value; - Err err = segy_get_field_int( header, SEGY_TR_TRACE_ID, &read_value ); + segy_field_data read_value; + Err err = segy_get_field( header, SEGY_TR_TRACE_ID, &read_value ); CHECK( success( err ) ); - CHECK( read_value == value ); + CHECK( read_value.datatype == SEGY_SIGNED_SHORT_2_BYTE ); + CHECK( read_value.value.i16 == value ); } } @@ -2066,7 +2068,11 @@ TEST_CASE("segy_set_field write values correctly", "[c.segy]" ) { SECTION("test edge cases int16") { int16_t value = GENERATE(0, 1, -1, 0x0102, 0x0201, -32767, -32766); - Err err = segy_set_field_int( header, SEGY_TR_TRACE_ID, value ); + + segy_field_data fd; + fd.datatype = SEGY_SIGNED_SHORT_2_BYTE; + fd.value.i16 = value; + Err err = segy_set_field( header, SEGY_TR_TRACE_ID, fd ); CHECK( err == Err::ok() ); uint8_t b0 = header[SEGY_TR_TRACE_ID-0]; @@ -2080,9 +2086,17 @@ TEST_CASE("segy_set_field write invalid value", "[c.segy]" ) { char header[ SEGY_TRACE_HEADER_SIZE ] = { 0 }; - SECTION("test value outside of int16 range") { + SECTION("test value outside of int16 range for segy_set_field_int") { int32_t value = 0xFFFF + 1; Err err = segy_set_field_int( header, SEGY_TR_TRACE_ID, value ); CHECK( err == Err::value() ); } + + SECTION("test mismatched type") { + segy_field_data fd; + fd.value.i16 = 42; + fd.datatype = SEGY_SIGNED_INTEGER_4_BYTE; + Err err = segy_set_field( header, SEGY_TR_TRACE_ID, fd ); + CHECK( err == Err::datatype() ); + } } diff --git a/python/segyio/segyio.cpp b/python/segyio/segyio.cpp index 2105764e..aed2553a 100644 --- a/python/segyio/segyio.cpp +++ b/python/segyio/segyio.cpp @@ -1846,7 +1846,7 @@ PyObject* putfield( PyObject*, PyObject *args ) { return KeyError( "Field %d has unknown datatype %d", field, fd.datatype ); } - int err = segy_set_field( buffer.buf< char >(), field, &fd ); + int err = segy_set_field( buffer.buf< char >(), field, fd ); switch( err ) { case SEGY_OK: From b7837d534bbc0ab6d240ead49473cc723518dd5e Mon Sep 17 00:00:00 2001 From: Alena Chaikouskaya Date: Fri, 25 Jul 2025 20:59:47 +0200 Subject: [PATCH 10/10] Disable building wheels on python 3.14 --- .github/workflows/wheels.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/wheels.yaml b/.github/workflows/wheels.yaml index ae943f21..53467a39 100644 --- a/.github/workflows/wheels.yaml +++ b/.github/workflows/wheels.yaml @@ -54,7 +54,7 @@ jobs: CIBW_ENVIRONMENT_WINDOWS: > CMAKE_GENERATOR="${{ matrix.cmake_generator }}" CMAKE_GENERATOR_PLATFORM="${{ matrix.cmake_generator_platform }}" - CIBW_SKIP: pp* *-musllinux_* cp36-* cp37-* cp38-* + CIBW_SKIP: pp* *-musllinux_* cp36-* cp37-* cp38-* cp314* CIBW_ARCHS: ${{ matrix.arch }} run: | python -m cibuildwheel --output-dir wheelhouse python/