swf: Return concrete data types in `Reader` methods

Where possible, return the specific data type instead of the generic
`Tag` type. Most reader methods do this already, so this brings the
rest in-line.
This commit is contained in:
relrelb 2022-05-09 23:07:54 +03:00 committed by Mike Welsh
parent 7352aca3bc
commit 781d091d42
2 changed files with 51 additions and 50 deletions

View File

@ -40,7 +40,7 @@ use std::cell::{Ref, RefMut};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use swf::extensions::ReadSwfExt; use swf::extensions::ReadSwfExt;
use swf::{ClipEventFlag, FrameLabelData, Tag}; use swf::{ClipEventFlag, FrameLabelData};
type FrameNumber = u16; type FrameNumber = u16;
@ -2490,23 +2490,19 @@ impl<'gc, 'a> MovieClipData<'gc> {
context: &mut UpdateContext<'_, 'gc, '_>, context: &mut UpdateContext<'_, 'gc, '_>,
reader: &mut SwfStream, reader: &mut SwfStream,
) -> DecodeResult { ) -> DecodeResult {
match reader.read_video_frame()? { let vframe = reader.read_video_frame()?;
Tag::VideoFrame(vframe) => { let library = context.library.library_for_movie_mut(self.movie());
let library = context.library.library_for_movie_mut(self.movie()); match library.character_by_id(vframe.stream_id) {
match library.character_by_id(vframe.stream_id) { Some(Character::Video(mut v)) => {
Some(Character::Video(mut v)) => { v.preload_swf_frame(vframe, context);
v.preload_swf_frame(vframe, context);
Ok(()) Ok(())
}
_ => Err(format!(
"Attempted to preload video frames into non-video character {}",
vframe.stream_id
)
.into()),
}
} }
_ => unreachable!(), _ => Err(format!(
"Attempted to preload video frames into non-video character {}",
vframe.stream_id
)
.into()),
} }
} }
@ -2863,18 +2859,13 @@ impl<'gc, 'a> MovieClipData<'gc> {
context: &mut UpdateContext<'_, 'gc, '_>, context: &mut UpdateContext<'_, 'gc, '_>,
reader: &mut SwfStream, reader: &mut SwfStream,
) -> DecodeResult { ) -> DecodeResult {
match reader.read_define_video_stream()? { let streamdef = reader.read_define_video_stream()?;
Tag::DefineVideoStream(streamdef) => { let id = streamdef.id;
let id = streamdef.id; let video = Video::from_swf_tag(self.movie(), streamdef, context.gc_context);
let video = Video::from_swf_tag(self.movie(), streamdef, context.gc_context); context
context .library
.library .library_for_movie_mut(self.movie())
.library_for_movie_mut(self.movie()) .register_character(id, Character::Video(video));
.register_character(id, Character::Video(video));
}
_ => unreachable!(),
};
Ok(()) Ok(())
} }

View File

@ -377,8 +377,12 @@ impl<'a> Reader<'a> {
let jpeg_data = tag_reader.read_slice_to_end(); let jpeg_data = tag_reader.read_slice_to_end();
Tag::DefineBitsJpeg2 { id, jpeg_data } Tag::DefineBitsJpeg2 { id, jpeg_data }
} }
TagCode::DefineBitsJpeg3 => tag_reader.read_define_bits_jpeg_3(3)?, TagCode::DefineBitsJpeg3 => {
TagCode::DefineBitsJpeg4 => tag_reader.read_define_bits_jpeg_3(4)?, Tag::DefineBitsJpeg3(tag_reader.read_define_bits_jpeg_3(3)?)
}
TagCode::DefineBitsJpeg4 => {
Tag::DefineBitsJpeg3(tag_reader.read_define_bits_jpeg_3(4)?)
}
TagCode::DefineButton => { TagCode::DefineButton => {
Tag::DefineButton(Box::new(tag_reader.read_define_button_1()?)) Tag::DefineButton(Box::new(tag_reader.read_define_button_1()?))
} }
@ -399,8 +403,12 @@ impl<'a> Reader<'a> {
TagCode::DefineFont3 => Tag::DefineFont2(Box::new(tag_reader.read_define_font_2(3)?)), TagCode::DefineFont3 => Tag::DefineFont2(Box::new(tag_reader.read_define_font_2(3)?)),
TagCode::DefineFont4 => Tag::DefineFont4(tag_reader.read_define_font_4()?), TagCode::DefineFont4 => Tag::DefineFont4(tag_reader.read_define_font_4()?),
TagCode::DefineFontAlignZones => tag_reader.read_define_font_align_zones()?, TagCode::DefineFontAlignZones => tag_reader.read_define_font_align_zones()?,
TagCode::DefineFontInfo => tag_reader.read_define_font_info(1)?, TagCode::DefineFontInfo => {
TagCode::DefineFontInfo2 => tag_reader.read_define_font_info(2)?, Tag::DefineFontInfo(Box::new(tag_reader.read_define_font_info(1)?))
}
TagCode::DefineFontInfo2 => {
Tag::DefineFontInfo(Box::new(tag_reader.read_define_font_info(2)?))
}
TagCode::DefineFontName => tag_reader.read_define_font_name()?, TagCode::DefineFontName => tag_reader.read_define_font_name()?,
TagCode::DefineMorphShape => { TagCode::DefineMorphShape => {
Tag::DefineMorphShape(Box::new(tag_reader.read_define_morph_shape(1)?)) Tag::DefineMorphShape(Box::new(tag_reader.read_define_morph_shape(1)?))
@ -415,7 +423,9 @@ impl<'a> Reader<'a> {
TagCode::DefineSound => Tag::DefineSound(Box::new(tag_reader.read_define_sound()?)), TagCode::DefineSound => Tag::DefineSound(Box::new(tag_reader.read_define_sound()?)),
TagCode::DefineText => Tag::DefineText(Box::new(tag_reader.read_define_text(1)?)), TagCode::DefineText => Tag::DefineText(Box::new(tag_reader.read_define_text(1)?)),
TagCode::DefineText2 => Tag::DefineText(Box::new(tag_reader.read_define_text(2)?)), TagCode::DefineText2 => Tag::DefineText(Box::new(tag_reader.read_define_text(2)?)),
TagCode::DefineVideoStream => tag_reader.read_define_video_stream()?, TagCode::DefineVideoStream => {
Tag::DefineVideoStream(tag_reader.read_define_video_stream()?)
}
TagCode::EnableTelemetry => { TagCode::EnableTelemetry => {
tag_reader.read_u16()?; // Reserved tag_reader.read_u16()?; // Reserved
let password_hash = if length > 2 { let password_hash = if length > 2 {
@ -565,7 +575,7 @@ impl<'a> Reader<'a> {
TagCode::FrameLabel => Tag::FrameLabel(tag_reader.read_frame_label(length)?), TagCode::FrameLabel => Tag::FrameLabel(tag_reader.read_frame_label(length)?),
TagCode::DefineSprite => tag_reader.read_define_sprite()?, TagCode::DefineSprite => Tag::DefineSprite(tag_reader.read_define_sprite()?),
TagCode::PlaceObject => { TagCode::PlaceObject => {
Tag::PlaceObject(Box::new(tag_reader.read_place_object(length)?)) Tag::PlaceObject(Box::new(tag_reader.read_place_object(length)?))
@ -584,7 +594,7 @@ impl<'a> Reader<'a> {
TagCode::RemoveObject2 => Tag::RemoveObject(tag_reader.read_remove_object_2()?), TagCode::RemoveObject2 => Tag::RemoveObject(tag_reader.read_remove_object_2()?),
TagCode::VideoFrame => tag_reader.read_video_frame()?, TagCode::VideoFrame => Tag::VideoFrame(tag_reader.read_video_frame()?),
TagCode::ProductInfo => Tag::ProductInfo(tag_reader.read_product_info()?), TagCode::ProductInfo => Tag::ProductInfo(tag_reader.read_product_info()?),
TagCode::NameCharacter => Tag::NameCharacter(tag_reader.read_name_character()?), TagCode::NameCharacter => Tag::NameCharacter(tag_reader.read_name_character()?),
}; };
@ -1206,7 +1216,7 @@ impl<'a> Reader<'a> {
Ok(zone) Ok(zone)
} }
fn read_define_font_info(&mut self, version: u8) -> Result<Tag<'a>> { fn read_define_font_info(&mut self, version: u8) -> Result<FontInfo<'a>> {
let id = self.read_u16()?; let id = self.read_u16()?;
let name = self.read_str_with_len()?; let name = self.read_str_with_len()?;
let flags = FontInfoFlag::from_bits_truncate(self.read_u8()?); let flags = FontInfoFlag::from_bits_truncate(self.read_u8()?);
@ -1230,14 +1240,14 @@ impl<'a> Reader<'a> {
} }
// SWF19 has ANSI and Shift-JIS backwards? // SWF19 has ANSI and Shift-JIS backwards?
Ok(Tag::DefineFontInfo(Box::new(FontInfo { Ok(FontInfo {
id, id,
version, version,
name, name,
flags, flags,
language, language,
code_table, code_table,
}))) })
} }
fn read_define_font_name(&mut self) -> Result<Tag<'a>> { fn read_define_font_name(&mut self) -> Result<Tag<'a>> {
@ -1808,12 +1818,12 @@ impl<'a> Reader<'a> {
Ok(shape_record) Ok(shape_record)
} }
pub fn read_define_sprite(&mut self) -> Result<Tag<'a>> { pub fn read_define_sprite(&mut self) -> Result<Sprite<'a>> {
Ok(Tag::DefineSprite(Sprite { Ok(Sprite {
id: self.read_u16()?, id: self.read_u16()?,
num_frames: self.read_u16()?, num_frames: self.read_u16()?,
tags: self.read_tag_list()?, tags: self.read_tag_list()?,
})) })
} }
pub fn read_file_attributes(&mut self) -> Result<FileAttributes> { pub fn read_file_attributes(&mut self) -> Result<FileAttributes> {
@ -2459,7 +2469,7 @@ impl<'a> Reader<'a> {
}) })
} }
pub fn read_define_video_stream(&mut self) -> Result<Tag<'a>> { pub fn read_define_video_stream(&mut self) -> Result<DefineVideoStream> {
let id = self.read_character_id()?; let id = self.read_character_id()?;
let num_frames = self.read_u16()?; let num_frames = self.read_u16()?;
let width = self.read_u16()?; let width = self.read_u16()?;
@ -2468,7 +2478,7 @@ impl<'a> Reader<'a> {
// TODO(Herschel): Check SWF version. // TODO(Herschel): Check SWF version.
let codec = VideoCodec::from_u8(self.read_u8()?) let codec = VideoCodec::from_u8(self.read_u8()?)
.ok_or_else(|| Error::invalid_data("Invalid video codec."))?; .ok_or_else(|| Error::invalid_data("Invalid video codec."))?;
Ok(Tag::DefineVideoStream(DefineVideoStream { Ok(DefineVideoStream {
id, id,
num_frames, num_frames,
width, width,
@ -2477,21 +2487,21 @@ impl<'a> Reader<'a> {
codec, codec,
deblocking: VideoDeblocking::from_u8((flags >> 1) & 0b111) deblocking: VideoDeblocking::from_u8((flags >> 1) & 0b111)
.ok_or_else(|| Error::invalid_data("Invalid video deblocking value."))?, .ok_or_else(|| Error::invalid_data("Invalid video deblocking value."))?,
})) })
} }
pub fn read_video_frame(&mut self) -> Result<Tag<'a>> { pub fn read_video_frame(&mut self) -> Result<VideoFrame<'a>> {
let stream_id = self.read_character_id()?; let stream_id = self.read_character_id()?;
let frame_num = self.read_u16()?; let frame_num = self.read_u16()?;
let data = self.read_slice_to_end(); let data = self.read_slice_to_end();
Ok(Tag::VideoFrame(VideoFrame { Ok(VideoFrame {
stream_id, stream_id,
frame_num, frame_num,
data, data,
})) })
} }
fn read_define_bits_jpeg_3(&mut self, version: u8) -> Result<Tag<'a>> { fn read_define_bits_jpeg_3(&mut self, version: u8) -> Result<DefineBitsJpeg3<'a>> {
let id = self.read_character_id()?; let id = self.read_character_id()?;
let data_size = self.read_u32()? as usize; let data_size = self.read_u32()? as usize;
let deblocking = if version >= 4 { let deblocking = if version >= 4 {
@ -2501,13 +2511,13 @@ impl<'a> Reader<'a> {
}; };
let data = self.read_slice(data_size)?; let data = self.read_slice(data_size)?;
let alpha_data = self.read_slice_to_end(); let alpha_data = self.read_slice_to_end();
Ok(Tag::DefineBitsJpeg3(DefineBitsJpeg3 { Ok(DefineBitsJpeg3 {
id, id,
version, version,
deblocking, deblocking,
data, data,
alpha_data, alpha_data,
})) })
} }
pub fn read_define_bits_lossless(&mut self, version: u8) -> Result<DefineBitsLossless<'a>> { pub fn read_define_bits_lossless(&mut self, version: u8) -> Result<DefineBitsLossless<'a>> {