diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoder.cs b/src/ImageSharp/Formats/Bmp/BmpDecoder.cs index 1754bcdd0..929a29b0b 100644 --- a/src/ImageSharp/Formats/Bmp/BmpDecoder.cs +++ b/src/ImageSharp/Formats/Bmp/BmpDecoder.cs @@ -25,32 +25,6 @@ namespace ImageSharp.Formats /// public class BmpDecoder : IImageDecoder { - /// - /// Gets the size of the header for this image type. - /// - /// The size of the header. - public int HeaderSize => 2; - - /// - /// Returns a value indicating whether the supports the specified - /// file header. - /// - /// The containing the file header. - /// - /// True if the decoder supports the file header; otherwise, false. - /// - public bool IsSupportedFileFormat(byte[] header) - { - bool isBmp = false; - if (header.Length >= 2) - { - isBmp = header[0] == 0x42 && // B - header[1] == 0x4D; // M - } - - return isBmp; - } - /// public void Decode(Image image, Stream stream) where TColor : struct, IPackedPixel diff --git a/src/ImageSharp/Formats/Bmp/BmpFormat.cs b/src/ImageSharp/Formats/Bmp/BmpFormat.cs index 35fdf35fa..c0ed5aaba 100644 --- a/src/ImageSharp/Formats/Bmp/BmpFormat.cs +++ b/src/ImageSharp/Formats/Bmp/BmpFormat.cs @@ -26,5 +26,21 @@ namespace ImageSharp.Formats /// public IImageEncoder Encoder => new BmpEncoder(); + + /// + public int HeaderSize => 2; + + /// + public bool IsSupportedFileFormat(byte[] header) + { + bool isBmp = false; + if (header.Length >= this.HeaderSize) + { + isBmp = header[0] == 0x42 && // B + header[1] == 0x4D; // M + } + + return isBmp; + } } } diff --git a/src/ImageSharp/Formats/Gif/GifDecoder.cs b/src/ImageSharp/Formats/Gif/GifDecoder.cs index 0c479db90..3ed8317d3 100644 --- a/src/ImageSharp/Formats/Gif/GifDecoder.cs +++ b/src/ImageSharp/Formats/Gif/GifDecoder.cs @@ -13,31 +13,6 @@ namespace ImageSharp.Formats /// public class GifDecoder : IImageDecoder { - /// - /// Gets the size of the header for this image type. - /// - /// The size of the header. - public int HeaderSize => 6; - - /// - /// Returns a value indicating whether the supports the specified - /// file header. - /// - /// The containing the file header. - /// - /// True if the decoder supports the file header; otherwise, false. - /// - public bool IsSupportedFileFormat(byte[] header) - { - return header.Length >= 6 && - header[0] == 0x47 && // G - header[1] == 0x49 && // I - header[2] == 0x46 && // F - header[3] == 0x38 && // 8 - (header[4] == 0x39 || header[4] == 0x37) && // 9 or 7 - header[5] == 0x61; // a - } - /// public void Decode(Image image, Stream stream) where TColor : struct, IPackedPixel diff --git a/src/ImageSharp/Formats/Gif/GifFormat.cs b/src/ImageSharp/Formats/Gif/GifFormat.cs index 7d29064b7..2851b0b6b 100644 --- a/src/ImageSharp/Formats/Gif/GifFormat.cs +++ b/src/ImageSharp/Formats/Gif/GifFormat.cs @@ -26,5 +26,20 @@ namespace ImageSharp.Formats /// public IImageEncoder Encoder => new GifEncoder(); + + /// + public int HeaderSize => 6; + + /// + public bool IsSupportedFileFormat(byte[] header) + { + return header.Length >= this.HeaderSize && + header[0] == 0x47 && // G + header[1] == 0x49 && // I + header[2] == 0x46 && // F + header[3] == 0x38 && // 8 + (header[4] == 0x39 || header[4] == 0x37) && // 9 or 7 + header[5] == 0x61; // a + } } } diff --git a/src/ImageSharp/Formats/IImageDecoder.cs b/src/ImageSharp/Formats/IImageDecoder.cs index 0f2008d64..1317ee4a5 100644 --- a/src/ImageSharp/Formats/IImageDecoder.cs +++ b/src/ImageSharp/Formats/IImageDecoder.cs @@ -13,22 +13,6 @@ namespace ImageSharp.Formats /// public interface IImageDecoder { - /// - /// Gets the size of the header for this image type. - /// - /// The size of the header. - int HeaderSize { get; } - - /// - /// Returns a value indicating whether the supports the specified - /// file header. - /// - /// The containing the file header. - /// - /// True if the decoder supports the file header; otherwise, false. - /// - bool IsSupportedFileFormat(byte[] header); - /// /// Decodes the image from the specified stream to the . /// diff --git a/src/ImageSharp/Formats/IImageFormat.cs b/src/ImageSharp/Formats/IImageFormat.cs index 4c696be6d..4f28cdc80 100644 --- a/src/ImageSharp/Formats/IImageFormat.cs +++ b/src/ImageSharp/Formats/IImageFormat.cs @@ -39,5 +39,21 @@ namespace ImageSharp.Formats /// Gets the image decoder for decoding an image from a stream. /// IImageDecoder Decoder { get; } + + /// + /// Gets the size of the header for this image type. + /// + /// The size of the header. + int HeaderSize { get; } + + /// + /// Returns a value indicating whether the supports the specified + /// file header. + /// + /// The containing the file header. + /// + /// True if the decoder supports the file header; otherwise, false. + /// + bool IsSupportedFileFormat(byte[] header); } } diff --git a/src/ImageSharp/Formats/Jpg/JpegDecoder.cs b/src/ImageSharp/Formats/Jpg/JpegDecoder.cs index 5e7321003..b9e9aa1b2 100644 --- a/src/ImageSharp/Formats/Jpg/JpegDecoder.cs +++ b/src/ImageSharp/Formats/Jpg/JpegDecoder.cs @@ -13,41 +13,6 @@ namespace ImageSharp.Formats /// public class JpegDecoder : IImageDecoder { - /// - /// Gets the size of the header for this image type. - /// - /// The size of the header. - public int HeaderSize => 11; - - /// - /// Indicates if the image decoder supports the specified - /// file header. - /// - /// The file header. - /// - /// true, if the decoder supports the specified - /// file header; otherwise false. - /// - /// - /// is null (Nothing in Visual Basic). - public bool IsSupportedFileFormat(byte[] header) - { - Guard.NotNull(header, "header"); - - bool isSupported = false; - - if (header.Length >= 11) - { - bool isJfif = IsJfif(header); - bool isExif = IsExif(header); - bool isJpeg = IsJpeg(header); - - isSupported = isJfif || isExif || isJpeg; - } - - return isSupported; - } - /// public void Decode(Image image, Stream stream) where TColor : struct, IPackedPixel @@ -61,54 +26,5 @@ namespace ImageSharp.Formats decoder.Decode(image, stream, false); } } - - /// - /// Returns a value indicating whether the given bytes identify Jfif data. - /// - /// The bytes representing the file header. - /// The - private static bool IsJfif(byte[] header) - { - bool isJfif = - header[6] == 0x4A && // J - header[7] == 0x46 && // F - header[8] == 0x49 && // I - header[9] == 0x46 && // F - header[10] == 0x00; - - return isJfif; - } - - /// - /// Returns a value indicating whether the given bytes identify EXIF data. - /// - /// The bytes representing the file header. - /// The - private static bool IsExif(byte[] header) - { - bool isExif = - header[6] == 0x45 && // E - header[7] == 0x78 && // X - header[8] == 0x69 && // I - header[9] == 0x66 && // F - header[10] == 0x00; - - return isExif; - } - - /// - /// Returns a value indicating whether the given bytes identify Jpeg data. - /// This is a last chance resort for jpegs that contain ICC information. - /// - /// The bytes representing the file header. - /// The - private static bool IsJpeg(byte[] header) - { - bool isJpg = - header[0] == 0xFF && // 255 - header[1] == 0xD8; // 216 - - return isJpg; - } } } diff --git a/src/ImageSharp/Formats/Jpg/JpegFormat.cs b/src/ImageSharp/Formats/Jpg/JpegFormat.cs index 7ac7d2a15..6712de54b 100644 --- a/src/ImageSharp/Formats/Jpg/JpegFormat.cs +++ b/src/ImageSharp/Formats/Jpg/JpegFormat.cs @@ -26,5 +26,76 @@ namespace ImageSharp.Formats /// public IImageEncoder Encoder => new JpegEncoder(); + + /// + public int HeaderSize => 11; + + /// + public bool IsSupportedFileFormat(byte[] header) + { + Guard.NotNull(header, "header"); + + bool isSupported = false; + + if (header.Length >= this.HeaderSize) + { + bool isJfif = IsJfif(header); + bool isExif = IsExif(header); + bool isJpeg = IsJpeg(header); + + isSupported = isJfif || isExif || isJpeg; + } + + return isSupported; + } + + /// + /// Returns a value indicating whether the given bytes identify Jfif data. + /// + /// The bytes representing the file header. + /// The + private static bool IsJfif(byte[] header) + { + bool isJfif = + header[6] == 0x4A && // J + header[7] == 0x46 && // F + header[8] == 0x49 && // I + header[9] == 0x46 && // F + header[10] == 0x00; + + return isJfif; + } + + /// + /// Returns a value indicating whether the given bytes identify EXIF data. + /// + /// The bytes representing the file header. + /// The + private static bool IsExif(byte[] header) + { + bool isExif = + header[6] == 0x45 && // E + header[7] == 0x78 && // X + header[8] == 0x69 && // I + header[9] == 0x66 && // F + header[10] == 0x00; + + return isExif; + } + + /// + /// Returns a value indicating whether the given bytes identify Jpeg data. + /// This is a last chance resort for jpegs that contain ICC information. + /// + /// The bytes representing the file header. + /// The + private static bool IsJpeg(byte[] header) + { + bool isJpg = + header[0] == 0xFF && // 255 + header[1] == 0xD8; // 216 + + return isJpg; + } } } diff --git a/src/ImageSharp/Formats/Png/PngDecoder.cs b/src/ImageSharp/Formats/Png/PngDecoder.cs index 851777000..8c4655b1d 100644 --- a/src/ImageSharp/Formats/Png/PngDecoder.cs +++ b/src/ImageSharp/Formats/Png/PngDecoder.cs @@ -30,33 +30,6 @@ namespace ImageSharp.Formats /// public class PngDecoder : IImageDecoder { - /// - /// Gets the size of the header for this image type. - /// - /// The size of the header. - public int HeaderSize => 8; - - /// - /// Returns a value indicating whether the supports the specified - /// file header. - /// - /// The containing the file header. - /// - /// True if the decoder supports the file header; otherwise, false. - /// - public bool IsSupportedFileFormat(byte[] header) - { - return header.Length >= 8 && - header[0] == 0x89 && - header[1] == 0x50 && // P - header[2] == 0x4E && // N - header[3] == 0x47 && // G - header[4] == 0x0D && // CR - header[5] == 0x0A && // LF - header[6] == 0x1A && // EOF - header[7] == 0x0A; // LF - } - /// /// Decodes the image from the specified stream to the . /// diff --git a/src/ImageSharp/Formats/Png/PngFormat.cs b/src/ImageSharp/Formats/Png/PngFormat.cs index 8f0042b08..0f5a74da0 100644 --- a/src/ImageSharp/Formats/Png/PngFormat.cs +++ b/src/ImageSharp/Formats/Png/PngFormat.cs @@ -26,5 +26,22 @@ namespace ImageSharp.Formats /// public IImageEncoder Encoder => new PngEncoder(); + + /// + public int HeaderSize => 8; + + /// + public bool IsSupportedFileFormat(byte[] header) + { + return header.Length >= this.HeaderSize && + header[0] == 0x89 && + header[1] == 0x50 && // P + header[2] == 0x4E && // N + header[3] == 0x47 && // G + header[4] == 0x0D && // CR + header[5] == 0x0A && // LF + header[6] == 0x1A && // EOF + header[7] == 0x0A; // LF + } } } diff --git a/src/ImageSharp/Image/Image.cs b/src/ImageSharp/Image/Image.cs index d9ad0078a..93e247b32 100644 --- a/src/ImageSharp/Image/Image.cs +++ b/src/ImageSharp/Image/Image.cs @@ -399,7 +399,7 @@ namespace ImageSharp /// private bool Decode(Stream stream) { - int maxHeaderSize = Bootstrapper.ImageFormats.Max(x => x.Decoder.HeaderSize); + int maxHeaderSize = Bootstrapper.ImageFormats.Max(x => x.HeaderSize); if (maxHeaderSize > 0) { byte[] header = new byte[maxHeaderSize]; @@ -408,7 +408,7 @@ namespace ImageSharp stream.Read(header, 0, maxHeaderSize); stream.Position = 0; - IImageFormat format = Bootstrapper.ImageFormats.FirstOrDefault(x => x.Decoder.IsSupportedFileFormat(header)); + IImageFormat format = Bootstrapper.ImageFormats.FirstOrDefault(x => x.IsSupportedFileFormat(header)); if (format != null) { format.Decoder.Decode(this, stream); diff --git a/tests/ImageSharp.Tests/BootstrapperTests.cs b/tests/ImageSharp.Tests/BootstrapperTests.cs index df93f99c9..b07fc01da 100644 --- a/tests/ImageSharp.Tests/BootstrapperTests.cs +++ b/tests/ImageSharp.Tests/BootstrapperTests.cs @@ -39,6 +39,10 @@ namespace ImageSharp.Tests public string Extension { get { return this.extension; } set { this.extension = value; } } public IEnumerable SupportedExtensions { get { return this.supportedExtensions; } set { this.supportedExtensions = value; } } + + public int HeaderSize { get { throw new NotImplementedException(); } } + + public bool IsSupportedFileFormat(byte[] header) { throw new NotImplementedException(); } } [Fact]