Skip to content

Commit aa33cde

Browse files
authored
Add dump-art command (#9)
1 parent 4d6d9cd commit aa33cde

File tree

4 files changed

+54
-2
lines changed

4 files changed

+54
-2
lines changed

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ glob = "0.3.2"
2525
serde = {version = "1.0.217", features = ["derive"]}
2626
serde_json = "1.0.137"
2727
polars = {version = "0.45.1", features=["csv", "lazy", "list_eval", "dtype-full"]}
28-
rayon = "1.10.0"
28+
rayon = "1.10.0"
29+
image = { git = "https://github.com/RunDevelopment/image", branch = "new-dds-decoder" }
2930

3031
[dev-dependencies]
3132
criterion = { version = "0.3", features = ["html_reports"] }

src/bin/poe_files.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ use poe_tools::{
55
bundle_fs::{from_cdn, from_steam},
66
bundle_loader::cdn_base_url,
77
commands::{
8-
cat::cat_file, dump_tables::dump_tables, extract::extract_files, list::list_files, Patch,
8+
cat::cat_file, dump_art::extract_art, dump_tables::dump_tables, extract::extract_files,
9+
list::list_files, Patch,
910
},
1011
};
1112
use std::path::PathBuf;
@@ -42,6 +43,13 @@ enum Command {
4243
/// Path to write out the parsed tables to - Only supports CSV for now
4344
output_folder: PathBuf,
4445
},
46+
DumpArt {
47+
/// Path to the folder to output the extracted files
48+
output_folder: PathBuf,
49+
/// Glob pattern to filter the list of files
50+
#[clap(default_value = "*")]
51+
glob: Pattern,
52+
},
4553
}
4654

4755
/// A simple CLI tool that extracts the virtual filenames from PoE data files.
@@ -143,6 +151,10 @@ fn main() -> Result<()> {
143151
output_folder,
144152
} => dump_tables(&datc64_root, &schema_path, &output_folder, &args.patch)
145153
.context("Dump Tables command failed")?,
154+
Command::DumpArt {
155+
output_folder,
156+
glob,
157+
} => extract_art(&mut fs, &glob, &output_folder).context("Dump Art command failed")?,
146158
}
147159

148160
Ok(())

src/commands/dump_art.rs

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
use std::{fs, path::Path};
2+
3+
use glob::Pattern;
4+
5+
use crate::bundle_fs::FS;
6+
use anyhow::{ensure, Context, Result};
7+
8+
/// Extract files to disk matching a glob pattern
9+
pub fn extract_art(fs: &mut FS, pattern: &Pattern, output_folder: &Path) -> Result<()> {
10+
ensure!(
11+
pattern.as_str().ends_with(".dds"),
12+
"Only .dds art export is supported."
13+
);
14+
15+
fs.list()
16+
.iter()
17+
.filter(|filename| pattern.matches(filename))
18+
.map(|filename| -> Result<_, anyhow::Error> {
19+
// Dump it to disk
20+
let contents = fs.read(filename).context("Failed to read file")?;
21+
22+
let img = image::load_from_memory(&contents).context("Failed to pares DDS image")?;
23+
24+
let out_filename = output_folder.join(filename).with_extension("png");
25+
fs::create_dir_all(out_filename.parent().unwrap())
26+
.context("Failed to create folder")?;
27+
28+
img.save(out_filename).context("Failed to write file")?;
29+
30+
Ok(filename)
31+
})
32+
.for_each(|result| match result {
33+
Ok(filename) => eprintln!("Extracted file: {}", filename),
34+
Err(e) => eprintln!("Failed to extract file: {:?}", e),
35+
});
36+
37+
Ok(())
38+
}

src/commands/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub mod cat;
2+
pub mod dump_art;
23
pub mod dump_tables;
34
pub mod extract;
45
pub mod list;

0 commit comments

Comments
 (0)