private bool TestBitmapFileHeader(StreamReaderHelper stream, out int offset) { offset = 0; // File must start with "BM". if (stream.GetWord(0, true) == 0x424d) { int filesize = (int)stream.GetDWord(2, false); // Integrity check: filesize set in BM header should match size of the stream. // We test "<" instead of "!=" to allow extra bytes at the end of the stream. if (filesize < stream.Length) return false; offset = (int)stream.GetDWord(10, false); stream.CurrentOffset += 14; return true; } return false; }
private bool TestBitmapFileHeader(StreamReaderHelper stream, out int offset) { offset = 0; // File must start with "BM". if (stream.GetWord(0, true) == 0x424d) { int filesize = (int)stream.GetDWord(2, false); // Integrity check: filesize set in BM header should match size of the stream. // We test "<" instead of "!=" to allow extra bytes at the end of the stream. if (filesize < stream.Length) { return(false); } offset = (int)stream.GetDWord(10, false); stream.CurrentOffset += 14; return(true); } return(false); }
private bool TestJfifHeader(StreamReaderHelper stream, ImportedImage ii) { // The App0 header should be the first header in every JFIF file. if (stream.GetWord(0, true) == 0xffe0) { // Now check for text "JFIF". if (stream.GetDWord(4, true) == 0x4a464946) { int blockLength = stream.GetWord(2, true); if (blockLength >= 16) { int version = stream.GetWord(9, true); int units = stream.GetByte(11); int densityX = stream.GetWord(12, true); int densityY = stream.GetWord(14, true); switch (units) { case 0: // Aspect ratio only. ii.Information.HorizontalAspectRatio = densityX; ii.Information.VerticalAspectRatio = densityY; break; case 1: // DPI. ii.Information.HorizontalDPI = densityX; ii.Information.VerticalDPI = densityY; break; case 2: // DPCM. ii.Information.HorizontalDPM = densityX * 100; ii.Information.VerticalDPM = densityY * 100; break; } // More information here? More tests? return(true); } } } return(false); }
private bool TestBitmapInfoHeader(StreamReaderHelper stream, ImportedImage ii, int offset) { int size = (int)stream.GetDWord(0, false); if (size == 40 || size == 108 || size == 124) // sizeof BITMAPINFOHEADER == 40, sizeof BITMAPV4HEADER == 108, sizeof BITMAPV5HEADER == 124 { uint width = stream.GetDWord(4, false); int height = (int)stream.GetDWord(8, false); int planes = stream.GetWord(12, false); int bitcount = stream.GetWord(14, false); int compression = (int)stream.GetDWord(16, false); int sizeImage = (int)stream.GetDWord(20, false); int xPelsPerMeter = (int)stream.GetDWord(24, false); int yPelsPerMeter = (int)stream.GetDWord(28, false); uint colorsUsed = stream.GetDWord(32, false); uint colorsImportant = stream.GetDWord(36, false); // TODO Integrity and plausibility checks. if (sizeImage != 0 && sizeImage + offset > stream.Length) { return(false); } ImagePrivateDataBitmap privateData = (ImagePrivateDataBitmap)ii.Data; // Return true only for supported formats. if (compression == 0 || compression == 3) // BI_RGB == 0, BI_BITFIELDS == 3 { ((ImagePrivateDataBitmap)ii.Data).Offset = offset; ((ImagePrivateDataBitmap)ii.Data).ColorPaletteOffset = stream.CurrentOffset + size; ii.Information.Width = width; ii.Information.Height = (uint)Math.Abs(height); ii.Information.HorizontalDPM = xPelsPerMeter; ii.Information.VerticalDPM = yPelsPerMeter; privateData.FlippedImage = height < 0; if (planes == 1 && bitcount == 24) { // RGB24 ii.Information.ImageFormat = ImageInformation.ImageFormats.RGB24; // TODO: Verify Mask if size >= 108 && compression == 3. return(true); } if (planes == 1 && bitcount == 32) { // ARGB32 //ii.Information.ImageFormat = ImageInformation.ImageFormats.ARGB32; ii.Information.ImageFormat = compression == 0 ? ImageInformation.ImageFormats.RGB24 : ImageInformation.ImageFormats.ARGB32; // TODO: tell RGB from ARGB. Idea: assume RGB if alpha is always 0. // TODO: Verify Mask if size >= 108 && compression == 3. return(true); } if (planes == 1 && bitcount == 8) { // Palette8 ii.Information.ImageFormat = ImageInformation.ImageFormats.Palette8; ii.Information.ColorsUsed = colorsUsed; return(true); } if (planes == 1 && bitcount == 4) { // Palette8 ii.Information.ImageFormat = ImageInformation.ImageFormats.Palette4; ii.Information.ColorsUsed = colorsUsed; return(true); } if (planes == 1 && bitcount == 1) { // Palette8 ii.Information.ImageFormat = ImageInformation.ImageFormats.Palette1; ii.Information.ColorsUsed = colorsUsed; return(true); } // TODO Implement more formats! } } return(false); }
private bool TestJfifHeader(StreamReaderHelper stream, ImportedImage ii) { // The App0 header should be the first header in every JFIF file. if (stream.GetWord(0, true) == 0xffe0) { // Now check for text "JFIF". if (stream.GetDWord(4, true) == 0x4a464946) { int blockLength = stream.GetWord(2, true); if (blockLength >= 16) { int version = stream.GetWord(9, true); int units = stream.GetByte(11); int densityX = stream.GetWord(12, true); int densityY = stream.GetWord(14, true); switch (units) { case 0: // Aspect ratio only. ii.Information.HorizontalAspectRatio = densityX; ii.Information.VerticalAspectRatio = densityY; break; case 1: // DPI. ii.Information.HorizontalDPI = densityX; ii.Information.VerticalDPI = densityY; break; case 2: // DPCM. ii.Information.HorizontalDPM = densityX * 100; ii.Information.VerticalDPM = densityY * 100; break; } // More information here? More tests? return true; } } } return false; }
private bool TestBitmapInfoHeader(StreamReaderHelper stream, ImportedImage ii, int offset) { int size = (int)stream.GetDWord(0, false); if (size == 40 || size == 108 || size == 124) // sizeof BITMAPINFOHEADER == 40, sizeof BITMAPV4HEADER == 108, sizeof BITMAPV5HEADER == 124 { uint width = stream.GetDWord(4, false); int height = (int)stream.GetDWord(8, false); int planes = stream.GetWord(12, false); int bitcount = stream.GetWord(14, false); int compression = (int)stream.GetDWord(16, false); int sizeImage = (int)stream.GetDWord(20, false); int xPelsPerMeter = (int)stream.GetDWord(24, false); int yPelsPerMeter = (int)stream.GetDWord(28, false); uint colorsUsed = stream.GetDWord(32, false); uint colorsImportant = stream.GetDWord(36, false); // TODO Integrity and plausibility checks. if (sizeImage != 0 && sizeImage + offset > stream.Length) return false; ImagePrivateDataBitmap privateData = (ImagePrivateDataBitmap)ii.Data; // Return true only for supported formats. if (compression == 0 || compression == 3) // BI_RGB == 0, BI_BITFIELDS == 3 { ((ImagePrivateDataBitmap)ii.Data).Offset = offset; ((ImagePrivateDataBitmap)ii.Data).ColorPaletteOffset = stream.CurrentOffset + size; ii.Information.Width = width; ii.Information.Height = (uint)Math.Abs(height); ii.Information.HorizontalDPM = xPelsPerMeter; ii.Information.VerticalDPM = yPelsPerMeter; privateData.FlippedImage = height < 0; if (planes == 1 && bitcount == 24) { // RGB24 ii.Information.ImageFormat = ImageInformation.ImageFormats.RGB24; // TODO: Verify Mask if size >= 108 && compression == 3. return true; } if (planes == 1 && bitcount == 32) { // ARGB32 //ii.Information.ImageFormat = ImageInformation.ImageFormats.ARGB32; ii.Information.ImageFormat = compression == 0 ? ImageInformation.ImageFormats.RGB24 : ImageInformation.ImageFormats.ARGB32; // TODO: tell RGB from ARGB. Idea: assume RGB if alpha is always 0. // TODO: Verify Mask if size >= 108 && compression == 3. return true; } if (planes == 1 && bitcount == 8) { // Palette8 ii.Information.ImageFormat = ImageInformation.ImageFormats.Palette8; ii.Information.ColorsUsed = colorsUsed; return true; } if (planes == 1 && bitcount == 4) { // Palette8 ii.Information.ImageFormat = ImageInformation.ImageFormats.Palette4; ii.Information.ColorsUsed = colorsUsed; return true; } if (planes == 1 && bitcount == 1) { // Palette8 ii.Information.ImageFormat = ImageInformation.ImageFormats.Palette1; ii.Information.ColorsUsed = colorsUsed; return true; } // TODO Implement more formats! } } return false; }