scurest / apicula

Convert Nintendo DS .nsbmd models
BSD Zero Clause License
156 stars 17 forks source link

Add support for compressed files in "convert" (LZ77) #29

Open Ecconia opened 4 years ago

Ecconia commented 4 years ago

I am currently working on a related tool and extracted the files myself, I then ran these on this tool.

Issue: apicula convert does not recognize the file-prefix "LZ77", which is used for compressed files.

It seems (did not test it), that the apicula extract does have support for it though.

Expected behavior/suggestion: Make the apicula convert check if a file has the prefix "LZ77", then unpack that file and check the prefix again.

scurest commented 4 years ago

Like this I guess? Not sure if I want to do it though....

diff --git a/src/db.rs b/src/db.rs
index 620ac00..1561280 100644
--- a/src/db.rs
+++ b/src/db.rs
@@ -83,7 +83,7 @@ impl Database {
         for file_id in 0..self.file_paths.len() {
             debug!("Processing {:?}...", self.file_paths[file_id]);

-            let buf = match std::fs::read(&self.file_paths[file_id]) {
+            let mut buf = match std::fs::read(&self.file_paths[file_id]) {
                 Ok(buf) => buf,
                 Err(e) =>{
                     error!("file-system error reading {}: {}",
@@ -93,6 +93,13 @@ impl Database {
                 }
             };

+            // If buf looks compressed, decompress it.
+            use decompress::decompress;
+            let off = if buf.starts_with(b"LZ77") { 4 } else { 0 };
+            if let Ok(result) = decompress(Cur::from_buf_pos(&buf, off)) {
+                buf = result.data;
+            }
+
             use nitro::container::read_container;
             match read_container(Cur::new(&buf)) {
                 Ok(cont) => {
Ecconia commented 4 years ago

In my humble opinion, the file(-ending) seems to have the possibility to be compressed, and thus it should be handled.

Your change seems small and efficient. And its effect is only advantageous.

Whether and how you do it - I leave that choice up to you :)