/// <summary> /// Compression using a run length encoding algorithm. /// See MS-OVBA Section 2.4 /// </summary> /// <param name="part">Byte array to decompress</param> /// <returns></returns> internal static byte[] CompressPart(byte[] part) { using (var ms = RecyclableMemory.GetStream(4096)) { BinaryWriter br = new BinaryWriter(ms); br.Write((byte)1); int compStart = 1; int compEnd = 4098; int decompStart = 0; int decompEnd = part.Length < 4096 ? part.Length : 4096; while (decompStart < decompEnd && compStart < compEnd) { byte[] chunk = CompressChunk(part, ref decompStart); ushort header; if (chunk == null || chunk.Length == 0) { header = 4096 | 0x600; //B=011 A=0 } else { header = (ushort)(((chunk.Length - 1) & 0xFFF)); header |= 0xB000; //B=011 A=1 br.Write(header); br.Write(chunk); } decompEnd = part.Length < decompStart + 4096 ? part.Length : decompStart + 4096; } br.Flush(); return(ms.ToArray()); } }
/// <summary> /// Decompression using a run length encoding algorithm. /// See MS-OVBA Section 2.4 /// </summary> /// <param name="part">Byte array to decompress</param> /// <param name="startPos"></param> /// <returns></returns> internal static byte[] DecompressPart(byte[] part, int startPos) { if (part[startPos] != 1) { return(null); } using (var ms = RecyclableMemory.GetStream(4096)) { int compressPos = startPos + 1; while (compressPos < part.Length - 1) { DecompressChunk(ms, part, ref compressPos); } return(ms.ToArray()); } }