Browse Source

修正图片检测导致流被释放的bug

懒得勤快 3 years ago
parent
commit
c4857d6c6d

+ 1 - 1
Masuit.Tools.Abstractions/Masuit.Tools.Abstractions.csproj

@@ -3,7 +3,7 @@
         <TargetFrameworks>netstandard2.0;netstandard2.1;net461;net5;net6</TargetFrameworks>
         <LangVersion>latest</LangVersion>
         <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
-        <Version>2.5.6.2</Version>
+        <Version>2.5.7</Version>
         <Authors>懒得勤快</Authors>
         <Description>Masuit.Tools基础公共库,包含一些常用的操作类,大都是静态类,加密解密,反射操作,Excel简单导出,权重随机筛选算法,分布式短id,表达式树,linq扩展,文件压缩,多线程下载和FTP客户端,硬件信息,字符串扩展方法,日期时间扩展操作,中国农历,大文件拷贝,图像裁剪,验证码,断点续传,集合扩展等常用封装。</Description>
         <Copyright>懒得勤快,长空X</Copyright>

+ 5 - 486
Masuit.Tools.Abstractions/Media/ImageDetectExt.cs

@@ -12,9 +12,6 @@ public static class ImageDetectExt
 {
     private const float MToInch = 39.3700787F;
     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
     {
@@ -36,7 +33,7 @@ public static class ImageDetectExt
     /// <returns></returns>
     public static ImageFormat? GetImageType(this Stream ms)
     {
-        using var br = new BinaryReader(ms);
+        var br = new BinaryReader(ms);
         if (IsJpg(br))
         {
             return ImageFormat.Jpg;
@@ -123,62 +120,6 @@ public static class ImageDetectExt
         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)
     {
         if (IsGZip(img))
@@ -227,70 +168,6 @@ public static class ImageDetectExt
         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)
     {
         br.BaseStream.Position = 0;
@@ -298,21 +175,6 @@ public static class ImageDetectExt
         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)
     {
         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.
     }
 
-    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)
     {
         try
@@ -369,25 +199,6 @@ public static class ImageDetectExt
 
     #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)
     {
         br.BaseStream.Seek(0, SeekOrigin.Begin);
@@ -400,46 +211,6 @@ public static class ImageDetectExt
 
     #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)
     {
         try
@@ -461,14 +232,6 @@ public static class ImageDetectExt
 
     #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)
     {
         var ms = br.BaseStream;
@@ -575,10 +338,8 @@ public static class ImageDetectExt
         {
             return GetInt16BigEndian(br);
         }
-        else
-        {
-            return br.ReadInt16();
-        }
+
+        return br.ReadInt16();
     }
 
     private static int GetTifInt32(BinaryReader br, bool isBigEndian)
@@ -587,80 +348,14 @@ public static class ImageDetectExt
         {
             return GetInt32BigEndian(br);
         }
-        else
-        {
-            return br.ReadInt32();
-        }
+
+        return br.ReadInt32();
     }
 
     #endregion Tiff
 
     #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)
     {
         br.BaseStream.Position = 0;
@@ -672,36 +367,6 @@ public static class ImageDetectExt
 
     #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)
     {
         br.BaseStream.Position = 0;
@@ -713,57 +378,6 @@ public static class ImageDetectExt
 
     #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)
     {
         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 });
     }
 
-    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
 
     #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)
     {
         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
 
     private static ushort GetUInt16BigEndian(BinaryReader br)

+ 1 - 1
Masuit.Tools.AspNetCore/Masuit.Tools.AspNetCore.csproj

@@ -17,7 +17,7 @@
         <Product>Masuit.Tools.AspNetCore</Product>
         <PackageId>Masuit.Tools.AspNetCore</PackageId>
         <LangVersion>latest</LangVersion>
-        <Version>1.1.6.3</Version>
+        <Version>1.1.7</Version>
         <RepositoryType></RepositoryType>
         <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
         <FileVersion>$(Version)</FileVersion>

+ 1 - 1
Masuit.Tools.Core/Masuit.Tools.Core.csproj

@@ -20,7 +20,7 @@ github:https://github.com/ldqk/Masuit.Tools
         <UserSecretsId>830c282f-f7c1-42be-8651-4cd06ac8e73f</UserSecretsId>
         <RepositoryType></RepositoryType>
         <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
-        <Version>2.5.6.3</Version>
+        <Version>2.5.7</Version>
         <FileVersion>$(Version)</FileVersion>
         <Company>masuit.org</Company>
         <AssemblyVersion>$(Version)</AssemblyVersion>

+ 1 - 1
Masuit.Tools.Net45/package.nuspec

@@ -2,7 +2,7 @@
 <package>
   <metadata>
     <id>Masuit.Tools.Net45</id>
-    <version>2.5.6.2</version>
+    <version>2.5.7</version>
     <title>Masuit.Tools</title>
     <authors>懒得勤快</authors>
     <owners>masuit.com</owners>

+ 1 - 1
Masuit.Tools/package.nuspec

@@ -2,7 +2,7 @@
 <package>
   <metadata>
     <id>Masuit.Tools.Net</id>
-    <version>2.5.6.2</version>
+    <version>2.5.7</version>
     <title>Masuit.Tools</title>
     <authors>懒得勤快</authors>
     <owners>masuit.com</owners>