/// <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); }
/// <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; } } }