tags:

views:

319

answers:

3

I am trying to convert compressed swf files to uncompressed swf files using the cws2fws utility written by Alex Beregszaszi and which is part of the ffmpeg set of conversion routines. The compressed files I am using are valid files as they can be opened and played by Firefox and other programs, but when I run them through cws2fws the program gives an error (-5) indicating that the files is corrupt. I have downloaded the source for the program and compiled it using Visual Studio. When I run my file through the newly compiled program I get the same result as from the program I downloaded from the web. While debugging the program I noticed that the two of the four bytes that are used to determine the uncompressed file size of the swf are negative (see line 64 below).

00056     if (buf_in[0] != 'C' || buf_in[1] != 'W' || buf_in[2] != 'S')
00057     {
00058         printf("Not a compressed flash file\n");
00059         exit(1);
00060     }
00061 
00062     fstat(fd_in, &statbuf);
00063     comp_len = statbuf.st_size;
00064     uncomp_len = buf_in[4] | (buf_in[5] << 8) | (buf_in[6] << 16) | (buf_in[7] << 24);
00065 
00066     printf("Compressed size: %d Uncompressed size: %d\n", comp_len-4, uncomp_len-4);

So, my questions are:

1) I am feeling a bit dense, so could someone please explain the logic of determining the file size from the 4 bytes as shown in line 64. I understand that the size is probably the addition of a series of powers of 2 up to 2^32, but how are the bitwise operators working on the bytes to get the right number?

2) buf_in[5] and buf_in[6] are both negative which might be a problem between OS's as I am on a windows machine and this code was developed apparently on a *nix machine. To me this indicates a bug in the program which has to do with signed and unsigned integers. Am I correct and how do I proceed?

3) Is it possible that this code can't handle newer swf files?

4) Has anyone recently used this program with success?

Thanks for you help in advance.

A: 

I have just found another version of Alex's code that was updated by Wang Lu. Lu found the same bug I found. The code is located at: http://theliel.papipapito.com/Doc/Code/CWS2FWS.c.

Please note that Lu has introduced a bug into his revision. The line:

if (buf_in[0] != 'F' || buf_in[1] != 'W' || buf_in[2] != 'S')
     {
     printf("Not a compressed flash file\n");
     exit(1);
     }

Tests for an uncompressed SWF file, when it should test for a compressed file. The snippet should be:

if (buf_in[0] != 'C' || buf_in[1] != 'W' || buf_in[2] != 'S')
     {
     printf("Not a compressed flash file\n");
     exit(1);
     }
jay
I am still feeling dense with respect to question 1). Any takers?
jay
+2  A: 

What is the type of buf_in? If it is char *, change it to unsigned char *: the signedness of char varies by platform and compiler and options, and clearly unsigned arithmetic is intended here. It is taking 4 bytes at offset 3 in buf_in and reading them as a little-endian 32-bit integer.

That being said, I write a dumb little SWF decompresser eons ago.

#!/usr/bin/perl
use Compress::Zlib;
undef $/;
binmode(ARGV);
while (<>) {
    my ($a, $b, $c) = unpack 'a3a5a*' => $_;
    if ($a eq 'CWS') {
        open FH, '>:raw', "${ARGV}.raw";
        syswrite FH, "FWS$b";
        syswrite FH, uncompress($c);
    }
}

Should work on any reasonable Perl installation.

ephemient
Err, s/offset 3/offset 4/ of course.
ephemient
A: 

I was having the same problem and this thread helped a lot. Thanks :)

sas
You should use comments to comment.
Camilo Martin