private bool TestColorFormatHeader(StreamReaderHelper stream, ImportedImage ii) { // The SOS header (start of scan). if (stream.GetWord(0, true) == 0xffda) { int components = stream.GetByte(4); if (components < 1 || components > 4 || components == 2) { return(false); } // 1 for grayscale, 3 for RGB, 4 for CMYK. int blockLength = stream.GetWord(2, true); // Integrity check: correct size? if (blockLength != 6 + 2 * components) { return(false); } // Eventually do more tests here. // Magic: we assume that all JPEG files with 4 components are RGBW (inverted CMYK) and not CMYK. // We add a test to tell CMYK from RGBW when we encounter a test file in CMYK format. ii.Information.ImageFormat = components == 3 ? ImageInformation.ImageFormats.JPEG : (components == 1 ? ImageInformation.ImageFormats.JPEGGRAY : ImageInformation.ImageFormats.JPEGRGBW); return(true); } return(false); }
private bool MoveToNextHeader(StreamReaderHelper stream) { int blockLength = stream.GetWord(2, true); int headerMagic = stream.GetByte(0); int headerType = stream.GetByte(1); if (headerMagic == 0xff) { // EOI: last header. if (headerType == 0xd9) { return(false); } // Check for standalone markers. if (headerType == 0x01 || headerType >= 0xd0 && headerType <= 0xd7) { stream.CurrentOffset += 2; return(true); } // Now assume header with block size. stream.CurrentOffset += 2 + blockLength; 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 TestInfoHeader(StreamReaderHelper stream, ImportedImage ii) { // The SOF header (start of frame). int header = stream.GetWord(0, true); if (header >= 0xffc0 && header <= 0xffc3 || header >= 0xffc9 && header <= 0xffcb) { // Lines in image. int sizeY = stream.GetWord(5, true); // Samples per line. int sizeX = stream.GetWord(7, true); // $THHO TODO: Check if we always get useful information here. ii.Information.Width = (uint)sizeX; ii.Information.Height = (uint)sizeY; 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 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 TestFileHeader(StreamReaderHelper stream) { // File must start with 0xffd8. return(stream.GetWord(0, true) == 0xffd8); }
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 TestFileHeader(StreamReaderHelper stream) { // File must start with 0xffd8. return stream.GetWord(0, true) == 0xffd8; }
private bool MoveToNextHeader(StreamReaderHelper stream) { int blockLength = stream.GetWord(2, true); int headerMagic = stream.GetByte(0); int headerType = stream.GetByte(1); if (headerMagic == 0xff) { // EOI: last header. if (headerType == 0xd9) return false; // Check for standalone markers. if (headerType == 0x01 || headerType >= 0xd0 && headerType <= 0xd7) { stream.CurrentOffset += 2; return true; } // Now assume header with block size. stream.CurrentOffset += 2 + blockLength; return true; } return false; }
private bool TestInfoHeader(StreamReaderHelper stream, ImportedImage ii) { // The SOF header (start of frame). int header = stream.GetWord(0, true); if (header >= 0xffc0 && header <= 0xffc3 || header >= 0xffc9 && header <= 0xffcb) { // Lines in image. int sizeY = stream.GetWord(5, true); // Samples per line. int sizeX = stream.GetWord(7, true); // $THHO TODO: Check if we always get useful information here. ii.Information.Width = (uint)sizeX; ii.Information.Height = (uint)sizeY; return true; } return false; }
private bool TestColorFormatHeader(StreamReaderHelper stream, ImportedImage ii) { // The SOS header (start of scan). if (stream.GetWord(0, true) == 0xffda) { int components = stream.GetByte(4); if (components < 1 || components > 4 || components == 2) return false; // 1 for grayscale, 3 for RGB, 4 for CMYK. int blockLength = stream.GetWord(2, true); // Integrity check: correct size? if (blockLength != 6 + 2 * components) return false; // Eventually do more tests here. // Magic: we assume that all JPEG files with 4 components are RGBW (inverted CMYK) and not CMYK. // We add a test to tell CMYK from RGBW when we encounter a test file in CMYK format. ii.Information.ImageFormat = components == 3 ? ImageInformation.ImageFormats.JPEG : (components == 1 ? ImageInformation.ImageFormats.JPEGGRAY : ImageInformation.ImageFormats.JPEGRGBW); 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 TestFileHeader(StreamReaderHelper stream) => // File must start with 0xffd8. stream.GetWord(0, true) == 0xffd8;