SoFunction
Updated on 2025-04-06

Detailed explanation of the reading of segy files in C/C++

This document will introduce the reading and writing process of SEGY, including the conversion of two data formats: IBM and PC.

The program will call the file to complete the conversion of IBM and PC formats.

Create new header files and C++ files, as well as the main program.

1. Writing and specifications of header files

1.1 Program description, call, declaration, definition

/**********************************************************************

  * Copyright(C) 2018,Company All Rights Reserved (1)Copyright Statement
    *
  * @file : (2) File name
    *
  * @brief : Realize the read and write operations of earthquake data (3) Introduction to the main functions of this file
    *
  * @version : 1.0 (4) Version information
    *
  * @author : Fan XinRan (5) Create the author
    *
  * @date: Tuesday, 2022/2/8 (6) Creation time
    *
  * Others: (7) Notes, changes, etc.
    ************************************************************************
  
//Call the required C header file#include<>   //C Language header file  
#include<>
#include<>
#include<>

//Call the required C++ header file#include<iostream>  // C++ header file
#include<vector>
#include<algorithm>

//Calling non-standard library#include"" // Used to create multidimensional arrays#include"" // Contains segy and bhed structures to extract information collected and stored in the roll head and the trail head
// Define global variables and namespaces#define PI 3.141592654   //Constant Number Definition
#define EPS 0.0000001

using namespace std;

1.2 Declare functions

unsigned short exchangeLowHigh16(unsigned short Data_temp);//The 16-bit high and low-bit conversion function short accounts for 2 bytes, 2*8unsigned int exchangeLowHigh32(unsigned int Data_temp); //32-bit high and low bit conversion function 4*8float ibm2pc(unsigned int Data_temp);      //IBM to PC dataunsigned int pc2ibm(float input);          //PC to IBM datafloat ieee2pc(unsigned int Data_temp);   //IEEE to PC
void trace_ibm2pc(float *data_output, int *data_input, int nt); //The seismic channel data is converted from IBM to PC formatvoid trace_pc2ibm(float *data_input, int *data_output, int nt); //The seismic channel data is converted from PC to IBM format
bool copySeismicDataIBM(const char *filenameInput, const char *filenameOutput); //Copy seismic data from Inputfile to Outputfile

1.3 Complete Code

/**********************************************************************

  * Copyright(C) 2018,Company All Rights Reserved
    *
  * @file:
    *
  * @brief: Realize the read and write operations of earthquake data
    *
  * @version : 1.0
    *
  * @author : Fan XinRan
    *
  * @date: Tuesday, 2022/2/8
    *
  * Others:
    ************************************************************************

//(1) Call the required C header file#include<>   // C Language header file  
#include<>
#include<>
#include<>

//(2) Call the required C++ header file#include<iostream>  // C++ header file
#include<vector>
#include<algorithm>

//(3) Call the required non-standard library header file#include""   // project header file 
#include""
#include

//(4) Define global constant#define PI 3.141592654   // Constant Number Definition
#define EPS 0.0000001

//(5) Declare the namespaceusing namespace std;

//(6) Declare the function name, input, output and its typeunsigned short exchangeLowHigh16(unsigned short Data_temp);//The 16-bit high and low-bit conversion function short accounts for 2 bytes, 2*8unsigned int exchangeLowHigh32(unsigned int Data_temp); //32-bit high and low bit conversion function 4*8float ibm2pc(unsigned int Data_temp);      //IBM to PC dataunsigned int pc2ibm(float input);          //PC to IBM datafloat ieee2pc(unsigned int Data_temp);   //IEEE to PC
void trace_ibm2pc(float *data_output, int *data_input, int nt); //The seismic channel data is converted from IBM to PC formatvoid trace_pc2ibm(float *data_input, int *data_output, int nt); //The seismic channel data is converted from PC to IBM format
bool copySeismicDataIBM(const char *filenameInput, const char *filenameOutput); //Copy seismic data from Inputfile to Outputfile

2. Writing and specifications of C++ files

2.1 Necessary Notes

/*************************************************************************************************************

  Function: copySeismicDataIBM (1) Function name
  Description: copy segy file from input data to output data (2) Briefly describe its functions
  Input:
                  const char *filenameInput [in] input filename (.segy) (3) Input variables and input file type
  Output:
                  const char *filenameOutput[out] output filename (.segy) (4) Output variable and output file type
  Return:
              bool true program success
			  bool false program failed (5)Return value and description
  Author: Fan XinRan (6) Create the author
  Date: 2022/2/8 (7) Creation time
  Others: (8) Notes, changes, etc.
 
 ******************************************************************************************************************************************

2.2 Defining Reading and Write Functions

#include ""
bool copySeismicDataIBM(const char *filenameInput, const char *filenameOutput){

    //Implementation code    ...

}

(1) Define the structure variables and numerical variables to be used

bhedandsegyAll are defined inThe structure in the structure contains binary volume header information and path header information, and uses member access operators(.)Get its content;

useunsigned intDeclare integer variables, uselong longor__int64Declare the number of bytes of SEGY file and the number of bytes of seismic channel to prevent the amount of data from exceeding the range, and initialize the variables as much as possible.

bhed fileheader;        // file headersegy traceheader;       // trace headerunsigned int nt=0;        // number of sampleunsigned int sizefileheader=sizeof(fileheader);   // size of fileheader;
unsigned int sizetraceheader=sizeof(traceheader);  // size of traceheader;

unsigned int ncdp = 0;      // number of cdp channel numberlong long  size_file = 0;   //size of input file
long long  size_trace = 0;  //size of per-trace

(2) Create a new pointer variable

In the task of reading and writing seismic channel data, input pointer, output pointer, seismic channel data pointer, head pointer and a temporary pointer variable are used, including five pointer variables.

FILE *fpinput = NULL;   // input file pointer
FILE *fpoutput = NULL;   // output file pointer
float *dataInput = NULL;  // input data pointer
segy *traceheaderArray = NULL; // traceheader pointer
int* temp = NULL;  // temp pointer 

In previous missionsfread(dataInput[itrace],nt * sizeof(float),1,fpinput)

The entire reading and writing process is:fpinput-->Read nt data-->dataInput[itrace]-->Write nt data-->fpoutput

In this task, the data needs to be transformed, and the process becomes:fpinput-->Read nt data-->temp-->IBM/PC conversion-->dataInput[itrace]-->Write nt data-->fpoutput

(3) Open the input and output file pointers

fpinput = fopen(filenameInput, "rb");  //open input file pointer 
fpoutput = fopen(filenameOutput,"wb");  //open output file pointer

//Read and write operations...
    
//Fopen() and fclose() appear in pairs. Remember to close the file after the operation of the file is completed.fclose(fpinput);  //close input file pointer
fclose(fpoutput); //close output file pointer

(4) Determine the file opening situation

if(fpinput==NULL){                                            //If the file pointer is NULL	printf("Cannot open %s file\n", filenameInput);           //Print "File opening failed"	return false;                                             //End the program}

if(fpoutput==NULL){
	printf("Cannot open %s file\n", filenameOutput);
	return false;
}

(5) Read/calculate volume and channel information

fread(&fileheader,sizefileheader,1,fpinput); // Read the volume header information from the input stream (fpinput) to the specified address----->fileheader
nt = exchangeLowHigh16() // High and low bit conversion
_fseeki64(fpinput,0,SEEK_END);   // Offset the 0 lengths of this structure from the end of the file to the file pointer fpinput, that is, fpinput points to the end of the file at this time
size_file = _ftelli64(fpinput);  // Return to the current file location, that is, the total number of bytes of the filesize_trace = nt*sizeof(float)+sizetraceheader;  // Number of bytes per channel = number of sampled points + number of header bytes
ncdp = (size_file - (long long)sizefileheader)/size_trace; // Number of channels = (Total number of file bytes - Number of volume header bytes)/Number of bytes per channel
_fseeki64(fpinput,sizefileheader,SEEK_SET); // Offset the sizefileheader (number of volume header) length from the beginning of the file to the pointer fpinput, that is, fpinput points to the beginning of the first path at this timefwrite(&fileheader, sizefileheader, 1, fpoutput); // Write to the header first
  • fread()Read data from a given stream into the array pointed to by the pointer;
  • fwrite(*ptr, size, nmemb,*stream)Parameters andfread()Same,ptrThe data in the pointed array is written to the given streamstreammiddle;
  • _fseeki64Usage andfseekSame, means a certain number of bytes offset from the specified location of the file; the former has higher compatibility;
  • _ftelli64andftellSimilarly, return the current file location of the given stream;
  • exchangeLowHigh16()Finishshorthigh and low conversion,intUse high and low bit conversionexchangeLowHigh64()

(6) Traverse each earthquake channel and read and write data

dataInput=alloc2float(nt,ncdp); // Allocate the memory space required for nt*ncdp (sampling points × number of channels) to store two-dimensional seismic channel data// Where alloc2float is a function in uninstallation, creating a float-type two-dimensional array//dataInput is a secondary pointer, which can be simply recorded as dataInput pointing to the beginning of each line
memset(dataInput[0], 0, nt*ncdp * sizeof(float)); // Start from the beginning of the first line, assign nt*ncdp characters in the memory block to 0// dataInput points to the beginning of each line, and dataInput[0] is the starting position of the entire 2D array
// Allocate ncdp continuous space with length of sizetraceheader in the dynamic memory areatraceheaderArray = (segy*)calloc(ncdp,sizetraceheader);

temp = (int*)calloc(nt,sizeof(int));

//Read the data of the trail head and seismic roads one by onefor(int itrace = 0; itrace < ncdp; itrace++){
    fread(&traceheaderArray[itrace],sizetraceheader,1,fpinput); // &traceheaderArray[itrace] is the address of the itrace channel, and read the header information of the channel    fread(temp,nt * sizeof(float),1,fpinput); // Read the information of nt sampling points and point the result to temp    
    // Use trace_ibm2pc to convert the data of the nt sampling points after the temp position and perform IBM-->PC conversion, and the result points to the beginning of each channel (dataInput[itrace])    trace_ibm2pc(dataInput[itrace], temp, nt); 
    
}//end for(int itrace = 0; itrace < ncdp; itrace++)

//Write the data of the trailhead and earthquake roads one by onefor (int itrace = 0; itrace < ncdp; itrace++) {
    fwrite(&traceheaderArray[itrace], sizetraceheader, 1, fpoutput); // Write the header information    
    // Use trace_pc2ibm to convert the data of the nt sampling points after the temp position to PC-->IBM, and the result points to the beginning of each channel (dataInput[itrace])    trace_pc2ibm(dataInput[itrace],temp,nt); 
    
    fwrite(temp, nt * sizeof(int), 1, fpoutput); // Save back to fpoutput in IBM format}//end for(int itrace = 0; itrace < ncdp; itrace++)
 // Add notes at the end of each loop for easy search and distinction
//Release the memory after the write operation is completedfree(temp); // free temp pointer
free(traceheaderArray); // free traceheader pointer
free2float(dataInput);  // free data input pointer
  • calloc(num,size): Allocated in the dynamic memory storage areanumThe length issizeThe continuous space of the function returns a pointer to the starting address of the allocation; if the allocation is unsuccessful, return NULL;
  • malloc(size): Function andcalloc()Similar, the difference ismalloc()The memory value will not be initialized to 0, andcalloc()The newly requested memory will be filled with 0.

2.3 Complete code

/*****************************************************************************
 Function:       CopySeismicData                                              
 Description:    copy segy file from input data to output data                   
 Input:          
                 const char *filenameInput [in]    input filename (.segy)         
 Output:         
                 const char  *filenameOutput[out]  output filename (.segy)        
 Return:         
             bool  true    program success
			 bool  false   program failed                                         
 Author:     Fan XinRan                                                         
 Date  :     2022/2/8                                                             
 Others:                                                                           
*****************************************************************************/
#include ""

bool copySeismicDataIBM(const char *filenameInput, const char *filenameOutput){

	segy traceheader;       // trace header 
	bhed fileheader;        // file header
	unsigned int nt = 0;        // number of sample
	unsigned int sizetraceheader = sizeof(traceheader);  // size of traceheader;
	unsigned int sizefileheader = sizeof(fileheader);   // size of fileheader;
	unsigned int ncdp = 0;     // number of cdp
	long long   size_file = 0;  //size of input file
	long long  size_trace = 0;  //size of per-trace

	FILE *fpinput = NULL;   // input file pointer
	FILE *fpoutput = NULL;   //output file pointer
	float **dataInput = NULL;  //input data pointer
	segy *traceheaderArray = NULL; //
	int* temp = NULL;

	fpinput = fopen(filenameInput, "rb");  //open input file pointer 
	fpoutput = fopen(filenameOutput, "wb");  //open output file pointer


	if (fpinput == NULL) {
		printf("Cannot open %s file\n", filenameInput);
		return false;
	}

	if (fpoutput == NULL) {
		printf("Cannot open %s file\n", filenameOutput);
		return false;
	}

	fread(&fileheader, sizefileheader, 1, fpinput);

	nt = ;
	nt = exchangeLowHigh16();
	_fseeki64(fpinput, 0, SEEK_END);
	size_file = _ftelli64(fpinput);
	size_trace = nt * sizeof(float) + sizetraceheader;

	ncdp = (size_file - (long long)sizefileheader) / size_trace;

	_fseeki64(fpinput, sizefileheader, SEEK_SET);


	dataInput = alloc2float(nt, ncdp);
	memset(dataInput[0], 0, nt*ncdp * sizeof(float));
	traceheaderArray = (segy*)calloc(ncdp, sizetraceheader);

	temp = (int*)calloc(nt,sizeof(int));


	fwrite(&fileheader,sizefileheader,1, fpoutput);
	for (int itrace = 0; itrace < ncdp; itrace++) {

		fread(&traceheaderArray[itrace], sizetraceheader, 1, fpinput);
		fread(temp, nt * sizeof(int), 1, fpinput);
		trace_ibm2pc(dataInput[itrace], temp, nt);
	}//end for(int itrace = 0; itrace < ncdp; itrace++)

	for (int itrace = 0; itrace < ncdp; itrace++) {
		fwrite(&traceheaderArray[itrace], sizetraceheader, 1, fpoutput);
		trace_pc2ibm(dataInput[itrace],temp,nt);
		fwrite(temp, nt * sizeof(int), 1, fpoutput);
	}//end for(int itrace = 0; itrace < ncdp; itrace++)


	free(temp);
	free(traceheaderArray);
	free2float(dataInput);  // free data input pointer
	fclose(fpoutput); //close output file pointer
	fclose(fpinput);  //close input file pointer
	return true;
}

3 Main function and operation results

#include""

void main(){

	copySeismicDataIBM("","");

}

After running the main function, the program will read it in, this is an IBM format data. Write to, thereby completing the copying of the SEGY file.

The above is the detailed explanation of the detailed reading of C/C++ segy files. For more information about C++ segy files, please pay attention to my other related articles!