/// <summary> /// Decompresses the provided data, returning the inflated result. /// </summary> /// <param name="data">the deflated picture data.</param> /// <returns>the inflated picture data.</returns> private static byte[] InflatePictureData(byte[] data) { using (MemoryStream out1 = new MemoryStream()) { try { using (MemoryStream ms = new MemoryStream(data)) { using (ZlibStream in1 = new ZlibStream(ms, CompressionMode.Decompress)) { byte[] buf = new byte[4096]; int ReadBytes; while ((ReadBytes = in1.Read(buf, 0, buf.Length)) > 0) { out1.Write(buf, 0, ReadBytes); } return out1.ToArray(); } } } catch (IOException e) { log.Log(POILogger.INFO, "Possibly corrupt compression or non-compressed data", e); return data; } } }
/// <summary> /// This version of dump is a translation from the open office escher dump routine. /// </summary> /// <param name="maxLength">The number of bytes to Read</param> /// <param name="in1">An input stream to Read from.</param> public void DumpOld(long maxLength, Stream in1) { long remainingBytes = maxLength; short options; // 4 bits for the version and 12 bits for the instance short recordId; int recordBytesRemaining; // including enclosing records StringBuilder stringBuf = new StringBuilder(); short nDumpSize; String recordName; bool atEOF = false; while (!atEOF && (remainingBytes > 0)) { stringBuf = new StringBuilder(); options = LittleEndian.ReadShort(in1); recordId = LittleEndian.ReadShort(in1); recordBytesRemaining = LittleEndian.ReadInt(in1); remainingBytes -= 2 + 2 + 4; switch (recordId) { case unchecked((short)0xF000): recordName = "MsofbtDggContainer"; break; case unchecked((short)0xF006): recordName = "MsofbtDgg"; break; case unchecked((short)0xF016): recordName = "MsofbtCLSID"; break; case unchecked((short)0xF00B): recordName = "MsofbtOPT"; break; case unchecked((short)0xF11A): recordName = "MsofbtColorMRU"; break; case unchecked((short)0xF11E): recordName = "MsofbtSplitMenuColors"; break; case unchecked((short)0xF001): recordName = "MsofbtBstoreContainer"; break; case unchecked((short)0xF007): recordName = "MsofbtBSE"; break; case unchecked((short)0xF002): recordName = "MsofbtDgContainer"; break; case unchecked((short)0xF008): recordName = "MsofbtDg"; break; case unchecked((short)0xF118): recordName = "MsofbtRegroupItem"; break; case unchecked((short)0xF120): recordName = "MsofbtColorScheme"; break; case unchecked((short)0xF003): recordName = "MsofbtSpgrContainer"; break; case unchecked((short)0xF004): recordName = "MsofbtSpContainer"; break; case unchecked((short)0xF009): recordName = "MsofbtSpgr"; break; case unchecked((short)0xF00A): recordName = "MsofbtSp"; break; case unchecked((short)0xF00C): recordName = "MsofbtTextbox"; break; case unchecked((short)0xF00D): recordName = "MsofbtClientTextbox"; break; case unchecked((short)0xF00E): recordName = "MsofbtAnchor"; break; case unchecked((short)0xF00F): recordName = "MsofbtChildAnchor"; break; case unchecked((short)0xF010): recordName = "MsofbtClientAnchor"; break; case unchecked((short)0xF011): recordName = "MsofbtClientData"; break; case unchecked((short)0xF11F): recordName = "MsofbtOleObject"; break; case unchecked((short)0xF11D): recordName = "MsofbtDeletedPspl"; break; case unchecked((short)0xF005): recordName = "MsofbtSolverContainer"; break; case unchecked((short)0xF012): recordName = "MsofbtConnectorRule"; break; case unchecked((short)0xF013): recordName = "MsofbtAlignRule"; break; case unchecked((short)0xF014): recordName = "MsofbtArcRule"; break; case unchecked((short)0xF015): recordName = "MsofbtClientRule"; break; case unchecked((short)0xF017): recordName = "MsofbtCalloutRule"; break; case unchecked((short)0xF119): recordName = "MsofbtSelection"; break; case unchecked((short)0xF122): recordName = "MsofbtUDefProp"; break; default: if (recordId >= unchecked((short)0xF018) && recordId <= unchecked((short)0xF117)) recordName = "MsofbtBLIP"; else if ((options & (short)0x000F) == (short)0x000F) recordName = "UNKNOWN container"; else recordName = "UNKNOWN ID"; break; } stringBuf.Append(" "); stringBuf.Append(HexDump.ToHex(recordId)); stringBuf.Append(" ").Append(recordName).Append(" ["); stringBuf.Append(HexDump.ToHex(options)); stringBuf.Append(','); stringBuf.Append(HexDump.ToHex(recordBytesRemaining)); stringBuf.Append("] instance: "); stringBuf.Append(HexDump.ToHex(((short)(options >> 4)))); Console.WriteLine(stringBuf.ToString()); if (recordId == (unchecked((short)0xF007)) && 36 <= remainingBytes && 36 <= recordBytesRemaining) { // BSE, FBSE // ULONG nP = pIn->GetRecPos(); byte n8; // short n16; // int n32; stringBuf = new StringBuilder(" btWin32: "); n8 = (byte)in1.ReadByte(); stringBuf.Append(HexDump.ToHex(n8)); stringBuf.Append(GetBlipType(n8)); stringBuf.Append(" btMacOS: "); n8 = (byte)in1.ReadByte(); stringBuf.Append(HexDump.ToHex(n8)); stringBuf.Append(GetBlipType(n8)); Console.WriteLine(stringBuf.ToString()); Console.WriteLine(" rgbUid:"); HexDump.Dump(in1, 0, 16); Console.Write(" tag: "); OutHex(2, in1); Console.WriteLine(); Console.Write(" size: "); OutHex(4, in1); Console.WriteLine(); Console.Write(" cRef: "); OutHex(4, in1); Console.WriteLine(); Console.Write(" offs: "); OutHex(4, in1); Console.WriteLine(); Console.Write(" usage: "); OutHex(4, in1); Console.WriteLine(); Console.Write(" cbName: "); OutHex(4, in1); Console.WriteLine(); Console.Write(" unused2: "); OutHex(4, in1); Console.WriteLine(); Console.Write(" unused3: "); OutHex(4, in1); Console.WriteLine(); // subtract the number of bytes we've Read remainingBytes -= 36; //n -= pIn->GetRecPos() - nP; recordBytesRemaining = 0; // loop to MsofbtBLIP } else if (recordId == unchecked((short)0xF010) && 0x12 <= remainingBytes && 0x12 <= recordBytesRemaining) { // ClientAnchor //ULONG nP = pIn->GetRecPos(); // short n16; Console.Write(" Flag: "); OutHex(2, in1); Console.WriteLine(); Console.Write(" Col1: "); OutHex(2, in1); Console.Write(" dX1: "); OutHex(2, in1); Console.Write(" Row1: "); OutHex(2, in1); Console.Write(" dY1: "); OutHex(2, in1); Console.WriteLine(); Console.Write(" Col2: "); OutHex(2, in1); Console.Write(" dX2: "); OutHex(2, in1); Console.Write(" Row2: "); OutHex(2, in1); Console.Write(" dY2: "); OutHex(2, in1); Console.WriteLine(); remainingBytes -= 18; recordBytesRemaining -= 18; } else if (recordId == unchecked((short)0xF00B) || recordId == unchecked((short)0xF122)) { // OPT int nComplex = 0; Console.WriteLine(" PROPID VALUE"); while (recordBytesRemaining >= 6 + nComplex && remainingBytes >= 6 + nComplex) { short n16; int n32; n16 = LittleEndian.ReadShort(in1); n32 = LittleEndian.ReadInt(in1); recordBytesRemaining -= 6; remainingBytes -= 6; Console.Write(" "); Console.Write(HexDump.ToHex(n16)); Console.Write(" ("); int propertyId = n16 & (short)0x3FFF; Console.Write(" " + propertyId); if ((n16 & unchecked((short)0x8000)) == 0) { if ((n16 & (short)0x4000) != 0) Console.Write(", fBlipID"); Console.Write(") "); Console.Write(HexDump.ToHex(n32)); if ((n16 & (short)0x4000) == 0) { Console.Write(" ("); Console.Write(Dec1616(n32)); Console.Write(')'); Console.Write(" {" + PropertyName((short)propertyId) + "}"); } Console.WriteLine(); } else { Console.Write(", fComplex) "); Console.Write(HexDump.ToHex(n32)); Console.Write(" - Complex prop len"); Console.WriteLine(" {" + PropertyName((short)propertyId) + "}"); nComplex += n32; } } // complex property data while ((nComplex & remainingBytes) > 0) { nDumpSize = (nComplex > (int)remainingBytes) ? (short)remainingBytes : (short)nComplex; HexDump.Dump(in1, 0, nDumpSize); nComplex -= nDumpSize; recordBytesRemaining -= nDumpSize; remainingBytes -= nDumpSize; } } else if (recordId == (unchecked((short)0xF012))) { Console.Write(" Connector rule: "); Console.Write(LittleEndian.ReadInt(in1)); Console.Write(" ShapeID A: "); Console.Write(LittleEndian.ReadInt(in1)); Console.Write(" ShapeID B: "); Console.Write(LittleEndian.ReadInt(in1)); Console.Write(" ShapeID connector: "); Console.Write(LittleEndian.ReadInt(in1)); Console.Write(" Connect pt A: "); Console.Write(LittleEndian.ReadInt(in1)); Console.Write(" Connect pt B: "); Console.WriteLine(LittleEndian.ReadInt(in1)); recordBytesRemaining -= 24; remainingBytes -= 24; } else if (recordId >= unchecked((short)0xF018) && recordId < unchecked((short)0xF117)) { Console.WriteLine(" Secondary UID: "); HexDump.Dump(in1, 0, 16); Console.WriteLine(" Cache of size: " + HexDump.ToHex(LittleEndian.ReadInt(in1))); Console.WriteLine(" Boundary top: " + HexDump.ToHex(LittleEndian.ReadInt(in1))); Console.WriteLine(" Boundary left: " + HexDump.ToHex(LittleEndian.ReadInt(in1))); Console.WriteLine(" Boundary width: " + HexDump.ToHex(LittleEndian.ReadInt(in1))); Console.WriteLine(" Boundary height: " + HexDump.ToHex(LittleEndian.ReadInt(in1))); Console.WriteLine(" X: " + HexDump.ToHex(LittleEndian.ReadInt(in1))); Console.WriteLine(" Y: " + HexDump.ToHex(LittleEndian.ReadInt(in1))); Console.WriteLine(" Cache of saved size: " + HexDump.ToHex(LittleEndian.ReadInt(in1))); Console.WriteLine(" Compression Flag: " + HexDump.ToHex((byte)in1.ReadByte())); Console.WriteLine(" Filter: " + HexDump.ToHex((byte)in1.ReadByte())); Console.WriteLine(" Data (after decompression): "); recordBytesRemaining -= 34 + 16; remainingBytes -= 34 + 16; nDumpSize = (recordBytesRemaining > (int)remainingBytes) ? (short)remainingBytes : (short)recordBytesRemaining; byte[] buf = new byte[nDumpSize]; int Read = in1.Read(buf,0,buf.Length); while (Read != -1 && Read < nDumpSize) Read += in1.Read(buf, Read, buf.Length); using (MemoryStream bin = new MemoryStream(buf)) { using (ZlibStream in2 = new ZlibStream(bin, CompressionMode.Decompress, false)) { int bytesToDump = -1; HexDump.Dump(in2, 0, bytesToDump); recordBytesRemaining -= nDumpSize; remainingBytes -= nDumpSize; } } } bool isContainer = (options & (short)0x000F) == (short)0x000F; if (isContainer && remainingBytes >= 0) { // Container if (recordBytesRemaining <= (int)remainingBytes) Console.WriteLine(" completed within"); else Console.WriteLine(" continued elsewhere"); } else if (remainingBytes >= 0) // -> 0x0000 ... 0x0FFF { nDumpSize = (recordBytesRemaining > (int)remainingBytes) ? (short)remainingBytes : (short)recordBytesRemaining; if (nDumpSize != 0) { HexDump.Dump(in1, 0, nDumpSize); remainingBytes -= nDumpSize; } } else Console.WriteLine(" >> OVERRUN <<"); } }
/// <summary> /// Decompresses the specified data. /// </summary> /// <param name="data">The compressed byte array.</param> /// <param name="pos">The starting position into the byte array.</param> /// <param name="Length">The number of compressed bytes to decompress.</param> /// <returns>An uncompressed byte array</returns> public static byte[] Decompress(byte[] data, int pos, int Length) { byte[] compressedData = new byte[Length]; Array.Copy(data, pos + 50, compressedData, 0, Length); using (MemoryStream ms = new MemoryStream(compressedData)) { using (ZlibStream inflaterInputStream = new ZlibStream(ms, CompressionMode.Decompress)) { using (MemoryStream out1 = new MemoryStream()) { int c; try { while ((c = inflaterInputStream.ReadByte()) != -1) out1.WriteByte((byte)c); return out1.ToArray(); } catch (IOException e) { throw new RecordFormatException(e.ToString()); } } } } }
/// <summary> /// Compress the contents of the provided array /// </summary> /// <param name="data">An uncompressed byte array</param> /// <returns></returns> public static byte[] Compress(byte[] data) { using (MemoryStream out1 = new MemoryStream()) { ZlibStream deflaterOutputStream = new ZlibStream(out1, CompressionMode.Compress); try { //for (int i = 0; i < data.Length; i++) //deflaterOutputStream.WriteByte(data[i]); deflaterOutputStream.Write(data, 0, data.Length); //Tony Qu changed the code return out1.ToArray(); } catch (IOException e) { throw new RecordFormatException(e.ToString()); } finally { out1.Close(); if (deflaterOutputStream != null) { deflaterOutputStream.Close(); } } } }
/// <summary> /// Uncompress a ZLIB-compressed byte array into a byte array. /// </summary> /// /// <seealso cref="ZlibStream.CompressBuffer(byte[])"/> /// <seealso cref="ZlibStream.UncompressString(byte[])"/> /// /// <param name="compressed"> /// A buffer containing ZLIB-compressed data. /// </param> /// /// <returns>The data in uncompressed form</returns> public static byte[] UncompressBuffer(byte[] compressed) { using (var input = new MemoryStream(compressed)) { Stream decompressor = new ZlibStream( input, CompressionMode.Decompress ); return ZlibBaseStream.UncompressBuffer(compressed, decompressor); } }
/// <summary> /// Compress a byte array into a new byte array using ZLIB. /// </summary> /// /// <remarks> /// Uncompress it with <see cref="ZlibStream.UncompressBuffer(byte[])"/>. /// </remarks> /// /// <seealso cref="ZlibStream.CompressString(string)"/> /// <seealso cref="ZlibStream.UncompressBuffer(byte[])"/> /// /// <param name="b"> /// A buffer to compress. /// </param> /// /// <returns>The data in compressed form</returns> public static byte[] CompressBuffer(byte[] b) { using (var ms = new MemoryStream()) { Stream compressor = new ZlibStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression ); ZlibBaseStream.CompressBuffer(b, compressor); return ms.ToArray(); } }