aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--Cargo.lock230
-rw-r--r--Cargo.toml1
-rw-r--r--exporter/Cargo.toml1
-rw-r--r--exporter/src/bin/audioclips.rs64
-rw-r--r--src/classes/audio_clip.rs93
-rw-r--r--src/classes/cubemap.rs2
-rw-r--r--src/classes/mesh.rs2
-rw-r--r--src/classes/mod.rs6
-rw-r--r--src/classes/streamed_resource.rs50
-rw-r--r--src/classes/streaming_info.rs (renamed from src/classes/streaminginfo.rs)3
-rw-r--r--src/classes/texture2d.rs2
-rw-r--r--src/object/read.rs1
13 files changed, 447 insertions, 11 deletions
diff --git a/.gitignore b/.gitignore
index faa49a3..835805d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
-/target
+/target*
+/perf*
/samples
/src/bin/debug.rs
diff --git a/Cargo.lock b/Cargo.lock
index 7279d7d..48b8fb9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -80,12 +80,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
[[package]]
+name = "aotuv_lancer_vorbis_sys"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c22da1eae146e1ac2956da45bd1856b2f9ad788e6f7af535b861df497d726a1"
+dependencies = [
+ "cc",
+ "ogg_next_sys",
+]
+
+[[package]]
name = "arbitrary"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
[[package]]
+name = "arbitrary-int"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "825297538d77367557b912770ca3083f778a196054b3ee63b22673c4a3cae0a5"
+
+[[package]]
name = "arg_enum_proc_macro"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -138,6 +154,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]]
+name = "bilge"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc707ed8ebf81de5cd6c7f48f54b4c8621760926cdf35a57000747c512e67b57"
+dependencies = [
+ "arbitrary-int",
+ "bilge-impl",
+]
+
+[[package]]
+name = "bilge-impl"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "feb11e002038ad243af39c2068c8a72bcf147acf05025dcdb916fcc000adb2d8"
+dependencies = [
+ "itertools 0.11.0",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "bit_field"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -306,6 +345,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
+name = "errno"
+version = "0.3.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
+dependencies = [
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
name = "exporter"
version = "0.1.0"
dependencies = [
@@ -315,6 +364,7 @@ dependencies = [
"glam",
"gltf",
"gltf-json",
+ "hound",
"log",
"serde_json",
"serde_yml",
@@ -356,6 +406,19 @@ dependencies = [
]
[[package]]
+name = "fsbex"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "362e570e47b98ed9966c238a72cb0b64120f9dc6d44373c35b27ae2223ca7dcc"
+dependencies = [
+ "bilge",
+ "lewton",
+ "phf",
+ "tap",
+ "vorbis_rs",
+]
+
+[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -447,6 +510,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
+name = "hound"
+version = "3.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62adaabb884c94955b19907d60019f4e145d091c75345379e70d1ee696f7854f"
+
+[[package]]
name = "humansize"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -529,6 +598,15 @@ checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itertools"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itertools"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
@@ -594,6 +672,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8"
[[package]]
+name = "lewton"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "777b48df9aaab155475a83a7df3070395ea1ac6902f5cd062b8f2b028075c030"
+dependencies = [
+ "byteorder 1.5.0",
+ "tinyvec",
+]
+
+[[package]]
name = "libc"
version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -763,6 +851,15 @@ dependencies = [
]
[[package]]
+name = "ogg_next_sys"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c990730c2782b922815753a62af535e4205267df190dfbd8aa5d74e11d7dcc3"
+dependencies = [
+ "cc",
+]
+
+[[package]]
name = "once_cell"
version = "1.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -775,6 +872,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
+name = "phf"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078"
+dependencies = [
+ "phf_macros",
+ "phf_shared",
+]
+
+[[package]]
+name = "phf_generator"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d"
+dependencies = [
+ "phf_shared",
+ "rand",
+]
+
+[[package]]
+name = "phf_macros"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216"
+dependencies = [
+ "phf_generator",
+ "phf_shared",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "phf_shared"
+version = "0.11.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5"
+dependencies = [
+ "siphasher",
+]
+
+[[package]]
name = "pkg-config"
version = "0.3.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -818,6 +957,29 @@ dependencies = [
]
[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
name = "proc-macro2"
version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -913,7 +1075,7 @@ dependencies = [
"built",
"cfg-if",
"interpolate_name",
- "itertools",
+ "itertools 0.12.1",
"libc",
"libfuzzer-sys",
"log",
@@ -929,7 +1091,7 @@ dependencies = [
"rand_chacha",
"simd_helpers",
"system-deps",
- "thiserror",
+ "thiserror 1.0.69",
"v_frame",
"wasm-bindgen",
]
@@ -1094,6 +1256,12 @@ dependencies = [
]
[[package]]
+name = "siphasher"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d"
+
+[[package]]
name = "smallvec"
version = "1.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1130,6 +1298,12 @@ dependencies = [
]
[[package]]
+name = "tap"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
+
+[[package]]
name = "target-lexicon"
version = "0.12.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1158,7 +1332,16 @@ version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
- "thiserror-impl",
+ "thiserror-impl 1.0.69",
+]
+
+[[package]]
+name = "thiserror"
+version = "2.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
+dependencies = [
+ "thiserror-impl 2.0.12",
]
[[package]]
@@ -1173,6 +1356,17 @@ dependencies = [
]
[[package]]
+name = "thiserror-impl"
+version = "2.0.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "tiff"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1184,6 +1378,21 @@ dependencies = [
]
[[package]]
+name = "tinyvec"
+version = "1.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71"
+dependencies = [
+ "tinyvec_macros",
+]
+
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
+[[package]]
name = "toml"
version = "0.8.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1239,6 +1448,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"env_logger",
+ "fsbex",
"glam",
"humansize",
"image",
@@ -1287,6 +1497,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
+name = "vorbis_rs"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "874075ad757c0f6031d4706ed75703a9ba6c711164a0b1dab55af86800cd618f"
+dependencies = [
+ "aotuv_lancer_vorbis_sys",
+ "errno",
+ "getrandom",
+ "ogg_next_sys",
+ "thiserror 2.0.12",
+ "tinyvec",
+]
+
+[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 702632a..462a69c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,3 +21,4 @@ glam = { version = "0.30.0", features = ["serde"] }
texpresso = "2.0.1"
image = "0.25.5"
texture2ddecoder = { git = "https://github.com/UniversalGameExtraction/texture2ddecoder", rev = "d2b4653fda298f1da39917da86bc509b17879808" }
+fsbex = "0.3.0"
diff --git a/exporter/Cargo.toml b/exporter/Cargo.toml
index 02eca5c..12fe97f 100644
--- a/exporter/Cargo.toml
+++ b/exporter/Cargo.toml
@@ -14,3 +14,4 @@ glam = { version = "0.30.0", features = ["serde"] }
gltf-json = "1.4.1"
gltf = "1.4.1"
bytemuck = "1.22.0"
+hound = "3.5.1"
diff --git a/exporter/src/bin/audioclips.rs b/exporter/src/bin/audioclips.rs
new file mode 100644
index 0000000..cc16a22
--- /dev/null
+++ b/exporter/src/bin/audioclips.rs
@@ -0,0 +1,64 @@
+#![feature(array_chunks)]
+use std::{
+ env::args,
+ fs::{File, create_dir_all},
+ io::{BufReader, BufWriter, Write},
+};
+use unity_tools::{
+ assetbundle::AssetBundle,
+ classes::audio_clip::{AudioClip, AudioCompressionFormat},
+};
+
+fn main() -> anyhow::Result<()> {
+ env_logger::init_from_env("LOG");
+ let file = BufReader::new(File::open(args().nth(1).unwrap()).unwrap());
+ let mut bundle = AssetBundle::open(file, "samples")?;
+
+ let mut i = 0;
+ create_dir_all("/tmp/a").unwrap();
+
+ for ob in bundle.all_toplevel_of_class("AudioClip") {
+ let clip = ob.load(&mut bundle)?.parse::<AudioClip>()?;
+
+ if clip.compression_format == AudioCompressionFormat::Vorbis {
+ let mut ogg = BufWriter::new(File::create(format!(
+ "/tmp/a/{}_{i}.ogg",
+ clip.name.replace("/", "-").replace(".", "-")
+ ))?);
+ ogg.write_all(&clip.read_ogg(&bundle.fs)?)?;
+ }
+
+ // let wav = BufWriter::new(File::create(format!(
+ // "/tmp/a/{}_{i}.wav",
+ // clip.name.replace("/", "-").replace(".", "-")
+ // ))?);
+ // let mut writer = hound::WavWriter::new(
+ // wav,
+ // WavSpec {
+ // bits_per_sample: 32,
+ // channels: clip.channels as u16,
+ // sample_format: hound::SampleFormat::Float,
+ // sample_rate: clip.frequency as u32,
+ // },
+ // )?;
+
+ // if clip.channels == 2 {
+ // for (l, r) in samples[0]
+ // .clone()
+ // .into_iter()
+ // .zip(samples[1].clone().into_iter())
+ // {
+ // writer.write_sample(l)?;
+ // writer.write_sample(r)?;
+ // }
+ // } else {
+ // todo!()
+ // }
+
+ // writer.finalize()?;
+
+ i += 1;
+ }
+
+ Ok(())
+}
diff --git a/src/classes/audio_clip.rs b/src/classes/audio_clip.rs
new file mode 100644
index 0000000..18bd297
--- /dev/null
+++ b/src/classes/audio_clip.rs
@@ -0,0 +1,93 @@
+use super::streamed_resource::StreamedResource;
+use crate::{
+ object::{Value, parser::FromValue},
+ unityfs::UnityFS,
+};
+use anyhow::{Result, anyhow, bail};
+use log::info;
+use serde::Serialize;
+use std::io::{Cursor, Read, Seek};
+
+#[derive(Debug, Serialize)]
+pub struct AudioClip {
+ pub resource: StreamedResource,
+ pub channels: i32,
+ pub ambisonic: bool,
+ pub bits_per_sample: i32,
+ pub compression_format: AudioCompressionFormat,
+ pub frequency: i32,
+ pub is_tracker_format: bool,
+ pub legacy_3d: bool,
+ pub length: f32,
+ pub name: String,
+ pub subsound_index: i32,
+}
+
+impl FromValue for AudioClip {
+ fn from_value(v: Value) -> Result<Self> {
+ let mut fields = v.as_class("AudioClip")?;
+ Ok(AudioClip {
+ resource: fields.field("m_Resource")?,
+ ambisonic: fields.field("m_Ambisonic")?,
+ bits_per_sample: fields.field("m_BitsPerSample")?,
+ compression_format: fields.field("m_CompressionFormat")?,
+ channels: fields.field("m_Channels")?,
+ frequency: fields.field("m_Frequency")?,
+ is_tracker_format: fields.field("m_IsTrackerFormat")?,
+ legacy_3d: fields.field("m_Legacy3D")?,
+ length: fields.field("m_Length")?,
+ name: fields.field("m_Name")?,
+ subsound_index: fields.field("m_SubsoundIndex")?,
+ })
+ }
+}
+
+impl AudioClip {
+ pub fn read_ogg(&self, fs: &UnityFS<impl Read + Seek>) -> Result<Vec<u8>> {
+ let data = self.resource.read(&fs)?;
+ match self.compression_format {
+ AudioCompressionFormat::Vorbis => {
+ info!("reading vorbis FMOD sound bank");
+ let bank = fsbex::Bank::new(Cursor::new(data))?;
+ assert_eq!(bank.format(), fsbex::AudioFormat::Vorbis);
+ assert_eq!(u32::from(bank.num_streams()), 1);
+ let stream = bank.into_iter().next().unwrap();
+
+ let mut buf = Cursor::new(Vec::new());
+ stream.write(&mut buf)?;
+ Ok(buf.into_inner())
+ }
+ x => todo!("audio format {x:?}"),
+ }
+ }
+}
+
+impl FromValue for AudioCompressionFormat {
+ fn from_value(v: Value) -> Result<Self> {
+ let x = v
+ .as_i32()
+ .ok_or(anyhow!("expected i32 AudioCompressionFormat"))?;
+ if x < 10 {
+ Ok(unsafe { std::mem::transmute(x) })
+ } else {
+ bail!("AudioCompressionFormat out of range")
+ }
+ }
+}
+
+#[allow(non_camel_case_types)]
+#[repr(i32)]
+#[derive(Debug, Serialize, PartialEq, Clone, Copy)]
+
+pub enum AudioCompressionFormat {
+ PCM,
+ Vorbis,
+ ADPCM,
+ MP3,
+ PSMVAG,
+ HEVAG,
+ XMA,
+ AAC,
+ GCADPCM,
+ ATRAC9,
+}
diff --git a/src/classes/cubemap.rs b/src/classes/cubemap.rs
index bd80408..653ec38 100644
--- a/src/classes/cubemap.rs
+++ b/src/classes/cubemap.rs
@@ -1,4 +1,4 @@
-use super::{streaminginfo::StreamingInfo, texture2d::TextureFormat};
+use super::{streaming_info::StreamingInfo, texture2d::TextureFormat};
use crate::object::{Value, parser::FromValue};
use anyhow::Result;
use glam::{UVec2, Vec3Swizzles, uvec2, vec2, vec3};
diff --git a/src/classes/mesh.rs b/src/classes/mesh.rs
index 96e42c2..09efe66 100644
--- a/src/classes/mesh.rs
+++ b/src/classes/mesh.rs
@@ -1,4 +1,4 @@
-use super::streaminginfo::StreamingInfo;
+use super::streaming_info::StreamingInfo;
use crate::object::{Value, parser::FromValue};
use anyhow::{Result, anyhow, bail};
use glam::{Mat4, Vec2, Vec3, Vec3A, Vec4};
diff --git a/src/classes/mod.rs b/src/classes/mod.rs
index c312c6a..2bba6c1 100644
--- a/src/classes/mod.rs
+++ b/src/classes/mod.rs
@@ -3,7 +3,7 @@ pub mod gameobject;
pub mod material;
pub mod mesh;
pub mod pptr;
-pub mod streaminginfo;
+pub mod streaming_info;
pub mod texture2d;
pub mod transform;
pub mod vectors;
@@ -11,6 +11,8 @@ pub mod renderer;
pub mod shader;
pub mod cubemap;
pub mod render_settings;
+pub mod audio_clip;
+pub mod streamed_resource;
use crate::object::{Value, parser::FromValue};
use anyhow::Result;
@@ -21,7 +23,7 @@ use mesh::Mesh;
use pptr::PPtr;
use serde::Serialize;
use std::collections::BTreeMap;
-use streaminginfo::StreamingInfo;
+use streaming_info::StreamingInfo;
use texture2d::Texture2D;
use transform::Transform;
diff --git a/src/classes/streamed_resource.rs b/src/classes/streamed_resource.rs
new file mode 100644
index 0000000..945c8e1
--- /dev/null
+++ b/src/classes/streamed_resource.rs
@@ -0,0 +1,50 @@
+use crate::{
+ object::{Value, parser::FromValue},
+ unityfs::UnityFS,
+};
+use anyhow::{Result, anyhow, bail};
+use serde::Serialize;
+use std::io::{Read, Seek, SeekFrom};
+
+#[derive(Debug, Serialize)]
+pub struct StreamedResource {
+ pub offset: u64,
+ pub size: u64,
+ pub path: String,
+}
+
+impl FromValue for StreamedResource {
+ fn from_value(v: Value) -> Result<Self> {
+ let mut fields = v.as_class("StreamedResource")?;
+ Ok(StreamedResource {
+ offset: fields.field("m_Offset")?,
+ size: fields.field("m_Size")?,
+ path: fields.field("m_Source")?,
+ })
+ }
+}
+
+impl StreamedResource {
+ pub fn read(&self, fs: &UnityFS<impl Read + Seek>) -> Result<Vec<u8>> {
+ if !self.path.starts_with("archive:") {
+ bail!(
+ "StreamedResource path does not start on 'archive:' ({:?})",
+ self.path
+ )
+ }
+ let nodeinfo = fs
+ .header
+ .nodes()
+ .iter()
+ .find(|n| self.path.ends_with(&n.name))
+ .ok_or(anyhow!("node with path {:?} not found", self.path))?
+ .to_owned();
+
+ let mut buf = Vec::new();
+
+ let mut node = fs.read(&nodeinfo)?;
+ node.seek(SeekFrom::Start(self.offset))?;
+ node.take(self.size).read_to_end(&mut buf)?;
+ Ok(buf)
+ }
+}
diff --git a/src/classes/streaminginfo.rs b/src/classes/streaming_info.rs
index d593a5b..9f7ce23 100644
--- a/src/classes/streaminginfo.rs
+++ b/src/classes/streaming_info.rs
@@ -1,11 +1,10 @@
-use std::io::{Read, Seek, SeekFrom};
-
use crate::{
object::{Value, parser::FromValue},
unityfs::UnityFS,
};
use anyhow::{Result, anyhow, bail};
use serde::Serialize;
+use std::io::{Read, Seek, SeekFrom};
#[derive(Debug, Serialize)]
pub struct StreamingInfo {
diff --git a/src/classes/texture2d.rs b/src/classes/texture2d.rs
index 8f87625..41820b0 100644
--- a/src/classes/texture2d.rs
+++ b/src/classes/texture2d.rs
@@ -1,4 +1,4 @@
-use super::streaminginfo::StreamingInfo;
+use super::streaming_info::StreamingInfo;
use crate::object::{Value, parser::FromValue};
use anyhow::{Result, anyhow, bail};
use image::{DynamicImage, ImageBuffer, Luma, Rgb, Rgba};
diff --git a/src/object/read.rs b/src/object/read.rs
index 013874c..1f79e30 100644
--- a/src/object/read.rs
+++ b/src/object/read.rs
@@ -33,6 +33,7 @@ impl Value {
"SInt32" => Ok(Value::I32(data.read_i32(e)?)),
"SInt64" => Ok(Value::I64(data.read_i64(e)?)),
"bool" => Ok(Value::Bool(data.read_u8()? != 0)),
+ "FileSize" => Ok(Value::U64(data.read_u64(e)?)),
"float" => {
data.align(4)?;
Ok(Value::F32(data.read_f32(e)?))