private void DecompressChunk(object context)
        {
            DecompressChunkParms parms = (DecompressChunkParms)context;

            try {
                DecompressChunk(parms.CompressedBytes, parms.ChunkSize, parms.ChunkOffset, parms.DeferredFormatter);
            } catch (Exception ex) {
                parms.Exceptions.Add(ex);
            }
        }
Example #2
0
        void IDeferredSerializable.FinishDeserialization(Stream input, DeferredFormatter context)
        {
            // Allocate the memory
            if (this.bitmapWidth != 0 && this.bitmapHeight != 0)
            {
                this.voidStar = Allocate(this.bitmapWidth, this.bitmapHeight, out this.bitmapHandle).ToPointer();
                this.valid    = true;
            }
            else
            {
                this.voidStar = Allocate(this.length).ToPointer();
                this.valid    = true;
            }

            // formatVersion should equal 0
            int formatVersion = input.ReadByte();

            if (formatVersion == -1)
            {
                throw new EndOfStreamException();
            }

            if (formatVersion != 0 && formatVersion != 1)
            {
                throw new SerializationException("formatVersion was neither zero nor one");
            }

            // chunkSize
            uint chunkSize = ReadUInt(input);

            PaintDotNet.Threading.ThreadPool threadPool = new PaintDotNet.Threading.ThreadPool(Processor.LogicalCpuCount);
            ArrayList    exceptions = new ArrayList(Processor.LogicalCpuCount);
            WaitCallback callback   = new WaitCallback(DecompressChunk);

            // calculate chunkCount
            uint chunkCount = (uint)((this.length + (long)chunkSize - 1) / (long)chunkSize);

            bool[] chunksFound = new bool[chunkCount];

            for (uint i = 0; i < chunkCount; ++i)
            {
                // chunkNumber
                uint chunkNumber = ReadUInt(input);

                if (chunkNumber >= chunkCount)
                {
                    throw new SerializationException("chunkNumber read from stream is out of bounds");
                }

                if (chunksFound[chunkNumber])
                {
                    throw new SerializationException("already encountered chunk #" + chunkNumber.ToString());
                }

                chunksFound[chunkNumber] = true;

                // dataSize
                uint dataSize = ReadUInt(input);

                // calculate chunkOffset
                long chunkOffset = (long)chunkNumber * (long)chunkSize;

                // calculate decompressed chunkSize
                uint thisChunkSize = Math.Min(chunkSize, (uint)(this.length - chunkOffset));

                // bounds checking
                if (chunkOffset < 0 || chunkOffset >= this.length || chunkOffset + thisChunkSize > this.length)
                {
                    throw new SerializationException("data was specified to be out of bounds");
                }

                // read compressed data
                byte[] compressedBytes = new byte[dataSize];
                Utility.ReadFromStream(input, compressedBytes, 0, compressedBytes.Length);

                // decompress data
                if (formatVersion == 0)
                {
                    DecompressChunkParms parms = new DecompressChunkParms(compressedBytes, thisChunkSize, chunkOffset, context, exceptions);
                    threadPool.QueueUserWorkItem(callback, parms);
                }
                else
                {
                    fixed(byte *pbSrc = compressedBytes)
                    {
                        Memory.Copy((void *)((byte *)this.VoidStar + chunkOffset), (void *)pbSrc, thisChunkSize);
                    }
                }
            }

            threadPool.Drain();

            if (exceptions.Count > 0)
            {
                throw new SerializationException("Exception thrown by worker thread", (Exception)exceptions[0]);
            }
        }
Example #3
0
        void IDeferredSerializable.FinishDeserialization(Stream input, DeferredFormatter context)
        {
            // Allocate the memory
            if (this.bitmapWidth != 0 && this.bitmapHeight != 0)
            {
                this.voidStar = Allocate(this.bitmapWidth, this.bitmapHeight, out this.bitmapHandle).ToPointer();
                this.valid = true;
            }
            else
            {
                this.voidStar = Allocate(this.length).ToPointer();
                this.valid = true;
            }
            
            // formatVersion should equal 0
            int formatVersion = input.ReadByte();

            if (formatVersion == -1)
            {
                throw new EndOfStreamException();
            }

            if (formatVersion != 0 && formatVersion != 1)
            {
                throw new SerializationException("formatVersion was neither zero nor one");
            }

            // chunkSize
            uint chunkSize = ReadUInt(input);

            PaintDotNet.Threading.ThreadPool threadPool = new PaintDotNet.Threading.ThreadPool(Processor.LogicalCpuCount);
            ArrayList exceptions = new ArrayList(Processor.LogicalCpuCount);
            WaitCallback callback = new WaitCallback(DecompressChunk);

            // calculate chunkCount
            uint chunkCount = (uint)((this.length + (long)chunkSize - 1) / (long)chunkSize);
            bool[] chunksFound = new bool[chunkCount];

            for (uint i = 0; i < chunkCount; ++i)
            {
                // chunkNumber
                uint chunkNumber = ReadUInt(input);

                if (chunkNumber >= chunkCount)
                {
                    throw new SerializationException("chunkNumber read from stream is out of bounds");
                }

                if (chunksFound[chunkNumber])
                {
                    throw new SerializationException("already encountered chunk #" + chunkNumber.ToString());
                }

                chunksFound[chunkNumber] = true;
                
                // dataSize
                uint dataSize = ReadUInt(input);

                // calculate chunkOffset
                long chunkOffset = (long)chunkNumber * (long)chunkSize;

                // calculate decompressed chunkSize
                uint thisChunkSize = Math.Min(chunkSize, (uint)(this.length - chunkOffset));

                // bounds checking
                if (chunkOffset < 0 || chunkOffset >= this.length || chunkOffset + thisChunkSize > this.length)
                {
                    throw new SerializationException("data was specified to be out of bounds");
                }

                // read compressed data
                byte[] compressedBytes = new byte[dataSize];
                Utility.ReadFromStream(input, compressedBytes, 0, compressedBytes.Length);

                // decompress data
                if (formatVersion == 0)
                {
                    DecompressChunkParms parms = new DecompressChunkParms(compressedBytes, thisChunkSize, chunkOffset, context, exceptions);
                    threadPool.QueueUserWorkItem(callback, parms);
                }
                else
                {
                    fixed (byte *pbSrc = compressedBytes)
                    {
                        Memory.Copy((void *)((byte *)this.VoidStar + chunkOffset), (void *)pbSrc, thisChunkSize);
                    }
                }
            }

            threadPool.Drain();

            if (exceptions.Count > 0)
            {
                throw new SerializationException("Exception thrown by worker thread", (Exception)exceptions[0]);
            }
        }