diff options
| author | stefan <stefan@hegedues.at> | 2018-09-12 19:26:21 +0200 |
|---|---|---|
| committer | stefan <stefan@hegedues.at> | 2018-09-12 19:26:21 +0200 |
| commit | 48facb797ed912e4ea6b04b17d1ff190ac2daac4 (patch) | |
| tree | 8dae77a31670a888d733484cb17dd4077d5444e8 /Emby.Drawing | |
| parent | c32d8656382a0eacb301692e0084377fc433ae9b (diff) | |
Update to 3.5.2 and .net core 2.1
Diffstat (limited to 'Emby.Drawing')
| -rw-r--r-- | Emby.Drawing/Common/ImageHeader.cs | 21 | ||||
| -rw-r--r-- | Emby.Drawing/Emby.Drawing.csproj | 76 | ||||
| -rw-r--r-- | Emby.Drawing/ImageProcessor.cs | 185 |
3 files changed, 102 insertions, 180 deletions
diff --git a/Emby.Drawing/Common/ImageHeader.cs b/Emby.Drawing/Common/ImageHeader.cs index 4f56498a5..121e20deb 100644 --- a/Emby.Drawing/Common/ImageHeader.cs +++ b/Emby.Drawing/Common/ImageHeader.cs @@ -27,10 +27,10 @@ namespace Emby.Drawing.Common /// The image format decoders /// </summary> private static readonly KeyValuePair<byte[], Func<BinaryReader, ImageSize>>[] ImageFormatDecoders = new Dictionary<byte[], Func<BinaryReader, ImageSize>> - { - { new byte[] { 0x42, 0x4D }, DecodeBitmap }, - { new byte[] { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, DecodeGif }, - { new byte[] { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, DecodeGif }, + { + { new byte[] { 0x42, 0x4D }, DecodeBitmap }, + { new byte[] { 0x47, 0x49, 0x46, 0x38, 0x37, 0x61 }, DecodeGif }, + { new byte[] { 0x47, 0x49, 0x46, 0x38, 0x39, 0x61 }, DecodeGif }, { new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }, DecodePng }, { new byte[] { 0xff, 0xd8 }, DecodeJfif } @@ -38,6 +38,8 @@ namespace Emby.Drawing.Common private static readonly int MaxMagicBytesLength = ImageFormatDecoders.Select(i => i.Key.Length).OrderByDescending(i => i).First(); + private static string[] SupportedExtensions = new string[] { ".jpg", ".jpeg", ".png", ".gif" }; + /// <summary> /// Gets the dimensions of an image. /// </summary> @@ -48,6 +50,17 @@ namespace Emby.Drawing.Common /// <exception cref="ArgumentException">The image was of an unrecognised format.</exception> public static ImageSize GetDimensions(string path, ILogger logger, IFileSystem fileSystem) { + var extension = Path.GetExtension(path); + + if (string.IsNullOrEmpty(extension)) + { + throw new ArgumentException("ImageHeader doesn't support image file"); + } + if (!SupportedExtensions.Contains(extension)) + { + throw new ArgumentException("ImageHeader doesn't support " + extension); + } + using (var fs = fileSystem.OpenRead(path)) { using (var binaryReader = new BinaryReader(fs)) diff --git a/Emby.Drawing/Emby.Drawing.csproj b/Emby.Drawing/Emby.Drawing.csproj index c5dd671a8..e4c9a0c35 100644 --- a/Emby.Drawing/Emby.Drawing.csproj +++ b/Emby.Drawing/Emby.Drawing.csproj @@ -1,67 +1,17 @@ -<?xml version="1.0" encoding="utf-8"?> -<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> - <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> - <PropertyGroup> - <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> - <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> - <ProjectGuid>{08FFF49B-F175-4807-A2B5-73B0EBD9F716}</ProjectGuid> - <OutputType>Library</OutputType> - <AppDesignerFolder>Properties</AppDesignerFolder> - <RootNamespace>Emby.Drawing</RootNamespace> - <AssemblyName>Emby.Drawing</AssemblyName> - <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> - <TargetFrameworkProfile>Profile7</TargetFrameworkProfile> - <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> - <FileAlignment>512</FileAlignment> - <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\</SolutionDir> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> - <DebugSymbols>true</DebugSymbols> - <DebugType>full</DebugType> - <Optimize>false</Optimize> - <OutputPath>bin\Debug\</OutputPath> - <DefineConstants>DEBUG;TRACE</DefineConstants> - <ErrorReport>prompt</ErrorReport> - <WarningLevel>4</WarningLevel> - </PropertyGroup> - <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> - <DebugType>pdbonly</DebugType> - <Optimize>true</Optimize> - <OutputPath>bin\Release\</OutputPath> - <DefineConstants>TRACE</DefineConstants> - <ErrorReport>prompt</ErrorReport> - <WarningLevel>4</WarningLevel> - </PropertyGroup> +<Project Sdk="Microsoft.NET.Sdk"> + <ItemGroup> - <Compile Include="..\SharedVersion.cs"> - <Link>Properties\SharedVersion.cs</Link> - </Compile> - <Compile Include="Common\ImageHeader.cs" /> - <Compile Include="ImageProcessor.cs" /> - <Compile Include="NullImageEncoder.cs" /> - <Compile Include="Properties\AssemblyInfo.cs" /> + <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj" /> + <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj" /> </ItemGroup> + <ItemGroup> - <ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj"> - <Project>{9142eefa-7570-41e1-bfcc-468bb571af2f}</Project> - <Name>MediaBrowser.Common</Name> - </ProjectReference> - <ProjectReference Include="..\MediaBrowser.Controller\MediaBrowser.Controller.csproj"> - <Project>{17e1f4e6-8abd-4fe5-9ecf-43d4b6087ba2}</Project> - <Name>MediaBrowser.Controller</Name> - </ProjectReference> - <ProjectReference Include="..\MediaBrowser.Model\MediaBrowser.Model.csproj"> - <Project>{7eeeb4bb-f3e8-48fc-b4c5-70f0fff8329b}</Project> - <Name>MediaBrowser.Model</Name> - </ProjectReference> + <Compile Include="..\SharedVersion.cs"/> </ItemGroup> - <ItemGroup /> - <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" /> - <!-- To modify your build process, add your task inside one of the targets below and uncomment it. - Other similar extension points exist, see Microsoft.Common.targets. - <Target Name="BeforeBuild"> - </Target> - <Target Name="AfterBuild"> - </Target> - --> -</Project>
\ No newline at end of file + + <PropertyGroup> + <TargetFramework>netcoreapp2.1</TargetFramework> + <GenerateAssemblyInfo>false</GenerateAssemblyInfo> + </PropertyGroup> + +</Project> diff --git a/Emby.Drawing/ImageProcessor.cs b/Emby.Drawing/ImageProcessor.cs index f91cb4675..eeb5b8f9f 100644 --- a/Emby.Drawing/ImageProcessor.cs +++ b/Emby.Drawing/ImageProcessor.cs @@ -169,7 +169,7 @@ namespace Emby.Drawing return _imageEncoder.SupportedOutputFormats; } - private static readonly string[] TransparentImageTypes = new string[] { ".png", ".webp" }; + private readonly string[] TransparentImageTypes = new string[] { ".png", ".webp", ".gif" }; public bool SupportsTransparency(string path) { return TransparentImageTypes.Contains(Path.GetExtension(path) ?? string.Empty); @@ -183,7 +183,7 @@ namespace Emby.Drawing } var originalImage = options.Image; - IHasMetadata item = options.Item; + var item = options.Item; if (!originalImage.IsLocalFile) { @@ -196,6 +196,7 @@ namespace Emby.Drawing var originalImagePath = originalImage.Path; var dateModified = originalImage.DateModified; + var originalImageSize = originalImage.Width > 0 && originalImage.Height > 0 ? new ImageSize(originalImage.Width, originalImage.Height) : (ImageSize?)null; if (!_imageEncoder.SupportsImageEncoding) { @@ -207,7 +208,7 @@ namespace Emby.Drawing dateModified = supportedImageInfo.Item2; var requiresTransparency = TransparentImageTypes.Contains(Path.GetExtension(originalImagePath) ?? string.Empty); - if (options.Enhancers.Count > 0) + if (options.Enhancers.Length > 0) { if (item == null) { @@ -225,18 +226,32 @@ namespace Emby.Drawing originalImagePath = tuple.Item1; dateModified = tuple.Item2; requiresTransparency = tuple.Item3; + // TODO: Get this info + originalImageSize = null; } var photo = item as Photo; var autoOrient = false; ImageOrientation? orientation = null; - if (photo != null && photo.Orientation.HasValue && photo.Orientation.Value != ImageOrientation.TopLeft) + if (photo != null) { - autoOrient = true; - orientation = photo.Orientation; + if (photo.Orientation.HasValue) + { + if (photo.Orientation.Value != ImageOrientation.TopLeft) + { + autoOrient = true; + orientation = photo.Orientation; + } + } + else + { + // Orientation unknown, so do it + autoOrient = true; + orientation = photo.Orientation; + } } - if (options.HasDefaultOptions(originalImagePath) && (!autoOrient || !options.RequiresAutoOrientation)) + if (options.HasDefaultOptions(originalImagePath, originalImageSize) && (!autoOrient || !options.RequiresAutoOrientation)) { // Just spit out the original file if all the options are default return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified); @@ -247,7 +262,7 @@ namespace Emby.Drawing //{ // // Just spit out the original file if all the options are default // _logger.Info("Returning original image {0}", originalImagePath); - // return new Tuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified); + // return new ValueTuple<string, string, DateTime>(originalImagePath, MimeTypes.GetMimeType(originalImagePath), dateModified); //} var newSize = ImageHelper.GetNewImageSize(options, null); @@ -317,7 +332,7 @@ namespace Emby.Drawing } // If transparency is needed and webp isn't supported, than png is the only option - if (requiresTransparency) + if (requiresTransparency && clientSupportedFormats.Contains(ImageFormat.Png)) { return ImageFormat.Png; } @@ -346,21 +361,6 @@ namespace Emby.Drawing } } - //private static int[][] OPERATIONS = new int[][] { - // TopLeft - //new int[] { 0, NONE}, - // TopRight - //new int[] { 0, HORIZONTAL}, - //new int[] {180, NONE}, - // LeftTop - //new int[] { 0, VERTICAL}, - //new int[] { 90, HORIZONTAL}, - // RightTop - //new int[] { 90, NONE}, - //new int[] {-90, HORIZONTAL}, - //new int[] {-90, NONE}, - //}; - private string GetMimeType(ImageFormat format, string path) { if (format == ImageFormat.Bmp) @@ -494,55 +494,19 @@ namespace Emby.Drawing throw new ArgumentNullException("path"); } - return GetImageSizeInternal(path, allowSlowMethod); - } - - /// <summary> - /// Gets the image size internal. - /// </summary> - /// <param name="path">The path.</param> - /// <param name="allowSlowMethod">if set to <c>true</c> [allow slow method].</param> - /// <returns>ImageSize.</returns> - private ImageSize GetImageSizeInternal(string path, bool allowSlowMethod) - { - //try - //{ - // using (var fileStream = _fileSystem.OpenRead(path)) - // { - // using (var file = TagLib.File.Create(new StreamFileAbstraction(Path.GetFileName(path), fileStream, null))) - // { - // var image = file as TagLib.Image.File; - - // if (image != null) - // { - // var properties = image.Properties; - - // return new ImageSize - // { - // Height = properties.PhotoHeight, - // Width = properties.PhotoWidth - // }; - // } - // } - // } - //} - //catch - //{ - //} - try { return ImageHeader.GetDimensions(path, _logger, _fileSystem); } catch { - if (allowSlowMethod) + if (!allowSlowMethod) { - return _imageEncoder.GetImageSize(path); + throw; } - - throw; } + + return _imageEncoder.GetImageSize(path); } /// <summary> @@ -552,21 +516,28 @@ namespace Emby.Drawing /// <param name="image">The image.</param> /// <returns>Guid.</returns> /// <exception cref="System.ArgumentNullException">item</exception> - public string GetImageCacheTag(IHasMetadata item, ItemImageInfo image) + public string GetImageCacheTag(BaseItem item, ItemImageInfo image) { - if (item == null) + var supportedEnhancers = GetSupportedEnhancers(item, image.Type); + + return GetImageCacheTag(item, image, supportedEnhancers); + } + + public string GetImageCacheTag(BaseItem item, ChapterInfo chapter) + { + try { - throw new ArgumentNullException("item"); + return GetImageCacheTag(item, new ItemImageInfo + { + Path = chapter.ImagePath, + Type = ImageType.Chapter, + DateModified = chapter.ImageDateModified + }); } - - if (image == null) + catch { - throw new ArgumentNullException("image"); + return null; } - - var supportedEnhancers = GetSupportedEnhancers(item, image.Type); - - return GetImageCacheTag(item, image, supportedEnhancers); } /// <summary> @@ -577,29 +548,14 @@ namespace Emby.Drawing /// <param name="imageEnhancers">The image enhancers.</param> /// <returns>Guid.</returns> /// <exception cref="System.ArgumentNullException">item</exception> - public string GetImageCacheTag(IHasMetadata item, ItemImageInfo image, List<IImageEnhancer> imageEnhancers) + public string GetImageCacheTag(BaseItem item, ItemImageInfo image, IImageEnhancer[] imageEnhancers) { - if (item == null) - { - throw new ArgumentNullException("item"); - } - - if (imageEnhancers == null) - { - throw new ArgumentNullException("imageEnhancers"); - } - - if (image == null) - { - throw new ArgumentNullException("image"); - } - var originalImagePath = image.Path; var dateModified = image.DateModified; var imageType = image.Type; // Optimization - if (imageEnhancers.Count == 0) + if (imageEnhancers.Length == 0) { return (originalImagePath + dateModified.Ticks).GetMD5().ToString("N"); } @@ -611,7 +567,7 @@ namespace Emby.Drawing return string.Join("|", cacheKeys.ToArray(cacheKeys.Count)).GetMD5().ToString("N"); } - private async Task<Tuple<string, DateTime>> GetSupportedImage(string originalImagePath, DateTime dateModified) + private async Task<ValueTuple<string, DateTime>> GetSupportedImage(string originalImagePath, DateTime dateModified) { var inputFormat = (Path.GetExtension(originalImagePath) ?? string.Empty) .TrimStart('.') @@ -620,7 +576,7 @@ namespace Emby.Drawing // These are just jpg files renamed as tbn if (string.Equals(inputFormat, "tbn", StringComparison.OrdinalIgnoreCase)) { - return new Tuple<string, DateTime>(originalImagePath, dateModified); + return new ValueTuple<string, DateTime>(originalImagePath, dateModified); } if (!_imageEncoder.SupportedInputFormats.Contains(inputFormat, StringComparer.OrdinalIgnoreCase)) @@ -651,7 +607,7 @@ namespace Emby.Drawing } } - return new Tuple<string, DateTime>(originalImagePath, dateModified); + return new ValueTuple<string, DateTime>(originalImagePath, dateModified); } /// <summary> @@ -661,7 +617,7 @@ namespace Emby.Drawing /// <param name="imageType">Type of the image.</param> /// <param name="imageIndex">Index of the image.</param> /// <returns>Task{System.String}.</returns> - public async Task<string> GetEnhancedImage(IHasMetadata item, ImageType imageType, int imageIndex) + public async Task<string> GetEnhancedImage(BaseItem item, ImageType imageType, int imageIndex) { var enhancers = GetSupportedEnhancers(item, imageType); @@ -674,11 +630,11 @@ namespace Emby.Drawing return result.Item1; } - private async Task<Tuple<string, DateTime, bool>> GetEnhancedImage(ItemImageInfo image, + private async Task<ValueTuple<string, DateTime, bool>> GetEnhancedImage(ItemImageInfo image, bool inputImageSupportsTransparency, - IHasMetadata item, + BaseItem item, int imageIndex, - List<IImageEnhancer> enhancers, + IImageEnhancer[] enhancers, CancellationToken cancellationToken) { var originalImagePath = image.Path; @@ -699,7 +655,7 @@ namespace Emby.Drawing { var treatmentRequiresTransparency = ehnancedImageInfo.Item2; - return new Tuple<string, DateTime, bool>(ehnancedImagePath, _fileSystem.GetLastWriteTimeUtc(ehnancedImagePath), treatmentRequiresTransparency); + return new ValueTuple<string, DateTime, bool>(ehnancedImagePath, _fileSystem.GetLastWriteTimeUtc(ehnancedImagePath), treatmentRequiresTransparency); } } catch (Exception ex) @@ -707,7 +663,7 @@ namespace Emby.Drawing _logger.ErrorException("Error enhancing image", ex); } - return new Tuple<string, DateTime, bool>(originalImagePath, dateModified, inputImageSupportsTransparency); + return new ValueTuple<string, DateTime, bool>(originalImagePath, dateModified, inputImageSupportsTransparency); } /// <summary> @@ -725,11 +681,11 @@ namespace Emby.Drawing /// or /// item /// </exception> - private async Task<Tuple<string, bool>> GetEnhancedImageInternal(string originalImagePath, - IHasMetadata item, + private async Task<ValueTuple<string, bool>> GetEnhancedImageInternal(string originalImagePath, + BaseItem item, ImageType imageType, int imageIndex, - List<IImageEnhancer> supportedEnhancers, + IImageEnhancer[] supportedEnhancers, string cacheGuid, CancellationToken cancellationToken) { @@ -753,8 +709,8 @@ namespace Emby.Drawing } // All enhanced images are saved as png to allow transparency - var cacheExtension = _imageEncoder.SupportedOutputFormats.Contains(ImageFormat.Webp) ? - ".webp" : + var cacheExtension = _imageEncoder.SupportedOutputFormats.Contains(ImageFormat.Webp) ? + ".webp" : (treatmentRequiresTransparency ? ".png" : ".jpg"); var enhancedImagePath = GetCachePath(EnhancedImageCachePath, cacheGuid + cacheExtension); @@ -768,14 +724,14 @@ namespace Emby.Drawing // Check again in case of contention if (_fileSystem.FileExists(enhancedImagePath)) { - return new Tuple<string, bool>(enhancedImagePath, treatmentRequiresTransparency); + return new ValueTuple<string, bool>(enhancedImagePath, treatmentRequiresTransparency); } _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(enhancedImagePath)); await ExecuteImageEnhancers(supportedEnhancers, originalImagePath, enhancedImagePath, item, imageType, imageIndex).ConfigureAwait(false); - return new Tuple<string, bool>(enhancedImagePath, treatmentRequiresTransparency); + return new ValueTuple<string, bool>(enhancedImagePath, treatmentRequiresTransparency); } finally { @@ -793,7 +749,7 @@ namespace Emby.Drawing /// <param name="imageType">Type of the image.</param> /// <param name="imageIndex">Index of the image.</param> /// <returns>Task{EnhancedImage}.</returns> - private async Task ExecuteImageEnhancers(IEnumerable<IImageEnhancer> imageEnhancers, string inputPath, string outputPath, IHasMetadata item, ImageType imageType, int imageIndex) + private async Task ExecuteImageEnhancers(IEnumerable<IImageEnhancer> imageEnhancers, string inputPath, string outputPath, BaseItem item, ImageType imageType, int imageIndex) { // Run the enhancers sequentially in order of priority foreach (var enhancer in imageEnhancers) @@ -878,9 +834,9 @@ namespace Emby.Drawing _logger.Info("Completed creation of image collage and saved to {0}", options.OutputPath); } - public List<IImageEnhancer> GetSupportedEnhancers(IHasMetadata item, ImageType imageType) + public IImageEnhancer[] GetSupportedEnhancers(BaseItem item, ImageType imageType) { - var list = new List<IImageEnhancer>(); + List<IImageEnhancer> list = null; foreach (var i in ImageEnhancers) { @@ -888,6 +844,10 @@ namespace Emby.Drawing { if (i.Supports(item, imageType)) { + if (list == null) + { + list = new List<IImageEnhancer>(); + } list.Add(i); } } @@ -896,7 +856,8 @@ namespace Emby.Drawing _logger.ErrorException("Error in image enhancer: {0}", ex, i.GetType().Name); } } - return list; + + return list == null ? Array.Empty<IImageEnhancer>() : list.ToArray(); } private Dictionary<string, LockInfo> _locks = new Dictionary<string, LockInfo>(); @@ -948,8 +909,6 @@ namespace Emby.Drawing { disposable.Dispose(); } - - GC.SuppressFinalize(this); } private void CheckDisposed() |
