示例#1
0
        /// <summary>
        /// Takes regular image data and returns it in a compressed form ready for archiving
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public byte[] CompressTex(byte[] data)
        {
            int chunkSize = 131072; //Set at this stage. Easy to change later
            int noChunks = (data.Length + chunkSize - 1) / chunkSize;
            CompressedChunkBlock[] chunks = new CompressedChunkBlock[noChunks];
            int pos = 0;
            for (int i = 0; i < noChunks; i++)
            {
                if (data.Length - (pos + chunkSize) < 0)
                {
                    chunks[i].uncSize = data.Length - pos;
                    chunks[i].rawData = new byte[chunks[i].uncSize];
                    Buffer.BlockCopy(data, pos, chunks[i].rawData, 0, chunks[i].uncSize);
                    pos += chunks[i].uncSize;
                }
                else
                {
                    chunks[i].uncSize = chunkSize;
                    chunks[i].rawData = new byte[chunkSize];
                    Buffer.BlockCopy(data, pos, chunks[i].rawData, 0, chunkSize);
                    pos += chunks[i].uncSize;
                }
            }
            pos = 0;
            CompressedChunkBlock[] newChunks = new CompressedChunkBlock[noChunks];
            for (int i = 0; i < noChunks; i++)
            {
                newChunks[i].rawData = LZO1X.Compress(chunks[i].rawData);
                newChunks[i].cprSize = newChunks[i].rawData.Length;
                newChunks[i].uncSize = chunks[i].uncSize;
                pos += newChunks[i].cprSize;
            }
            byte[] result;
            using (MemoryStream stream = new MemoryStream())
            {
                byte[] magic = new byte[] { 0xC1, 0x83, 0x2A, 0x9E, 0x00, 0x00, 0x02, 0x00 };
                pos = Gibbed.IO.NumberHelpers.LittleEndian(pos);
                BinaryWriter bin = new BinaryWriter(stream);
                bin.Write(magic);
                bin.Write(pos);
                pos = Gibbed.IO.NumberHelpers.LittleEndian(data.Length); //unc size
                bin.Write(pos);
                for (int i = 0; i < noChunks; i++)
                {
                    int uncSize = newChunks[i].uncSize;
                    int cprSize = newChunks[i].cprSize;
                    uncSize = Gibbed.IO.NumberHelpers.LittleEndian(uncSize);
                    cprSize = Gibbed.IO.NumberHelpers.LittleEndian(cprSize);
                    bin.Write(cprSize);
                    bin.Write(uncSize);
                }
                for (int i = 0; i < noChunks; i++)
                {
                    bin.Write(newChunks[i].rawData);
                }
                result = stream.ToArray();
            }

            return result;
        }
示例#2
0
 private void ReadChunks(Stream s)
 {
     try
     {
         DebugLog.PrintLn("Reading Chunks...");
         for (int i = 0; i < Header.Chunks.Count; i++)
         {
             if (verbose)
             {
                 DebugLog.PrintLn("Reading Chunk(" + i + ") Header...");
             }
             CompressedChunk c = Header.Chunks[i];
             s.Seek(c.CompOffset, 0);
             c.Magic = ReadUInt(s);
             if (c.Magic != 0x9E2A83C1)
             {
                 throw new Exception("Not a valid Chunkheader, wrong magic!(#" + i + ")");
             }
             c.BlockSize = ReadUInt(s);
             ReadUInt(s);
             ReadUInt(s);
             uint count = (c.UnCompSize + c.BlockSize - 1) / c.BlockSize;
             c.Blocks = new List <CompressedChunkBlock>();
             if (verbose)
             {
                 DebugLog.PrintLn("Reading Chunk(" + i + ") Blocks...");
             }
             for (int j = 0; j < count; j++)
             {
                 CompressedChunkBlock b = new CompressedChunkBlock();
                 b.CompSize   = ReadUInt(s);
                 b.UnCompSize = ReadUInt(s);
                 b.loaded     = false;
                 c.Blocks.Add(b);
             }
             Header.Chunks[i] = c;
         }
         if (Header.Chunks.Count != 0)
         {
             uint FullSize = Header.Chunks[Header.Chunks.Count - 1].UnCompOffset + Header.Chunks[Header.Chunks.Count - 1].UnCompSize;
             Header.DeCompBuffer = new MemoryStream(new byte[FullSize]);
             Header.DeCompBuffer.Seek(0, 0);
             Source.Seek(0, 0);
             byte[] buff = new byte[Header._offsetCompFlagEnd];
             Source.Read(buff, 0, (int)Header._offsetCompFlagEnd);
             Header.DeCompBuffer.Write(buff, 0, (int)Header._offsetCompFlagEnd);
             Header.DeCompBuffer.Write(BitConverter.GetBytes(0), 0, 4);
             Header.DeCompBuffer.Write(BitConverter.GetBytes(Header.unk7), 0, 4);
             Header.DeCompBuffer.Write(BitConverter.GetBytes(Header.unk8), 0, 4);
             Header.DeCompBuffer.Seek(Header._offsetFlag, 0);
             uint newFlags = (Header.Flags ^ 0x02000000);
             Header.DeCompBuffer.Write(BitConverter.GetBytes(newFlags), 0, 4);
         }
     }
     catch (Exception ex)
     {
         DebugLog.PrintLn("PCCPACKAGE::READCHUNKS ERROR:\n" + ex.Message);
     }
 }
示例#3
0
 private void UncompressRange(uint offset, uint size)
 {
     try
     {
         int startchunk = 0;
         int endchunk   = -1;
         for (int i = 0; i < Header.Chunks.Count; i++)
         {
             if (Header.Chunks[i].UnCompOffset > offset)
             {
                 break;
             }
             startchunk = i;
         }
         for (int i = 0; i < Header.Chunks.Count; i++)
         {
             if (Header.Chunks[i].UnCompOffset >= offset + size)
             {
                 break;
             }
             endchunk = i;
         }
         if (startchunk == -1 || endchunk == -1)
         {
             return;
         }
         for (int i = startchunk; i <= endchunk; i++)
         {
             CompressedChunk c = Header.Chunks[i];
             Header.DeCompBuffer.Seek(c.UnCompOffset, 0);
             for (int j = 0; j < c.Blocks.Count; j++)
             {
                 CompressedChunkBlock b = c.Blocks[j];
                 uint startblock        = (uint)Header.DeCompBuffer.Position;
                 uint endblock          = (uint)Header.DeCompBuffer.Position + b.UnCompSize;
                 if (((startblock >= offset && startblock < offset + size) ||
                      (endblock >= offset && endblock < offset + size) ||
                      (offset >= startblock && offset < endblock) ||
                      (offset + size > startblock && offset + size <= endblock)) &&
                     !b.loaded)
                 {
                     Header.DeCompBuffer.Write(UncompressBlock(i, j), 0, (int)b.UnCompSize);
                     b.loaded         = true;
                     c.Blocks[j]      = b;
                     Header.Chunks[i] = c;
                 }
                 else
                 {
                     Header.DeCompBuffer.Seek(b.UnCompSize, SeekOrigin.Current);
                 }
             }
         }
     }
     catch (Exception ex)
     {
         DebugLog.PrintLn("PCCPACKAGE::UNCOMPRESSRANGE ERROR:\n" + ex.Message);
     }
 }
示例#4
0
        /// <summary>
        /// Takes compressed archived image data and returns the raw image data
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public byte[] DecompressTex(Stream archiveStream, int offset, int uncSize, int cprSize)
        {
            int pos = 0;
            archiveStream.Seek(offset, SeekOrigin.Begin);
            int magicNumber = archiveStream.ReadValueS32();
            pos += 4;
            if (magicNumber != -1641380927)
            {
                throw new FormatException("Magic Number is not correct. Invalid archive data");
            }
            int blockSize = archiveStream.ReadValueS32();
            pos += 4;
            int readCprSize = archiveStream.ReadValueS32(); //Archive cprSize doesn't include header size
            pos += 4;
            int uncReadSize = archiveStream.ReadValueS32();
            if (uncReadSize != uncSize)
            {
                throw new FormatException("Uncompressed data sizes don't match. Read: " + uncReadSize + ", expected: " + uncSize);
            }
            pos += 4;
            int noChunks = (uncSize + blockSize - 1) / blockSize;

            CompressedChunkBlock[] chunks = new CompressedChunkBlock[noChunks];
            for (int i = 0; i < noChunks; i++)
            {
                CompressedChunkBlock chunk = new CompressedChunkBlock();
                chunk.cprSize = archiveStream.ReadValueS32();
                chunk.uncSize = archiveStream.ReadValueS32();
                chunk.rawData = new byte[chunk.cprSize];
                pos += 8;
                chunks[i] = chunk;
            }
            if (readCprSize + pos != cprSize)
            {
                throw new FormatException("Compressed data sizes don't match. Invalid archive data");
            }
            byte[] rawData = new byte[readCprSize];
            rawData = archiveStream.ReadBytes(readCprSize);
            archiveStream.Close();
            using (MemoryStream data = new MemoryStream(rawData))
            {
                for (int i = 0; i < noChunks; i++)
                {
                    chunks[i].rawData = data.ReadBytes(chunks[i].cprSize);
                }
            }

            byte[] imgBuffer = new byte[uncSize];
            int resultPos = 0;

            for (int i = 0; i < noChunks; i++)
            {
                CompressedChunkBlock chunk = chunks[i];
                byte[] tempResult = new byte[chunk.uncSize];
                try
                {
                    LZO1X.Decompress(chunk.rawData, tempResult);
                }
                catch
                {
                    throw new Exception("LZO decompression failed!");
                }
                Buffer.BlockCopy(tempResult, 0, imgBuffer, resultPos, chunk.uncSize);
                resultPos += chunk.uncSize;
            }

            return imgBuffer;
        }
示例#5
0
        /// <summary>
        /// Takes regular image data and returns it in a compressed form ready for archiving
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public byte[] CompressTex(byte[] data)
        {
            int chunkSize = 131072; //Set at this stage. Easy to change later
            int noChunks  = (data.Length + chunkSize - 1) / chunkSize;

            CompressedChunkBlock[] chunks = new CompressedChunkBlock[noChunks];
            int pos = 0;

            for (int i = 0; i < noChunks; i++)
            {
                if (data.Length - (pos + chunkSize) < 0)
                {
                    chunks[i].uncSize = data.Length - pos;
                    chunks[i].rawData = new byte[chunks[i].uncSize];
                    Buffer.BlockCopy(data, pos, chunks[i].rawData, 0, chunks[i].uncSize);
                    pos += chunks[i].uncSize;
                }
                else
                {
                    chunks[i].uncSize = chunkSize;
                    chunks[i].rawData = new byte[chunkSize];
                    Buffer.BlockCopy(data, pos, chunks[i].rawData, 0, chunkSize);
                    pos += chunks[i].uncSize;
                }
            }
            pos = 0;
            CompressedChunkBlock[] newChunks = new CompressedChunkBlock[noChunks];
            for (int i = 0; i < noChunks; i++)
            {
                newChunks[i].rawData = LZO1X.Compress(chunks[i].rawData);
                if (newChunks[i].rawData.Length == 0)
                {
                    throw new Exception("LZO compression failed!");
                }
                newChunks[i].cprSize = newChunks[i].rawData.Length;
                newChunks[i].uncSize = chunks[i].uncSize;
                pos += newChunks[i].cprSize;
            }
            byte[] result;
            using (MemoryStream stream = new MemoryStream())
            {
                byte[] magic = new byte[] { 0xC1, 0x83, 0x2A, 0x9E, 0x00, 0x00, 0x02, 0x00 };
                pos = Gibbed.IO.NumberHelpers.LittleEndian(pos);
                BinaryWriter bin = new BinaryWriter(stream);
                bin.Write(magic);
                bin.Write(pos);
                pos = Gibbed.IO.NumberHelpers.LittleEndian(data.Length); //unc size
                bin.Write(pos);
                for (int i = 0; i < noChunks; i++)
                {
                    int uncSize = newChunks[i].uncSize;
                    int cprSize = newChunks[i].cprSize;
                    uncSize = Gibbed.IO.NumberHelpers.LittleEndian(uncSize);
                    cprSize = Gibbed.IO.NumberHelpers.LittleEndian(cprSize);
                    bin.Write(cprSize);
                    bin.Write(uncSize);
                }
                for (int i = 0; i < noChunks; i++)
                {
                    bin.Write(newChunks[i].rawData);
                }
                result = stream.ToArray();
            }

            return(result);
        }
示例#6
0
        /// <summary>
        /// Takes compressed archived image data and returns the raw image data
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public byte[] DecompressTex(Stream archiveStream, int offset, int uncSize, int cprSize)
        {
            int pos = 0;

            archiveStream.Seek(offset, SeekOrigin.Begin);
            int magicNumber = archiveStream.ReadValueS32();

            pos += 4;
            if (magicNumber != -1641380927)
            {
                throw new FormatException("Magic Number is not correct. Invalid archive data");
            }
            int blockSize = archiveStream.ReadValueS32();

            pos += 4;
            int readCprSize = archiveStream.ReadValueS32(); //Archive cprSize doesn't include header size

            pos += 4;
            int uncReadSize = archiveStream.ReadValueS32();

            if (uncReadSize != uncSize)
            {
                throw new FormatException("Uncompressed data sizes don't match. Read: " + uncReadSize + ", expected: " + uncSize);
            }
            pos += 4;
            int noChunks = (uncSize + blockSize - 1) / blockSize;

            CompressedChunkBlock[] chunks = new CompressedChunkBlock[noChunks];
            for (int i = 0; i < noChunks; i++)
            {
                CompressedChunkBlock chunk = new CompressedChunkBlock();
                chunk.cprSize = archiveStream.ReadValueS32();
                chunk.uncSize = archiveStream.ReadValueS32();
                chunk.rawData = new byte[chunk.cprSize];
                pos          += 8;
                chunks[i]     = chunk;
            }
            if (readCprSize + pos != cprSize)
            {
                throw new FormatException("Compressed data sizes don't match. Invalid archive data");
            }
            byte[] rawData = new byte[readCprSize];
            rawData = archiveStream.ReadBytes(readCprSize);
            archiveStream.Close();
            using (MemoryStream data = new MemoryStream(rawData))
            {
                for (int i = 0; i < noChunks; i++)
                {
                    chunks[i].rawData = data.ReadBytes(chunks[i].cprSize);
                }
            }

            byte[] imgBuffer = new byte[uncSize];
            int    resultPos = 0;

            for (int i = 0; i < noChunks; i++)
            {
                CompressedChunkBlock chunk = chunks[i];
                byte[] tempResult          = new byte[chunk.uncSize];
                try
                {
                    LZO1X.Decompress(chunk.rawData, tempResult);
                }
                catch
                {
                    throw new Exception("LZO decompression failed!");
                }
                Buffer.BlockCopy(tempResult, 0, imgBuffer, resultPos, chunk.uncSize);
                resultPos += chunk.uncSize;
            }

            return(imgBuffer);
        }
        /// <summary>
        /// Takes regular image data and returns it in a compressed form ready for archiving
        /// </summary>
        /// <param name="data">Data to compress</param>
        /// <returns>Compressed texture</returns>
        public static byte[] CompressTex(byte[] data)
        {
            int chunkSize = 131072; //Set at this stage. Easy to change later
            int noChunks = (data.Length + chunkSize - 1) / chunkSize;
            CompressedChunkBlock[] chunks = new CompressedChunkBlock[noChunks];
            int pos = 0;
            for (int i = 0; i < noChunks; i++)
            {
                if (data.Length - (pos + chunkSize) < 0)
                {
                    chunks[i].uncSize = data.Length - pos;
                    chunks[i].rawData = new byte[chunks[i].uncSize];
                    Buffer.BlockCopy(data, pos, chunks[i].rawData, 0, chunks[i].uncSize);
                    pos += chunks[i].uncSize;
                }
                else
                {
                    chunks[i].uncSize = chunkSize;
                    chunks[i].rawData = new byte[chunkSize];
                    Buffer.BlockCopy(data, pos, chunks[i].rawData, 0, chunkSize);
                    pos += chunks[i].uncSize;
                }
            }
            pos = 0;
            CompressedChunkBlock[] newChunks = new CompressedChunkBlock[noChunks];
            for (int i = 0; i < noChunks; i++)
            {
                newChunks[i].rawData = LZOCompress(chunks[i].rawData);
                //MiniLZO.Compress(chunks[i].rawData, out newChunks[i].rawData);
                if (newChunks[i].rawData.Length == 0)
                    throw new Exception("LZO compression failed!");
                newChunks[i].cprSize = newChunks[i].rawData.Length;
                newChunks[i].uncSize = chunks[i].uncSize;
                pos += newChunks[i].cprSize;
            }
            byte[] result;
            using (MemoryStream stream = new MemoryStream())
            {
                byte[] magic = new byte[] { 0xC1, 0x83, 0x2A, 0x9E, 0x00, 0x00, 0x02, 0x00 };
                BinaryWriter bin = new BinaryWriter(stream);
                bin.Write(magic);
                bin.Write(pos);
                pos = data.Length; //unc size
                bin.Write(pos);
                for (int i = 0; i < noChunks; i++)
                {
                    int uncSize = newChunks[i].uncSize;
                    int cprSize = newChunks[i].cprSize;
                    bin.Write(cprSize);
                    bin.Write(uncSize);
                }
                for (int i = 0; i < noChunks; i++)
                {
                    bin.Write(newChunks[i].rawData);
                }
                result = stream.ToArray();
            }

            return result;
        }
示例#8
0
 private void ReadChunks(Stream s)
 {
     try
     {
         DebugLog.PrintLn("Reading Chunks...");
         for (int i = 0; i < Header.Chunks.Count; i++)
         {
             if(verbose)
                 DebugLog.PrintLn("Reading Chunk(" + i + ") Header...");
             CompressedChunk c = Header.Chunks[i];
             s.Seek(c.CompOffset, 0);
             c.Magic = ReadUInt(s);
             if (c.Magic != 0x9E2A83C1)
                 throw new Exception("Not a valid Chunkheader, wrong magic!(#" + i + ")");
             c.BlockSize = ReadUInt(s);
             ReadUInt(s); 
             ReadUInt(s);
             uint count = (c.UnCompSize + c.BlockSize - 1) / c.BlockSize;
             c.Blocks = new List<CompressedChunkBlock>();
             if (verbose)
                 DebugLog.PrintLn("Reading Chunk(" + i + ") Blocks...");
             for (int j = 0; j < count; j++)
             {
                 CompressedChunkBlock b = new CompressedChunkBlock();
                 b.CompSize = ReadUInt(s);
                 b.UnCompSize = ReadUInt(s);
                 b.loaded = false;
                 c.Blocks.Add(b);
             }
             Header.Chunks[i] = c;
         }
         if (Header.Chunks.Count != 0)
         {
             uint FullSize = Header.Chunks[Header.Chunks.Count - 1].UnCompOffset + Header.Chunks[Header.Chunks.Count - 1].UnCompSize;
             Header.DeCompBuffer = new MemoryStream(new byte[FullSize]);
             Header.DeCompBuffer.Seek(0, 0);
             Source.Seek(0, 0);
             byte[]buff = new byte[Header._offsetCompFlagEnd];
             Source.Read(buff, 0, (int)Header._offsetCompFlagEnd);
             Header.DeCompBuffer.Write(buff, 0, (int)Header._offsetCompFlagEnd);
             Header.DeCompBuffer.Write(BitConverter.GetBytes(0), 0, 4);
             Header.DeCompBuffer.Write(BitConverter.GetBytes(Header.unk7), 0, 4);
             Header.DeCompBuffer.Write(BitConverter.GetBytes(Header.unk8), 0, 4);
             Header.DeCompBuffer.Seek(Header._offsetFlag, 0);
             uint newFlags = (Header.Flags ^ 0x02000000);
             Header.DeCompBuffer.Write(BitConverter.GetBytes(newFlags), 0, 4);
         }
     }
     catch (Exception ex)
     {
         DebugLog.PrintLn("PCCPACKAGE::READCHUNKS ERROR:\n" + ex.Message);
     }
 }