Skip to content
This repository has been archived by the owner on May 15, 2022. It is now read-only.

Added LZMA support #23

Merged
merged 3 commits into from
Jul 11, 2012
Merged

Added LZMA support #23

merged 3 commits into from
Jul 11, 2012

Conversation

DmitriyYukhanov
Copy link
Contributor

Let's make an another try!)

claus added a commit that referenced this pull request Jul 11, 2012
@claus claus merged commit 90b2a83 into claus:master Jul 11, 2012
@claus
Copy link
Owner

claus commented Jul 11, 2012

Cheers, mate!

@DmitriyYukhanov
Copy link
Contributor Author

Glad to help! Hope it will work, haha)

@claus
Copy link
Owner

claus commented Jul 24, 2012

OK this works:

public function swfUncompress(compressionMethod:String, uncompressedLength:uint = 0):void {
    var pos:uint = position;
    var ba:ByteArray = new ByteArray();

    if(compressionMethod == SWF.COMPRESSION_METHOD_ZLIB) {
        readBytes(ba);
        ba.position = 0;
        ba.uncompress();
    } else if(compressionMethod == SWF.COMPRESSION_METHOD_LZMA) {
        // Write LZMA properties
        for(var i:uint = 0; i < 5; i++) {
            ba.writeByte(this[i + 12]);
        }
        // Write uncompressed length (64 bit)
        ba.endian = Endian.LITTLE_ENDIAN;
        ba.writeUnsignedInt(uncompressedLength - 8);
        ba.writeUnsignedInt(0);
        // Write compressed data
        position = 17;
        readBytes(ba, 13);
        // Uncompress
        ba.position = 0;
        ba.uncompress(compressionMethod);
    } else {
        throw(new Error("Unknown compression method: " + compressionMethod));
    }

    length = position = pos;
    writeBytes(ba);
    position = pos;
}

@DmitriyYukhanov
Copy link
Contributor Author

Hey, that's great! We need a renewed SWF spec to make working code from the start...
Would you push those changes in the GitHub repo?

@claus
Copy link
Owner

claus commented Jul 24, 2012

Yeah i've been nagging Thibault for an updated SWF spec like forever now ;) We're at 17, the spec is at 10. I guess not that much changed, but anyways.

I'll commit once i feel confident that this actually works correctly, and once swfCompress is working too.

@claus
Copy link
Owner

claus commented Jul 24, 2012

For the record:

The uncompressed part of a compressed SWF is always (first 8 bytes):
bytes 0-3: CWS/ZWS + version
bytes 4-7: Uncompressed size

What follows is compressed data until end of file.

A LZMA compressed SWF looks like this (example):

0000 5A 57 53 0F   // ZWS + Version 15
0004 DF 52 00 00   // Uncompressed size: 21215
// ZWS-specific:
0008 94 3B 00 00   // Compressed size: 15252
000C 5D 00 00 00 01   // LZMA Properties
0011 00 3B FF FC A6 14 16 5A ...   // LZMA Compressed Data (until EOF)

To convert the compressed data into something that can be uncompressed by ByteArray.uncompress (7z), the compressed size has to be thrown away, and the uncompressed size (padded to 64 bits) has to be injected
after the LZMA properties.

As the uncompressed size in SWF refers to the size of the entire SWF (including the uncompressed header of 8
bytes), but uncompressed size in the LZMA header refers to only the LZMA data, we need to subtract 8.

0000 5D 00 00 00 01   // LZMA Properties
0005 D7 52 00 00 00 00 00 00   // Uncompressed size: 21207 (64 bit)
000D 00 3B FF FC A6 14 16 5A ...   // LZMA Compressed Data (until EOF)

@DmitriyYukhanov
Copy link
Contributor Author

Thanks, good to know!
It should be in docs as example somewhere in ByteArray.uncompress() description.
Or even better, it should be done internally, so we just call ByteArray.uncompress() on everything after ZWS+Version and voila!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants