/// <summary> /// Try to compress RLE stream, with given bitmap compression type. /// </summary> /// <param name="dest">The destination stream that will contains compressed pixel data.</param> /// <param name="source">The source stream we want to compress from.</param> /// <param name="sourceSize">The size of the source.</param> /// <param name="compression">The compression of destination stream.</param> public static void Compress(Stream dest, Stream source, int sourceSize, BitmapCompression compression) { switch (compression) { case BitmapCompression.TwentyFourBitsRLE: CompressTwentyFourBitsRLE(dest, source, sourceSize); break; default: throw new MbmException(String.Format("Unsupported decompression type: {0}", compression.ToString())); } }
/// <summary> /// Try to decompress RLE stream, with given bitmap compression type. /// </summary> /// <param name="dest">The destination stream that will contains decompressed pixel data.</param> /// <param name="source">The source stream we want to decompress from.</param> /// <param name="compression">The compression of source stream.</param> public static void Decompress(Stream dest, Stream source, int sourceSize, BitmapCompression compression) { switch (compression) { case BitmapCompression.TwentyFourBitsRLE: DecompressTwentyFourBitsRLE(dest, source, sourceSize); using (var stream = new FileStream("test.bin", FileMode.OpenOrCreate, FileAccess.Write)) { var last = dest.Position; dest.Position = 0; dest.CopyTo(stream); dest.Position = last; } break; default: throw new MbmException(String.Format("Unsupported decompression type: {0}", compression.ToString())); } }
public static void Save(Document input, Stream output, Surface scratchSurface, UInt32 bpp, BitmapColor colorMode) { // Flatten the image first input.Flatten(scratchSurface); // Build up SBM Header SBMHeader header = new SBMHeader(); header.headerLength = 40; header.sizeInPixel.Width = input.Width; header.sizeInPixel.Height = input.Height; header.sizeInTwips.Width = input.Width * 15; header.sizeInTwips.Height = input.Height * 15; header.colorMode = colorMode; header.bitsPerPixel = bpp; // Determine what compression to use BitmapCompression compressionToUse = ChooseBestCompressionMode(input.Width, input.Height, bpp, colorMode); header.compression = compressionToUse; Int32 stride = MbmFile.GetStride(input.Width, (Byte)bpp); byte[] rawBitmapData = new byte[stride * input.Height]; byte[] compressedBitmapData = null; MemoryStream bitmapStream = new MemoryStream(rawBitmapData, 0, rawBitmapData.Length); ReadRawBitmapData(scratchSurface, bitmapStream, (Byte)bpp); bitmapStream.Seek(0, SeekOrigin.Begin); switch (compressionToUse) { case BitmapCompression comp when(comp >= BitmapCompression.ByteRLE && comp <= BitmapCompression.ThirtyTwoABitsRLE): compressedBitmapData = new byte[stride * input.Height]; MemoryStream compressedDestStream = new MemoryStream(compressedBitmapData, 0, compressedBitmapData.Length); compressedDestStream.Seek(0, SeekOrigin.Begin); Algorithm.RLECompressor.Compress(compressedDestStream, bitmapStream, stride * input.Height, compressionToUse); header.bitmapSize = (UInt32)(40 + compressedDestStream.Position); break; case BitmapCompression.None: header.bitmapSize = (UInt32)(40 + stride * input.Height); break; default: throw new MbmException(String.Format("Unsupported bitmap compression type {0}", compressionToUse.ToString())); } output.Seek(/*sizeof(MbmHeader)*/ 20, SeekOrigin.Begin); MbmBinaryWriter writer = new MbmBinaryWriter(output); // Try to write our header writer.WriteUInt32(header.bitmapSize); writer.WriteUInt32(header.headerLength); writer.WriteSize(header.sizeInPixel); writer.WriteSize(header.sizeInTwips); writer.WriteUInt32(header.bitsPerPixel); writer.WriteUInt32((UInt32)header.colorMode); writer.WriteUInt32(header.paletteSize); writer.WriteUInt32((UInt32)header.compression); // Write data switch (compressionToUse) { case BitmapCompression comp when(comp >= BitmapCompression.ByteRLE && comp <= BitmapCompression.ThirtyTwoABitsRLE): output.Write(compressedBitmapData, 0, (int)(header.bitmapSize - header.headerLength)); break; case BitmapCompression.None: output.Write(rawBitmapData, 0, rawBitmapData.Length); break; default: break; } // Write trailer UInt32 trailerOffset = writer.Tell(); writer.WriteUInt32(1); writer.WriteUInt32(20); // Seek back and write our header writer.Seek(0); writer.WriteUInt32(MbmHeader.directFileStoreUIDNum); writer.WriteUInt32(MbmHeader.multiBitmapUIDNum); writer.WriteUInt32(0); writer.WriteUInt32(0); // Checksum writer.WriteUInt32(trailerOffset); }