Browse Source

Moved HeaderSize and IsSupportedFileFormat to IImageFormat.

pull/52/head
Dirk Lemstra 9 years ago
parent
commit
bb0226d239
  1. 26
      src/ImageSharp/Formats/Bmp/BmpDecoder.cs
  2. 16
      src/ImageSharp/Formats/Bmp/BmpFormat.cs
  3. 25
      src/ImageSharp/Formats/Gif/GifDecoder.cs
  4. 15
      src/ImageSharp/Formats/Gif/GifFormat.cs
  5. 16
      src/ImageSharp/Formats/IImageDecoder.cs
  6. 16
      src/ImageSharp/Formats/IImageFormat.cs
  7. 84
      src/ImageSharp/Formats/Jpg/JpegDecoder.cs
  8. 71
      src/ImageSharp/Formats/Jpg/JpegFormat.cs
  9. 27
      src/ImageSharp/Formats/Png/PngDecoder.cs
  10. 17
      src/ImageSharp/Formats/Png/PngFormat.cs
  11. 4
      src/ImageSharp/Image/Image.cs
  12. 4
      tests/ImageSharp.Tests/BootstrapperTests.cs

26
src/ImageSharp/Formats/Bmp/BmpDecoder.cs

@ -25,32 +25,6 @@ namespace ImageSharp.Formats
/// </remarks>
public class BmpDecoder : IImageDecoder
{
/// <summary>
/// Gets the size of the header for this image type.
/// </summary>
/// <value>The size of the header.</value>
public int HeaderSize => 2;
/// <summary>
/// Returns a value indicating whether the <see cref="IImageDecoder"/> supports the specified
/// file header.
/// </summary>
/// <param name="header">The <see cref="T:byte[]"/> containing the file header.</param>
/// <returns>
/// True if the decoder supports the file header; otherwise, false.
/// </returns>
public bool IsSupportedFileFormat(byte[] header)
{
bool isBmp = false;
if (header.Length >= 2)
{
isBmp = header[0] == 0x42 && // B
header[1] == 0x4D; // M
}
return isBmp;
}
/// <inheritdoc/>
public void Decode<TColor, TPacked>(Image<TColor, TPacked> image, Stream stream)
where TColor : struct, IPackedPixel<TPacked>

16
src/ImageSharp/Formats/Bmp/BmpFormat.cs

@ -26,5 +26,21 @@ namespace ImageSharp.Formats
/// <inheritdoc/>
public IImageEncoder Encoder => new BmpEncoder();
/// <inheritdoc/>
public int HeaderSize => 2;
/// <inheritdoc/>
public bool IsSupportedFileFormat(byte[] header)
{
bool isBmp = false;
if (header.Length >= this.HeaderSize)
{
isBmp = header[0] == 0x42 && // B
header[1] == 0x4D; // M
}
return isBmp;
}
}
}

25
src/ImageSharp/Formats/Gif/GifDecoder.cs

@ -13,31 +13,6 @@ namespace ImageSharp.Formats
/// </summary>
public class GifDecoder : IImageDecoder
{
/// <summary>
/// Gets the size of the header for this image type.
/// </summary>
/// <value>The size of the header.</value>
public int HeaderSize => 6;
/// <summary>
/// Returns a value indicating whether the <see cref="IImageDecoder"/> supports the specified
/// file header.
/// </summary>
/// <param name="header">The <see cref="T:byte[]"/> containing the file header.</param>
/// <returns>
/// True if the decoder supports the file header; otherwise, false.
/// </returns>
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
}
/// <inheritdoc/>
public void Decode<TColor, TPacked>(Image<TColor, TPacked> image, Stream stream)
where TColor : struct, IPackedPixel<TPacked>

15
src/ImageSharp/Formats/Gif/GifFormat.cs

@ -26,5 +26,20 @@ namespace ImageSharp.Formats
/// <inheritdoc/>
public IImageEncoder Encoder => new GifEncoder();
/// <inheritdoc/>
public int HeaderSize => 6;
/// <inheritdoc/>
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
}
}
}

16
src/ImageSharp/Formats/IImageDecoder.cs

@ -13,22 +13,6 @@ namespace ImageSharp.Formats
/// </summary>
public interface IImageDecoder
{
/// <summary>
/// Gets the size of the header for this image type.
/// </summary>
/// <value>The size of the header.</value>
int HeaderSize { get; }
/// <summary>
/// Returns a value indicating whether the <see cref="IImageDecoder"/> supports the specified
/// file header.
/// </summary>
/// <param name="header">The <see cref="T:byte[]"/> containing the file header.</param>
/// <returns>
/// True if the decoder supports the file header; otherwise, false.
/// </returns>
bool IsSupportedFileFormat(byte[] header);
/// <summary>
/// Decodes the image from the specified stream to the <see cref="ImageBase{TColor, TPacked}"/>.
/// </summary>

16
src/ImageSharp/Formats/IImageFormat.cs

@ -39,5 +39,21 @@ namespace ImageSharp.Formats
/// Gets the image decoder for decoding an image from a stream.
/// </summary>
IImageDecoder Decoder { get; }
/// <summary>
/// Gets the size of the header for this image type.
/// </summary>
/// <value>The size of the header.</value>
int HeaderSize { get; }
/// <summary>
/// Returns a value indicating whether the <see cref="IImageDecoder"/> supports the specified
/// file header.
/// </summary>
/// <param name="header">The <see cref="T:byte[]"/> containing the file header.</param>
/// <returns>
/// True if the decoder supports the file header; otherwise, false.
/// </returns>
bool IsSupportedFileFormat(byte[] header);
}
}

84
src/ImageSharp/Formats/Jpg/JpegDecoder.cs

@ -13,41 +13,6 @@ namespace ImageSharp.Formats
/// </summary>
public class JpegDecoder : IImageDecoder
{
/// <summary>
/// Gets the size of the header for this image type.
/// </summary>
/// <value>The size of the header.</value>
public int HeaderSize => 11;
/// <summary>
/// Indicates if the image decoder supports the specified
/// file header.
/// </summary>
/// <param name="header">The file header.</param>
/// <returns>
/// <c>true</c>, if the decoder supports the specified
/// file header; otherwise <c>false</c>.
/// </returns>
/// <exception cref="System.ArgumentNullException"><paramref name="header"/>
/// is null (Nothing in Visual Basic).</exception>
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;
}
/// <inheritdoc/>
public void Decode<TColor, TPacked>(Image<TColor, TPacked> image, Stream stream)
where TColor : struct, IPackedPixel<TPacked>
@ -61,54 +26,5 @@ namespace ImageSharp.Formats
decoder.Decode(image, stream, false);
}
}
/// <summary>
/// Returns a value indicating whether the given bytes identify Jfif data.
/// </summary>
/// <param name="header">The bytes representing the file header.</param>
/// <returns>The <see cref="bool"/></returns>
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;
}
/// <summary>
/// Returns a value indicating whether the given bytes identify EXIF data.
/// </summary>
/// <param name="header">The bytes representing the file header.</param>
/// <returns>The <see cref="bool"/></returns>
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;
}
/// <summary>
/// Returns a value indicating whether the given bytes identify Jpeg data.
/// This is a last chance resort for jpegs that contain ICC information.
/// </summary>
/// <param name="header">The bytes representing the file header.</param>
/// <returns>The <see cref="bool"/></returns>
private static bool IsJpeg(byte[] header)
{
bool isJpg =
header[0] == 0xFF && // 255
header[1] == 0xD8; // 216
return isJpg;
}
}
}

71
src/ImageSharp/Formats/Jpg/JpegFormat.cs

@ -26,5 +26,76 @@ namespace ImageSharp.Formats
/// <inheritdoc/>
public IImageEncoder Encoder => new JpegEncoder();
/// <inheritdoc/>
public int HeaderSize => 11;
/// <inheritdoc/>
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;
}
/// <summary>
/// Returns a value indicating whether the given bytes identify Jfif data.
/// </summary>
/// <param name="header">The bytes representing the file header.</param>
/// <returns>The <see cref="bool"/></returns>
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;
}
/// <summary>
/// Returns a value indicating whether the given bytes identify EXIF data.
/// </summary>
/// <param name="header">The bytes representing the file header.</param>
/// <returns>The <see cref="bool"/></returns>
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;
}
/// <summary>
/// Returns a value indicating whether the given bytes identify Jpeg data.
/// This is a last chance resort for jpegs that contain ICC information.
/// </summary>
/// <param name="header">The bytes representing the file header.</param>
/// <returns>The <see cref="bool"/></returns>
private static bool IsJpeg(byte[] header)
{
bool isJpg =
header[0] == 0xFF && // 255
header[1] == 0xD8; // 216
return isJpg;
}
}
}

27
src/ImageSharp/Formats/Png/PngDecoder.cs

@ -30,33 +30,6 @@ namespace ImageSharp.Formats
/// </remarks>
public class PngDecoder : IImageDecoder
{
/// <summary>
/// Gets the size of the header for this image type.
/// </summary>
/// <value>The size of the header.</value>
public int HeaderSize => 8;
/// <summary>
/// Returns a value indicating whether the <see cref="IImageDecoder"/> supports the specified
/// file header.
/// </summary>
/// <param name="header">The <see cref="T:byte[]"/> containing the file header.</param>
/// <returns>
/// True if the decoder supports the file header; otherwise, false.
/// </returns>
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
}
/// <summary>
/// Decodes the image from the specified stream to the <see cref="ImageBase{TColor, TPacked}"/>.
/// </summary>

17
src/ImageSharp/Formats/Png/PngFormat.cs

@ -26,5 +26,22 @@ namespace ImageSharp.Formats
/// <inheritdoc/>
public IImageEncoder Encoder => new PngEncoder();
/// <inheritdoc/>
public int HeaderSize => 8;
/// <inheritdoc/>
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
}
}
}

4
src/ImageSharp/Image/Image.cs

@ -399,7 +399,7 @@ namespace ImageSharp
/// </returns>
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);

4
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<string> 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]

Loading…
Cancel
Save