Ejemplo n.º 1
0
        internal static byte[] Compress(byte[] bytesToCompress, CompressionFlavor flavor)
        {
            if (bytesToCompress == null)
            {
                throw new InvalidDataException("Cannot compress null array");
            }

            if (flavor == CompressionFlavor.StoreUncompressed)
            {
                throw new InvalidOperationException("Chunk format cannot be used for uncompressed data");
            }

            MemoryStream output = new MemoryStream(bytesToCompress.Length);
            BinaryWriter writer = new BinaryWriter(output);

            writer.Write(Chunk.Header);
            writer.Write(Chunk.DefaultVersion);
            writer.Write((byte)CompressionMethod.ZLib);
            writer.Write(NoObfuscation);

            using (MemoryStream compressedStream = new MemoryStream(bytesToCompress.Length))
            {
                compressedStream.WriteByte(0x78); //ZLib header first byte
                compressedStream.WriteByte(0xDA); //ZLib header second byte

                switch (flavor)
                {
                case CompressionFlavor.ZLibDeflate:
                    using (DeflateStream deflateStream = new DeflateStream(compressedStream, CompressionLevel.Optimal, true))
                        deflateStream.Write(bytesToCompress, 0, bytesToCompress.Length);
                    break;

                case CompressionFlavor.i5ZopfliDeflate:
                case CompressionFlavor.i10ZopfliDeflate:
                case CompressionFlavor.i15ZopfliDeflate:

                    if (bytesToCompress.Length < Strategy.ZopfliBreakEven)    //Skip Zopfli if file is small
                    {
                        goto case CompressionFlavor.ZLibDeflate;
                    }

                    ZopfliDeflater zstream = new ZopfliDeflater(compressedStream);
                    zstream.NumberOfIterations = (int)flavor;
                    zstream.MasterBlockSize    = 0;
                    zstream.Deflate(bytesToCompress, true);
                    break;

                default:
                    throw new InvalidOperationException("Unknow compression flavor");
                }
                var compressedDataArray = compressedStream.ToArray();           //Change to stream
                int checksum            = ComputeChecksum(compressedDataArray); //Change to stream

                writer.Write(compressedDataArray.Length);
                writer.Write(bytesToCompress.Length);
                writer.Write(checksum);
                writer.Write(compressedDataArray);
            }
            return(output.ToArray());
        }
Ejemplo n.º 2
0
        internal void CompressIDAT(bool useZopfli)
        {
            byte[] data = idat.GetChunkData();
            using (MemoryStream inputStream = new MemoryStream(data, 2, data.Length - 6))
            {
                using (MemoryStream tempStream = new MemoryStream())
                {
                    using (DeflateStream inflateStream = new DeflateStream(inputStream, CompressionMode.Decompress, true))
                    {
                        inflateStream.CopyTo(tempStream);
                    }
                    //ZOutputStream zOutputStream1 = new ZOutputStream(tempStream);
                    //CopyStream(inputStream, zOutputStream1);
                    //zOutputStream1.Flush();

                    tempStream.Position = 0;
                    using (MemoryStream outputStream = new MemoryStream())
                    {
                        if (useZopfli)
                        {
                            outputStream.Write(zlibBestCompressionFlag, 0, 2);
                            byte[] dataRaw = new byte[tempStream.Length];
                            tempStream.Read(dataRaw, 0, dataRaw.Length);
                            ZopfliDeflater zopfliDeflater = new ZopfliDeflater(outputStream);
                            zopfliDeflater.Deflate(dataRaw, false);
                        }
                        else
                        {
                            ZOutputStream zOutputStream = new ZOutputStream(outputStream, zlibConst.Z_NO_COMPRESSION);
                            CopyStream(tempStream, zOutputStream);
                            zOutputStream.Flush();
                            //outputStream.Write(zlibNoCompressionFlag, 0, 2);
                            //using (DeflateStream deflateStream = new DeflateStream(outputStream, CompressionLevel.NoCompression, true))
                            //{
                            //    tempStream.CopyTo(deflateStream, 34572);
                            //}
                        }

                        byte[] dataNew = new byte[outputStream.Length];
                        outputStream.Position = 0;
                        outputStream.Read(dataNew, 0, dataNew.Length);
                        for (int j = 0; j < dataNew.Length; j++)
                        {
                            if (data[j] != dataNew[j])
                            {
                                Console.WriteLine("{0:D}", j);
                            }
                        }

                        idat.SetChunkData(dataNew);
                        idat.Refresh();
                    }
                }
            }
        }