diff --git a/src/read.rs b/src/read.rs index 9f18bd00f..2685dd03e 100644 --- a/src/read.rs +++ b/src/read.rs @@ -138,6 +138,10 @@ pub trait SwfRead { self.get_inner().read_u32::() } + fn read_u64(&mut self) -> Result { + self.get_inner().read_u64::() + } + fn read_i8(&mut self) -> Result { self.get_inner().read_i8() } @@ -598,7 +602,7 @@ impl Reader { Some(TagCode::RemoveObject2) => Tag::RemoveObject(tag_reader.read_remove_object_2()?), Some(TagCode::VideoFrame) => tag_reader.read_video_frame()?, - + Some(TagCode::ProductInfo) => Tag::ProductInfo(tag_reader.read_product_info()?), _ => { let size = length as usize; let mut data = vec![0; size]; @@ -1936,7 +1940,11 @@ impl Reader { action: PlaceObjectAction::Place(reader.read_u16()?), depth: reader.read_i16()?, matrix: Some(reader.read_matrix()?), - color_transform: if !reader.get_ref().is_empty() { Some(reader.read_color_transform_no_alpha()?) } else { None }, + color_transform: if !reader.get_ref().is_empty() { + Some(reader.read_color_transform_no_alpha()?) + } else { + None + }, ratio: None, name: None, clip_depth: None, @@ -2674,6 +2682,19 @@ impl Reader { data, }) } + + pub fn read_product_info(&mut self) -> Result { + // Not document in SWF19 reference. + // See http://wahlers.com.br/claus/blog/undocumented-swf-tags-written-by-mxmlc/ + Ok(ProductInfo { + product_id: self.read_u32()?, + edition: self.read_u32()?, + major_version: self.read_u8()?, + minor_version: self.read_u8()?, + build_number: self.get_mut().read_u64::()?, + compilation_date: self.get_mut().read_u64::()?, + }) + } } #[cfg(test)] diff --git a/src/tag_code.rs b/src/tag_code.rs index 7c79bd6eb..9cd7a06f1 100644 --- a/src/tag_code.rs +++ b/src/tag_code.rs @@ -42,6 +42,8 @@ pub enum TagCode { DefineSprite = 39, + ProductInfo = 41, + FrameLabel = 43, SoundStreamHead2 = 45, diff --git a/src/types.rs b/src/types.rs index dea6e4938..8e98aea46 100644 --- a/src/types.rs +++ b/src/types.rs @@ -538,6 +538,8 @@ pub enum Tag { FrameLabel(FrameLabel), DefineSceneAndFrameLabelData(DefineSceneAndFrameLabelData), + ProductInfo(ProductInfo), + Unknown { tag_code: u16, data: Vec, @@ -1087,3 +1089,16 @@ pub struct DoAbc { pub type DoAction = Vec; pub type JpegTables = Vec; + +/// `ProductInfo` contains information about the software used to generate the SWF. +/// Not document in the SWF19 reference. Emitted by mxmlc. +/// See http://wahlers.com.br/claus/blog/undocumented-swf-tags-written-by-mxmlc/ +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct ProductInfo { + pub product_id: u32, + pub edition: u32, + pub major_version: u8, + pub minor_version: u8, + pub build_number: u64, + pub compilation_date: u64, +} diff --git a/src/write.rs b/src/write.rs index b6ebeb4c5..e6b2a5cbe 100644 --- a/src/write.rs +++ b/src/write.rs @@ -138,6 +138,10 @@ pub trait SwfWrite { self.get_inner().write_u32::(n) } + fn write_u64(&mut self, n: u64) -> Result<()> { + self.get_inner().write_u64::(n) + } + fn write_i8(&mut self, n: i8) -> Result<()> { self.get_inner().write_i8(n) } @@ -1039,6 +1043,7 @@ impl Writer { } Tag::DefineSceneAndFrameLabelData(ref data) => self.write_define_scene_and_frame_label_data(data)?, + Tag::ProductInfo(ref product_info) => self.write_product_info(product_info)?, Tag::Unknown { tag_code, ref data } => { self.write_tag_code_and_length(tag_code, data.len() as u32)?; @@ -2660,6 +2665,17 @@ impl Writer { Ok(()) } + fn write_product_info(&mut self, product_info: &ProductInfo) -> Result<()> { + self.write_tag_header(TagCode::ProductInfo, 26)?; + self.write_u32(product_info.product_id)?; + self.write_u32(product_info.edition)?; + self.write_u8(product_info.major_version)?; + self.write_u8(product_info.minor_version)?; + self.write_u64(product_info.build_number)?; + self.write_u64(product_info.compilation_date)?; + Ok(()) + } + fn write_tag_header(&mut self, tag_code: TagCode, length: u32) -> Result<()> { self.write_tag_code_and_length(tag_code as u16, length) }