pythonreadfileutf-16writefile

How can I correctly read and save a bcrf file in Python using utf-16 encoding?


I tried to read a *.bcrf file generated by SPIP tool and intended to save it back to a *.bcrf file as exactly same content as the original. But the results seems not going well. Here is the link description of the bcrf file format: http://www.imagemet.com/WebHelp6/Default.htm#Reference_Guide/BCR_STM_File_Format.htm The bcrf file I tried to read: bcrf file

import struct

def read_bcrf_file(filename):
    header_size = 2048
    data_size = 900 * 900 * 4  # Assuming 32-bit floating point data (bcrf format)

    with open(filename, 'rb') as file:
        # Read the header
        header = file.read(header_size)

        # Parse the header values
        header_dict = {}
        decoded_header = header.decode('utf-16').replace('\x00', '')
        for line in decoded_header.split('\n'):
            if '=' in line:
                key, value = line.strip().split('=')
                header_dict[key.strip()] = value.strip()

        # Read the data
        data = file.read(data_size)

    return header_dict, data


def convert_data_to_float(data):
    float_data = struct.unpack('<' + 'f' * (len(data) // 4), data)
    return float_data


def write_bcr_file(filename, header_dict, data):
    header_size = 2048

    # Create the header string
    header = ""
    for key, value in header_dict.items():
        header += key + " = " + value + "\n"

    # Pad the header to the required size
    header = header.ljust(header_size, '\x00')

    with open(filename, 'wb') as file:
        # Write the header
        file.write(header.encode('utf-16')[2:])

        # Write the data
        data_bytes = struct.pack('<' + 'f' * len(data), *data)
        file.write(data_bytes)


# Example usage
header, binary_data = read_bcrf_file('test_file.bcrf')
data = convert_data_to_float(binary_data)
write_bcr_file('new.bcrf', header_dict=header, data=data)
# Process the data as needed

The new image is dislocation


Solution

  • header = header.ljust(header_size, '\x00') this line is wrong, try my code

    import struct
    
    def read_bcrf_file(filename):
        header_size = 4096
        data_size = 900 * 900 * 4  # Assuming 32-bit floating point data (bcrf format)
    
        with open(filename, 'rb') as file:
            # Read the header
            header = file.read(header_size)
    
            # Parse the header values
            header_dict = {}
            decoded_header = header.decode('utf-16le')
            for line in decoded_header.split('\n'):
                if '=' in line:
                    key, value = line.strip().split('=')
                    header_dict[key.strip()] = value.strip()
    
            # Read the data
            data = file.read(data_size)
        return header_dict, data
    
    
    def convert_data_to_float(data):
        float_data = struct.unpack('<' + 'f' * (len(data) // 4), data)
        # print(float_data[:10])
        return float_data
    
    
    def write_bcr_file(filename, header_dict, data):
        header_size = 4096
    
        # Create the header string
        header = ""
        for key, value in header_dict.items():
            header += key + " = " + value + "\n"
    
        # Pad the header to the required size
        header = header.ljust(header_size//2, '%')
    
        with open(filename, 'wb') as file:
            # Write the header
            file.write(header.encode('utf-16le'))
    
            # Write the data
            data_bytes = struct.pack('<' + 'f' * len(data), *data)
            file.write(data_bytes)
    
    
    # Example usage
    header, binary_data = read_bcrf_file('test_file.bcrf')
    data = convert_data_to_float(binary_data)
    write_bcr_file('new.bcrf', header_dict=header, data=data)
    # Process the data as needed