ASecondGuy / EasyFiles

MIT License
10 stars 2 forks source link

Compressed Files like gzip #2

Open Sciumo opened 3 months ago

Sciumo commented 3 months ago

I noticed GD compression only works with their own per https://github.com/godotengine/godot/issues/28999 Someone on that issue has a work around that would be nice to have in easyfiles.

static func open_gzip(fpath: String) -> PackedByteArray:
    var f := FileAccess.open(fpath, FileAccess.READ)
    if f == null:
        push_error("Could not open file ", fpath, ", error ", FileAccess.get_open_error())
        return PackedByteArray()

    # https://docs.fileformat.com/compression/gz/
    # Read 10-byte header
    var header := f.get_16() # 1f 8b
    var compression_method := f.get_8() # 08 for DEFLATE
    var file_flags := f.get_8()
    var timestamp := f.get_32()
    var compression_flags := f.get_8()
    var os_id := f.get_8()
    # Assuming no other extra header stuff, which my file doesn't have, 
    # but might need to be handled eventually

    var compressed_data_position := f.get_position()
    print("compressed_data_position ", compressed_data_position)
    var total_file_length := f.get_length()
    var footer_length := 8
    var compressed_data_size := total_file_length - compressed_data_position - footer_length
    var compressed_data := f.get_buffer(compressed_data_size)

    # Read footer
    var checksum_crc32 := f.get_32()
    var decompressed_data_size := f.get_32()
    print(f.get_position())
    print("decompressed_data_size ", decompressed_data_size)
    print("CRC32 ", checksum_crc32)

    f = null

    #compressed_data = FileAccess.get_file_as_bytes(fpath)

    # Decompress data ourselves. Usually the format is DEFLATE.
    # Godot allows to specify either GZIP or DEFLATE, but there is no difference in the 
    # implementation.
    var decompressed_data := compressed_data.decompress_dynamic(-1, FileAccess.COMPRESSION_DEFLATE)
    print("decompressed_data.size(): ", decompressed_data.size())

    return decompressed_data
ASecondGuy commented 2 months ago

This workaround would not work with easyfiles because it relies on the get and store methods of FileAccess. So I'd need a wrapper that does this workaround in the background or use a tempfile that is in Godot format.

I might do it when I have time. Could take some time because I don't normally use the compression feature.