/// <summary> /// /// </summary> /// <param name="stream"></param> /// <returns></returns> public static BmpFileHeader FillFromStream(Stream stream) { byte[] buffer = new byte[_SIZE]; BmpFileHeader header = new BmpFileHeader(); stream.Read(buffer, 0, _SIZE); // Fill header.BitmapType = BitConverter.ToInt16(buffer, 0); header.Size = BitConverter.ToInt32(buffer, 2); header.OffsetToData = BitConverter.ToInt32(buffer, 10); // Return results return(header); }
/// <summary> /// /// </summary> /// <param name="stream"></param> /// <returns></returns> public static BmpFileHeader FillFromStream(Stream stream) { byte[] buffer = new byte[_SIZE]; BmpFileHeader header = new BmpFileHeader(); stream.Read(buffer, 0, _SIZE); // Fill header.BitmapType = BitConverter.ToInt16(buffer, 0); header.Size = BitConverter.ToInt32(buffer, 2); header.OffsetToData = BitConverter.ToInt32(buffer, 10); // Return results return header; }
/// <summary> /// Decodes a bitmap stream into an editable image. /// </summary> /// <param name="stream"></param> /// <returns></returns> public static EditableImage Decode(Stream stream) { EditableImage image = null; // See http://en.wikipedia.org/wiki/BMP_file_format try { byte[] buffer; BmpFileHeader fHeader; BmpInfoHeader iHeader; // Read File Header fHeader = BmpFileHeader.FillFromStream(stream); // Validate file type if (fHeader.BitmapType != 19778) { throw new Exception("Invalid BMP file"); } // Read Info Header iHeader = BmpInfoHeader.FillFromStream(stream); // Data if ((iHeader.Compression == 0) && (iHeader.BitsPerPixel == 24)) { // Read bits into the buffer buffer = new byte[iHeader.ImageSize]; stream.Read(buffer, 0, iHeader.ImageSize); // Standard RGB file image = Read24BitBmp(buffer, iHeader); } else if ((iHeader.Compression == 0) && (iHeader.BitsPerPixel <= 8)) { int count = iHeader.ColorCount * 4; // 4 bytes per color Color[] palette; // Read colors buffer = new byte[count]; stream.Read(buffer, 0, count); palette = FillColorPalette(buffer, iHeader.ColorCount); // Read data buffer = new byte[iHeader.ImageSize]; stream.Read(buffer, 0, iHeader.ImageSize); image = ReadPaletteBmp(buffer, palette, iHeader, iHeader.BitsPerPixel); } else if ((iHeader.Compression == 3) && (iHeader.BitsPerPixel == 16)) { // Special 565 16 bit encoding - see http://www.virtualdub.org/blog/pivot/entry.php?id=177 int remainder = fHeader.OffsetToData - (int)stream.Position; int rMask; int bMask; int gMask; // Read remainder buffer = new byte[remainder]; stream.Read(buffer, 0, remainder); // Read masks rMask = BitConverter.ToInt32(buffer, 0); gMask = BitConverter.ToInt32(buffer, 4); bMask = BitConverter.ToInt32(buffer, 8); if ((_REDMASK != rMask) || (_GREENMASK != gMask) || (_BLUEMASK != bMask)) { // Not 565 format throw new Exception("Unsupported 16 bit format: " + rMask.ToString("X2") + ", " + bMask.ToString("X2") + ", " + gMask.ToString("X2")); } // Read data remainder = iHeader.Height * iHeader.Width * 2; // 2 bytes per pixel buffer = new byte[remainder]; stream.Read(buffer, 0, remainder); // Convert to an image image = Read565Bmp(buffer, iHeader); } else { throw new Exception("Unsupported format (compression: " + iHeader.Compression.ToString() + ", Bits per pixel: " + iHeader.BitsPerPixel.ToString() + ")"); } } catch (Exception ex) { #if SILVERLIGHT HtmlPage.Window.Alert("Error parsing BMP file: " + ex.Message); #else throw; #endif } return(image); }