swf: General cleanup
Just mechanical cleanups to ease future refactors.
This commit is contained in:
parent
8e7ce18cc2
commit
ef9c073d26
|
@ -18,7 +18,7 @@ use std::fs::File;
|
|||
|
||||
let file = File::open("file.swf").unwrap();
|
||||
let reader = BufReader::new(file);
|
||||
let swf = swf::read_swf(reader).unwrap();
|
||||
let swf = swf::parse_swf(reader).unwrap();
|
||||
println!("The SWF has {} frames", swf.header.num_frames);
|
||||
```
|
||||
|
||||
|
@ -64,4 +64,4 @@ at your option.
|
|||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
||||
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
|
||||
additional terms or conditions.
|
||||
additional terms or conditions.
|
||||
|
|
|
@ -41,6 +41,18 @@ impl<'a> Reader<'a> {
|
|||
&mut self.input
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_f64_me(&mut self) -> Result<f64> {
|
||||
// Flash weirdly stores (some?) f64 as two LE 32-bit chunks.
|
||||
// First word is the hi-word, second word is the lo-word.
|
||||
let mut bytes = self.read_u64()?.to_le_bytes();
|
||||
bytes.swap(0, 4);
|
||||
bytes.swap(1, 5);
|
||||
bytes.swap(2, 6);
|
||||
bytes.swap(3, 7);
|
||||
Ok(f64::from_le_bytes(bytes))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn read_action(&mut self) -> Result<Option<Action<'a>>> {
|
||||
let (opcode, mut length) = self.read_opcode_and_length()?;
|
||||
|
@ -79,7 +91,6 @@ impl<'a> Reader<'a> {
|
|||
/// The `length` passed in should be the length excluding any sub-blocks.
|
||||
/// The final `length` returned will be total length of the action, including sub-blocks.
|
||||
#[inline]
|
||||
#[allow(clippy::inconsistent_digit_grouping)]
|
||||
fn read_op(&mut self, opcode: u8, length: &mut usize) -> Result<Option<Action<'a>>> {
|
||||
use num_traits::FromPrimitive;
|
||||
let action = if let Some(op) = OpCode::from_u8(opcode) {
|
||||
|
|
|
@ -1,90 +1,86 @@
|
|||
#![allow(clippy::cognitive_complexity, clippy::unreadable_literal)]
|
||||
|
||||
use crate::avm1::opcode::OpCode;
|
||||
use crate::avm1::types::*;
|
||||
use crate::string::SwfStr;
|
||||
use crate::write::SwfWriteExt;
|
||||
use byteorder::{LittleEndian, WriteBytesExt};
|
||||
use std::io::{self, Result, Write};
|
||||
use std::io::{Result, Write};
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct Writer<W: Write> {
|
||||
output: W,
|
||||
#[allow(dead_code)]
|
||||
version: u8,
|
||||
}
|
||||
|
||||
impl<W: Write> SwfWriteExt for Writer<W> {
|
||||
#[inline]
|
||||
fn write_u8(&mut self, n: u8) -> io::Result<()> {
|
||||
fn write_u8(&mut self, n: u8) -> Result<()> {
|
||||
self.output.write_u8(n)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u16(&mut self, n: u16) -> io::Result<()> {
|
||||
fn write_u16(&mut self, n: u16) -> Result<()> {
|
||||
self.output.write_u16::<LittleEndian>(n)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u32(&mut self, n: u32) -> io::Result<()> {
|
||||
fn write_u32(&mut self, n: u32) -> Result<()> {
|
||||
self.output.write_u32::<LittleEndian>(n)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_u64(&mut self, n: u64) -> io::Result<()> {
|
||||
fn write_u64(&mut self, n: u64) -> Result<()> {
|
||||
self.output.write_u64::<LittleEndian>(n)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_i8(&mut self, n: i8) -> io::Result<()> {
|
||||
fn write_i8(&mut self, n: i8) -> Result<()> {
|
||||
self.output.write_i8(n)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_i16(&mut self, n: i16) -> io::Result<()> {
|
||||
fn write_i16(&mut self, n: i16) -> Result<()> {
|
||||
self.output.write_i16::<LittleEndian>(n)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_i32(&mut self, n: i32) -> io::Result<()> {
|
||||
fn write_i32(&mut self, n: i32) -> Result<()> {
|
||||
self.output.write_i32::<LittleEndian>(n)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_f32(&mut self, n: f32) -> io::Result<()> {
|
||||
fn write_f32(&mut self, n: f32) -> Result<()> {
|
||||
self.output.write_f32::<LittleEndian>(n)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_f64(&mut self, n: f64) -> io::Result<()> {
|
||||
fn write_f64(&mut self, n: f64) -> Result<()> {
|
||||
self.output.write_f64::<LittleEndian>(n)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_string(&mut self, s: &'_ SwfStr) -> io::Result<()> {
|
||||
fn write_string(&mut self, s: &'_ SwfStr) -> Result<()> {
|
||||
self.output.write_all(s.as_bytes())?;
|
||||
self.write_u8(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<W: Write> Writer<W> {
|
||||
pub fn new(output: W, version: u8) -> Writer<W> {
|
||||
Writer { output, version }
|
||||
pub fn new(output: W, version: u8) -> Self {
|
||||
Self { output, version }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_f64_me(&mut self, n: f64) -> io::Result<()> {
|
||||
fn write_f64_me(&mut self, n: f64) -> Result<()> {
|
||||
// Flash weirdly stores f64 as two LE 32-bit chunks.
|
||||
// First word is the hi-word, second word is the lo-word.
|
||||
let mut num = [0u8; 8];
|
||||
(&mut num[..]).write_f64::<LittleEndian>(n)?;
|
||||
num.swap(0, 4);
|
||||
num.swap(1, 5);
|
||||
num.swap(2, 6);
|
||||
num.swap(3, 7);
|
||||
self.output.write_all(&num)
|
||||
let mut bytes = n.to_le_bytes();
|
||||
bytes.swap(0, 4);
|
||||
bytes.swap(1, 5);
|
||||
bytes.swap(2, 6);
|
||||
bytes.swap(3, 7);
|
||||
self.output.write_all(&bytes)
|
||||
}
|
||||
|
||||
#[allow(clippy::inconsistent_digit_grouping)]
|
||||
pub fn write_action(&mut self, action: &Action) -> Result<()> {
|
||||
match *action {
|
||||
Action::Add => self.write_action_header(OpCode::Add, 0)?,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![allow(clippy::unusual_byte_groupings)]
|
||||
|
||||
use crate::avm2::types::*;
|
||||
use crate::error::{Error, Result};
|
||||
use crate::extensions::ReadSwfExt;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![allow(clippy::unusual_byte_groupings)]
|
||||
|
||||
use crate::avm2::opcode::OpCode;
|
||||
use crate::avm2::types::*;
|
||||
use crate::string::SwfStr;
|
||||
|
@ -63,8 +65,8 @@ impl<W: Write> SwfWriteExt for Writer<W> {
|
|||
}
|
||||
|
||||
impl<W: Write> Writer<W> {
|
||||
pub fn new(output: W) -> Writer<W> {
|
||||
Writer { output }
|
||||
pub fn new(output: W) -> Self {
|
||||
Self { output }
|
||||
}
|
||||
|
||||
pub fn write(&mut self, abc_file: AbcFile) -> Result<()> {
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use crate::byteorder::{LittleEndian, ReadBytesExt};
|
||||
use crate::error::Result;
|
||||
use crate::string::SwfStr;
|
||||
use crate::{Fixed16, Fixed8};
|
||||
use std::io::{self, Read};
|
||||
use byteorder::{LittleEndian, ReadBytesExt};
|
||||
use std::io;
|
||||
|
||||
pub trait ReadSwfExt<'a> {
|
||||
fn as_mut_slice(&mut self) -> &mut &'a [u8];
|
||||
|
@ -15,9 +14,9 @@ pub trait ReadSwfExt<'a> {
|
|||
|
||||
// TODO: Make this fallible?
|
||||
fn seek(&mut self, data: &'a [u8], relative_offset: isize) {
|
||||
let mut pos = self.pos(data);
|
||||
pos = (pos as isize + relative_offset) as usize;
|
||||
pos = pos.min(data.len());
|
||||
let pos = self.pos(data);
|
||||
let pos = (pos as isize + relative_offset) as usize;
|
||||
let pos = pos.min(data.len());
|
||||
*self.as_mut_slice() = &data[pos..];
|
||||
}
|
||||
|
||||
|
@ -66,16 +65,6 @@ pub trait ReadSwfExt<'a> {
|
|||
Ok(ReadBytesExt::read_f64::<LittleEndian>(self.as_mut_slice())?)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_fixed8(&mut self) -> Result<Fixed8> {
|
||||
Ok(Fixed8::from_bits(self.read_i16()?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_fixed16(&mut self) -> Result<Fixed16> {
|
||||
Ok(Fixed16::from_bits(self.read_i32()?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_encoded_u32(&mut self) -> Result<u32> {
|
||||
let mut val: u32 = 0;
|
||||
|
@ -89,19 +78,6 @@ pub trait ReadSwfExt<'a> {
|
|||
Ok(val)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_f64_me(&mut self) -> Result<f64> {
|
||||
// Flash weirdly stores (some?) f64 as two LE 32-bit chunks.
|
||||
// First word is the hi-word, second word is the lo-word.
|
||||
let mut num = [0u8; 8];
|
||||
self.as_mut_slice().read_exact(&mut num)?;
|
||||
num.swap(0, 4);
|
||||
num.swap(1, 5);
|
||||
num.swap(2, 6);
|
||||
num.swap(3, 7);
|
||||
Ok(ReadBytesExt::read_f64::<LittleEndian>(&mut &num[..])?)
|
||||
}
|
||||
|
||||
fn read_slice(&mut self, len: usize) -> Result<&'a [u8]> {
|
||||
let slice = self.as_mut_slice();
|
||||
if slice.len() >= len {
|
||||
|
|
|
@ -6,14 +6,7 @@
|
|||
//!
|
||||
//! This library consists of a `read` module for decoding SWF data, and a `write` library for
|
||||
//! writing SWF data.
|
||||
#![allow(
|
||||
renamed_and_removed_lints,
|
||||
clippy::unknown_clippy_lints,
|
||||
clippy::unusual_byte_groupings,
|
||||
clippy::upper_case_acronyms
|
||||
)]
|
||||
|
||||
extern crate byteorder;
|
||||
#[cfg(feature = "flate2")]
|
||||
extern crate flate2;
|
||||
#[cfg(feature = "libflate")]
|
||||
|
@ -36,7 +29,7 @@ pub mod write;
|
|||
#[cfg(test)]
|
||||
mod test_data;
|
||||
|
||||
/// Reexports
|
||||
/// Re-exports
|
||||
pub use read::{decompress_swf, parse_swf};
|
||||
pub use string::*;
|
||||
pub use tag_code::TagCode;
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
#![allow(
|
||||
renamed_and_removed_lints,
|
||||
clippy::unknown_clippy_lints,
|
||||
clippy::inconsistent_digit_grouping,
|
||||
clippy::unreadable_literal
|
||||
)]
|
||||
#![allow(clippy::unusual_byte_groupings)]
|
||||
|
||||
use crate::extensions::ReadSwfExt;
|
||||
use crate::{
|
||||
|
@ -16,7 +11,7 @@ use bitstream_io::BitRead;
|
|||
use byteorder::{LittleEndian, ReadBytesExt};
|
||||
use std::io::{self, Read};
|
||||
|
||||
/// Parse a decompressed SWF and return a `Vec` of tags.
|
||||
/// Parse a decompressed SWF.
|
||||
///
|
||||
/// # Example
|
||||
/// ```
|
||||
|
@ -220,16 +215,11 @@ fn make_lzma_reader<'a, R: Read + 'a>(
|
|||
))
|
||||
}
|
||||
|
||||
pub struct BitReader<'a, 'b> {
|
||||
struct BitReader<'a, 'b> {
|
||||
bits: bitstream_io::BitReader<&'b mut &'a [u8], bitstream_io::BigEndian>,
|
||||
}
|
||||
|
||||
impl<'a, 'b> BitReader<'a, 'b> {
|
||||
#[inline]
|
||||
fn byte_align(&mut self) {
|
||||
self.bits.byte_align();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_bit(&mut self) -> io::Result<bool> {
|
||||
self.bits.read_bit()
|
||||
|
@ -271,7 +261,7 @@ impl<'a, 'b> BitReader<'a, 'b> {
|
|||
|
||||
#[inline]
|
||||
fn reader(&mut self) -> &mut &'a [u8] {
|
||||
self.byte_align();
|
||||
self.bits.byte_align();
|
||||
self.bits.reader().unwrap()
|
||||
}
|
||||
}
|
||||
|
@ -295,8 +285,8 @@ impl<'a> ReadSwfExt<'a> for Reader<'a> {
|
|||
|
||||
impl<'a> Reader<'a> {
|
||||
#[inline]
|
||||
pub const fn new(input: &'a [u8], version: u8) -> Reader<'a> {
|
||||
Reader { input, version }
|
||||
pub const fn new(input: &'a [u8], version: u8) -> Self {
|
||||
Self { input, version }
|
||||
}
|
||||
|
||||
/// Returns the suggested string encoding for this SWF.
|
||||
|
@ -333,6 +323,16 @@ impl<'a> Reader<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_fixed8(&mut self) -> Result<Fixed8> {
|
||||
Ok(Fixed8::from_bits(self.read_i16()?))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn read_fixed16(&mut self) -> Result<Fixed16> {
|
||||
Ok(Fixed16::from_bits(self.read_i32()?))
|
||||
}
|
||||
|
||||
/// Reads the next SWF tag from the stream.
|
||||
/// # Example
|
||||
/// ```
|
||||
|
@ -795,8 +795,7 @@ impl<'a> Reader<'a> {
|
|||
// to the characters in a button in sequence.
|
||||
|
||||
// We don't know how many color transforms this tag will contain, so read it into a buffer.
|
||||
let version = self.version;
|
||||
let mut reader = Reader::new(self.read_slice(tag_length)?, version);
|
||||
let mut reader = Reader::new(self.read_slice(tag_length)?, self.version);
|
||||
|
||||
let id = reader.read_character_id()?;
|
||||
let mut color_transforms = Vec::new();
|
||||
|
@ -1819,7 +1818,6 @@ impl<'a> Reader<'a> {
|
|||
// but SWFs in the wild exist with them in DefineShape1 (generated by third party tools),
|
||||
// and these run correctly in the Flash Player.
|
||||
if (flags & 0b10000) != 0 {
|
||||
bits.byte_align();
|
||||
let mut reader = Reader::new(bits.reader(), context.swf_version);
|
||||
let (new_styles, num_fill_bits, num_line_bits) =
|
||||
reader.read_shape_styles(context.shape_version)?;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#![allow(clippy::inconsistent_digit_grouping, clippy::unreadable_literal)]
|
||||
#![allow(clippy::unusual_byte_groupings)]
|
||||
|
||||
use crate::avm1::types::*;
|
||||
use crate::avm2::read::tests::read_abc_from_file;
|
||||
|
|
|
@ -13,7 +13,7 @@ pub use fixed::*;
|
|||
pub use matrix::Matrix;
|
||||
|
||||
/// A complete header and tags in the SWF file.
|
||||
/// This is returned by the `swf::read_swf` convenience method.
|
||||
/// This is returned by the `swf::parse_swf` convenience method.
|
||||
#[derive(Debug)]
|
||||
pub struct Swf<'a> {
|
||||
pub header: HeaderExt,
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
#![allow(
|
||||
clippy::cognitive_complexity,
|
||||
clippy::float_cmp,
|
||||
clippy::inconsistent_digit_grouping,
|
||||
clippy::unreadable_literal
|
||||
)]
|
||||
#![allow(clippy::unusual_byte_groupings)]
|
||||
|
||||
use crate::{
|
||||
error::{Error, Result},
|
||||
|
@ -22,16 +17,16 @@ use std::io::{self, Write};
|
|||
/// use swf::*;
|
||||
///
|
||||
/// let header = Header {
|
||||
/// compression: Compression::Zlib,
|
||||
/// version: 6,
|
||||
/// stage_size: Rectangle { x_min: Twips::from_pixels(0.0), x_max: Twips::from_pixels(400.0), y_min: Twips::from_pixels(0.0), y_max: Twips::from_pixels(400.0) },
|
||||
/// frame_rate: Fixed8::from_f32(60.0),
|
||||
/// num_frames: 1,
|
||||
/// };
|
||||
/// compression: Compression::Zlib,
|
||||
/// version: 6,
|
||||
/// stage_size: Rectangle { x_min: Twips::from_pixels(0.0), x_max: Twips::from_pixels(400.0), y_min: Twips::from_pixels(0.0), y_max: Twips::from_pixels(400.0) },
|
||||
/// frame_rate: Fixed8::from_f32(60.0),
|
||||
/// num_frames: 1,
|
||||
/// };
|
||||
/// let tags = [
|
||||
/// Tag::SetBackgroundColor(Color { r: 255, g: 0, b: 0, a: 255 }),
|
||||
/// Tag::ShowFrame
|
||||
/// ];
|
||||
/// Tag::SetBackgroundColor(Color { r: 255, g: 0, b: 0, a: 255 }),
|
||||
/// Tag::ShowFrame,
|
||||
/// ];
|
||||
/// let output = Vec::new();
|
||||
/// swf::write_swf(&header, &tags, output).unwrap();
|
||||
/// ```
|
||||
|
@ -63,22 +58,16 @@ pub fn write_swf<W: Write>(header: &Header, tags: &[Tag<'_>], mut output: W) ->
|
|||
|
||||
// Compress SWF body.
|
||||
match header.compression {
|
||||
Compression::None => {
|
||||
output.write_all(&swf_body)?;
|
||||
}
|
||||
Compression::None => output.write_all(&swf_body)?,
|
||||
|
||||
Compression::Zlib => write_zlib_swf(&mut output, &swf_body)?,
|
||||
|
||||
// LZMA header.
|
||||
// SWF format has a mangled LZMA header, so we have to do some magic to convert the
|
||||
// standard LZMA header to SWF format.
|
||||
// https://adobe.ly/2s8oYzn
|
||||
Compression::Lzma => {
|
||||
write_lzma_swf(&mut output, &swf_body)?;
|
||||
// 5 bytes of garbage data?
|
||||
//output.write_all(&[0xFF, 0xB5, 0xE6, 0xF8, 0xCB])?;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -265,13 +254,8 @@ impl<W: Write> SwfWriteExt for Writer<W> {
|
|||
}
|
||||
|
||||
impl<W: Write> Writer<W> {
|
||||
fn new(output: W, version: u8) -> Writer<W> {
|
||||
Writer { output, version }
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn into_inner(self) -> W {
|
||||
self.output
|
||||
fn new(output: W, version: u8) -> Self {
|
||||
Self { output, version }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -281,10 +265,12 @@ impl<W: Write> Writer<W> {
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_fixed8(&mut self, n: Fixed8) -> io::Result<()> {
|
||||
self.write_i16(n.get())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_fixed16(&mut self, n: Fixed16) -> io::Result<()> {
|
||||
self.write_i32(n.get())
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue