Skip to content

Commit

Permalink
Use zlib-rs as primary deflate backend
Browse files Browse the repository at this point in the history
This fixes the issue we had with the "data\wav\worm_tail_damage.wav" sound file that can't be read with miniz_oxide of libflate.

Interestingly, the trait BufRead is implemented for `&[u8]` and the internals of `read_to_end()` essentially handles the writing into uninitialized memory of the Vector extremely efficiently then.
  • Loading branch information
hasenbanck committed Jan 1, 2025
1 parent 52ddb26 commit 39603d5
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 26 deletions.
23 changes: 16 additions & 7 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ cpal = "0.15"
derive-new = "0.7"
etherparse = "0.16"
fast-srgb8 = "1"
flate2 = "1"
flate2 = { version = "1", default-features = false }
glidesort = "0.1"
hashbrown = "0.15"
image = { version = "0.25", default-features = false }
Expand Down Expand Up @@ -50,7 +50,6 @@ walkdir = "2.5"
wgpu = "23.0"
winit = "0.30"
xml-rs = "0.8"
yazi = "0.2"

[profile.dev.build-override]
opt-level = 3
Expand Down
3 changes: 1 addition & 2 deletions korangar/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ cgmath = { workspace = true, features = ["mint", "serde"] }
chrono = { workspace = true }
cosmic-text = { workspace = true, features = ["std", "fontconfig"] }
derive-new = { workspace = true }
flate2 = { workspace = true }
flate2 = { workspace = true, features = ["zlib-rs"] }
hashbrown = { workspace = true }
glidesort = { workspace = true }
image = { workspace = true, features = ["bmp", "jpeg", "png", "tga", "rayon"] }
Expand Down Expand Up @@ -39,7 +39,6 @@ walkdir = { workspace = true }
wgpu = { workspace = true }
winit = { workspace = true }
xml-rs = { workspace = true }
yazi = { workspace = true }

[features]
debug = ["korangar_debug", "korangar_audio/debug", "ragnarok_packets/debug", "random_color"]
Expand Down
22 changes: 15 additions & 7 deletions korangar/src/loaders/archive/native/builder.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
//! Implements an writable instance of a GRF File
//! Implements a writable instance of a GRF File
//! This way, we can provide a temporal storage to files before the final write
//! occurs while keeping it outside of the
//! occurs while keeping it outside the
//! [`NativeArchive`](super::NativeArchive) implementation
use std::io::Read;
use std::path::{Path, PathBuf};

use flate2::bufread::ZlibEncoder;
use flate2::Compression;
use ragnarok_bytes::ToBytes;
use ragnarok_formats::archive::{AssetTable, FileTableRow, Header};
use yazi::{compress, CompressionLevel, Format};

use super::FileTable;
use crate::loaders::archive::Writable;
Expand All @@ -29,7 +32,9 @@ impl NativeArchiveBuilder {

impl Writable for NativeArchiveBuilder {
fn add_file(&mut self, path: &str, asset: Vec<u8>) {
let compressed = compress(&asset, Format::Zlib, CompressionLevel::Default).unwrap();
let mut encoder = ZlibEncoder::new(asset.as_slice(), Compression::default());
let mut compressed = Vec::default();
encoder.read_to_end(&mut compressed).expect("can't compress asset");

let compressed_size = compressed.len() as u32;
let compressed_size_aligned = compressed_size;
Expand Down Expand Up @@ -66,14 +71,17 @@ impl Writable for NativeArchiveBuilder {
file_table_data.extend(file_information.to_bytes().unwrap());
}

let compressed_file_information_data = compress(&file_table_data, Format::Zlib, CompressionLevel::Default).unwrap();
let mut encoder = ZlibEncoder::new(file_table_data.as_slice(), Compression::default());
let mut compressed = Vec::default();
encoder.read_to_end(&mut compressed).expect("can't compress file information");

let file_table = AssetTable {
compressed_size: compressed_file_information_data.len() as u32,
compressed_size: compressed.len() as u32,
uncompressed_size: file_table_data.len() as u32,
};

bytes.extend(file_table.to_bytes().unwrap());
bytes.extend(compressed_file_information_data);
bytes.extend(compressed);

std::fs::write(&self.os_file_path, bytes).expect("unable to write file");
}
Expand Down
20 changes: 12 additions & 8 deletions korangar/src/loaders/archive/native/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ use std::io::{Read, Seek, SeekFrom};
use std::path::Path;
use std::sync::Mutex;

use flate2::bufread::ZlibDecoder;
#[cfg(feature = "debug")]
use korangar_debug::logging::{Colorize, Timer};
use ragnarok_bytes::{ByteReader, FixedByteSize, FromBytes};
use ragnarok_formats::archive::{AssetTable, FileTableRow, Header};
use yazi::{decompress, Format};

pub use self::builder::NativeArchiveBuilder;
use crate::loaders::archive::native::mixcrypt::decrypt_file;
Expand Down Expand Up @@ -44,11 +44,14 @@ impl Archive for NativeArchive {
let mut file_table_buffer = vec![0; AssetTable::size_in_bytes()];

file.read_exact(&mut file_table_buffer).unwrap();
let file_table = AssetTable::from_bytes(&mut ByteReader::without_metadata(&file_table_buffer)).unwrap();
let file_table = AssetTable::from_bytes(&mut ByteReader::without_metadata(&file_table_buffer)).expect("can't read file table");

let mut compressed_file_table_buffer = vec![0u8; file_table.compressed_size as usize];
file.read_exact(&mut compressed_file_table_buffer).unwrap();
let (decompressed, _checksum) = decompress(&compressed_file_table_buffer, Format::Zlib).unwrap();

let mut decoder = ZlibDecoder::new(compressed_file_table_buffer.as_slice());
let mut decompressed = Vec::with_capacity(file_table.uncompressed_size as usize);
decoder.read_to_end(&mut decompressed).expect("can't decompress file table");

let file_count = file_header.get_file_count();

Expand All @@ -66,7 +69,7 @@ impl Archive for NativeArchive {
timer.stop();

// TODO: only take 64..? bytes so that loaded game archives can be extended
// aswell
// as well.
Self {
file_table: assets,
file_handle: Mutex::new(file),
Expand All @@ -86,15 +89,16 @@ impl Archive for NativeArchive {
file_handle.seek(SeekFrom::Start(position)).unwrap();
file_handle
.read_exact(&mut compressed_file_buffer)
.expect("Can't read archive content");
.expect("can't read archive content");
}

decrypt_file(file_information, &mut compressed_file_buffer);

let (uncompressed_file_buffer, _checksum) =
decompress(&compressed_file_buffer, Format::Zlib).expect("Can't decompress archive content");
let mut decoder = ZlibDecoder::new(compressed_file_buffer.as_slice());
let mut decompressed = Vec::with_capacity(file_information.uncompressed_size as usize);
decoder.read_to_end(&mut decompressed).expect("can't decompress archive content");

uncompressed_file_buffer
decompressed
})
}

Expand Down

0 comments on commit 39603d5

Please sign in to comment.