예제 #1
0
        /// <summary>
        /// Decompresses the compressed data stored in one or more IDAT chunks.
        /// </summary>
        private byte[] Decompress()
        {
            Inflater     inf          = new Inflater();
            MemoryStream decompressed = new MemoryStream();
            MemoryStream compressed   = new MemoryStream();

            byte[] buf = new byte[1];

            // decompress the image data
            foreach (Chunk c in _image.Chunks)
            {
                if (c.Type == "IDAT")
                {
                    IDATChunk idat = c as IDATChunk;

                    compressed.Write(idat.Data, 0, idat.Data.Length);

                    if (compressed.Length > 15)
                    {
                        inf.SetInput(compressed.ToArray());

                        while (!inf.IsNeedingInput)
                        {
                            if (inf.Inflate(buf) == -1)
                            {
                                break;
                            }

                            decompressed.WriteByte(buf[0]);
                        }

                        compressed = new MemoryStream();
                    }
                }
            }

            inf.SetInput(compressed.ToArray());

            while (!inf.IsNeedingInput)
            {
                if (inf.Inflate(buf) == -1)
                {
                    break;
                }

                decompressed.WriteByte(buf[0]);
            }

            if (!inf.IsFinished)
            {
                throw new InvalidCompressedDataException("Inflater is not finished but there are no more IDAT chunks.");
            }

            byte[] arr = decompressed.ToArray();

            decompressed.Close();

            return(arr);
        }
예제 #2
0
        /// <summary>
        /// Modifies the underlying image's chunks to save the image.
        /// </summary>
        /// <param name="data">The uncompressed image data.</param>
        private void SaveChunks(byte[] data)
        {
            // remove all existing data chunks
            _image.Chunks.RemoveAll(new Predicate <Chunk>(
                                        delegate(Chunk c)
            {
                if (c.Type == "IDAT")
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }));

            // insert our new data chunk just before the end
            for (int i = 0; i < _image.Chunks.Count; i++)
            {
                if (_image.Chunks[i].Type == "IEND")
                {
                    IDATChunk            idat   = new IDATChunk(_image);
                    MemoryStream         ms     = new MemoryStream();
                    DeflaterOutputStream dos    = new DeflaterOutputStream(ms, new Deflater(CompressionLevel.Level));
                    BinaryWriter         bwdata = new BinaryWriter(dos);

                    bwdata.Write(data);
                    dos.Finish();
                    idat.Data = ms.ToArray();
                    bwdata.Close();
                    ms.Close();

                    _image.Chunks.Insert(i, idat);

                    break;
                }
            }
        }