core: Implement getBytes{Loaded,Total} (simpler approach)

This commit is contained in:
relrelb 2020-10-23 17:06:16 +03:00 committed by Mike Welsh
parent 14a71b69cc
commit 083e2a2ff5
5 changed files with 26 additions and 25 deletions

View File

@ -721,19 +721,19 @@ pub fn duplicate_movie_clip_with_bias<'gc>(
}
fn get_bytes_loaded<'gc>(
_movie_clip: MovieClip<'gc>,
activation: &mut Activation<'_, 'gc, '_>,
movie_clip: MovieClip<'gc>,
_activation: &mut Activation<'_, 'gc, '_>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
Ok(activation.context.swf.header().uncompressed_length.into())
Ok((movie_clip.movie().unwrap().data().len() + 20).into())
}
fn get_bytes_total<'gc>(
_movie_clip: MovieClip<'gc>,
activation: &mut Activation<'_, 'gc, '_>,
movie_clip: MovieClip<'gc>,
_activation: &mut Activation<'_, 'gc, '_>,
_args: &[Value<'gc>],
) -> Result<Value<'gc>, Error<'gc>> {
Ok(activation.context.swf.header().uncompressed_length.into())
Ok((movie_clip.movie().unwrap().data().len() + 20).into())
}
fn get_next_highest_depth<'gc>(

View File

@ -1,7 +1,6 @@
use crate::backend::navigator::url_from_relative_path;
use crate::property_map::PropertyMap;
use gc_arena::Collect;
use std::convert::TryInto;
use std::path::Path;
use std::sync::Arc;
use swf::{Header, TagCode};
@ -33,9 +32,8 @@ impl SwfMovie {
pub fn empty(swf_version: u8) -> Self {
Self {
header: Header {
compression: swf::Compression::None,
version: swf_version,
uncompressed_length: 0,
compression: swf::Compression::None,
stage_size: swf::Rectangle::default(),
frame_rate: 1.0,
num_frames: 0,
@ -87,11 +85,11 @@ impl SwfMovie {
// It always errors, and doesn't return all the data if you use read_to_end,
// but read_exact at least returns the data... why?
// Does the decoder need to be flushed somehow?
let mut data = vec![0u8; header.uncompressed_length.try_into().unwrap()];
let mut data = vec![0u8; swf_stream.uncompressed_length];
let _ = reader.get_mut().read_exact(&mut data);
data
} else {
let mut data = Vec::with_capacity(header.uncompressed_length.try_into().unwrap());
let mut data = Vec::with_capacity(swf_stream.uncompressed_length);
if let Err(e) = reader.get_mut().read_to_end(&mut data) {
return Err(format!("Error decompressing SWF, may be corrupt: {}", e).into());
}

View File

@ -35,11 +35,11 @@ pub fn read_swf<R: Read>(input: R) -> Result<Swf> {
// It always errors, and doesn't return all the data if you use read_to_end,
// but read_exact at least returns the data... why?
// Does the decoder need to be flushed somehow?
let mut data = vec![0u8; header.uncompressed_length.try_into().unwrap()];
let mut data = vec![0u8; swf_stream.uncompressed_length];
let _ = reader.get_mut().read_exact(&mut data);
data
} else {
let mut data = Vec::with_capacity(header.uncompressed_length.try_into().unwrap());
let mut data = Vec::with_capacity(swf_stream.uncompressed_length);
if let Err(e) = reader.get_mut().read_to_end(&mut data) {
log::error!("Error decompressing SWF, may be corrupt: {}", e);
}
@ -55,7 +55,7 @@ pub fn read_swf<R: Read>(input: R) -> Result<Swf> {
if let Err(e) = reader.get_mut().read_to_end(&mut data) {
log::warn!("Error decompressing SWF stream, may be corrupt: {}", e);
}
if data.len() != header.uncompressed_length.try_into().unwrap() {
if data.len() != swf_stream.uncompressed_length {
log::warn!("SWF length doesn't match header, may be corrupt");
}
let mut reader = Reader::new(&data[..], version);
@ -81,7 +81,10 @@ pub fn read_swf_header<'a, R: Read + 'a>(mut input: R) -> Result<SwfStream<'a>>
// Read SWF header.
let compression = Reader::read_compression_type(&mut input)?;
let version = input.read_u8()?;
let uncompressed_length = input.read_u32::<LittleEndian>()?;
// Uncompressed length includes the 4-byte header and 4-byte uncompressed length itself,
// subtract it here.
let uncompressed_length = input.read_u32::<LittleEndian>()? - 8;
// Now the SWF switches to a compressed stream.
let decompressed_input: Box<dyn Read> = match compression {
@ -102,9 +105,7 @@ pub fn read_swf_header<'a, R: Read + 'a>(mut input: R) -> Result<SwfStream<'a>>
version
);
}
// Uncompressed length includes the 4-byte header and 4-byte uncompressed length itself,
// subtract it here.
make_lzma_reader(input, uncompressed_length - 8)?
make_lzma_reader(input, uncompressed_length)?
}
};
@ -113,14 +114,17 @@ pub fn read_swf_header<'a, R: Read + 'a>(mut input: R) -> Result<SwfStream<'a>>
let frame_rate = reader.read_fixed8()?;
let num_frames = reader.read_u16()?;
let header = Header {
compression,
version,
uncompressed_length,
compression,
stage_size,
frame_rate,
num_frames,
};
Ok(SwfStream { header, reader })
Ok(SwfStream {
header,
uncompressed_length: uncompressed_length.try_into().unwrap(),
reader,
})
}
#[cfg(feature = "flate2")]

View File

@ -22,6 +22,7 @@ pub struct Swf {
/// stream as well as the uncompressed data length.
pub struct SwfStream<'a> {
pub header: Header,
pub uncompressed_length: usize,
pub reader: crate::read::Reader<Box<dyn std::io::Read + 'a>>,
}
@ -32,9 +33,8 @@ pub struct SwfStream<'a> {
/// [SWF19 p.27](https://www.adobe.com/content/dam/acom/en/devnet/pdf/swf-file-format-spec.pdf#page=27)
#[derive(Debug, PartialEq, Clone)]
pub struct Header {
pub compression: Compression,
pub version: u8,
pub uncompressed_length: u32,
pub compression: Compression,
pub stage_size: Rectangle,
pub frame_rate: f32,
pub num_frames: u16,

View File

@ -2760,9 +2760,8 @@ mod tests {
fn new_swf() -> Swf {
Swf {
header: Header {
compression: Compression::Zlib,
version: 13,
uncompressed_length: 1024,
compression: Compression::Zlib,
stage_size: Rectangle {
x_min: Twips::from_pixels(0.0),
x_max: Twips::from_pixels(640.0),