【问题标题】:How To Decompress a LZMA Compressed File Using ByteArray Method In As3?如何在 As3 中使用 ByteArray 方法解压 LZMA 压缩文件?
【发布时间】:2012-08-25 10:09:05
【问题描述】:

这是我用来压缩/解压缩文件的代码:

package {
import flash.display.Sprite;
import flash.events.Event;
import flash.net.FileFilter;
import flash.net.FileReference;
import flash.utils.ByteArray;

public class Compressor extends Sprite
{
    private var ref:FileReference;

    public function Compressor()
    {
        ref = new FileReference();
        ref.addEventListener(Event.SELECT, load);
        ref.browse([new FileFilter("SWF Files", "*.swf")]);
    }

    private function load(e:Event):void
    {
        ref.addEventListener(Event.COMPLETE, processSWF);
        ref.load();
    }

    private function processSWF(e:Event):void
    {
        var swf:ByteArray;
        switch(ref.data.readMultiByte(3, "us-ascii"))
        {
            case "CWS":
                swf = decompress(ref.data);
                break;
            case "FWS":
                swf = compress(ref.data);
                break;
            default:
                throw Error("Not SWF...");
                break;
        }

        new FileReference().save(swf);
    }

    private function compress(data:ByteArray):ByteArray
    {
        var header:ByteArray = new ByteArray();
        var decompressed:ByteArray = new ByteArray();
        var compressed:ByteArray = new ByteArray();

        header.writeBytes(data, 3, 5); //read the header, excluding the signature
        decompressed.writeBytes(data, 8); //read the rest

        decompressed.compress();

        compressed.writeMultiByte("CWS", "us-ascii"); //mark as compressed
        compressed.writeBytes(header);
        compressed.writeBytes(decompressed);

        return compressed;
    }

    private function decompress(data:ByteArray):ByteArray
    {
        var header:ByteArray = new ByteArray();
        var compressed:ByteArray = new ByteArray();
        var decompressed:ByteArray = new ByteArray();

        header.writeBytes(data, 3, 5); //read the uncompressed header, excluding the signature
        compressed.writeBytes(data, 8); //read the rest, compressed

        compressed.uncompress();

        decompressed.writeMultiByte("FWS", "us-ascii"); //mark as uncompressed
        decompressed.writeBytes(header); //write the header back
        decompressed.writeBytes(compressed); //write the now uncompressed content

        return decompressed;
    }

}
}

我的问题:这种方法不能解压 LZMA 压缩文件 :(

谁能告诉我如何重构上面的代码来实现 LZMA 解压缩以及上面的压缩代码是否足够好用于 LZMA 压缩?如果不是,请举个例子。

编辑:经过长时间的搜索,我得到了this 但我不太明白其中的示例代码:(有人帮忙吗?

【问题讨论】:

    标签: actionscript-3 bytearray compression lzma


    【解决方案1】:

    找到了一种解决方法,Flash 只有DEFLATEZLIB 压缩算法,所以我不得不等待LZMA 更新,这可能会发生也可能不会发生,或者创建我自己的实用程序,所以我得到了Python,经过几次脖子-花了几个小时试图弄清楚如何使用它,我终于能够得到我想要的。

    参考地点:

    1. The python code to decompress LZMA-format swf files
    2. The pylzma source file

    【讨论】:

      【解决方案2】:

      我只是想补充一下您编辑中提供的the link,以防有人偶然发现它并像我一样对格式感到困惑,它也有一些奇怪的东西,两次写入几个字节,所以这是我对其进行了大量修改的版本(文件部分需要 AIR)。例如。我放弃了按位运算符,转而使用 ByteArray 读/写函数。

      注意:至少现在AS3的ByteArray.decompress()支持LZMA解​​压,所以我在用那个,但它不直接支持SWF LZMA格式,只有LZMA,所以还有点修修补补请注意,此代码可能会有所改进。

      import flash.filesystem.File;
      import flash.filesystem.FileStream;
      import flash.filesystem.FileMode;
      import flash.utils.ByteArray; 
      
      function decompressLZMA(idata:ByteArray){
          idata.endian = "littleEndian"
          var signature:ByteArray = new ByteArray;
          //I 0-3 = signature + version
          idata.readBytes(signature, 0, 3)
          var version:uint = idata.readUnsignedByte()
          switch (signature[0]){
              case 90: // Z = lzma compressed
      
              var odata:ByteArray = new ByteArray;
              odata.endian = "littleEndian"
      
              var i:uint;
      
              //O 0-3 = signature + version
              signature[0] = 70 // F = uncompressed
              odata.writeBytes(signature)
              odata.writeByte(version)
      
              //I 4-7 = swf file length
              idata.position = 4
              var scriptlen:uint = idata.readUnsignedInt()
              //8 = swf header size
              scriptlen -= 8
      
              //O 4-7 swf file length
              odata.writeUnsignedInt(scriptlen + 8) // Re-add swf header removed earlier
      
              var tdata:ByteArray = new ByteArray;
              tdata.endian = "littleEndian"
              //I 12    = lzma properties
              //I 13-16 = lzma dictionary size
              idata.position = 12
              //T 0   = lzma properties
              //T 1-4 = lzma dictionary size
              tdata.writeByte(idata.readByte())
              tdata.writeUnsignedInt(idata.readUnsignedInt())
      
              // lzma uncompressed length is stored as LE UI64:
              //T 5-8 = uncompressed length
              tdata.writeUnsignedInt(scriptlen)
              //T 9-12 = uncompressed length continued
              tdata.writeUnsignedInt(0)
      
              //16 = LZMA header size
              idata.position = 17
              //12 = SWF LZMA header size
              idata.readBytes(tdata, 13, idata.length-idata.position)
      
              tdata.uncompress(CompressionAlgorithm.LZMA)
              odata.writeBytes(tdata)
              return odata;
      
              break
          }
          return idata;
      }
      
      var file:File;
      var stream:FileStream;
      var idata:ByteArray;
      var odata:ByteArray;
      var path:String
      
      path = File.applicationDirectory.resolvePath('LZMA.swf').nativePath;
      file = new File(path);
      stream = new FileStream();
      stream.open(file, FileMode.READ); 
      idata = new ByteArray
      stream.readBytes(idata)
      stream.close()
      
      odata = decompressLZMA(idata)
      
      path = File.applicationDirectory.resolvePath('LZMA_decompressed.swf').nativePath;
      file = new File(path);
      stream = new FileStream(); 
      stream.open(file, FileMode.WRITE);
      stream.writeBytes(odata)
      stream.close()
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-03-22
        • 2011-07-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多