コード例 #1
0
ファイル: ZLib.cs プロジェクト: tandj1116/pandorasbox3
        /// <summary>
        /// Decompresses data corresponding to a Serializable object
        /// </summary>
        /// <param name="data">The array of bytes representing the compressed stream</param>
        /// <param name="type">The type of the object being deserialized</param>
        /// <returns>A Serializable object</returns>
        public static object Decompress(byte[] data, Type type)
        {
            try
            {
                // Get length
                int length = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);

                byte[] actualData = new byte[data.Length - 4];
                Array.Copy(data, 4, actualData, 0, data.Length - 4);

                // Uncompress
                byte[] output = new byte[length];

                ZLibError result = uncompress(output, ref length, actualData, actualData.Length);

                if (result != ZLibError.Z_OK)
                {
                    return(null);
                }

                MemoryStream stream = new MemoryStream(output);

                XmlSerializer serializer = new XmlSerializer(type);

                object o = serializer.Deserialize(stream);

                stream.Close();

                return(o);
            }
            catch
            {
                return(null);
            }
        }
コード例 #2
0
        internal void FlushBuffer()
        {
            if (!m_IsCompressed || m_BufferAll || m_Buffer.Position <= 0)
            {
                return;
            }

            int outLen = (int)(m_Buffer.Position * 1.1);

            if (m_CompBuff == null || m_CompBuff.Length < outLen)
            {
                m_CompBuff = new byte[outLen];
            }
            else
            {
                outLen = m_CompBuff.Length;
            }

            ZLibError error = ZLib.compress2(m_CompBuff, ref outLen, m_Buffer.ToArray(), (int)m_Buffer.Position, ZLibCompressionLevel.Z_BEST_COMPRESSION);

            if (error != ZLibError.Z_OK)
            {
                throw new Exception("ZLib error during copression: " + error.ToString());
            }

            Raw.Write((int)outLen);
            Raw.Write((int)m_Buffer.Position);
            Raw.Write(m_CompBuff, 0, outLen);

            m_Buffer.Position = 0;
        }
コード例 #3
0
        public void Decompress(BinaryReader source, long offset, int clength, int ulength, bool compressed, BinaryWriter destination)
        {
            source.BaseStream.Seek(offset + m_DataOffset + 4, SeekOrigin.Begin);

            byte[] destData   = new byte[ulength];
            byte[] sourceData = new byte[clength];
            int    destLength = ulength;

            if (source.Read(sourceData, 0, clength) != clength)
            {
                throw new Exception("Error reading data from stream!");
            }

            if (compressed)
            {
                ZLibError error = Zlib.Decompress(destData, ref destLength, sourceData, clength);

                if (error != ZLibError.Okay)
                {
                    throw new Exception(String.Format("Error decompressing: {0}", error));
                }

                destination.Write(destData, 0, ulength);
            }
            else
            {
                destination.Write(sourceData, 0, clength);
            }
        }
コード例 #4
0
ファイル: Network.cs プロジェクト: blasterdude9/ForkUO-1
        public static Packet Compress(Packet p)
        {
            int length;

            byte[] source = p.Compile(false, out length);

            if (length > 100 && length < 60000)
            {
                byte[] dest     = new byte[(int)(length * 1.001) + 10];
                int    destSize = dest.Length;

                ZLibError error = Compression.Pack(dest, ref destSize, source, length, ZLibQuality.Default);

                if (error != ZLibError.Okay)
                {
                    Console.WriteLine("WARNING: Unable to compress admin packet, zlib error: {0}", error);
                    return(p);
                }
                else
                {
                    return(new AdminCompressedPacket(dest, destSize, length));
                }
            }
            else
            {
                return(p);
            }
        }
コード例 #5
0
ファイル: Network.cs プロジェクト: BackupTheBerlios/sunuo-svn
        public static Packet Compress(Packet p)
        {
            byte[] source = p.Compile(false);

            if (source.Length > 100 && source.Length < 60000)
            {
                byte[] dest     = new byte[(int)(source.Length * 1.001) + 1];
                int    destSize = dest.Length;

                ZLibError error = ZLib.compress2(dest, ref destSize, source, source.Length, ZLibCompressionLevel.Z_BEST_COMPRESSION);                  // best compression (slowest)

                if (error != ZLibError.Z_OK)
                {
                    log.Error(String.Format("Unable to compress admin packet, zlib error: {0}",
                                            error));
                    return(p);
                }
                else
                {
                    return(new AdminCompressedPacket(dest, destSize, source.Length));
                }
            }
            else
            {
                return(p);
            }
        }
コード例 #6
0
        public static byte[] BuildAdminCompressedConsoleDataPacketBuffer(string text)
        {
            byte[] internalbytes = ConsoleDataPacketTest.BuildConsoleDataPacketBuffer(text);

            byte[]    CompData = new byte[(int)(internalbytes.Length * 1.001) + 20];
            int       compLen  = 0;
            ZLibError error    = Compression.Pack(CompData, ref compLen, internalbytes, internalbytes.Length, ZLibQuality.Default);

            int packetLen = 1 + 2 + 2 + compLen;

            byte[] packetData = new byte[packetLen];
            int    index      = 0;

            packetData[index++] = (byte)ServerPacketId.AdminCompressed;
            packetData[index++] = (byte)((packetLen & 0xFF00) >> 8);
            packetData[index++] = (byte)(packetLen & 0xFF);
            packetData[index++] = (byte)((internalbytes.Length & 0xFF00) >> 8);
            packetData[index++] = (byte)(internalbytes.Length & 0xFF);

            for (int i = 0; i < compLen; i++)
            {
                packetData[index + i] = CompData[i];
            }

            return(packetData);
        }
コード例 #7
0
        public void ZLibCompressStreamTest()
        {
            ZLibCompressor target = new ZLibCompressor();

            string originalText = "Test string.";

            MemoryStream msOriginal = new MemoryStream(ASCIIEncoding.ASCII.GetBytes(originalText));

            byte[]       compressbuffer = new byte[2000];
            MemoryStream msCompressed   = new MemoryStream(compressbuffer);

            int outLen = 0;

            ZLibError err = target.Compress(msOriginal, msCompressed, ref outLen, ZLibQuality.Default);

            Assert.AreEqual(ZLibError.Okay, err);

            MemoryStream msToDecompress = new MemoryStream(compressbuffer, 0, outLen);

            byte[]       decompressbuffer = new byte[2000];
            MemoryStream msFinalResult    = new MemoryStream(decompressbuffer);

            err = target.Decompress(msToDecompress, msFinalResult, ref outLen);
            Assert.AreEqual(ZLibError.Okay, err);

            string result = ASCIIEncoding.ASCII.GetString(decompressbuffer, 0, outLen);

            Assert.AreEqual(originalText, result);
        }
コード例 #8
0
        public static Packet Compress(Packet p)
        {
            int length;

            byte[] source = p.Compile(false, out length);

            if (length > 100 && length < 60000)
            {
                byte[] dest     = new byte[(int)(length * 1.001) + 1];
                int    destSize = dest.Length;

                ZLibError error = ZLib.compress2(dest, ref destSize, source, length, ZLibCompressionLevel.Z_BEST_COMPRESSION);                   // best compression (slowest)

                if (error != ZLibError.Z_OK)
                {
                    Console.WriteLine("WARNING: Unable to compress admin packet, zlib error: {0}", error);
                    return(p);
                }
                else
                {
                    return(new AdminCompressedPacket(dest, destSize, length));
                }
            }
            else
            {
                return(p);
            }
        }
コード例 #9
0
        /// <summary>
        /// Unpacks this file<paramref name="source"/>.
        /// </summary>
        /// <param name="source">Binary file (.uop source).</param>
        /// <returns>Binary data from this file.</returns>
        public byte[] Unpack(BinaryReader source)
        {
            source.BaseStream.Seek(m_DataBlockAddress + m_DataBlockLength, SeekOrigin.Begin);

            byte[] sourceData = new byte[m_CompressedSize];

            if (source.Read(sourceData, 0, m_CompressedSize) != m_CompressedSize)
            {
                throw new StreamSourceException();
            }

            switch (m_Compression)
            {
            case CompressionFlag.Zlib:
            {
                byte[]    destData   = new byte[m_DecompressedSize];
                int       destLength = m_DecompressedSize;
                ZLibError error      = Zlib.Decompress(destData, ref destLength, sourceData, m_CompressedSize);

                if (error != ZLibError.Okay)
                {
                    throw new CompressionException(error);
                }

                return(destData);
            }

            case CompressionFlag.None:
            {
                return(sourceData);
            }
            }

            return(null);
        }
コード例 #10
0
        public ZLibError Decompress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
        {
            long      destLengthLong = destLength;
            ZLibError z = SafeNativeMethods.uncompress(dest, ref destLengthLong, source, sourceLength);

            destLength = (int)destLengthLong;
            return(z);
        }
コード例 #11
0
        public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength, ZLibQuality quality)
        {
            long      destLengthLong = destLength;
            ZLibError z = SafeNativeMethods.compress2(dest, ref destLengthLong, source, sourceLength, quality);

            destLength = (int)destLengthLong;
            return(z);
        }
コード例 #12
0
        public ZLibError Compress(byte[] dest, ref int destLength, byte[] source, int sourceLength, ZLibQuality quality)
        {
            ulong     destLengthLong = (ulong)destLength;
            ZLibError z = compress2(dest, ref destLengthLong, source, sourceLength, quality);

            destLength = (int)destLengthLong;
            return(z);
        }
コード例 #13
0
        public ZLibError Decompress(byte[] dest, ref int destLength, byte[] source, int sourceLength)
        {
            ulong     destLengthLong = (ulong)destLength;
            ZLibError z = uncompress(dest, ref destLengthLong, source, sourceLength);

            destLength = (int)destLengthLong;
            return(z);
        }
コード例 #14
0
        /// <summary>
        /// Updates <see cref="Mythic.Package.MythicPackageFile.DataBlockAddress"/> within .uop file,
        /// <see cref="Mythic.Package.MythicPackageFile.CompressedSize"/> and <see cref="Mythic.Package.MythicPackageFile.DecompressedSize"/>.
        /// </summary>
        /// <param name="pointer">Address of <see cref="Mythic.Package.MythicPackageFile.DataBlockAddress"/>.</param>
        public void UpdateOffsets(ref long pointer)
        {
            m_DataBlockAddress = pointer;
            m_DataBlockLength  = 0;            // Custom .uop files don't need data header.

            if (m_Added || m_Modified)
            {
                if (!File.Exists(m_SourceFileName))
                {
                    throw new FileNotFoundException();
                }

                FileInfo info = new FileInfo(m_SourceFileName);

                m_CompressedSize   = (int)info.Length;
                m_DecompressedSize = (int)info.Length;

                byte[] sourceBuffer;

                using (BinaryReader reader = new BinaryReader(info.OpenRead()))
                {
                    sourceBuffer = reader.ReadBytes(m_DecompressedSize);
                }

                if (sourceBuffer.Length < 4)
                {
                    m_Compression = CompressionFlag.None;
                }

                switch (m_Compression)
                {
                case CompressionFlag.Zlib:
                {
                    m_SourceBuffer = new byte[m_CompressedSize];
                    ZLibError error = Zlib.Compress(m_SourceBuffer, ref m_CompressedSize, sourceBuffer, m_DecompressedSize, ZLibQuality.Speed);

                    if (error != ZLibError.Okay)
                    {
                        throw new CompressionException(error);
                    }

                    break;
                }

                case CompressionFlag.None:
                {
                    m_SourceBuffer = sourceBuffer;
                    break;
                }
                }
            }
            else
            {
                m_SourceBuffer = null;
            }

            pointer += m_DataBlockLength + m_CompressedSize;
        }
コード例 #15
0
        public override int Read(byte[] buffer, int offset, int count)
        {
            if (m_Compressed)
            {
                long pos = m_Uncomp.Position;
                m_Uncomp.Seek(0, SeekOrigin.End);

                while (pos + count > m_Uncomp.Length && RawStream.Position + 8 < RawStream.Length)
                {
                    int block = Raw.ReadInt32();
                    int ucLen = Raw.ReadInt32();

                    if (block > 0x10000000 || block <= 0 || ucLen > 0x10000000 || ucLen <= 0)
                    {
                        break;
                    }

                    if (RawStream.Position + block > RawStream.Length)
                    {
                        break;
                    }

                    if (m_ReadBuff == null || m_ReadBuff.Length < block)
                    {
                        m_ReadBuff = new byte[block];
                    }

                    if (m_CompBuff == null || m_CompBuff.Length < ucLen)
                    {
                        m_CompBuff = new byte[ucLen];
                    }
                    else
                    {
                        ucLen = m_CompBuff.Length;
                    }

                    Raw.Read(m_ReadBuff, 0, block);

                    ZLibError error = ZLib.uncompress(m_CompBuff, ref ucLen, m_ReadBuff, block);
                    if (error != ZLibError.Z_OK)
                    {
                        throw new Exception("ZLib error uncompressing: " + error.ToString());
                    }

                    m_Uncomp.Write(m_CompBuff, 0, ucLen);
                }

                m_Uncomp.Position = pos;
                return(m_Uncomp.Read(buffer, offset, count));
            }
            else
            {
                return(RawStream.Read(buffer, offset, count));
            }
        }
コード例 #16
0
        public override long Seek(long offset, SeekOrigin origin)
        {
            if (m_Compressed)
            {
                long absPos = offset;
                if (origin == SeekOrigin.Current)
                {
                    absPos += m_Uncomp.Position;
                }

                if (absPos < 0)
                {
                    throw new Exception("Cannot seek past the begining of the stream.");
                }

                long pos = m_Uncomp.Position;
                m_Uncomp.Seek(0, SeekOrigin.End);

                while ((origin == SeekOrigin.End || absPos >= m_Uncomp.Length) && RawStream.Position < RawStream.Length)
                {
                    int block = Raw.ReadInt32();
                    int ucLen = Raw.ReadInt32();
                    if (m_ReadBuff == null || m_ReadBuff.Length < block)
                    {
                        m_ReadBuff = new byte[block];
                    }

                    if (m_CompBuff == null || m_CompBuff.Length < ucLen)
                    {
                        m_CompBuff = new byte[ucLen];
                    }
                    else
                    {
                        ucLen = m_CompBuff.Length;
                    }

                    Raw.Read(m_ReadBuff, 0, block);

                    ZLibError error = ZLib.uncompress(m_CompBuff, ref ucLen, m_ReadBuff, block);
                    if (error != ZLibError.Z_OK)
                    {
                        throw new Exception("ZLib error uncompressing: " + error.ToString());
                    }

                    m_Uncomp.Write(m_CompBuff, 0, ucLen);
                }

                m_Uncomp.Position = pos;
                return(m_Uncomp.Seek(offset, origin));
            }
            else
            {
                return(RawStream.Seek(offset, origin));
            }
        }
コード例 #17
0
        public static unsafe ZLibError Unpack(Span <byte> dest, ref int destLength, ReadOnlySpan <byte> source, int sourceLength)
        {
            ulong destLengthLong = (ulong)destLength;

            fixed(byte *dPtr = &MemoryMarshal.GetReference(dest), sPtr = &MemoryMarshal.GetReference(source))
            {
                ZLibError e = Compressor.Decompress(Unsafe.AsRef <int>(dPtr), ref destLengthLong, Unsafe.AsRef <int>(sPtr), (ulong)sourceLength);

                destLength = (int)destLengthLong;
                return(e);
            }
        }
コード例 #18
0
ファイル: ZLib.cs プロジェクト: tandj1116/pandorasbox3
        /// <summary>
        /// Compresses a Serializable object
        /// </summary>
        /// <param name="source">The Serializable object that should be compressed</param>
        /// <returns>An array of bytes</returns>
        public static byte[] Compress(object source)
        {
            try
            {
                // Xml serialization to a stream
                XmlSerializer serializer = new XmlSerializer(source.GetType());
                MemoryStream  stream     = new MemoryStream();
                serializer.Serialize(stream, source);

                // Convert stream to bytes
                byte[] SourceBytes = stream.ToArray();

                stream.Close();

                int length = SourceBytes.Length;

                // Create output array
                int    DestLength = SourceBytes.Length + 1;
                byte[] Dest       = new byte[DestLength];

                // Compression
                ZLibError result = compress2(Dest, ref DestLength, SourceBytes, SourceBytes.Length, ZLibCompressionLevel.Z_BEST_COMPRESSION);

                if (result != ZLibError.Z_OK)
                {
                    return(new byte[0]);
                }
                else
                {
                    // Trim the results according to the useful length
                    byte[] compressed = new byte[DestLength + 4];

                    Array.Copy(Dest, 0, compressed, 4, DestLength);

                    // Copy length to the start of the array
                    compressed[0] = (byte)length;
                    compressed[1] = (byte)(length >> 8);
                    compressed[2] = (byte)(length >> 16);
                    compressed[3] = (byte)(length >> 24);

                    return(compressed);
                }
            }
            catch (Exception err)
            {
                System.Windows.Forms.Clipboard.SetDataObject(err.ToString());
                return(new byte[0]);
            }
        }
コード例 #19
0
ファイル: UopData.cs プロジェクト: lxq2537664558/Source2
        public byte[] Extract(bool isCompressed, uint uncompressedLength)
        {
            if (!isCompressed)
            {
                return(m_CompressedData);
            }
            else
            {
                int       iUncompressLength = ((int)(uncompressedLength));
                byte[]    bUnCompressData   = new byte[iUncompressLength];
                ZLibError zResult           = Compressor.Decompress(bUnCompressData, ref iUncompressLength, m_CompressedData, m_CompressedData.Length);

                return((zResult == ZLibError.Okay) ? bUnCompressData : null);
            }
        }
コード例 #20
0
        public static byte[] Compress(byte[] inFile)
        {
            byte[] outFile   = new byte[inFile.Length + 64];
            int    outLength = -1;

            ZLibError err = compress2(outFile, ref outLength, inFile, inFile.Length, 6);

            if (err == ZLibError.Z_OK && (outLength > -1 && outLength < inFile.Length))
            {
                Array.Resize(ref outFile, outLength);
                return(outFile);
            }
            else
            {
                throw new Exception("An error occured while compressing! Code: " + err.ToString());
            }
        }
コード例 #21
0
ファイル: ZLib.cs プロジェクト: BackupTheBerlios/sunuo-svn
 public static ZLibError compress(byte[] dest, ref int destLength,
                                  byte[] source, int sourceLength)
 {
     if (unix)
     {
         long      dl2 = destLength;
         ZLibError ret = ZLibUnix.compress(dest, ref dl2,
                                           source, sourceLength);
         destLength = (int)dl2;
         return(ret);
     }
     else
     {
         return(ZLibWin32.compress(dest, ref destLength,
                                   source, sourceLength));
     }
 }
コード例 #22
0
ファイル: ZLib.cs プロジェクト: BackupTheBerlios/sunuo-svn
 public static ZLibError uncompress(byte[] dest, ref int destLen,
                                    byte[] source, int sourceLen)
 {
     if (unix)
     {
         long      dl2 = destLen;
         ZLibError ret = ZLibUnix.uncompress(dest, ref dl2,
                                             source, sourceLen);
         destLen = (int)dl2;
         return(ret);
     }
     else
     {
         return(ZLibWin32.uncompress(dest, ref destLen,
                                     source, sourceLen));
     }
 }
コード例 #23
0
ファイル: ZLib.cs プロジェクト: tandj1116/pandorasbox3
        /// <summary>
        /// Decompresses a stream of bytes
        /// </summary>
        /// <param name="data">The bytes stream to decompress</param>
        /// <returns>The decompressed stream</returns>
        public static byte[] Decompress(byte[] data)
        {
            int length = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);

            byte[] realData = new byte[data.Length - 4];
            Array.Copy(data, 4, realData, 0, data.Length - 4);

            byte[] result = new byte[length];

            ZLibError err = uncompress(result, ref length, realData, realData.Length);

            if (err != ZLibError.Z_OK)
            {
                return(null);
            }

            return(result);
        }
コード例 #24
0
ファイル: ZLib.cs プロジェクト: dpisanu/xrunuo
 public static ZLibError compress2(byte[] dest, ref int destLength, byte[] source, int sourceLength, ZLibCompressionLevel level)
 {
     if (Core.Unix)
     {
         long      dl2 = destLength;
         ZLibError ret = ZLibUnix.compress2(dest, ref dl2, source, sourceLength, level);
         destLength = (int)dl2;
         return(ret);
     }
     else if (Core.Is64Bit)
     {
         return(ZLibWin64.compress2(dest, ref destLength, source, sourceLength, level));
     }
     else
     {
         return(ZLibWin32.compress2(dest, ref destLength, source, sourceLength, level));
     }
 }
コード例 #25
0
ファイル: UltimaPackage.cs プロジェクト: uotools/SpyUO-1
        /// <summary>
        /// Gets file data.
        /// </summary>
        /// <param name="fileNameHash">File hash.</param>
        /// <returns>File data.</returns>
        public byte[] GetFile(ulong fileNameHash)
        {
            UltimaPackageFile file = null;

            if (!_Files.TryGetValue(fileNameHash, out file))
            {
                return(null);
            }

            _Stream.Seek(file.FileAddress, SeekOrigin.Begin);

            byte[] compressed = new byte[file.CompressedSize];

            if (_Reader.Read(compressed, 0, file.CompressedSize) != file.CompressedSize)
            {
                throw new FileLoadException("Error reading file");
            }

            if (file.Compression == FileCompression.Zlib)
            {
                int    decompressedSize = file.DecompressedSize;
                byte[] decompressed     = new byte[decompressedSize];

                ZLibError error = Zlib.Decompress(decompressed, ref decompressedSize, compressed, compressed.Length);

                if (decompressedSize != file.DecompressedSize)
                {
                    throw new PackageException("Error decompressing vile. Decompressed length missmatch. Defined={0} Actual={1}", file.DecompressedSize, decompressedSize);
                }

                if (error == ZLibError.Okay)
                {
                    return(decompressed);
                }

                throw new PackageException("Error decompressing file. Error={0}", error);
            }

            return(compressed);
        }
コード例 #26
0
 /// <summary>
 /// Initializes a new instance.
 /// </summary>
 public CompressionException(ZLibError error) : base(string.Format("Error compressing/decompressing: {0}", error))
 {
 }
コード例 #27
0
        internal static R_MythicPackageData Pack(string current_file)
        {
            /*
             * * [4] - Data Block/File (sizeof: 12+Lenght bytes)
             * * WORD -> flag compressed ( 0008 )
             * * WORD -> offset  ( 0003 )
             * * QWORD -> FileTime
             * * BYTE(Lenght) 0xd88 -> compressed data
             * * ...this is repeated until all Files from FileIndexes are processed
             */
            FileStream reading = new FileStream(current_file, FileMode.Open);

            int usize = (int)reading.Length;            //Stream Size
            int csize = usize;                          //Compressed Size REF

            byte[] sourceData = new byte[usize];        //Stream to be compressed
            byte[] destData   = new byte[csize];        //Stream compressed
            bool   compressed = true;                   //Must say if datas are TO BE compressed or not.


            R_MythicPackageData final = new R_MythicPackageData();

            using (BinaryReader reader = new BinaryReader(reading))
            {
                reader.Read(sourceData, 0, usize);
            }
            if (sourceData.Length <= 10)//If file length is less than 10 bytes we do not compress it.
            {
                compressed = false;
            }

            if (compressed)
            {
                ZLibError error = Zlib.Zlib.Compress(destData, ref csize, sourceData, usize);

                if (error != ZLibError.Okay)
                {
                    throw new Exception(String.Format("Error Compressing: {0}", error));
                }
            }
            else
            {
                csize    = usize;
                destData = sourceData;
            }

            final.Flag       = 3;                                //Is this fixed?
            final.DataOffset = 8;                                //And this?
            final.DateTime   = System.DateTime.Now.ToFileTime(); //To check
            byte[] compressedData = new byte[csize];
            for (int i = 0; i < csize; i++)
            {
                compressedData[i] = destData[i];
            }
            final.Data       = compressedData; //Ok
            final.Compressed = compressed;     //Ok
            final.C_size     = csize;          //Ok
            final.U_size     = usize;          //Ok

            return(final);
        }
コード例 #28
0
ファイル: Packets.cs プロジェクト: DarkLotus/Klip
        public DesignStateDetailed(Serial serial, int revision, int xMin, int yMin, int xMax, int yMax, MultiTileEntry[] tiles) : base(0xD8)
        {
            EnsureCapacity(17 + (tiles.Length * 5));

            Write((byte)0x03);                // Compression Type
            Write((byte)0x00);                // Unknown
            Write((uint)serial);
            Write((int)revision);
            Write((short)tiles.Length);
            Write((short)0);               // Buffer length : reserved
            Write((byte)0);                // Plane count : reserved

            int totalLength = 1;           // includes plane count

            int width  = (xMax - xMin) + 1;
            int height = (yMax - yMin) + 1;

            if (m_PlaneBuffers == null)
            {
                m_PlaneBuffers = new byte[9][];
                m_PlaneUsed    = new bool[9];

                for (int i = 0; i < m_PlaneBuffers.Length; ++i)
                {
                    m_PlaneBuffers[i] = new byte[0x400];
                }

                m_StairBuffers = new byte[6][];

                for (int i = 0; i < m_StairBuffers.Length; ++i)
                {
                    m_StairBuffers[i] = new byte[MaxItemsPerStairBuffer * 5];
                }
            }
            else
            {
                for (int i = 0; i < m_PlaneUsed.Length; ++i)
                {
                    m_PlaneUsed[i] = false;
                }

                Clear(m_PlaneBuffers[0], width * height * 2);

                for (int i = 0; i < 4; ++i)
                {
                    Clear(m_PlaneBuffers[1 + i], (width - 1) * (height - 2) * 2);
                    Clear(m_PlaneBuffers[5 + i], width * (height - 1) * 2);
                }
            }

            int totalStairsUsed = 0;

            for (int i = 0; i < tiles.Length; ++i)
            {
                MultiTileEntry mte = tiles[i];
                int            x = mte.m_OffsetX - xMin;
                int            y = mte.m_OffsetY - yMin;
                int            z = mte.m_OffsetZ;
                int            plane, size;
                bool           floor = false;
                try
                {
                    floor = (Ultima.TileData.ItemTable[mte.m_ItemID & 0x3FFF].Height <= 0);
                }
                catch
                {
                }

                switch (z)
                {
                case 0: plane = 0; break;

                case 7: plane = 1; break;

                case 27: plane = 2; break;

                case 47: plane = 3; break;

                case 67: plane = 4; break;

                default:
                {
                    int    stairBufferIndex = (totalStairsUsed / MaxItemsPerStairBuffer);
                    byte[] stairBuffer      = m_StairBuffers[stairBufferIndex];

                    int byteIndex = (totalStairsUsed % MaxItemsPerStairBuffer) * 5;

                    stairBuffer[byteIndex++] = (byte)((mte.m_ItemID >> 8) & 0x3F);
                    stairBuffer[byteIndex++] = (byte)mte.m_ItemID;

                    stairBuffer[byteIndex++] = (byte)mte.m_OffsetX;
                    stairBuffer[byteIndex++] = (byte)mte.m_OffsetY;
                    stairBuffer[byteIndex++] = (byte)mte.m_OffsetZ;

                    ++totalStairsUsed;

                    continue;
                }
                }

                if (plane == 0)
                {
                    size = height;
                }
                else if (floor)
                {
                    size = height - 2;
                    x   -= 1;
                    y   -= 1;
                }
                else
                {
                    size   = height - 1;
                    plane += 4;
                }

                int index = ((x * size) + y) * 2;

                m_PlaneUsed[plane]               = true;
                m_PlaneBuffers[plane][index]     = (byte)((mte.m_ItemID >> 8) & 0x3F);
                m_PlaneBuffers[plane][index + 1] = (byte)mte.m_ItemID;
            }

            int planeCount = 0;

            for (int i = 0; i < m_PlaneBuffers.Length; ++i)
            {
                if (!m_PlaneUsed[i])
                {
                    continue;
                }

                ++planeCount;

                int size = 0;

                if (i == 0)
                {
                    size = width * height * 2;
                }
                else if (i < 5)
                {
                    size = (width - 1) * (height - 2) * 2;
                }
                else
                {
                    size = width * (height - 1) * 2;
                }

                byte[] inflatedBuffer = m_PlaneBuffers[i];

                int       deflatedLength = m_DeflatedBuffer.Length;
                ZLibError ce             = ZLib.compress2(m_DeflatedBuffer, ref deflatedLength, inflatedBuffer, size, ZLibCompressionLevel.Z_DEFAULT_COMPRESSION);

                if (ce != ZLibError.Z_OK)
                {
                    Console.WriteLine("ZLib error: {0} (#{1})", ce, (int)ce);
                    deflatedLength = 0;
                    size           = 0;
                }

                Write((byte)(0x20 | i));
                Write((byte)size);
                Write((byte)deflatedLength);
                Write((byte)(((size >> 4) & 0xF0) | ((deflatedLength >> 8) & 0xF)));
                Write(m_DeflatedBuffer, 0, deflatedLength);

                totalLength += 4 + deflatedLength;
            }

            int totalStairBuffersUsed = (totalStairsUsed + (MaxItemsPerStairBuffer - 1)) / MaxItemsPerStairBuffer;

            for (int i = 0; i < totalStairBuffersUsed; ++i)
            {
                ++planeCount;

                int count = (totalStairsUsed - (i * MaxItemsPerStairBuffer));

                if (count > MaxItemsPerStairBuffer)
                {
                    count = MaxItemsPerStairBuffer;
                }

                int size = count * 5;

                byte[] inflatedBuffer = m_StairBuffers[i];

                int       deflatedLength = m_DeflatedBuffer.Length;
                ZLibError ce             = ZLib.compress2(m_DeflatedBuffer, ref deflatedLength, inflatedBuffer, size, ZLibCompressionLevel.Z_DEFAULT_COMPRESSION);

                if (ce != ZLibError.Z_OK)
                {
                    Console.WriteLine("ZLib error: {0} (#{1})", ce, (int)ce);
                    deflatedLength = 0;
                    size           = 0;
                }

                Write((byte)(9 + i));
                Write((byte)size);
                Write((byte)deflatedLength);
                Write((byte)(((size >> 4) & 0xF0) | ((deflatedLength >> 8) & 0xF)));
                Write(m_DeflatedBuffer, 0, deflatedLength);

                totalLength += 4 + deflatedLength;
            }

            Seek(15, System.IO.SeekOrigin.Begin);

            Write((short)totalLength);              // Buffer length
            Write((byte)planeCount);                // Plane count

            /*int planes = (tiles.Length + (MaxItemsPerPlane - 1)) / MaxItemsPerPlane;
             *
             * if ( planes > 255 )
             *      planes = 255;
             *
             * int totalLength = 0;
             *
             * Write( (byte) planes );
             ++totalLength;
             *
             * int itemIndex = 0;
             *
             * for ( int i = 0; i < planes; ++i )
             * {
             *      int byteIndex = 0;
             *
             *      for ( int j = 0; j < MaxItemsPerPlane && itemIndex < tiles.Length; ++j, ++itemIndex )
             *      {
             *              MultiTileEntry e = tiles[itemIndex];
             *
             *              m_InflatedBuffer[byteIndex++] = (byte)((e.m_ItemID >> 8) & 0x3F);
             *              m_InflatedBuffer[byteIndex++] = (byte)e.m_ItemID;
             *              m_InflatedBuffer[byteIndex++] = (byte)e.m_OffsetX;
             *              m_InflatedBuffer[byteIndex++] = (byte)e.m_OffsetY;
             *              m_InflatedBuffer[byteIndex++] = (byte)e.m_OffsetZ;
             *      }
             *
             *      int deflatedLength = m_DeflatedBuffer.Length;
             *      ZLibError ce = ZLib.compress2( m_DeflatedBuffer, ref deflatedLength, m_InflatedBuffer, byteIndex, ZLibCompressionLevel.Z_DEFAULT_COMPRESSION );
             *
             *      if ( ce != ZLibError.Z_OK )
             *      {
             *              Console.WriteLine( "ZLib error: {0} (#{1})", ce, (int)ce );
             *              deflatedLength = 0;
             *              byteIndex = 0;
             *      }
             *
             *      Write( (byte) 0x00 );
             *      Write( (byte) byteIndex );
             *      Write( (byte) deflatedLength );
             *      Write( (byte) (((byteIndex >> 4) & 0xF0) | ((deflatedLength >> 8) & 0xF)) );
             *      Write( m_DeflatedBuffer, 0, deflatedLength );
             *
             *      totalLength += 4 + deflatedLength;
             * }
             *
             * Seek( 15, System.IO.SeekOrigin.Begin );
             * Write( (short) totalLength ); // Buffer length*/
        }
コード例 #29
0
        public bool Write()
        {
            String[] files   = null;
            String   uopname = "";

            if (this.p is MapParameter)
            {
                IComparer icomp = new MapFileComparer();
                files = Directory.GetFiles(p.temppath, "facet" + ((MapParameter)p).facetId + "*.*");
                Array.Sort(files, icomp);
                uopname = "facet" + ((MapParameter)p).facetId + ".uop";
            }
            foreach (String filename in files)
            {
                byte[]    source  = File.ReadAllBytes(filename);
                byte[]    dest    = new byte[(int)(source.Length * 1.1 + 12)];
                int       destlen = dest.Length;
                ZLibError res     = Compressor.Compress(dest, ref destlen, source, source.Length);
                if (res != ZLibError.Okay)
                {
                    err.WriteLine("Error compressing " + filename + ", error code:" + (int)res);
                    err.Close();
                    return(false);
                }
                if (destlen != dest.Length)
                {
                    byte[] desttemp = new byte[destlen];
                    Array.Copy(dest, desttemp, destlen);
                    dest = desttemp;
                }
                File.WriteAllBytes(p.temppath + filename + ".zlib", dest);
            }
            File.Delete(p.temppath.Replace("Temp\\", "") + uopname);
            uopfile = new BinaryWriter(File.OpenWrite(p.temppath.Replace("Temp\\", "") + uopname));

            // Header

            uopfile.Write(new byte[] { (byte)'M', (byte)'Y', (byte)'P', 0 });
            uopfile.Write((uint)4);          //Version
            uopfile.Write((uint)0xFD23EC43); //File Time
            uopfile.Write((uint)40);         //Header size
            uopfile.Write((uint)0);          // Empty
            uopfile.Write((uint)0x64);       //Block size
            uopfile.Write((uint)files.Length);
            uopfile.Write((ulong)0);         // Unk
            uopfile.Write((uint)0);          //Unk

            int numIndex = files.Length / 100;

            if ((numIndex * 100) < files.Length)
            {
                numIndex++;
            }

            int      realindex;
            FileInfo compressed, uncompressed;
            int      i, j;

            for (i = 0; i < numIndex; i++)
            {
                List <UOPFileData>     datas   = new List <UOPFileData>();
                List <UOPFileIndexDef> indexes = new List <UOPFileIndexDef>();

                ulong totalLengthData = 0;
                for (j = 0; j < ((numIndex == i - 1)?files.Length - ((numIndex - 1) * 100):100); j++)
                {
                    realindex    = i * 100 + j;
                    compressed   = new FileInfo(files[realindex] + ".zlib");
                    uncompressed = new FileInfo(files[realindex]);
                    UOPFileData filedata = new UOPFileData();
                    filedata.m_CompressedData = File.ReadAllBytes(files[realindex] + ".zlib");
                    filedata.m_FileTime       = compressed.LastAccessTime.ToFileTime();
                    UOPFileIndexDef def = new UOPFileIndexDef();
                    def.m_OffsetOfDataBlock  = (ulong)(uopfile.BaseStream.Position) + ((ulong)(UOPFileIndexDef.SIZE * 100)) + totalLengthData;
                    def.m_LenghtCompressed   = (uint)compressed.Length;
                    def.m_LenghtUncompressed = (uint)uncompressed.Length;
                    def.adlerCRC32           = filedata.Hash();
                    def.fileHash             = FileNameHasher.HashFileName(uncompressed.Name); // Controllare questo
                    datas.Add(filedata);
                    indexes.Add(def);
                    totalLengthData += filedata.GetLength();
                }
            }

            uopfile.Close();
            err.Close();
            return(true);
        }