Created
April 26, 2020 04:32
Revisions
-
mwgamera created this gist
Apr 26, 2020 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,94 @@ #!/usr/bin/env perl # Fix some JPG data in SWF file so that swfrender doesn't trip on it. # klg, Apr 2020 use strict; use warnings; use IO::Compress::Deflate; use IO::Uncompress::Inflate; my $src = \*STDIN; my $dst = \*STDOUT; open $src, '<', shift or die $! if @ARGV; # read the uncompressed part of the header read $src, $_, 8 or die $!; my ($magic, $version, $size) = unpack 'A3CV'; die 'Not an SWF file.' unless $magic =~ /^[FCZ]WS$/; die 'LZMA not supported' if $magic eq 'ZWS'; if ($magic eq 'CWS') { $src = IO::Uncompress::Inflate->new($src) or die "inflate: $!"; } print $dst pack 'A3CV', 'CWS', $version, $size or die $!; $dst = IO::Compress::Deflate->new($dst) or die "deflate: $!"; # read the rest of a header and copy it out read $src, $_, 1 or die $!; print $dst $_ or die $!; read $src, $_, (((ord >> 3) * 4 + 5 - 1) >> 3) + 4 or die $!; print $dst $_ or die $!; # read and copy all tags, modifying some until (eof $src) { read $src, $_, 2 or die $!; print $dst $_ or die $!; my $tag = unpack 'v'; my $len = $tag & 0x3f; if ($len == 0x3f) { read $src, $_, 4, or die $!; print $dst $_ or die $!; $len = unpack 'V'; } $tag >>= 6; if ($len) { read $src, $_, $len or die $!; $_ = fixjpgtags($tag, $_); print $dst $_ or die $!; } } sub fixjpgtags { my ($tag, $data) = @_; if ($tag == 6) { # DefineBits substr($data, 2) = fixjpgdata(substr $data, 2); } elsif ($tag == 8) { # JPEGTables $data = fixjpgdata($data); } elsif ($tag == 21) { # DefineBitsJPEG2 substr($data, 2) = fixjpgdata(substr $data, 2); } elsif ($tag == 35) { # DefineBitsJPEG3 my $len = unpack 'x2V', $data; substr($data, 6, $len) = fixjpgdata(substr $data, 6, $len); } return $data; } =for comment SWF File Format Specification says: "The data in this tag begins with the JPEG SOI marker 0xFF, 0xD8 and ends with the EOI marker 0xFF, 0xD9. Before version 8 of the SWF file format, SWF files could contain an erroneous header of 0xFF, 0xD9, 0xFF, 0xD8 before the JPEG SOI marker. In addition to specifying JPEG data, DefineBitsJPEG2 can also contain PNG image data and non-animated GIF89a." =for comment The offending files contained valid JFIF prefixed by EOI, i.e. data that started with FF D9 FF D8 FF E0... Swftools would remove FF D9 FF D8 and then complain that the rest starts with FF E0 so it does not look like JPEG. Normalize things to start with single SOI, and pad with zeros to keep sizes and alignment unchanged. =cut sub fixjpgdata { local ($_) = @_; return $_ if /\A\x89PNG|\AGIF/; m/\A((\xff[\xd8\xd9])+)/ or die 'unexpected data in tag'; my $L = length $1; return "\xff\xd8" . substr($_, $L) . "\0" x ($L-2); } 1;