mirror of
https://github.com/Ap0dexMe0/unixtract.git
synced 2026-07-15 21:00:03 +02:00
mstar: further code optimizations + lzop optimization. fix memory issue by writing directly to file
This commit is contained in:
+9
-18
@@ -5,12 +5,12 @@ use lz4::block::decompress;
|
|||||||
use lzma_rs::lzma_decompress;
|
use lzma_rs::lzma_decompress;
|
||||||
|
|
||||||
use crate::common;
|
use crate::common;
|
||||||
use crate::utils::lzop::{decompress_lzop};
|
use crate::utils::lzop::{unlzop_to_file};
|
||||||
use crate::utils::sparse::{unsparse_to_file};
|
use crate::utils::sparse::{unsparse_to_file};
|
||||||
|
|
||||||
//change whether the "userdata" partition is skipped
|
//change whether the "userdata" partition is skipped
|
||||||
// this is because the userdata partition is sometimes enourmous sizes like 27gb, and it will fail to allocate memory on most computers
|
// this is because the userdata partition is sometimes enourmous sizes like 27gb, and it is empty anyways
|
||||||
// if you want to attempt to extract "userdata" you can enable the option
|
// if you want to extract "userdata" you can disable the option
|
||||||
static CONFIG_SKIP_USERDATA: bool = true;
|
static CONFIG_SKIP_USERDATA: bool = true;
|
||||||
|
|
||||||
pub fn is_mstar_file(file: &File) -> bool {
|
pub fn is_mstar_file(file: &File) -> bool {
|
||||||
@@ -76,13 +76,9 @@ pub fn extract_mstar(file: &File, output_folder: &str) -> Result<(), Box<dyn std
|
|||||||
let lines: Vec<&str> = script_string.lines().map(|l| l.trim()).collect();
|
let lines: Vec<&str> = script_string.lines().map(|l| l.trim()).collect();
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
|
|
||||||
while i < lines.len() {
|
for line in &lines {
|
||||||
let line = lines[i];
|
|
||||||
|
|
||||||
if line.starts_with("filepartload") {
|
if line.starts_with("filepartload") {
|
||||||
let parts: Vec<&str> = line.split_whitespace().collect();
|
let parts: Vec<&str> = line.split_whitespace().collect();
|
||||||
|
|
||||||
if parts.len() >= 5 {
|
|
||||||
let offset = parse_number(parts[3]).unwrap_or(0);
|
let offset = parse_number(parts[3]).unwrap_or(0);
|
||||||
let size = parse_number(parts[4]).unwrap_or(0);
|
let size = parse_number(parts[4]).unwrap_or(0);
|
||||||
|
|
||||||
@@ -93,7 +89,6 @@ pub fn extract_mstar(file: &File, output_folder: &str) -> Result<(), Box<dyn std
|
|||||||
// "unknown"
|
// "unknown"
|
||||||
//};
|
//};
|
||||||
let mut partname = "unknown";
|
let mut partname = "unknown";
|
||||||
|
|
||||||
let mut compression = "none";
|
let mut compression = "none";
|
||||||
let mut lz4_expect_size = 0;
|
let mut lz4_expect_size = 0;
|
||||||
let mut j = i + 1;
|
let mut j = i + 1;
|
||||||
@@ -173,30 +168,26 @@ pub fn extract_mstar(file: &File, output_folder: &str) -> Result<(), Box<dyn std
|
|||||||
out_data = decompress_lz4(&data, lz4_expect_size.try_into().unwrap())?;
|
out_data = decompress_lz4(&data, lz4_expect_size.try_into().unwrap())?;
|
||||||
} else if compression == "lzo" {
|
} else if compression == "lzo" {
|
||||||
println!("- Decompessing LZO..");
|
println!("- Decompessing LZO..");
|
||||||
out_data = decompress_lzop(&data)?;
|
unlzop_to_file(&data, output_path)?;
|
||||||
|
println!("-- Saved file!");
|
||||||
|
i += 1;
|
||||||
|
continue
|
||||||
} else if compression == "sparse" {
|
} else if compression == "sparse" {
|
||||||
println!("- Unsparsing...");
|
println!("- Unsparsing...");
|
||||||
unsparse_to_file(&data, output_path)?;
|
unsparse_to_file(&data, output_path)?;
|
||||||
println!("-- Saved file!");
|
println!("-- Saved file!");
|
||||||
i += 1;
|
i += 1;
|
||||||
continue
|
continue
|
||||||
//out_data = unsparse(&data)?;
|
|
||||||
} else {
|
} else {
|
||||||
out_data = data;
|
out_data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
fs::create_dir_all(&output_folder)?;
|
fs::create_dir_all(&output_folder)?;
|
||||||
let mut out_file = OpenOptions::new()
|
let mut out_file = OpenOptions::new().append(true).create(true).open(output_path)?;
|
||||||
.append(true)
|
|
||||||
.create(true)
|
|
||||||
.open(output_path)?;
|
|
||||||
|
|
||||||
out_file.write_all(&out_data)?;
|
out_file.write_all(&out_data)?;
|
||||||
|
|
||||||
println!("-- Saved file!");
|
println!("-- Saved file!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-5
@@ -1,5 +1,7 @@
|
|||||||
use binrw::{BinRead, BinReaderExt};
|
use binrw::{BinRead, BinReaderExt};
|
||||||
use std::io::{Cursor};
|
use std::fs::OpenOptions;
|
||||||
|
use std::path::{PathBuf};
|
||||||
|
use std::io::{Cursor, Write};
|
||||||
|
|
||||||
use simd_adler32::adler32;
|
use simd_adler32::adler32;
|
||||||
use crate::common;
|
use crate::common;
|
||||||
@@ -28,7 +30,7 @@ struct SegmentHeader {
|
|||||||
checksum: u32,
|
checksum: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decompress_lzop(data: &[u8]) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
|
pub fn unlzop_to_file(data: &[u8], file_path: PathBuf) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
let mut data_reader = Cursor::new(data);
|
let mut data_reader = Cursor::new(data);
|
||||||
let header: LzopHeader = data_reader.read_be()?;
|
let header: LzopHeader = data_reader.read_be()?;
|
||||||
if header.magic_bytes != b"\x89LZO\x00\x0D\x0A\x1A\x0A" {
|
if header.magic_bytes != b"\x89LZO\x00\x0D\x0A\x1A\x0A" {
|
||||||
@@ -39,7 +41,7 @@ pub fn decompress_lzop(data: &[u8]) -> Result<Vec<u8>, Box<dyn std::error::Error
|
|||||||
}
|
}
|
||||||
|
|
||||||
let lzo = minilzo_rs::LZO::init()?;
|
let lzo = minilzo_rs::LZO::init()?;
|
||||||
let mut decompressed_output = Vec::new();
|
let mut out_file = OpenOptions::new().create(true).append(true).open(file_path)?;
|
||||||
loop {
|
loop {
|
||||||
if (data.len() as u64 - data_reader.position()) < 12 { //check if there are enough bytes to read a segment header
|
if (data.len() as u64 - data_reader.position()) < 12 { //check if there are enough bytes to read a segment header
|
||||||
break;
|
break;
|
||||||
@@ -66,8 +68,8 @@ pub fn decompress_lzop(data: &[u8]) -> Result<Vec<u8>, Box<dyn std::error::Error
|
|||||||
return Err("Invalid segment checksum! Data corrupted?".into());
|
return Err("Invalid segment checksum! Data corrupted?".into());
|
||||||
};
|
};
|
||||||
|
|
||||||
decompressed_output.extend_from_slice(&out_data);
|
out_file.write_all(&out_data)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(decompressed_output)
|
Ok(())
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user