mirror of
https://github.com/Ap0dexMe0/unixtract.git
synced 2026-07-15 21:00:03 +02:00
sddl_sec: automatically decompress comp. parts when splitting PEAKS
This commit is contained in:
@@ -150,7 +150,8 @@ Options:
|
||||
**Notes:** Pre-2011 files are not supported.
|
||||
**Options:**
|
||||
`sddl_sec:save_extra` - Save SDIT.FDI and .TXT files that are not extracted by default.
|
||||
`sddl_sec:split_peaks` - Split PEAKS module into partitions (only on older files).
|
||||
`sddl_sec:split_peaks` - Split PEAKS module into partitions (only on older files). This will also automatically decompress compressed partitions.
|
||||
`sddl_sec:no_decomp_peaks` - Do not automatically decompress partitions when splitting PEAKS with above option.
|
||||
|
||||
## SLP
|
||||
**Used in:** Samsung Tizen-based NX series cameras
|
||||
|
||||
@@ -70,6 +70,7 @@ pub fn extract_sddl_sec(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(),
|
||||
let mut file = app_ctx.file().ok_or("Extractor expected file")?;
|
||||
let save_extra = app_ctx.options.iter().any(|e| e == "sddl_sec:save_extra");
|
||||
let split_peaks = app_ctx.options.iter().any(|e| e == "sddl_sec:split_peaks");
|
||||
let decomp_peaks = !app_ctx.options.iter().any(|e| e == "sddl_sec:no_decomp_peaks");
|
||||
|
||||
let mut secfile_hdr_reader = Cursor::new(decipher(&common::read_exact(&mut file, 32)?));
|
||||
let secfile_header: SecHeader = secfile_hdr_reader.read_be()?;
|
||||
@@ -164,7 +165,7 @@ pub fn extract_sddl_sec(app_ctx: &AppContext, _ctx: Box<dyn Any>) -> Result<(),
|
||||
if split_peaks && module.module_name() == "PEAKS" {
|
||||
println!("\n- Splitting PEAKS");
|
||||
if let Some(ref path) = final_out_path {
|
||||
split_peaks_file(path, &app_ctx.output_dir)?;
|
||||
split_peaks_file(path, &app_ctx.output_dir, decomp_peaks)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
use binrw::{BinReaderExt, Endian};
|
||||
use crate::utils::common;
|
||||
use std::{fs::{self, File, OpenOptions}, io::Write, path::{Path, PathBuf}};
|
||||
use std::{fs::{self, File, OpenOptions}, io::{Cursor, Seek, SeekFrom, Write}, path::{Path, PathBuf}};
|
||||
|
||||
pub fn split_peaks_file(path: &PathBuf, out_path: &PathBuf) -> Result<(), Box<dyn std::error::Error>> {
|
||||
use crate::utils::compression::decompress_zlib;
|
||||
|
||||
pub fn split_peaks_file(path: &PathBuf, out_path: &PathBuf, do_decomp: bool) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut file = File::open(path)?;
|
||||
let file_size = file.metadata()?.len();
|
||||
let output_folder = Path::new(&out_path).join("PEAKS");
|
||||
@@ -70,14 +73,70 @@ pub fn split_peaks_file(path: &PathBuf, out_path: &PathBuf) -> Result<(), Box<dy
|
||||
|
||||
tsize += part_size;
|
||||
|
||||
let data = common::read_exact(&mut file, *part_size as usize)?;
|
||||
|
||||
let output_path = Path::new(&output_folder).join(format!("{}.bin", part_name));
|
||||
fs::create_dir_all(&output_folder)?;
|
||||
|
||||
let data = common::read_exact(&mut file, *part_size as usize)?;
|
||||
|
||||
if do_decomp && let Some(part_flag) = part_flag && *part_flag == "c" {
|
||||
println!("-- Decompressing ...");
|
||||
decompress_part_to_file(&data, &output_path)?;
|
||||
continue
|
||||
}
|
||||
|
||||
let mut out_file = OpenOptions::new().write(true).create(true).open(output_path)?;
|
||||
out_file.write_all(&data)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn decompress_part_to_file(data: &[u8], out_path: &PathBuf) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut reader = Cursor::new(data);
|
||||
let mut out_file = OpenOptions::new().append(true).create(true).open(out_path)?;
|
||||
|
||||
//detect endianness, we can safely assume uncomp size wontbe larger than 4294901760
|
||||
let uncomp_chen = common::read_exact(&mut reader, 4)?;
|
||||
let endianness = if uncomp_chen[0..2] == *b"\x00\x00" {
|
||||
Endian::Little
|
||||
} else {
|
||||
Endian::Big
|
||||
};
|
||||
|
||||
reader.seek(SeekFrom::Start(0))?;
|
||||
let uncompressed_size: u32 = reader.read_type(endianness)?;
|
||||
let first_blk: u32 = reader.read_type(endianness)?;
|
||||
let count_blks = (first_blk - 4) / 4;
|
||||
|
||||
println!("[INFO] Endianness: {}, Uncompressed size: {}, First block loc: {}, Block count: {}",
|
||||
endianness, uncompressed_size, first_blk, count_blks);
|
||||
|
||||
reader.seek(SeekFrom::Start(4))?;
|
||||
|
||||
let mut block_locs: Vec<u32> = Vec::new();
|
||||
|
||||
for _ in 0..count_blks {
|
||||
let loc: u32 = reader.read_type(endianness)?;
|
||||
block_locs.push(loc);
|
||||
}
|
||||
|
||||
for (n, blk) in block_locs.iter().enumerate() {
|
||||
reader.seek(SeekFrom::Start(*blk as u64))?;
|
||||
|
||||
print!("\rDecompressing... {}/{}",
|
||||
n + 1, count_blks);
|
||||
std::io::stdout().flush()?;
|
||||
|
||||
//special handling for last block since there is no next block to check, just assume 16k
|
||||
let blk_size = if n == count_blks as usize - 1 {16384} else {block_locs[n + 1] - blk};
|
||||
|
||||
let compressed = common::read_exact(&mut reader, blk_size as usize)?;
|
||||
let decompressed = decompress_zlib(&compressed)?;
|
||||
|
||||
out_file.write_all(&decompressed)?;
|
||||
}
|
||||
|
||||
println!();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Reference in New Issue
Block a user