示例#1
0
        private byte[] DecompressCommon(SymbianDecompressor aDecompressor, int aSeekOffset, int aAmountToRead, int aMaximumOutputSize, out int aNumberOfInputBytesRead)
        {
            System.Diagnostics.Debug.WriteLine("[SIContentE32Image] DecompressCommon - START - " + base.Image.Name + " # " + System.Threading.Thread.CurrentThread.Name);
            //
            uint imageContentSize = iFileSize;
            uint orighdrsz        = ImageHeader.TotalSize;
            uint remainder        = imageContentSize - orighdrsz;

            //
            using (SymbianStreamReaderLE reader = base.ImageStream.CreateReader(SymbianStreamReaderLE.TCloseOperation.EResetPosition))
            {
                long codePos = Image.ContentOffsetWithinDataStream + orighdrsz + aSeekOffset;
                reader.Seek(codePos);
                //
                byte[] input  = reader.ReadBytes(aAmountToRead);
                byte[] output = new byte[aMaximumOutputSize];

                // The decompressor tells us how many bytes of output it really created.
                int numberOfBytesCreated = aDecompressor.DecompressImage(input, output, out aNumberOfInputBytesRead);

                // We can then return that to the callee.
                byte[] ret = new byte[numberOfBytesCreated > 0 ? numberOfBytesCreated : 0];
                if (numberOfBytesCreated > 0)
                {
                    Array.Copy(output, ret, numberOfBytesCreated);
                }
                //
                System.Diagnostics.Debug.WriteLine("[SIContentE32Image] DecompressCommon - END - " + base.Image.Name + " # " + System.Threading.Thread.CurrentThread.Name);
                //
                return(ret);
            }
        }
示例#2
0
        private void DecompressBytePair(SymbianDecompressor aDecompressor)
        {
            int inputBytesRead = 0;
            //
            uint imageContentSize = iFileSize;
            uint orighdrsz        = ImageHeader.TotalSize;
            uint uncompressedSize = ImageHeader.UncompressedSize;

            // First decompress the code
            byte[] code = DecompressCommon(aDecompressor, 0, (int)(imageContentSize - orighdrsz), (int)uncompressedSize, out inputBytesRead);
            if (code.Length < ImageHeader.CodeSize)
            {
                throw new Exception("E32Image bytepair decompression did not provide enough code");
            }

            // Now get the data
            int remainder = (int)(uncompressedSize - inputBytesRead);

            byte[] data = DecompressCommon(aDecompressor, inputBytesRead, remainder, (int)uncompressedSize, out inputBytesRead);

            // We should have read all the decompressed data
            int totalAmountOfDecompressedDataSupplied = data.Length + code.Length;

            if (totalAmountOfDecompressedDataSupplied != uncompressedSize)
            {
                throw new Exception("E32Image bytepair decompression did not supply enough decompressed output");
            }

            lock ( iCodeSyncRoot )
            {
                iCode = new byte[uncompressedSize];
                Array.Copy(code, iCode, code.Length);
                Array.Copy(data, 0, iCode, code.Length, data.Length);
            }
        }
示例#3
0
        protected override void DoDecompress()
        {
            lock ( iCodeSyncRoot )
            {
                if (iCode == null)
                {
                    TSymbianCompressionType type = this.CompressionType;
                    switch (type)
                    {
                    default:
                    case TSymbianCompressionType.ENone:
                        // NB: This has not yet been observed in reality
                        DecompressNone();
                        break;

                    case TSymbianCompressionType.EDeflate:
                    case TSymbianCompressionType.EBytePair:
                    {
                        using (SymbianDecompressor decompressor = SymbianDecompressor.NewByType(type))
                        {
                            //
                            switch (type)
                            {
                            case TSymbianCompressionType.EBytePair:
                                DecompressBytePair(decompressor);
                                break;

                            case TSymbianCompressionType.EDeflate:
                                DecompressDeflate(decompressor);
                                break;
                            }
                        }
                        break;
                    }
                    }

                    if (iCode != null)
                    {
                        if (iStream != null)
                        {
                            iStream.Dispose();
                            iStream = null;
                        }
                        //
                        iStream = new MemoryStream(iCode);
                    }
                }
            }
        }
示例#4
0
        private void DecompressDeflate(SymbianDecompressor aDecompressor)
        {
            int inputBytesRead = 0;
            //
            uint imageContentSize = iFileSize;
            uint orighdrsz        = ImageHeader.TotalSize;
            uint uncompressedSize = ImageHeader.UncompressedSize;

            byte[] combinedDataAndCode = DecompressCommon(aDecompressor, 0, (int)(imageContentSize - orighdrsz), (int)uncompressedSize, out inputBytesRead);
            if (combinedDataAndCode.Length != uncompressedSize)
            {
                throw new Exception("E32Image inflate decompression did not supply enough decompressed output");
            }

            lock ( iCodeSyncRoot )
            {
                iCode = combinedDataAndCode;
            }
        }
示例#5
0
        private void DoDecompressBytePair()
        {
            if (iContentIsPrepared == false)
            {
                SIHeaderROM imageHeader = ImageHeader;
                base.Trace("[SymbianImageROM] DoDecompressBytePair() - START - header uncompressed rom size: {0}", imageHeader.UncompressedRomSize);

                // Create new buffer and copy over rom image header
                SIMemoryStream resultantDataStream = new SIMemoryStream(imageHeader.UncompressedRomSize);

                int  numPages        = imageHeader.NumberOfPages;
                uint pageTableOffset = imageHeader.RomPageIndexOffset;
                uint romDataOffset   = imageHeader.HeaderSizeLoader;
                base.Trace("[SymbianImageROM] DoDecompressBytePair() - numPages: {0}, pageTableOffset: {1}, romDataOffset: {2}", numPages, pageTableOffset, romDataOffset);
                //
                SymbianDecompressor decompressor = SymbianDecompressor.NewByType(TSymbianCompressionType.EBytePair);
                //
                List <SRomPageInfo> pages = new List <SRomPageInfo>(numPages + 1);
                for (int i = 0; i < numPages; i++)
                {
                    // Read a page table entry
                    long pageOffsetWithinFile = pageTableOffset + (i * SRomPageInfo.Size);

                    //base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - pageOffsetWithinFile: {1}", i, pageOffsetWithinFile );
                    base.ImageStream.Seek(pageOffsetWithinFile, SeekOrigin.Begin);
                    SRomPageInfo pageInfo = SRomPageInfo.New((Stream)base.ImageStream, romDataOffset);

                    // Process the entry based upon the compression type
                    //base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - pageInfo.DataSize: {1}, pageInfo.DataStart: {2}, pageInfo.CompressionType: {3}", i, pageInfo.DataSize, pageInfo.DataStart, pageInfo.CompressionType );
                    base.ImageStream.Seek(pageInfo.DataStart, SeekOrigin.Begin);

                    if (pageInfo.CompressionType == SRomPageInfo.TSymbianCompressionType.ENoCompression)
                    {
                        // Read data - no decompression needed
                        //base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - PAGE NOT COMPRESSED", i );
                        resultantDataStream.Write(base.ImageStream, (int)pageInfo.DataSize);
                    }
                    else if (pageInfo.CompressionType == SRomPageInfo.TSymbianCompressionType.EBytePair)
                    {
                        //base.Trace( "[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - BYTE PAIR PAGE", i );

                        // Read data - need to decompress it
                        byte[] compressedData = new byte[pageInfo.DataSize];
                        base.ImageStream.Read(compressedData, 0, compressedData.Length);

                        // Make destination buffer - which is a page big
                        byte[] uncompressedData = new byte[SRomPageInfo.KPageSize];

                        // Decompress to buffer - we're handling the page management, so we want raw decompression
                        int error = decompressor.DecompressRaw(compressedData, uncompressedData);

                        // Save it
                        if (error < 0)
                        {
                            base.Trace("[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - Exception - bytepair decompression error", i);
                            throw new Exception("BytePair decompression error: " + error.ToString());
                        }
                        else if (error != SRomPageInfo.KPageSize)
                        {
                            base.Trace("[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - Exception - bytepair underflow error", i);
                            throw new Exception("Decompressor underflow - only created " + error.ToString() + " bytes");
                        }
                        else
                        {
                            resultantDataStream.Write(uncompressedData);
                        }
                    }
                    else
                    {
                        base.Trace("[SymbianImageROM] DoDecompressBytePair() - page[{0:d5}] - UNSUPPORTED COMPRESSION TYPE - Exception!", i);
                        throw new NotSupportedException("Unsupported page compression type");
                    }

                    // Report progress
                    base.ReportDecompressionEvent(TDecompressionEvent.EEventDecompressionProgress, ((float)i / (float)numPages) * 100);
                }

                // Now we can replace the base class stream (which is just the raw compressed file data) with the new uncompressed version
                base.ImageStream   = resultantDataStream;
                iContentIsPrepared = true;

                base.Trace("[SymbianImageROM] DoDecompressBytePair() - END");
            }
        }