SegY 数据格式的转换小结

根据SegY的标准规范, 使用工作站格式记录的SegY数据要转换为float数值, 作者写了一些合适的方法, 感兴趣的童鞋可以一起讨论下

在400字节的二进制卷头中,  25-26 字节是格式编码

    String strDataFormat;
    switch (formatIndex)
    {
    case 1: //4-byte IBM float
        strDataFormat = "4-byte IBM float";
        break;
    case 2: //4-byte integer
        strDataFormat = "4 byte integer";
        break;
    case 3: //2-byte integer
        strDataFormat = "2-byte integer";
        break;
    case 5: //4-byte IEEE float
        strDataFormat = "4-byte IEEE float";
        break;
    case 8: //1-byte integer
        strDataFormat = "1-byte integer";
        break;
    default: //others
        strDataFormat = "Unknown Format";
        break;
    }

其实个人感觉8bit的就已经很够用了, 256个灰度级已经能够很清晰地表现地下反射特征

 
 

    /** @brief 二进制数据转换为浮点型     *     *  @details     *  @param  bufData   二进制数据     *  @param  traceData 浮点型道数据     *  @param  iSamples  traceData 的采样点个数     *  @param  format    bufData的数据编码格式     *  @return     */     static void data2float(const uchar* bufData, float* traceData, int iSamples, int format = 1);

    /** @brief   从 ibm float 格式的二进制转换到float数组    */     static void ibmFloat2float(const uchar* bufData, float* traceData, int iSamples );     /** @brief   从 ieee float 格式的二进制转换到float数组 */     static void ieeeFloat2float(const uchar* bufData, float* traceData, int iSamples );     /** @brief   从 定长4字节 格式的二进制转换到float数组 */     static void byte4int_2float(const uchar* bufData, float* traceData, int iSamples );     /** @brief   从 定长2字节 格式的二进制转换到float数组 */     static void byte2int_2float(const uchar* bufData, float* traceData, int iSamples );     /** @brief   从 定长1字节 格式的二进制转换到float数组 */     static void byte1int_2float(const uchar* bufData, float* traceData, int iSamples );

    /** @brief SegY数据转换静态方法声明     *     *  @details SegY数据转换静态方法声明     *  @param  traceData   float类型的道数据     *  @param  bufData     字节型的SegY数据,要保存进文件     *  @param  iSamples    traceData的采样点数     *  @param  format      bugData的数据格式类型     */     void float2data(const float* traceData, uchar* bufData, int iSamples, int format /*= 1*/ );     /** @brief   从 ibm float 格式的二进制转换到float数组 */     static void float2ibmFloat(const float* traceData,uchar* bufData, int iSamples );  /** @brief   从 float数组转换到 ieee float 格式的二进制*/     static void float2ieeeFloat(const float* traceData,uchar* bufData, int iSamples );     /** @brief   从float数组 转换到 定长1字节 格式的二进制 */     static void float2_byte1int(const float* traceData, uchar* bufData, int iSamples);     /** @brief   从 float数组转换到 定长2字节 格式的二进制*/     static void float2_byte2int(const float* traceData,uchar* bufData,int iSamples );     /** @brief   从 float数组转换到定长4字节 格式的二进制 */     static void float2_byte4int(const float* traceData, uchar* bufData, int iSamples );

    // 4字节int类型的高低位转换     static void swapBytes4(unsigned char*cp);     // 2字节short类型的高低位转换     static void swapBytes2(unsigned char*cp);

源码以最复杂的ibmfloat为例子吧

void SlSegYDataConvert::ibmFloat2float( const uchar* bufData, float* traceData, int iSamples )
{
    //  d24 = 1.0f/16777216.0f;
    int byte1,byte2,byte3,byte4,bsign;
    int exp,basep;

    for(int i = 0; i < iSamples ; i++)
    {
        int index = i * 4;

        byte1 = bufData[index++];
        byte2 = bufData[index++];
        byte3 = bufData[index++];
        byte4 = bufData[index];
        bsign = byte1 & 0x80;
        exp = (byte1 & 0x7F) -64;

        basep = byte2;
        basep = (basep <<8) + byte3;
        basep = (basep <<8) + byte4;
        if (0 == bsign)
            traceData[i] =  pow(16.0,exp) * basep * d24;
        else
            traceData[i] = -1 * pow(16.0,exp) * basep * d24;
    /*关于IBM Float 工作站编码, 可以自己查一下.  要从float 转回去,参照编码格式亦可完成, 此处不再缀述*/
    }
}

个人感觉这样写的可能高低位转换效率比较好, 请大神斧正, 给不吝回复一下

void SlSegYDataConvert::swapBytes4(unsigned char *cp)
{
    cp[0] ^= (cp[3]^=(cp[0]^=cp[3]));
    cp[1] ^= (cp[2]^=(cp[1]^=cp[2]));
}

void SlSegYDataConvert::swapBytes2(unsigned char* cp)
{
    cp[0] ^= (cp[1]^=(cp[0]^=cp[1]));
}




 

猜你喜欢

转载自blog.csdn.net/sdust_dx/article/details/9373129