mirror of
https://github.com/lifegpc/msg-tool.git
synced 2026-07-08 01:31:53 +08:00
Add hg3 export support
This commit is contained in:
1
Cargo.lock
generated
1
Cargo.lock
generated
@@ -319,6 +319,7 @@ dependencies = [
|
|||||||
"clap",
|
"clap",
|
||||||
"csv",
|
"csv",
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
|
"flate2",
|
||||||
"int-enum",
|
"int-enum",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"msg_tool_macro",
|
"msg_tool_macro",
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ blowfish = { version = "0.9", optional = true }
|
|||||||
clap = { version = "4.5", features = ["derive"] }
|
clap = { version = "4.5", features = ["derive"] }
|
||||||
csv = "1.3"
|
csv = "1.3"
|
||||||
encoding_rs = "0.8"
|
encoding_rs = "0.8"
|
||||||
|
flate2 = { version = "1.1", optional = true }
|
||||||
int-enum = { version = "1.2", optional = true }
|
int-enum = { version = "1.2", optional = true }
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
msg_tool_macro = { path = "./msg_tool_macro" }
|
msg_tool_macro = { path = "./msg_tool_macro" }
|
||||||
@@ -19,12 +20,13 @@ serde_json = "1"
|
|||||||
unicode-segmentation = "1.12"
|
unicode-segmentation = "1.12"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["bgi", "bgi-arc", "bgi-img", "cat-system", "cat-system-arc", "circus", "escude", "escude-arc", "yaneurao", "yaneurao-itufuru"]
|
default = ["bgi", "bgi-arc", "bgi-img", "cat-system", "cat-system-arc", "cat-system-img", "circus", "escude", "escude-arc", "yaneurao", "yaneurao-itufuru"]
|
||||||
bgi = []
|
bgi = []
|
||||||
bgi-arc = ["bgi", "utils-bit-stream"]
|
bgi-arc = ["bgi", "utils-bit-stream"]
|
||||||
bgi-img = ["bgi", "image", "utils-bit-stream"]
|
bgi-img = ["bgi", "image", "utils-bit-stream"]
|
||||||
cat-system = []
|
cat-system = []
|
||||||
cat-system-arc = ["cat-system", "blowfish", "utils-crc32"]
|
cat-system-arc = ["cat-system", "blowfish", "utils-crc32"]
|
||||||
|
cat-system-img = ["cat-system", "flate2"]
|
||||||
circus = []
|
circus = []
|
||||||
escude = ["int-enum"]
|
escude = ["int-enum"]
|
||||||
escude-arc = ["escude", "rand", "utils-bit-stream"]
|
escude-arc = ["escude", "rand", "utils-bit-stream"]
|
||||||
|
|||||||
227
src/ext/io.rs
227
src/ext/io.rs
@@ -6,9 +6,9 @@ use std::sync::Mutex;
|
|||||||
|
|
||||||
pub trait Peek {
|
pub trait Peek {
|
||||||
fn peek(&mut self, buf: &mut [u8]) -> Result<usize>;
|
fn peek(&mut self, buf: &mut [u8]) -> Result<usize>;
|
||||||
fn peek_extract(&mut self, buf: &mut [u8]) -> Result<()>;
|
fn peek_exact(&mut self, buf: &mut [u8]) -> Result<()>;
|
||||||
fn peek_at(&mut self, offset: usize, buf: &mut [u8]) -> Result<usize>;
|
fn peek_at(&mut self, offset: usize, buf: &mut [u8]) -> Result<usize>;
|
||||||
fn peek_extract_at(&mut self, offset: usize, buf: &mut [u8]) -> Result<()>;
|
fn peek_exact_at(&mut self, offset: usize, buf: &mut [u8]) -> Result<()>;
|
||||||
fn peek_at_vec(&mut self, offset: usize, len: usize) -> Result<Vec<u8>> {
|
fn peek_at_vec(&mut self, offset: usize, len: usize) -> Result<Vec<u8>> {
|
||||||
let mut buf = vec![0u8; len];
|
let mut buf = vec![0u8; len];
|
||||||
let bytes_read = self.peek_at(offset, &mut buf)?;
|
let bytes_read = self.peek_at(offset, &mut buf)?;
|
||||||
@@ -17,190 +17,190 @@ pub trait Peek {
|
|||||||
}
|
}
|
||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
fn peek_extract_at_vec(&mut self, offset: usize, len: usize) -> Result<Vec<u8>> {
|
fn peek_exact_at_vec(&mut self, offset: usize, len: usize) -> Result<Vec<u8>> {
|
||||||
let mut buf = vec![0u8; len];
|
let mut buf = vec![0u8; len];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn peek_u8(&mut self) -> Result<u8> {
|
fn peek_u8(&mut self) -> Result<u8> {
|
||||||
let mut buf = [0u8; 1];
|
let mut buf = [0u8; 1];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(buf[0])
|
Ok(buf[0])
|
||||||
}
|
}
|
||||||
fn peek_u16(&mut self) -> Result<u16> {
|
fn peek_u16(&mut self) -> Result<u16> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(u16::from_le_bytes(buf))
|
Ok(u16::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_u16_be(&mut self) -> Result<u16> {
|
fn peek_u16_be(&mut self) -> Result<u16> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(u16::from_be_bytes(buf))
|
Ok(u16::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_u32(&mut self) -> Result<u32> {
|
fn peek_u32(&mut self) -> Result<u32> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(u32::from_le_bytes(buf))
|
Ok(u32::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_u32_be(&mut self) -> Result<u32> {
|
fn peek_u32_be(&mut self) -> Result<u32> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(u32::from_be_bytes(buf))
|
Ok(u32::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_u64(&mut self) -> Result<u64> {
|
fn peek_u64(&mut self) -> Result<u64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(u64::from_le_bytes(buf))
|
Ok(u64::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_u64_be(&mut self) -> Result<u64> {
|
fn peek_u64_be(&mut self) -> Result<u64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(u64::from_be_bytes(buf))
|
Ok(u64::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_u128(&mut self) -> Result<u128> {
|
fn peek_u128(&mut self) -> Result<u128> {
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 16];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(u128::from_le_bytes(buf))
|
Ok(u128::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_u128_be(&mut self) -> Result<u128> {
|
fn peek_u128_be(&mut self) -> Result<u128> {
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 16];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(u128::from_be_bytes(buf))
|
Ok(u128::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i8(&mut self) -> Result<i8> {
|
fn peek_i8(&mut self) -> Result<i8> {
|
||||||
let mut buf = [0u8; 1];
|
let mut buf = [0u8; 1];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(i8::from_le_bytes(buf))
|
Ok(i8::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i16(&mut self) -> Result<i16> {
|
fn peek_i16(&mut self) -> Result<i16> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(i16::from_le_bytes(buf))
|
Ok(i16::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i16_be(&mut self) -> Result<i16> {
|
fn peek_i16_be(&mut self) -> Result<i16> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(i16::from_be_bytes(buf))
|
Ok(i16::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i32(&mut self) -> Result<i32> {
|
fn peek_i32(&mut self) -> Result<i32> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(i32::from_le_bytes(buf))
|
Ok(i32::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i32_be(&mut self) -> Result<i32> {
|
fn peek_i32_be(&mut self) -> Result<i32> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(i32::from_be_bytes(buf))
|
Ok(i32::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i64(&mut self) -> Result<i64> {
|
fn peek_i64(&mut self) -> Result<i64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(i64::from_le_bytes(buf))
|
Ok(i64::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i64_be(&mut self) -> Result<i64> {
|
fn peek_i64_be(&mut self) -> Result<i64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(i64::from_be_bytes(buf))
|
Ok(i64::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i128(&mut self) -> Result<i128> {
|
fn peek_i128(&mut self) -> Result<i128> {
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 16];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(i128::from_le_bytes(buf))
|
Ok(i128::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i128_be(&mut self) -> Result<i128> {
|
fn peek_i128_be(&mut self) -> Result<i128> {
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 16];
|
||||||
self.peek_extract(&mut buf)?;
|
self.peek_exact(&mut buf)?;
|
||||||
Ok(i128::from_be_bytes(buf))
|
Ok(i128::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_u8_at(&mut self, offset: usize) -> Result<u8> {
|
fn peek_u8_at(&mut self, offset: usize) -> Result<u8> {
|
||||||
let mut buf = [0u8; 1];
|
let mut buf = [0u8; 1];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(buf[0])
|
Ok(buf[0])
|
||||||
}
|
}
|
||||||
fn peek_u16_at(&mut self, offset: usize) -> Result<u16> {
|
fn peek_u16_at(&mut self, offset: usize) -> Result<u16> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(u16::from_le_bytes(buf))
|
Ok(u16::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_u16_be_at(&mut self, offset: usize) -> Result<u16> {
|
fn peek_u16_be_at(&mut self, offset: usize) -> Result<u16> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(u16::from_be_bytes(buf))
|
Ok(u16::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_u32_at(&mut self, offset: usize) -> Result<u32> {
|
fn peek_u32_at(&mut self, offset: usize) -> Result<u32> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(u32::from_le_bytes(buf))
|
Ok(u32::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_u32_be_at(&mut self, offset: usize) -> Result<u32> {
|
fn peek_u32_be_at(&mut self, offset: usize) -> Result<u32> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(u32::from_be_bytes(buf))
|
Ok(u32::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_u64_at(&mut self, offset: usize) -> Result<u64> {
|
fn peek_u64_at(&mut self, offset: usize) -> Result<u64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(u64::from_le_bytes(buf))
|
Ok(u64::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_u64_be_at(&mut self, offset: usize) -> Result<u64> {
|
fn peek_u64_be_at(&mut self, offset: usize) -> Result<u64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(u64::from_be_bytes(buf))
|
Ok(u64::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_u128_at(&mut self, offset: usize) -> Result<u128> {
|
fn peek_u128_at(&mut self, offset: usize) -> Result<u128> {
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 16];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(u128::from_le_bytes(buf))
|
Ok(u128::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_u128_be_at(&mut self, offset: usize) -> Result<u128> {
|
fn peek_u128_be_at(&mut self, offset: usize) -> Result<u128> {
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 16];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(u128::from_be_bytes(buf))
|
Ok(u128::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i8_at(&mut self, offset: usize) -> Result<i8> {
|
fn peek_i8_at(&mut self, offset: usize) -> Result<i8> {
|
||||||
let mut buf = [0u8; 1];
|
let mut buf = [0u8; 1];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i8::from_le_bytes(buf))
|
Ok(i8::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i16_at(&mut self, offset: usize) -> Result<i16> {
|
fn peek_i16_at(&mut self, offset: usize) -> Result<i16> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i16::from_le_bytes(buf))
|
Ok(i16::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i16_be_at(&mut self, offset: usize) -> Result<i16> {
|
fn peek_i16_be_at(&mut self, offset: usize) -> Result<i16> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i16::from_be_bytes(buf))
|
Ok(i16::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i32_at(&mut self, offset: usize) -> Result<i32> {
|
fn peek_i32_at(&mut self, offset: usize) -> Result<i32> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i32::from_le_bytes(buf))
|
Ok(i32::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i32_be_at(&mut self, offset: usize) -> Result<i32> {
|
fn peek_i32_be_at(&mut self, offset: usize) -> Result<i32> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i32::from_be_bytes(buf))
|
Ok(i32::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i64_at(&mut self, offset: usize) -> Result<i64> {
|
fn peek_i64_at(&mut self, offset: usize) -> Result<i64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i64::from_le_bytes(buf))
|
Ok(i64::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i64_be_at(&mut self, offset: usize) -> Result<i64> {
|
fn peek_i64_be_at(&mut self, offset: usize) -> Result<i64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i64::from_be_bytes(buf))
|
Ok(i64::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i128_at(&mut self, offset: usize) -> Result<i128> {
|
fn peek_i128_at(&mut self, offset: usize) -> Result<i128> {
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 16];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i128::from_le_bytes(buf))
|
Ok(i128::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn peek_i128_be_at(&mut self, offset: usize) -> Result<i128> {
|
fn peek_i128_be_at(&mut self, offset: usize) -> Result<i128> {
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 16];
|
||||||
self.peek_extract_at(offset, &mut buf)?;
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i128::from_be_bytes(buf))
|
Ok(i128::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,6 +220,29 @@ pub trait Peek {
|
|||||||
}
|
}
|
||||||
Ok(vec)
|
Ok(vec)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn peek_and_equal(&mut self, data: &[u8]) -> Result<()> {
|
||||||
|
let mut buf = vec![0u8; data.len()];
|
||||||
|
self.peek_exact(&mut buf)?;
|
||||||
|
if buf != data {
|
||||||
|
return Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::InvalidData,
|
||||||
|
"Data does not match",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn peek_and_equal_at(&mut self, offset: usize, data: &[u8]) -> Result<()> {
|
||||||
|
let mut buf = vec![0u8; data.len()];
|
||||||
|
self.peek_exact_at(offset, &mut buf)?;
|
||||||
|
if buf != data {
|
||||||
|
return Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::InvalidData,
|
||||||
|
"Data does not match at offset",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Read + Seek> Peek for T {
|
impl<T: Read + Seek> Peek for T {
|
||||||
@@ -230,7 +253,7 @@ impl<T: Read + Seek> Peek for T {
|
|||||||
Ok(bytes_read)
|
Ok(bytes_read)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn peek_extract(&mut self, buf: &mut [u8]) -> Result<()> {
|
fn peek_exact(&mut self, buf: &mut [u8]) -> Result<()> {
|
||||||
let current_pos = self.stream_position()?;
|
let current_pos = self.stream_position()?;
|
||||||
self.read_exact(buf)?;
|
self.read_exact(buf)?;
|
||||||
self.seek(SeekFrom::Start(current_pos))?;
|
self.seek(SeekFrom::Start(current_pos))?;
|
||||||
@@ -245,7 +268,7 @@ impl<T: Read + Seek> Peek for T {
|
|||||||
Ok(bytes_read)
|
Ok(bytes_read)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn peek_extract_at(&mut self, offset: usize, buf: &mut [u8]) -> Result<()> {
|
fn peek_exact_at(&mut self, offset: usize, buf: &mut [u8]) -> Result<()> {
|
||||||
let current_pos = self.stream_position()?;
|
let current_pos = self.stream_position()?;
|
||||||
self.seek(SeekFrom::Start(offset as u64))?;
|
self.seek(SeekFrom::Start(offset as u64))?;
|
||||||
self.read_exact(buf)?;
|
self.read_exact(buf)?;
|
||||||
@@ -292,7 +315,7 @@ impl<T: Read + Seek> Peek for T {
|
|||||||
|
|
||||||
pub trait CPeek {
|
pub trait CPeek {
|
||||||
fn cpeek(&self, buf: &mut [u8]) -> Result<usize>;
|
fn cpeek(&self, buf: &mut [u8]) -> Result<usize>;
|
||||||
fn cpeek_extract(&self, buf: &mut [u8]) -> Result<()> {
|
fn cpeek_exact(&self, buf: &mut [u8]) -> Result<()> {
|
||||||
let bytes_read = self.cpeek(buf)?;
|
let bytes_read = self.cpeek(buf)?;
|
||||||
if bytes_read < buf.len() {
|
if bytes_read < buf.len() {
|
||||||
return Err(std::io::Error::new(
|
return Err(std::io::Error::new(
|
||||||
@@ -303,7 +326,7 @@ pub trait CPeek {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn cpeek_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize>;
|
fn cpeek_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize>;
|
||||||
fn cpeek_extract_at(&self, offset: usize, buf: &mut [u8]) -> Result<()> {
|
fn cpeek_exact_at(&self, offset: usize, buf: &mut [u8]) -> Result<()> {
|
||||||
let bytes_read = self.cpeek_at(offset, buf)?;
|
let bytes_read = self.cpeek_at(offset, buf)?;
|
||||||
if bytes_read < buf.len() {
|
if bytes_read < buf.len() {
|
||||||
return Err(std::io::Error::new(
|
return Err(std::io::Error::new(
|
||||||
@@ -321,190 +344,190 @@ pub trait CPeek {
|
|||||||
}
|
}
|
||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
fn cpeek_extract_at_vec(&self, offset: usize, len: usize) -> Result<Vec<u8>> {
|
fn cpeek_exact_at_vec(&self, offset: usize, len: usize) -> Result<Vec<u8>> {
|
||||||
let mut buf = vec![0u8; len];
|
let mut buf = vec![0u8; len];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cpeek_u8(&self) -> Result<u8> {
|
fn cpeek_u8(&self) -> Result<u8> {
|
||||||
let mut buf = [0u8; 1];
|
let mut buf = [0u8; 1];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(buf[0])
|
Ok(buf[0])
|
||||||
}
|
}
|
||||||
fn cpeek_u16(&self) -> Result<u16> {
|
fn cpeek_u16(&self) -> Result<u16> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(u16::from_le_bytes(buf))
|
Ok(u16::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_u16_be(&self) -> Result<u16> {
|
fn cpeek_u16_be(&self) -> Result<u16> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(u16::from_be_bytes(buf))
|
Ok(u16::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_u32(&self) -> Result<u32> {
|
fn cpeek_u32(&self) -> Result<u32> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(u32::from_le_bytes(buf))
|
Ok(u32::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_u32_be(&self) -> Result<u32> {
|
fn cpeek_u32_be(&self) -> Result<u32> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(u32::from_be_bytes(buf))
|
Ok(u32::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_u64(&self) -> Result<u64> {
|
fn cpeek_u64(&self) -> Result<u64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(u64::from_le_bytes(buf))
|
Ok(u64::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_u64_be(&self) -> Result<u64> {
|
fn cpeek_u64_be(&self) -> Result<u64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(u64::from_be_bytes(buf))
|
Ok(u64::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_u128(&self) -> Result<u128> {
|
fn cpeek_u128(&self) -> Result<u128> {
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 16];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(u128::from_le_bytes(buf))
|
Ok(u128::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_u128_be(&self) -> Result<u128> {
|
fn cpeek_u128_be(&self) -> Result<u128> {
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 16];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(u128::from_be_bytes(buf))
|
Ok(u128::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i8(&self) -> Result<i8> {
|
fn cpeek_i8(&self) -> Result<i8> {
|
||||||
let mut buf = [0u8; 1];
|
let mut buf = [0u8; 1];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(i8::from_le_bytes(buf))
|
Ok(i8::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i16(&self) -> Result<i16> {
|
fn cpeek_i16(&self) -> Result<i16> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(i16::from_le_bytes(buf))
|
Ok(i16::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i16_be(&self) -> Result<i16> {
|
fn cpeek_i16_be(&self) -> Result<i16> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(i16::from_be_bytes(buf))
|
Ok(i16::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i32(&self) -> Result<i32> {
|
fn cpeek_i32(&self) -> Result<i32> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(i32::from_le_bytes(buf))
|
Ok(i32::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i32_be(&self) -> Result<i32> {
|
fn cpeek_i32_be(&self) -> Result<i32> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(i32::from_be_bytes(buf))
|
Ok(i32::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i64(&self) -> Result<i64> {
|
fn cpeek_i64(&self) -> Result<i64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(i64::from_le_bytes(buf))
|
Ok(i64::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i64_be(&self) -> Result<i64> {
|
fn cpeek_i64_be(&self) -> Result<i64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(i64::from_be_bytes(buf))
|
Ok(i64::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i128(&self) -> Result<i128> {
|
fn cpeek_i128(&self) -> Result<i128> {
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 16];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(i128::from_le_bytes(buf))
|
Ok(i128::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i128_be(&self) -> Result<i128> {
|
fn cpeek_i128_be(&self) -> Result<i128> {
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 16];
|
||||||
self.cpeek_extract(&mut buf)?;
|
self.cpeek_exact(&mut buf)?;
|
||||||
Ok(i128::from_be_bytes(buf))
|
Ok(i128::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_u8_at(&self, offset: usize) -> Result<u8> {
|
fn cpeek_u8_at(&self, offset: usize) -> Result<u8> {
|
||||||
let mut buf = [0u8; 1];
|
let mut buf = [0u8; 1];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(buf[0])
|
Ok(buf[0])
|
||||||
}
|
}
|
||||||
fn cpeek_u16_at(&self, offset: usize) -> Result<u16> {
|
fn cpeek_u16_at(&self, offset: usize) -> Result<u16> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(u16::from_le_bytes(buf))
|
Ok(u16::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_u16_be_at(&self, offset: usize) -> Result<u16> {
|
fn cpeek_u16_be_at(&self, offset: usize) -> Result<u16> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(u16::from_be_bytes(buf))
|
Ok(u16::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_u32_at(&self, offset: usize) -> Result<u32> {
|
fn cpeek_u32_at(&self, offset: usize) -> Result<u32> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(u32::from_le_bytes(buf))
|
Ok(u32::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_u32_be_at(&self, offset: usize) -> Result<u32> {
|
fn cpeek_u32_be_at(&self, offset: usize) -> Result<u32> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(u32::from_be_bytes(buf))
|
Ok(u32::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_u64_at(&self, offset: usize) -> Result<u64> {
|
fn cpeek_u64_at(&self, offset: usize) -> Result<u64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(u64::from_le_bytes(buf))
|
Ok(u64::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_u64_be_at(&self, offset: usize) -> Result<u64> {
|
fn cpeek_u64_be_at(&self, offset: usize) -> Result<u64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(u64::from_be_bytes(buf))
|
Ok(u64::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_u128_at(&self, offset: usize) -> Result<u128> {
|
fn cpeek_u128_at(&self, offset: usize) -> Result<u128> {
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 16];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(u128::from_le_bytes(buf))
|
Ok(u128::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_u128_be_at(&self, offset: usize) -> Result<u128> {
|
fn cpeek_u128_be_at(&self, offset: usize) -> Result<u128> {
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 16];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(u128::from_be_bytes(buf))
|
Ok(u128::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i8_at(&self, offset: usize) -> Result<i8> {
|
fn cpeek_i8_at(&self, offset: usize) -> Result<i8> {
|
||||||
let mut buf = [0u8; 1];
|
let mut buf = [0u8; 1];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i8::from_le_bytes(buf))
|
Ok(i8::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i16_at(&self, offset: usize) -> Result<i16> {
|
fn cpeek_i16_at(&self, offset: usize) -> Result<i16> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i16::from_le_bytes(buf))
|
Ok(i16::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i16_be_at(&self, offset: usize) -> Result<i16> {
|
fn cpeek_i16_be_at(&self, offset: usize) -> Result<i16> {
|
||||||
let mut buf = [0u8; 2];
|
let mut buf = [0u8; 2];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i16::from_be_bytes(buf))
|
Ok(i16::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i32_at(&self, offset: usize) -> Result<i32> {
|
fn cpeek_i32_at(&self, offset: usize) -> Result<i32> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i32::from_le_bytes(buf))
|
Ok(i32::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i32_be_at(&self, offset: usize) -> Result<i32> {
|
fn cpeek_i32_be_at(&self, offset: usize) -> Result<i32> {
|
||||||
let mut buf = [0u8; 4];
|
let mut buf = [0u8; 4];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i32::from_be_bytes(buf))
|
Ok(i32::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i64_at(&self, offset: usize) -> Result<i64> {
|
fn cpeek_i64_at(&self, offset: usize) -> Result<i64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i64::from_le_bytes(buf))
|
Ok(i64::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i64_be_at(&self, offset: usize) -> Result<i64> {
|
fn cpeek_i64_be_at(&self, offset: usize) -> Result<i64> {
|
||||||
let mut buf = [0u8; 8];
|
let mut buf = [0u8; 8];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i64::from_be_bytes(buf))
|
Ok(i64::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i128_at(&self, offset: usize) -> Result<i128> {
|
fn cpeek_i128_at(&self, offset: usize) -> Result<i128> {
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 16];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i128::from_le_bytes(buf))
|
Ok(i128::from_le_bytes(buf))
|
||||||
}
|
}
|
||||||
fn cpeek_i128_be_at(&self, offset: usize) -> Result<i128> {
|
fn cpeek_i128_be_at(&self, offset: usize) -> Result<i128> {
|
||||||
let mut buf = [0u8; 16];
|
let mut buf = [0u8; 16];
|
||||||
self.cpeek_extract_at(offset, &mut buf)?;
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
Ok(i128::from_be_bytes(buf))
|
Ok(i128::from_be_bytes(buf))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -518,6 +541,29 @@ pub trait CPeek {
|
|||||||
}
|
}
|
||||||
CString::new(buf).map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
|
CString::new(buf).map_err(|e| std::io::Error::new(std::io::ErrorKind::InvalidData, e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn cpeek_and_equal(&self, data: &[u8]) -> Result<()> {
|
||||||
|
let mut buf = vec![0u8; data.len()];
|
||||||
|
self.cpeek_exact(&mut buf)?;
|
||||||
|
if buf != data {
|
||||||
|
return Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::InvalidData,
|
||||||
|
"Data does not match",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn cpeek_and_equal_at(&self, offset: usize, data: &[u8]) -> Result<()> {
|
||||||
|
let mut buf = vec![0u8; data.len()];
|
||||||
|
self.cpeek_exact_at(offset, &mut buf)?;
|
||||||
|
if buf != data {
|
||||||
|
return Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::InvalidData,
|
||||||
|
"Data does not match at offset",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Peek> CPeek for Mutex<T> {
|
impl<T: Peek> CPeek for Mutex<T> {
|
||||||
@@ -560,6 +606,8 @@ pub trait ReadExt {
|
|||||||
fn read_fstring(&mut self, len: usize, encoding: Encoding, trim: bool) -> Result<String>;
|
fn read_fstring(&mut self, len: usize, encoding: Encoding, trim: bool) -> Result<String>;
|
||||||
|
|
||||||
fn read_exact_vec(&mut self, len: usize) -> Result<Vec<u8>>;
|
fn read_exact_vec(&mut self, len: usize) -> Result<Vec<u8>>;
|
||||||
|
|
||||||
|
fn read_and_equal(&mut self, data: &[u8]) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Read> ReadExt for T {
|
impl<T: Read> ReadExt for T {
|
||||||
@@ -685,6 +733,18 @@ impl<T: Read> ReadExt for T {
|
|||||||
self.read_exact(&mut buf)?;
|
self.read_exact(&mut buf)?;
|
||||||
Ok(buf)
|
Ok(buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn read_and_equal(&mut self, data: &[u8]) -> Result<()> {
|
||||||
|
let mut buf = vec![0u8; data.len()];
|
||||||
|
self.read_exact(&mut buf)?;
|
||||||
|
if buf != data {
|
||||||
|
return Err(std::io::Error::new(
|
||||||
|
std::io::ErrorKind::InvalidData,
|
||||||
|
"Data does not match",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait WriteExt {
|
pub trait WriteExt {
|
||||||
@@ -1047,6 +1107,9 @@ impl<'a> CPeek for MemReaderRef<'a> {
|
|||||||
|
|
||||||
fn cpeek_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
|
fn cpeek_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
|
||||||
let len = self.data.len();
|
let len = self.data.len();
|
||||||
|
if offset >= len {
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
let bytes_to_read = std::cmp::min(buf.len(), len - offset);
|
let bytes_to_read = std::cmp::min(buf.len(), len - offset);
|
||||||
buf[..bytes_to_read].copy_from_slice(&self.data[offset..offset + bytes_to_read]);
|
buf[..bytes_to_read].copy_from_slice(&self.data[offset..offset + bytes_to_read]);
|
||||||
Ok(bytes_to_read)
|
Ok(bytes_to_read)
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ impl Script for BgiImage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.data.cpeek_extract_at(0x10, &mut data)?;
|
self.data.cpeek_exact_at(0x10, &mut data)?;
|
||||||
}
|
}
|
||||||
Ok(ImageData {
|
Ok(ImageData {
|
||||||
width: self.width,
|
width: self.width,
|
||||||
|
|||||||
@@ -138,9 +138,7 @@ impl<T: Read + Seek> Read for Entry<T> {
|
|||||||
format!("Failed to lock mutex: {}", e),
|
format!("Failed to lock mutex: {}", e),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
reader.seek(SeekFrom::Start(
|
reader.seek(SeekFrom::Start(self.header.offset as u64 + self.pos as u64))?;
|
||||||
self.header.offset as u64 + self.pos as u64,
|
|
||||||
))?;
|
|
||||||
let bytes_read = buf.len().min(self.header.size as usize - self.pos);
|
let bytes_read = buf.len().min(self.header.size as usize - self.pos);
|
||||||
if bytes_read == 0 {
|
if bytes_read == 0 {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
@@ -302,15 +300,15 @@ impl<T: Read + Seek + std::fmt::Debug> CSIntArc<T> {
|
|||||||
let current_offset = reader.stream_position()?;
|
let current_offset = reader.stream_position()?;
|
||||||
let offset = reader.read_u32()?;
|
let offset = reader.read_u32()?;
|
||||||
let size = reader.read_u32()?;
|
let size = reader.read_u32()?;
|
||||||
if offset as u64 <= current_offset || !((offset as u64) < file_size && size as u64 <= file_size && offset as u64 <= file_size as u64 - size as u64) {
|
if offset as u64 <= current_offset
|
||||||
|
|| !((offset as u64) < file_size
|
||||||
|
&& size as u64 <= file_size
|
||||||
|
&& offset as u64 <= file_size as u64 - size as u64)
|
||||||
|
{
|
||||||
entries.clear();
|
entries.clear();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let entry = CSIntFileHeader {
|
let entry = CSIntFileHeader { name, offset, size };
|
||||||
name,
|
|
||||||
offset,
|
|
||||||
size,
|
|
||||||
};
|
|
||||||
entries.push(entry);
|
entries.push(entry);
|
||||||
}
|
}
|
||||||
if !entries.is_empty() {
|
if !entries.is_empty() {
|
||||||
@@ -378,14 +376,12 @@ impl<T: Read + Seek + std::fmt::Debug + 'static> Script for CSIntArc<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn iter_archive<'a>(&'a mut self) -> Result<Box<dyn Iterator<Item = Result<String>> + 'a>> {
|
fn iter_archive<'a>(&'a mut self) -> Result<Box<dyn Iterator<Item = Result<String>> + 'a>> {
|
||||||
Ok(Box::new(
|
Ok(Box::new(self.entries.iter().map(|e| Ok(e.name.clone()))))
|
||||||
self.entries.iter().map(|e| Ok(e.name.clone())),
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_archive_mut<'a>(
|
fn iter_archive_mut<'a>(
|
||||||
&'a mut self,
|
&'a mut self,
|
||||||
) -> Result<Box<dyn Iterator<Item = Result<Box<dyn ArchiveContent>>> + 'a>> {
|
) -> Result<Box<dyn Iterator<Item = Result<Box<dyn ArchiveContent>>> + 'a>> {
|
||||||
Ok(Box::new(CSIntArcIter {
|
Ok(Box::new(CSIntArcIter {
|
||||||
entries: self.entries.iter(),
|
entries: self.entries.iter(),
|
||||||
reader: self.reader.clone(),
|
reader: self.reader.clone(),
|
||||||
@@ -423,10 +419,12 @@ impl<'a, T: Iterator<Item = &'a CSIntFileHeader>, R: Read + Seek + 'static> Iter
|
|||||||
entry.pos = 0;
|
entry.pos = 0;
|
||||||
for i in 0..data.len() / 8 {
|
for i in 0..data.len() / 8 {
|
||||||
let j = i * 8;
|
let j = i * 8;
|
||||||
let l = data[j] as u32 | (data[j + 1] as u32) << 8
|
let l = data[j] as u32
|
||||||
|
| (data[j + 1] as u32) << 8
|
||||||
| (data[j + 2] as u32) << 16
|
| (data[j + 2] as u32) << 16
|
||||||
| (data[j + 3] as u32) << 24;
|
| (data[j + 3] as u32) << 24;
|
||||||
let r = data[j + 4] as u32 | (data[j + 5] as u32) << 8
|
let r = data[j + 4] as u32
|
||||||
|
| (data[j + 5] as u32) << 8
|
||||||
| (data[j + 6] as u32) << 16
|
| (data[j + 6] as u32) << 16
|
||||||
| (data[j + 7] as u32) << 24;
|
| (data[j + 7] as u32) << 24;
|
||||||
let result = encrypt.decrypt([l, r]);
|
let result = encrypt.decrypt([l, r]);
|
||||||
|
|||||||
309
src/scripts/cat_system/image/hg3.rs
Normal file
309
src/scripts/cat_system/image/hg3.rs
Normal file
@@ -0,0 +1,309 @@
|
|||||||
|
use crate::ext::io::*;
|
||||||
|
use crate::scripts::base::*;
|
||||||
|
use crate::types::*;
|
||||||
|
use crate::utils::bit_stream::*;
|
||||||
|
use crate::utils::img::*;
|
||||||
|
use crate::utils::struct_pack::*;
|
||||||
|
use anyhow::Result;
|
||||||
|
use flate2::{Decompress, FlushDecompress};
|
||||||
|
use msg_tool_macro::*;
|
||||||
|
use std::io::{Read, Seek, Write};
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Hg3ImageBuilder {}
|
||||||
|
|
||||||
|
impl Hg3ImageBuilder {
|
||||||
|
pub const fn new() -> Self {
|
||||||
|
Hg3ImageBuilder {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ScriptBuilder for Hg3ImageBuilder {
|
||||||
|
fn default_encoding(&self) -> Encoding {
|
||||||
|
Encoding::Cp932
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_script(
|
||||||
|
&self,
|
||||||
|
data: Vec<u8>,
|
||||||
|
_filename: &str,
|
||||||
|
_encoding: Encoding,
|
||||||
|
_archive_encoding: Encoding,
|
||||||
|
config: &ExtraConfig,
|
||||||
|
) -> Result<Box<dyn Script>> {
|
||||||
|
Ok(Box::new(Hg3Image::new(data, config)?))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extensions(&self) -> &'static [&'static str] {
|
||||||
|
&["hg3"]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn script_type(&self) -> &'static ScriptType {
|
||||||
|
&ScriptType::CatSystemHg3
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_this_format(&self, _filename: &str, buf: &[u8], buf_len: usize) -> Option<u8> {
|
||||||
|
if buf_len >= 4 && &buf[0..4] == b"HG-3" {
|
||||||
|
return Some(255);
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, StructPack, StructUnpack)]
|
||||||
|
struct Hg3Entry {
|
||||||
|
header_size: u32,
|
||||||
|
_unk: u32,
|
||||||
|
width: u32,
|
||||||
|
height: u32,
|
||||||
|
bpp: u32,
|
||||||
|
offset_x: u32,
|
||||||
|
offset_y: u32,
|
||||||
|
canvas_width: u32,
|
||||||
|
canvas_height: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Hg3Image {
|
||||||
|
data: MemReader,
|
||||||
|
entries: Vec<(Hg3Entry, usize, usize)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Hg3Image {
|
||||||
|
pub fn new(buf: Vec<u8>, _config: &ExtraConfig) -> Result<Self> {
|
||||||
|
let mut reader = MemReader::new(buf);
|
||||||
|
let mut magic = [0u8; 4];
|
||||||
|
reader.read_exact(&mut magic)?;
|
||||||
|
if &magic != b"HG-3" {
|
||||||
|
return Err(anyhow::anyhow!("Invalid HG-3 image format"));
|
||||||
|
}
|
||||||
|
let mut offset = 0xC;
|
||||||
|
let mut entries = Vec::new();
|
||||||
|
let len = reader.data.len();
|
||||||
|
while offset + 0x14 < len && reader.cpeek_and_equal_at(offset + 8, b"stdinfo").is_ok() {
|
||||||
|
let mut section_size = reader.cpeek_u32_at(offset)?;
|
||||||
|
if section_size == 0 {
|
||||||
|
section_size = (len - offset as usize) as u32;
|
||||||
|
}
|
||||||
|
let stdinfo_size = reader.cpeek_u32_at(offset + 0x10)?;
|
||||||
|
if reader
|
||||||
|
.cpeek_and_equal_at(offset + 8 + stdinfo_size as usize, b"img")
|
||||||
|
.is_ok()
|
||||||
|
{
|
||||||
|
reader.pos = offset + 16;
|
||||||
|
let entry = Hg3Entry::unpack(&mut reader, false, Encoding::Cp932)?;
|
||||||
|
entries.push((entry, offset + 8, section_size as usize - 8));
|
||||||
|
}
|
||||||
|
offset += section_size as usize;
|
||||||
|
}
|
||||||
|
if entries.is_empty() {
|
||||||
|
return Err(anyhow::anyhow!("No valid entries found in HG-3 image"));
|
||||||
|
}
|
||||||
|
Ok(Hg3Image {
|
||||||
|
data: reader,
|
||||||
|
entries,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Script for Hg3Image {
|
||||||
|
fn default_output_script_type(&self) -> OutputScriptType {
|
||||||
|
OutputScriptType::Json
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_format_type(&self) -> FormatOptions {
|
||||||
|
FormatOptions::None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_image(&self) -> bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn export_image(&self) -> Result<ImageData> {
|
||||||
|
if self.entries.len() > 1 {
|
||||||
|
eprintln!(
|
||||||
|
"WARN: There are multiple entries in the HG-3 image, only the first one will be exported."
|
||||||
|
);
|
||||||
|
crate::COUNTER.inc_warning();
|
||||||
|
}
|
||||||
|
let (entry, offset, size) = &self.entries[0];
|
||||||
|
let data = &self.data.data[*offset..*offset + *size];
|
||||||
|
let reader = Hg3Reader {
|
||||||
|
m_input: MemReaderRef::new(data),
|
||||||
|
m_info: entry.clone(),
|
||||||
|
m_pixel_size: entry.bpp / 8,
|
||||||
|
};
|
||||||
|
Ok(reader.unpack()?)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Hg3Reader<'a> {
|
||||||
|
m_input: MemReaderRef<'a>,
|
||||||
|
m_info: Hg3Entry,
|
||||||
|
m_pixel_size: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> Hg3Reader<'a> {
|
||||||
|
pub fn unpack_stream(
|
||||||
|
&mut self,
|
||||||
|
data_offset: usize,
|
||||||
|
data_packed: usize,
|
||||||
|
data_unpacked: usize,
|
||||||
|
ctl_packed: usize,
|
||||||
|
ctl_unpacked: usize,
|
||||||
|
) -> Result<Vec<u8>> {
|
||||||
|
let ctl_offset = data_offset + data_packed;
|
||||||
|
let mut data = Vec::with_capacity(data_unpacked);
|
||||||
|
data.resize(data_unpacked, 0);
|
||||||
|
let z = &self.m_input.data[data_offset..data_offset + data_packed];
|
||||||
|
let mut decompressor = Decompress::new(true);
|
||||||
|
decompressor.decompress(z, &mut data, FlushDecompress::Finish)?;
|
||||||
|
let z = &self.m_input.data[ctl_offset..ctl_offset + ctl_packed];
|
||||||
|
let mut ctl = Vec::with_capacity(ctl_unpacked);
|
||||||
|
ctl.resize(ctl_unpacked, 0);
|
||||||
|
let mut decompressor = Decompress::new(true);
|
||||||
|
decompressor.decompress(z, &mut ctl, FlushDecompress::Finish)?;
|
||||||
|
let mut bits = LsbBitStream::new(MemReaderRef::new(&ctl));
|
||||||
|
let mut copy = bits.get_next_bit()?;
|
||||||
|
let output_size = Self::get_bit_count(&mut bits)? as usize;
|
||||||
|
let mut output = Vec::with_capacity(output_size);
|
||||||
|
output.resize(output_size, 0);
|
||||||
|
let mut src = 0;
|
||||||
|
let mut dst = 0;
|
||||||
|
while dst < output_size {
|
||||||
|
let count = Self::get_bit_count(&mut bits)? as usize;
|
||||||
|
if copy {
|
||||||
|
output[dst..dst + count].copy_from_slice(&data[src..src + count]);
|
||||||
|
src += count;
|
||||||
|
}
|
||||||
|
dst += count;
|
||||||
|
copy = !copy;
|
||||||
|
}
|
||||||
|
Ok(self.apply_delta(&output))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_bit_count(bits: &mut LsbBitStream<MemReaderRef<'_>>) -> Result<u32> {
|
||||||
|
let mut n = 0;
|
||||||
|
while !bits.get_next_bit()? {
|
||||||
|
n += 1;
|
||||||
|
if n >= 0x20 {
|
||||||
|
return Err(anyhow::anyhow!("Overflow at HG-3 Reader."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut value = 1;
|
||||||
|
for _ in 0..n {
|
||||||
|
value = (value << 1) | (bits.get_next_bit()? as u32);
|
||||||
|
}
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_value(mut val: u8) -> u8 {
|
||||||
|
let carry = val & 1 != 0;
|
||||||
|
val >>= 1;
|
||||||
|
if carry { val ^ 0xff } else { val }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn apply_delta(&self, pixels: &[u8]) -> Vec<u8> {
|
||||||
|
let mut table = [[0u32; 0x100]; 4];
|
||||||
|
for i in 0..0x100u32 {
|
||||||
|
let mut val = i & 0xC0;
|
||||||
|
val <<= 6;
|
||||||
|
val |= i & 0x30;
|
||||||
|
val <<= 6;
|
||||||
|
val |= i & 0x0C;
|
||||||
|
val <<= 6;
|
||||||
|
val |= i & 0x03;
|
||||||
|
table[0][i as usize] = val << 6;
|
||||||
|
table[1][i as usize] = val << 4;
|
||||||
|
table[2][i as usize] = val << 2;
|
||||||
|
table[3][i as usize] = val;
|
||||||
|
}
|
||||||
|
let pxl_len = pixels.len();
|
||||||
|
let plane_size = pxl_len / 4;
|
||||||
|
let mut plane0 = 0;
|
||||||
|
let mut plane1 = plane0 + plane_size;
|
||||||
|
let mut plane2 = plane1 + plane_size;
|
||||||
|
let mut plane3 = plane2 + plane_size;
|
||||||
|
let mut output = Vec::with_capacity(pxl_len);
|
||||||
|
output.resize(pxl_len, 0);
|
||||||
|
let mut dst = 0;
|
||||||
|
while dst < pxl_len {
|
||||||
|
let val = table[0][pixels[plane0] as usize]
|
||||||
|
| table[1][pixels[plane1] as usize]
|
||||||
|
| table[2][pixels[plane2] as usize]
|
||||||
|
| table[3][pixels[plane3] as usize];
|
||||||
|
plane0 += 1;
|
||||||
|
plane1 += 1;
|
||||||
|
plane2 += 1;
|
||||||
|
plane3 += 1;
|
||||||
|
output[dst] = Self::convert_value(val as u8);
|
||||||
|
dst += 1;
|
||||||
|
output[dst] = Self::convert_value((val >> 8) as u8);
|
||||||
|
dst += 1;
|
||||||
|
output[dst] = Self::convert_value((val >> 16) as u8);
|
||||||
|
dst += 1;
|
||||||
|
output[dst] = Self::convert_value((val >> 24) as u8);
|
||||||
|
dst += 1;
|
||||||
|
}
|
||||||
|
let stride = self.m_info.width * self.m_pixel_size;
|
||||||
|
for x in self.m_pixel_size..stride {
|
||||||
|
output[x as usize] =
|
||||||
|
output[x as usize].wrapping_add(output[x as usize - self.m_pixel_size as usize]);
|
||||||
|
}
|
||||||
|
let mut prev = 0;
|
||||||
|
for _ in 1..self.m_info.height {
|
||||||
|
let line = prev + stride;
|
||||||
|
for x in 0..stride {
|
||||||
|
output[line as usize + x as usize] = output[line as usize + x as usize]
|
||||||
|
.wrapping_add(output[prev as usize + x as usize]);
|
||||||
|
}
|
||||||
|
prev = line;
|
||||||
|
}
|
||||||
|
output
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unpack(mut self) -> Result<ImageData> {
|
||||||
|
self.m_input.pos = self.m_info.header_size as usize;
|
||||||
|
let mut image_type = [0; 8];
|
||||||
|
self.m_input.read_exact(&mut image_type)?;
|
||||||
|
if &image_type == b"img0000\0" {
|
||||||
|
return self.unpack_img0000();
|
||||||
|
} else {
|
||||||
|
return Err(anyhow::anyhow!("Unsupported image type: {:?}", image_type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unpack_img0000(&mut self) -> Result<ImageData> {
|
||||||
|
self.m_input.pos = self.m_info.header_size as usize + 0x18;
|
||||||
|
let packed_data_size = self.m_input.read_u32()?;
|
||||||
|
let data_size = self.m_input.read_u32()?;
|
||||||
|
let ctl_packed_size = self.m_input.read_u32()?;
|
||||||
|
let ctl_size = self.m_input.read_u32()?;
|
||||||
|
let data = self.unpack_stream(
|
||||||
|
self.m_info.header_size as usize + 0x28,
|
||||||
|
packed_data_size as usize,
|
||||||
|
data_size as usize,
|
||||||
|
ctl_packed_size as usize,
|
||||||
|
ctl_size as usize,
|
||||||
|
)?;
|
||||||
|
let fmt = match self.m_info.bpp {
|
||||||
|
24 => ImageColorType::Bgr,
|
||||||
|
32 => ImageColorType::Bgra,
|
||||||
|
_ => {
|
||||||
|
return Err(anyhow::anyhow!(
|
||||||
|
"Unsupported BPP: {} in HG-3 image",
|
||||||
|
self.m_info.bpp
|
||||||
|
));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let mut img = ImageData {
|
||||||
|
width: self.m_info.width,
|
||||||
|
height: self.m_info.height,
|
||||||
|
color_type: fmt,
|
||||||
|
depth: 8,
|
||||||
|
data,
|
||||||
|
};
|
||||||
|
flip_image(&mut img)?;
|
||||||
|
Ok(img)
|
||||||
|
}
|
||||||
|
}
|
||||||
1
src/scripts/cat_system/image/mod.rs
Normal file
1
src/scripts/cat_system/image/mod.rs
Normal file
@@ -0,0 +1 @@
|
|||||||
|
pub mod hg3;
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
#[cfg(feature = "cat-system-arc")]
|
#[cfg(feature = "cat-system-arc")]
|
||||||
pub mod archive;
|
pub mod archive;
|
||||||
|
#[cfg(feature = "cat-system-img")]
|
||||||
|
pub mod image;
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ lazy_static::lazy_static! {
|
|||||||
Box::new(yaneurao::itufuru::archive::ItufuruArchiveBuilder::new()),
|
Box::new(yaneurao::itufuru::archive::ItufuruArchiveBuilder::new()),
|
||||||
#[cfg(feature = "cat-system-arc")]
|
#[cfg(feature = "cat-system-arc")]
|
||||||
Box::new(cat_system::archive::int::CSIntArcBuilder::new()),
|
Box::new(cat_system::archive::int::CSIntArcBuilder::new()),
|
||||||
|
#[cfg(feature = "cat-system-img")]
|
||||||
|
Box::new(cat_system::image::hg3::Hg3ImageBuilder::new()),
|
||||||
];
|
];
|
||||||
pub static ref ALL_EXTS: Vec<String> =
|
pub static ref ALL_EXTS: Vec<String> =
|
||||||
BUILDER.iter().flat_map(|b| b.extensions()).map(|s| s.to_string()).collect();
|
BUILDER.iter().flat_map(|b| b.extensions()).map(|s| s.to_string()).collect();
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ impl<'a, T: Iterator<Item = &'a CustomHeader>, R: Read + Seek> Iterator
|
|||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if let Some(entry) = self.entries.next() {
|
if let Some(entry) = self.entries.next() {
|
||||||
let file_offset = entry.offset as usize;
|
let file_offset = entry.offset as usize;
|
||||||
match self.reader.peek_extract_at_vec(
|
match self.reader.peek_exact_at_vec(
|
||||||
file_offset + self.first_file_offset as usize,
|
file_offset + self.first_file_offset as usize,
|
||||||
entry.size as usize,
|
entry.size as usize,
|
||||||
) {
|
) {
|
||||||
|
|||||||
@@ -245,6 +245,9 @@ pub enum ScriptType {
|
|||||||
#[cfg(feature = "cat-system-arc")]
|
#[cfg(feature = "cat-system-arc")]
|
||||||
/// CatSystem2 engine archive
|
/// CatSystem2 engine archive
|
||||||
CatSystemInt,
|
CatSystemInt,
|
||||||
|
#[cfg(feature = "cat-system-img")]
|
||||||
|
/// CatSystem2 engine image
|
||||||
|
CatSystemHg3,
|
||||||
#[cfg(feature = "circus")]
|
#[cfg(feature = "circus")]
|
||||||
/// Circus MES script
|
/// Circus MES script
|
||||||
Circus,
|
Circus,
|
||||||
|
|||||||
@@ -85,3 +85,51 @@ impl<'a, T: Write> MsbBitWriter<'a, T> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct LsbBitStream<T: Read> {
|
||||||
|
pub m_input: T,
|
||||||
|
m_bits: u32,
|
||||||
|
pub m_cached_bits: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Read> LsbBitStream<T> {
|
||||||
|
pub fn new(input: T) -> Self {
|
||||||
|
LsbBitStream {
|
||||||
|
m_input: input,
|
||||||
|
m_bits: 0,
|
||||||
|
m_cached_bits: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_bits(&mut self, mut count: u32) -> Result<u32> {
|
||||||
|
if self.m_cached_bits >= count {
|
||||||
|
let mask = (1 << count) - 1;
|
||||||
|
let value = self.m_bits & mask;
|
||||||
|
self.m_bits >>= count;
|
||||||
|
self.m_cached_bits -= count;
|
||||||
|
Ok(value)
|
||||||
|
} else {
|
||||||
|
let mut value = self.m_bits & ((1 << self.m_cached_bits) - 1);
|
||||||
|
count -= self.m_cached_bits;
|
||||||
|
let mut shift = self.m_cached_bits;
|
||||||
|
self.m_cached_bits = 0;
|
||||||
|
while count >= 8 {
|
||||||
|
let b = self.m_input.read_u8()?;
|
||||||
|
value |= (b as u32) << shift;
|
||||||
|
shift += 8;
|
||||||
|
count -= 8;
|
||||||
|
}
|
||||||
|
if count > 0 {
|
||||||
|
let b = self.m_input.read_u8()?;
|
||||||
|
value |= ((b as u32) & ((1 << count) - 1)) << shift;
|
||||||
|
self.m_bits = b as u32 >> count;
|
||||||
|
self.m_cached_bits = 8 - count;
|
||||||
|
}
|
||||||
|
Ok(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_next_bit(&mut self) -> Result<bool> {
|
||||||
|
Ok(self.get_bits(1)? == 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -160,3 +160,26 @@ pub fn decode_img(typ: ImageOutputType, filename: &str) -> Result<ImageData> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn flip_image(data: &mut ImageData) -> Result<()> {
|
||||||
|
if data.height <= 1 {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let row_size = data.data.len() / data.height as usize;
|
||||||
|
if row_size == 0 {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut i = 0;
|
||||||
|
let mut j = data.height as usize - 1;
|
||||||
|
while i < j {
|
||||||
|
let (top, bottom) = data.data.split_at_mut(j * row_size);
|
||||||
|
let top_row = &mut top[i * row_size..i * row_size + row_size];
|
||||||
|
let bottom_row = &mut bottom[0..row_size];
|
||||||
|
top_row.swap_with_slice(bottom_row);
|
||||||
|
i += 1;
|
||||||
|
j -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user