|
@@ -12,9 +12,6 @@ public static class ImageDetectExt
|
|
{
|
|
{
|
|
private const float MToInch = 39.3700787F;
|
|
private const float MToInch = 39.3700787F;
|
|
private const float CmToInch = MToInch * 0.01F;
|
|
private const float CmToInch = MToInch * 0.01F;
|
|
- private const float MmToInch = CmToInch * 0.1F;
|
|
|
|
- private const float HundredthThMmToInch = MmToInch * 0.01F;
|
|
|
|
- internal const float StandardDPI = 96f;
|
|
|
|
|
|
|
|
internal struct TifIfd
|
|
internal struct TifIfd
|
|
{
|
|
{
|
|
@@ -36,7 +33,7 @@ public static class ImageDetectExt
|
|
/// <returns></returns>
|
|
/// <returns></returns>
|
|
public static ImageFormat? GetImageType(this Stream ms)
|
|
public static ImageFormat? GetImageType(this Stream ms)
|
|
{
|
|
{
|
|
- using var br = new BinaryReader(ms);
|
|
|
|
|
|
+ var br = new BinaryReader(ms);
|
|
if (IsJpg(br))
|
|
if (IsJpg(br))
|
|
{
|
|
{
|
|
return ImageFormat.Jpg;
|
|
return ImageFormat.Jpg;
|
|
@@ -123,62 +120,6 @@ public static class ImageDetectExt
|
|
return sign.Length >= 2 && sign[0] == 0x1F && sign[1] == 0x8B;
|
|
return sign.Length >= 2 && sign[0] == 0x1F && sign[1] == 0x8B;
|
|
}
|
|
}
|
|
|
|
|
|
- internal static bool TryGetImageBounds(ImageFormat imageFormat, MemoryStream ms, ref double width, ref double height, out double horizontalResolution, out double verticalResolution)
|
|
|
|
- {
|
|
|
|
- width = 0;
|
|
|
|
- height = 0;
|
|
|
|
- horizontalResolution = verticalResolution = StandardDPI;
|
|
|
|
- try
|
|
|
|
- {
|
|
|
|
- ms.Seek(0, SeekOrigin.Begin);
|
|
|
|
- if (imageFormat == ImageFormat.Bmp && IsBmp(ms, ref width, ref height, ref horizontalResolution, ref verticalResolution))
|
|
|
|
- {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- if (imageFormat == ImageFormat.Jpg && IsJpg(ms, ref width, ref height, ref horizontalResolution, ref verticalResolution))
|
|
|
|
- {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- if (imageFormat == ImageFormat.Gif && IsGif(ms, ref width, ref height))
|
|
|
|
- {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- if (imageFormat == ImageFormat.Png && IsPng(ms, ref width, ref height, ref horizontalResolution, ref verticalResolution))
|
|
|
|
- {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- if (imageFormat == ImageFormat.Emf && IsEmf(ms, ref width, ref height, ref horizontalResolution, ref verticalResolution))
|
|
|
|
- {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- if (imageFormat == ImageFormat.Wmf && IsWmf(ms, ref width, ref height, ref horizontalResolution, ref verticalResolution))
|
|
|
|
- {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- else if (imageFormat == ImageFormat.Svg && IsSvg(ms, ref width, ref height))
|
|
|
|
- {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- else if (imageFormat == ImageFormat.Tif && IsTif(ms, ref width, ref height, ref horizontalResolution, ref verticalResolution))
|
|
|
|
- {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- else if (imageFormat == ImageFormat.WebP && IsWebP(ms, ref width, ref height, ref horizontalResolution, ref verticalResolution))
|
|
|
|
- {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- else if (imageFormat == ImageFormat.Ico && IsIcon(ms, ref width, ref height))
|
|
|
|
- {
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- catch
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
internal static byte[] ExtractImage(byte[] img, out ImageFormat? type)
|
|
internal static byte[] ExtractImage(byte[] img, out ImageFormat? type)
|
|
{
|
|
{
|
|
if (IsGZip(img))
|
|
if (IsGZip(img))
|
|
@@ -227,70 +168,6 @@ public static class ImageDetectExt
|
|
return img;
|
|
return img;
|
|
}
|
|
}
|
|
|
|
|
|
- private static bool IsJpg(MemoryStream ms, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
|
|
|
|
- {
|
|
|
|
- using (var br = new BinaryReader(ms))
|
|
|
|
- {
|
|
|
|
- if (IsJpg(br))
|
|
|
|
- {
|
|
|
|
- float xDensity = 1, yDensity = 1;
|
|
|
|
- while (ms.Position < ms.Length)
|
|
|
|
- {
|
|
|
|
- var id = GetUInt16BigEndian(br);
|
|
|
|
- var length = (int)GetInt16BigEndian(br);
|
|
|
|
- switch (id)
|
|
|
|
- {
|
|
|
|
- case 0xFFE0:
|
|
|
|
- var identifier = br.ReadBytes(5); //JFIF\0
|
|
|
|
- var version = br.ReadBytes(2);
|
|
|
|
- var unit = br.ReadByte();
|
|
|
|
- xDensity = (int)GetInt16BigEndian(br);
|
|
|
|
- yDensity = (int)GetInt16BigEndian(br);
|
|
|
|
-
|
|
|
|
- if (unit == 1)
|
|
|
|
- {
|
|
|
|
- horizontalResolution = xDensity;
|
|
|
|
- verticalResolution = yDensity;
|
|
|
|
- }
|
|
|
|
- else if (unit == 2)
|
|
|
|
- {
|
|
|
|
- horizontalResolution = xDensity * CmToInch;
|
|
|
|
- verticalResolution = yDensity * CmToInch;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ms.Position += length - 14;
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 0xFFE1:
|
|
|
|
- var pos = ms.Position;
|
|
|
|
- identifier = br.ReadBytes(6); //EXIF\0\0 or //EXIF\FF\FF
|
|
|
|
- double w = 0, h = 0;
|
|
|
|
- ReadTiffHeader(br, ref w, ref h, ref horizontalResolution, ref verticalResolution);
|
|
|
|
- ms.Position = pos + length - 2;
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case 0xFFC0:
|
|
|
|
- case 0xFFC1:
|
|
|
|
- case 0xFFC2:
|
|
|
|
- var precision = br.ReadByte(); //Bits
|
|
|
|
- height = GetUInt16BigEndian(br);
|
|
|
|
- width = GetUInt16BigEndian(br);
|
|
|
|
- br.Close();
|
|
|
|
- return true;
|
|
|
|
-
|
|
|
|
- case 0xFFD9:
|
|
|
|
- return height != 0 && width != 0;
|
|
|
|
-
|
|
|
|
- default:
|
|
|
|
- ms.Position += length - 2;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
private static bool IsJpg(BinaryReader br)
|
|
private static bool IsJpg(BinaryReader br)
|
|
{
|
|
{
|
|
br.BaseStream.Position = 0;
|
|
br.BaseStream.Position = 0;
|
|
@@ -298,21 +175,6 @@ public static class ImageDetectExt
|
|
return sign.Length >= 2 && sign[0] == 0xFF && sign[1] == 0xD8;
|
|
return sign.Length >= 2 && sign[0] == 0xFF && sign[1] == 0xD8;
|
|
}
|
|
}
|
|
|
|
|
|
- private static bool IsGif(MemoryStream ms, ref double width, ref double height)
|
|
|
|
- {
|
|
|
|
- using (var br = new BinaryReader(ms))
|
|
|
|
- {
|
|
|
|
- if (IsGif(br))
|
|
|
|
- {
|
|
|
|
- width = br.ReadUInt16();
|
|
|
|
- height = br.ReadUInt16();
|
|
|
|
- br.Close();
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
private static bool IsGif(BinaryReader br)
|
|
private static bool IsGif(BinaryReader br)
|
|
{
|
|
{
|
|
br.BaseStream.Seek(0, SeekOrigin.Begin);
|
|
br.BaseStream.Seek(0, SeekOrigin.Begin);
|
|
@@ -320,38 +182,6 @@ public static class ImageDetectExt
|
|
return b[0] == 0x47 && b[1] == 0x49 && b[2] == 0x46; //byte 4-6 contains the version, but we don't check them here.
|
|
return b[0] == 0x47 && b[1] == 0x49 && b[2] == 0x46; //byte 4-6 contains the version, but we don't check them here.
|
|
}
|
|
}
|
|
|
|
|
|
- private static bool IsBmp(MemoryStream ms, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
|
|
|
|
- {
|
|
|
|
- using (var br = new BinaryReader(ms))
|
|
|
|
- {
|
|
|
|
- if (IsBmp(br, out string sign))
|
|
|
|
- {
|
|
|
|
- var size = br.ReadInt32();
|
|
|
|
- var reserved = br.ReadBytes(4);
|
|
|
|
- var offsetData = br.ReadInt32();
|
|
|
|
-
|
|
|
|
- //Info Header
|
|
|
|
- var ihSize = br.ReadInt32(); //Should be 40
|
|
|
|
- width = br.ReadInt32();
|
|
|
|
- height = br.ReadInt32();
|
|
|
|
-
|
|
|
|
- if (sign == "BM")
|
|
|
|
- {
|
|
|
|
- br.ReadBytes(12);
|
|
|
|
- horizontalResolution = br.ReadInt32() / MToInch;
|
|
|
|
- verticalResolution = br.ReadInt32() / MToInch;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- horizontalResolution = verticalResolution = 1;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
internal static bool IsBmp(BinaryReader br, out string sign)
|
|
internal static bool IsBmp(BinaryReader br, out string sign)
|
|
{
|
|
{
|
|
try
|
|
try
|
|
@@ -369,25 +199,6 @@ public static class ImageDetectExt
|
|
|
|
|
|
#region Ico
|
|
#region Ico
|
|
|
|
|
|
- private static bool IsIcon(MemoryStream ms, ref double width, ref double height)
|
|
|
|
- {
|
|
|
|
- using (var br = new BinaryReader(ms))
|
|
|
|
- {
|
|
|
|
- if (IsIco(br))
|
|
|
|
- {
|
|
|
|
- var imageCount = br.ReadInt16();
|
|
|
|
- width = br.ReadByte();
|
|
|
|
- if (width == 0) width = 256;
|
|
|
|
- height = br.ReadByte();
|
|
|
|
- if (height == 0) height = 256;
|
|
|
|
- br.Close();
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- br.Close();
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
internal static bool IsIco(BinaryReader br)
|
|
internal static bool IsIco(BinaryReader br)
|
|
{
|
|
{
|
|
br.BaseStream.Seek(0, SeekOrigin.Begin);
|
|
br.BaseStream.Seek(0, SeekOrigin.Begin);
|
|
@@ -400,46 +211,6 @@ public static class ImageDetectExt
|
|
|
|
|
|
#region WebP
|
|
#region WebP
|
|
|
|
|
|
- private static bool IsWebP(MemoryStream ms, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
|
|
|
|
- {
|
|
|
|
- width = height = 0;
|
|
|
|
- horizontalResolution = verticalResolution = StandardDPI * (1 + 1 / 3); //Excel seems to render webp at 1 1/3 size.
|
|
|
|
- using (var br = new BinaryReader(ms))
|
|
|
|
- {
|
|
|
|
- if (IsWebP(br))
|
|
|
|
- {
|
|
|
|
- var vp8 = Encoding.ASCII.GetString(br.ReadBytes(4));
|
|
|
|
- switch (vp8)
|
|
|
|
- {
|
|
|
|
- case "VP8 ":
|
|
|
|
- var b = br.ReadBytes(10);
|
|
|
|
- var w = br.ReadInt16();
|
|
|
|
- width = w & 0x3FFF;
|
|
|
|
- var hScale = w >> 14;
|
|
|
|
- var h = br.ReadInt16();
|
|
|
|
- height = h & 0x3FFF;
|
|
|
|
- hScale = h >> 14;
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case "VP8X":
|
|
|
|
- br.ReadBytes(8);
|
|
|
|
- b = br.ReadBytes(6);
|
|
|
|
- width = BitConverter.ToInt32(new byte[] { b[0], b[1], b[2], 0 }, 0) + 1;
|
|
|
|
- height = BitConverter.ToInt32(new byte[] { b[3], b[4], b[5], 0 }, 0) + 1;
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case "VP8L":
|
|
|
|
- br.ReadBytes(5);
|
|
|
|
- b = br.ReadBytes(4);
|
|
|
|
- width = (b[0] | (b[1] & 0x3F) << 8) + 1;
|
|
|
|
- height = (b[1] >> 6 | b[2] << 2 | (b[3] & 0x0F) << 10) + 1;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return width != 0 && height != 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
internal static bool IsWebP(BinaryReader br)
|
|
internal static bool IsWebP(BinaryReader br)
|
|
{
|
|
{
|
|
try
|
|
try
|
|
@@ -461,14 +232,6 @@ public static class ImageDetectExt
|
|
|
|
|
|
#region Tiff
|
|
#region Tiff
|
|
|
|
|
|
- private static bool IsTif(MemoryStream ms, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
|
|
|
|
- {
|
|
|
|
- using (var br = new BinaryReader(ms))
|
|
|
|
- {
|
|
|
|
- return ReadTiffHeader(br, ref width, ref height, ref horizontalResolution, ref verticalResolution);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
private static bool ReadTiffHeader(BinaryReader br, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
|
|
private static bool ReadTiffHeader(BinaryReader br, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
|
|
{
|
|
{
|
|
var ms = br.BaseStream;
|
|
var ms = br.BaseStream;
|
|
@@ -575,10 +338,8 @@ public static class ImageDetectExt
|
|
{
|
|
{
|
|
return GetInt16BigEndian(br);
|
|
return GetInt16BigEndian(br);
|
|
}
|
|
}
|
|
- else
|
|
|
|
- {
|
|
|
|
- return br.ReadInt16();
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ return br.ReadInt16();
|
|
}
|
|
}
|
|
|
|
|
|
private static int GetTifInt32(BinaryReader br, bool isBigEndian)
|
|
private static int GetTifInt32(BinaryReader br, bool isBigEndian)
|
|
@@ -587,80 +348,14 @@ public static class ImageDetectExt
|
|
{
|
|
{
|
|
return GetInt32BigEndian(br);
|
|
return GetInt32BigEndian(br);
|
|
}
|
|
}
|
|
- else
|
|
|
|
- {
|
|
|
|
- return br.ReadInt32();
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
|
|
+ return br.ReadInt32();
|
|
}
|
|
}
|
|
|
|
|
|
#endregion Tiff
|
|
#endregion Tiff
|
|
|
|
|
|
#region Emf
|
|
#region Emf
|
|
|
|
|
|
- private static bool IsEmf(MemoryStream ms, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
|
|
|
|
- {
|
|
|
|
- using (var br = new BinaryReader(ms))
|
|
|
|
- {
|
|
|
|
- if (IsEmf(br))
|
|
|
|
- {
|
|
|
|
- var length = br.ReadInt32();
|
|
|
|
- var bounds = new int[4];
|
|
|
|
- bounds[0] = br.ReadInt32();
|
|
|
|
- bounds[1] = br.ReadInt32();
|
|
|
|
- bounds[2] = br.ReadInt32();
|
|
|
|
- bounds[3] = br.ReadInt32();
|
|
|
|
- var frame = new int[4];
|
|
|
|
- frame[0] = br.ReadInt32();
|
|
|
|
- frame[1] = br.ReadInt32();
|
|
|
|
- frame[2] = br.ReadInt32();
|
|
|
|
- frame[3] = br.ReadInt32();
|
|
|
|
-
|
|
|
|
- var signatureBytes = br.ReadBytes(4);
|
|
|
|
- var signature = Encoding.ASCII.GetString(signatureBytes);
|
|
|
|
- if (signature.Trim() == "EMF")
|
|
|
|
- {
|
|
|
|
- var version = br.ReadUInt32();
|
|
|
|
- var size = br.ReadUInt32();
|
|
|
|
- var records = br.ReadUInt32();
|
|
|
|
- var handles = br.ReadUInt16();
|
|
|
|
- var reserved = br.ReadUInt16();
|
|
|
|
-
|
|
|
|
- var nDescription = br.ReadUInt32();
|
|
|
|
- var offDescription = br.ReadUInt32();
|
|
|
|
- var nPalEntries = br.ReadUInt32();
|
|
|
|
- var device = new uint[2];
|
|
|
|
- device[0] = br.ReadUInt32();
|
|
|
|
- device[1] = br.ReadUInt32();
|
|
|
|
-
|
|
|
|
- var mm = new uint[2];
|
|
|
|
- mm[0] = br.ReadUInt32();
|
|
|
|
- mm[1] = br.ReadUInt32();
|
|
|
|
-
|
|
|
|
- //Extension 1
|
|
|
|
- var cbPixelFormat = br.ReadUInt32();
|
|
|
|
- var offPixelFormat = br.ReadUInt32();
|
|
|
|
- var bOpenGL = br.ReadUInt32();
|
|
|
|
-
|
|
|
|
- //Extension 2
|
|
|
|
- var hr = br.ReadUInt32();
|
|
|
|
- var vr = br.ReadUInt32();
|
|
|
|
-
|
|
|
|
- var id = br.ReadInt32();
|
|
|
|
- var size2 = br.ReadInt32();
|
|
|
|
-
|
|
|
|
- width = (bounds[2] - bounds[0] + 1);
|
|
|
|
- height = (bounds[3] - bounds[1] + 1);
|
|
|
|
-
|
|
|
|
- horizontalResolution = width / ((frame[2] - frame[0]) * HundredthThMmToInch * StandardDPI) * StandardDPI;
|
|
|
|
- verticalResolution = height / ((frame[3] - frame[1]) * HundredthThMmToInch * StandardDPI) * StandardDPI;
|
|
|
|
-
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
private static bool IsEmf(BinaryReader br)
|
|
private static bool IsEmf(BinaryReader br)
|
|
{
|
|
{
|
|
br.BaseStream.Position = 0;
|
|
br.BaseStream.Position = 0;
|
|
@@ -672,36 +367,6 @@ public static class ImageDetectExt
|
|
|
|
|
|
#region Wmf
|
|
#region Wmf
|
|
|
|
|
|
- private const double PIXELS_PER_TWIPS = 1D / 15D;
|
|
|
|
- private const double DEFAULT_TWIPS = 1440D;
|
|
|
|
-
|
|
|
|
- private static bool IsWmf(MemoryStream ms, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
|
|
|
|
- {
|
|
|
|
- using (var br = new BinaryReader(ms))
|
|
|
|
- {
|
|
|
|
- if (IsWmf(br))
|
|
|
|
- {
|
|
|
|
- var HWmf = br.ReadInt16();
|
|
|
|
- var bounds = new ushort[4];
|
|
|
|
- bounds[0] = br.ReadUInt16();
|
|
|
|
- bounds[1] = br.ReadUInt16();
|
|
|
|
- bounds[2] = br.ReadUInt16();
|
|
|
|
- bounds[3] = br.ReadUInt16();
|
|
|
|
-
|
|
|
|
- var inch = br.ReadInt16();
|
|
|
|
- width = bounds[2] - bounds[0];
|
|
|
|
- height = bounds[3] - bounds[1];
|
|
|
|
- if (inch != 0)
|
|
|
|
- {
|
|
|
|
- width *= (DEFAULT_TWIPS / inch) * PIXELS_PER_TWIPS;
|
|
|
|
- height *= (DEFAULT_TWIPS / inch) * PIXELS_PER_TWIPS;
|
|
|
|
- }
|
|
|
|
- return width != 0 && height != 0;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
private static bool IsWmf(BinaryReader br)
|
|
private static bool IsWmf(BinaryReader br)
|
|
{
|
|
{
|
|
br.BaseStream.Position = 0;
|
|
br.BaseStream.Position = 0;
|
|
@@ -713,57 +378,6 @@ public static class ImageDetectExt
|
|
|
|
|
|
#region Png
|
|
#region Png
|
|
|
|
|
|
- private static bool IsPng(MemoryStream ms, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution)
|
|
|
|
- {
|
|
|
|
- using (var br = new BinaryReader(ms))
|
|
|
|
- {
|
|
|
|
- return IsPng(br, ref width, ref height, ref horizontalResolution, ref verticalResolution);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private static bool IsPng(BinaryReader br, ref double width, ref double height, ref double horizontalResolution, ref double verticalResolution, long fileEndPosition = long.MinValue)
|
|
|
|
- {
|
|
|
|
- if (IsPng(br))
|
|
|
|
- {
|
|
|
|
- if (fileEndPosition == long.MinValue)
|
|
|
|
- {
|
|
|
|
- fileEndPosition = br.BaseStream.Length;
|
|
|
|
- }
|
|
|
|
- while (br.BaseStream.Position < fileEndPosition)
|
|
|
|
- {
|
|
|
|
- var chunkType = ReadPngChunkHeader(br, out int length);
|
|
|
|
- switch (chunkType)
|
|
|
|
- {
|
|
|
|
- case "IHDR":
|
|
|
|
- width = GetInt32BigEndian(br);
|
|
|
|
- height = GetInt32BigEndian(br);
|
|
|
|
- br.ReadBytes(5); //Ignored bytes, Depth compression etc.
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- case "pHYs":
|
|
|
|
- horizontalResolution = GetInt32BigEndian(br);
|
|
|
|
- verticalResolution = GetInt32BigEndian(br);
|
|
|
|
- var unitSpecifier = br.ReadByte();
|
|
|
|
- if (unitSpecifier == 1)
|
|
|
|
- {
|
|
|
|
- horizontalResolution /= MToInch;
|
|
|
|
- verticalResolution /= MToInch;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- br.Close();
|
|
|
|
- return true;
|
|
|
|
-
|
|
|
|
- default:
|
|
|
|
- br.ReadBytes(length);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- var crc = br.ReadInt32();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- br.Close();
|
|
|
|
- return width != 0 && height != 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
private static bool IsPng(BinaryReader br)
|
|
private static bool IsPng(BinaryReader br)
|
|
{
|
|
{
|
|
br.BaseStream.Position = 0;
|
|
br.BaseStream.Position = 0;
|
|
@@ -771,66 +385,10 @@ public static class ImageDetectExt
|
|
return signature.SequenceEqual(new byte[] { 137, 80, 78, 71, 13, 10, 26, 10 });
|
|
return signature.SequenceEqual(new byte[] { 137, 80, 78, 71, 13, 10, 26, 10 });
|
|
}
|
|
}
|
|
|
|
|
|
- private static string ReadPngChunkHeader(BinaryReader br, out int length)
|
|
|
|
- {
|
|
|
|
- length = GetInt32BigEndian(br);
|
|
|
|
- var b = br.ReadBytes(4);
|
|
|
|
- var type = Encoding.ASCII.GetString(b);
|
|
|
|
- return type;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
#endregion Png
|
|
#endregion Png
|
|
|
|
|
|
#region Svg
|
|
#region Svg
|
|
|
|
|
|
- private static bool IsSvg(MemoryStream ms, ref double width, ref double height)
|
|
|
|
- {
|
|
|
|
- try
|
|
|
|
- {
|
|
|
|
- var reader = new XmlTextReader(ms);
|
|
|
|
- while (reader.Read())
|
|
|
|
- {
|
|
|
|
- if (reader.LocalName == "svg" && reader.NodeType == XmlNodeType.Element)
|
|
|
|
- {
|
|
|
|
- var w = reader.GetAttribute("width");
|
|
|
|
- var h = reader.GetAttribute("height");
|
|
|
|
- var vb = reader.GetAttribute("viewBox");
|
|
|
|
- reader.Close();
|
|
|
|
- if (w == null || h == null)
|
|
|
|
- {
|
|
|
|
- if (vb == null)
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- var bounds = vb.Split(new char[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
- if (bounds.Length < 4)
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- if (string.IsNullOrEmpty(w))
|
|
|
|
- {
|
|
|
|
- w = bounds[2];
|
|
|
|
- }
|
|
|
|
- if (string.IsNullOrEmpty(h))
|
|
|
|
- {
|
|
|
|
- h = bounds[3];
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- width = GetSvgUnit(w);
|
|
|
|
- if (double.IsNaN(width)) return false;
|
|
|
|
- height = GetSvgUnit(h);
|
|
|
|
- if (double.IsNaN(height)) return false;
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- catch
|
|
|
|
- {
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
private static bool IsSvg(Stream ms)
|
|
private static bool IsSvg(Stream ms)
|
|
{
|
|
{
|
|
try
|
|
try
|
|
@@ -853,45 +411,6 @@ public static class ImageDetectExt
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- private static double GetSvgUnit(string v)
|
|
|
|
- {
|
|
|
|
- var factor = 1D;
|
|
|
|
- if (v.EndsWith("px", StringComparison.OrdinalIgnoreCase))
|
|
|
|
- {
|
|
|
|
- v = v.Substring(0, v.Length - 2);
|
|
|
|
- }
|
|
|
|
- else if (v.EndsWith("pt", StringComparison.OrdinalIgnoreCase))
|
|
|
|
- {
|
|
|
|
- factor = 1.25;
|
|
|
|
- v = v.Substring(0, v.Length - 2);
|
|
|
|
- }
|
|
|
|
- else if (v.EndsWith("pc", StringComparison.OrdinalIgnoreCase))
|
|
|
|
- {
|
|
|
|
- factor = 15;
|
|
|
|
- v = v.Substring(0, v.Length - 2);
|
|
|
|
- }
|
|
|
|
- else if (v.EndsWith("mm", StringComparison.OrdinalIgnoreCase))
|
|
|
|
- {
|
|
|
|
- factor = 3.543307;
|
|
|
|
- v = v.Substring(0, v.Length - 2);
|
|
|
|
- }
|
|
|
|
- else if (v.EndsWith("cm", StringComparison.OrdinalIgnoreCase))
|
|
|
|
- {
|
|
|
|
- factor = 35.43307;
|
|
|
|
- v = v.Substring(0, v.Length - 2);
|
|
|
|
- }
|
|
|
|
- else if (v.EndsWith("in", StringComparison.OrdinalIgnoreCase))
|
|
|
|
- {
|
|
|
|
- factor = 90;
|
|
|
|
- v = v.Substring(0, v.Length - 2);
|
|
|
|
- }
|
|
|
|
- if (double.TryParse(v, out double value))
|
|
|
|
- {
|
|
|
|
- return value * factor;
|
|
|
|
- }
|
|
|
|
- return double.NaN;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
#endregion Svg
|
|
#endregion Svg
|
|
|
|
|
|
private static ushort GetUInt16BigEndian(BinaryReader br)
|
|
private static ushort GetUInt16BigEndian(BinaryReader br)
|