diff --git a/src/formats.rs b/src/formats.rs index 6e0aeb6..4d150b7 100644 --- a/src/formats.rs +++ b/src/formats.rs @@ -10,6 +10,7 @@ pub mod slp; pub mod roku; pub mod sony_bdp; pub mod rvp; +pub mod funai_upg; pub mod pup; diff --git a/src/formats/funai_upg.rs b/src/formats/funai_upg.rs new file mode 100644 index 0000000..e2dac23 --- /dev/null +++ b/src/formats/funai_upg.rs @@ -0,0 +1,60 @@ +use std::fs::File; +use std::path::Path; +use std::fs::{self, OpenOptions}; +use std::io::{Write}; +use binrw::{BinRead, BinReaderExt}; + +use crate::common; + +#[derive(BinRead)] +struct Header { + #[br(count = 6)] _magic_bytes: Vec, + entry_count: u16, + file_size: u32, +} + +#[derive(BinRead)] +struct Entry { + entry_type: u16, + entry_size: u32, + _unk: u16, +} + +pub fn is_funai_upg_file(file: &File) -> bool { + let header = common::read_file(&file, 0, 6).expect("Failed to read from file."); + if header == b"UPG\x00\x00\x00" { + true + } else { + false + } +} + +pub fn extract_funai_upg(mut file: &File, output_folder: &str) -> Result<(), Box> { + let header: Header = file.read_le()?; + println!("File info:\nFile size: {}\nEntry count: {}", header.file_size, header.entry_count); + + for i in 0..header.entry_count { + let entry: Entry = file.read_le()?; + println!("\nEntry {}/{} - Type: {}, Size: {}", i + 1, header.entry_count, entry.entry_type, entry.entry_size); + + let data = common::read_exact(&mut file, entry.entry_size as usize - 2 - 4)?; //size has the unk field + crc32 at the end + let _crc32 = common::read_exact(&mut file, 4)?; //btw the CRC32 includes the entry header + + if entry.entry_type == 0 { + let entry_string = common::string_from_bytes(&data); + println!("Descriptor entry info:\n{}", entry_string); + } + + let output_path = Path::new(&output_folder).join(format!("{}_{}.bin", i + 1, entry.entry_type)); + + fs::create_dir_all(&output_folder)?; + let mut out_file = OpenOptions::new().write(true).create(true).open(output_path)?; + out_file.write_all(&data)?; + + println!("- Saved file!"); + } + + println!("\nExtraction finished!"); + + Ok(()) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index ed55bb5..546b85b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -95,6 +95,10 @@ fn main() -> Result<(), Box> { println!("RUF file detected!"); formats::ruf::extract_ruf(&file, &output_path)?; } + else if formats::funai_upg::is_funai_upg_file(&file) { + println!("Funai UPG file detected!"); + formats::funai_upg::extract_funai_upg(&file, &output_path)?; + } else if formats::pfl_upg::is_pfl_upg_file(&file) { println!("PFL UPG file detected!"); formats::pfl_upg::extract_pfl_upg(&file, &output_path)?;