From 042b15c9a180c1303fbde65a343a2bc1d5d82434 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Wed, 19 Sep 2018 23:02:57 -0400 Subject: [PATCH] improve skia error handling --- Emby.Drawing.Skia/SkiaEncoder.cs | 51 +++++++++++++++++------- Emby.Drawing.Skia/StripCollageBuilder.cs | 7 +++- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/Emby.Drawing.Skia/SkiaEncoder.cs b/Emby.Drawing.Skia/SkiaEncoder.cs index 7ccb75ec47..e222e0ad9c 100644 --- a/Emby.Drawing.Skia/SkiaEncoder.cs +++ b/Emby.Drawing.Skia/SkiaEncoder.cs @@ -184,7 +184,12 @@ private SKBitmap CropWhiteSpace(SKBitmap bitmap) public ImageSize GetImageSize(string path) { - using (var s = new SKFileStream(path)) + if (!_fileSystem.FileExists(path)) + { + throw new FileNotFoundException("File not found", path); + } + + using (var s = new SKFileStream(NormalizePath(path, _fileSystem))) { using (var codec = SKCodec.Create(s)) { @@ -263,7 +268,7 @@ private static SKCodecOrigin GetSKCodecOrigin(ImageOrientation? orientation) } private static string[] TransparentImageTypes = new string[] { ".png", ".gif", ".webp" }; - internal static SKBitmap Decode(string path, bool forceCleanBitmap, IFileSystem fileSystem, ImageOrientation? orientation, out SKCodecOrigin origin) + internal static SKBitmap Decode(string path, bool forceCleanBitmap, IFileSystem fileSystem, ILogger logger, ImageOrientation? orientation, out SKCodecOrigin origin) { if (!fileSystem.FileExists(path)) { @@ -272,9 +277,12 @@ internal static SKBitmap Decode(string path, bool forceCleanBitmap, IFileSystem var requiresTransparencyHack = TransparentImageTypes.Contains(Path.GetExtension(path) ?? string.Empty); + var normalizedPath = NormalizePath(path, fileSystem); + if (requiresTransparencyHack || forceCleanBitmap) { - using (var stream = new SKFileStream(NormalizePath(path, fileSystem))) + //logger.Debug("Opening {0} for decoding with forceCleanBitmap", normalizedPath); + using (var stream = new SKFileStream(normalizedPath)) { using (var codec = SKCodec.Create(stream)) { @@ -287,11 +295,17 @@ internal static SKBitmap Decode(string path, bool forceCleanBitmap, IFileSystem // create the bitmap var bitmap = new SKBitmap(codec.Info.Width, codec.Info.Height, !requiresTransparencyHack); - if (bitmap != null) + if (bitmap != null && !bitmap.IsNull && !bitmap.IsEmpty) { // decode - codec.GetPixels(bitmap.Info, bitmap.GetPixels()); - + var result = codec.GetPixels(bitmap.Info, bitmap.GetPixels()); + + if (result != SKCodecResult.Success) + { + origin = GetSKCodecOrigin(orientation); + return null; + } + origin = codec.Origin; } else @@ -304,11 +318,18 @@ internal static SKBitmap Decode(string path, bool forceCleanBitmap, IFileSystem } } - var resultBitmap = SKBitmap.Decode(NormalizePath(path, fileSystem)); + //logger.Debug("Opening {0} for decoding without forceCleanBitmap", normalizedPath); + var resultBitmap = SKBitmap.Decode(normalizedPath); + + if (resultBitmap == null || resultBitmap.IsNull || resultBitmap.IsEmpty) + { + return Decode(path, true, fileSystem, logger, orientation, out origin); + } - if (resultBitmap == null) + if (resultBitmap.IsNull || resultBitmap.IsEmpty) { - return Decode(path, true, fileSystem, orientation, out origin); + origin = GetSKCodecOrigin(orientation); + return null; } // If we have to resize these they often end up distorted @@ -316,7 +337,7 @@ internal static SKBitmap Decode(string path, bool forceCleanBitmap, IFileSystem { using (resultBitmap) { - return Decode(path, true, fileSystem, orientation, out origin); + return Decode(path, true, fileSystem, logger, orientation, out origin); } } @@ -328,13 +349,13 @@ private SKBitmap GetBitmap(string path, bool cropWhitespace, bool forceAnalyzeBi { if (cropWhitespace) { - using (var bitmap = Decode(path, forceAnalyzeBitmap, _fileSystem, orientation, out origin)) + using (var bitmap = Decode(path, forceAnalyzeBitmap, _fileSystem, _logger, orientation, out origin)) { return CropWhiteSpace(bitmap); } } - return Decode(path, forceAnalyzeBitmap, _fileSystem, orientation, out origin); + return Decode(path, forceAnalyzeBitmap, _fileSystem, _logger, orientation, out origin); } private SKBitmap GetBitmap(string path, bool cropWhitespace, bool autoOrient, ImageOrientation? orientation) @@ -633,16 +654,16 @@ public void CreateImageCollage(ImageCollageOptions options) if (ratio >= 1.4) { - new StripCollageBuilder(_appPaths, _fileSystem).BuildThumbCollage(options.InputPaths, options.OutputPath, options.Width, options.Height); + new StripCollageBuilder(_appPaths, _fileSystem, _logger).BuildThumbCollage(options.InputPaths, options.OutputPath, options.Width, options.Height); } else if (ratio >= .9) { - new StripCollageBuilder(_appPaths, _fileSystem).BuildSquareCollage(options.InputPaths, options.OutputPath, options.Width, options.Height); + new StripCollageBuilder(_appPaths, _fileSystem, _logger).BuildSquareCollage(options.InputPaths, options.OutputPath, options.Width, options.Height); } else { // @todo create Poster collage capability - new StripCollageBuilder(_appPaths, _fileSystem).BuildSquareCollage(options.InputPaths, options.OutputPath, options.Width, options.Height); + new StripCollageBuilder(_appPaths, _fileSystem, _logger).BuildSquareCollage(options.InputPaths, options.OutputPath, options.Width, options.Height); } } diff --git a/Emby.Drawing.Skia/StripCollageBuilder.cs b/Emby.Drawing.Skia/StripCollageBuilder.cs index 85eeaa9f59..71cc731e20 100644 --- a/Emby.Drawing.Skia/StripCollageBuilder.cs +++ b/Emby.Drawing.Skia/StripCollageBuilder.cs @@ -4,6 +4,7 @@ using System.IO; using MediaBrowser.Model.IO; using System.Collections.Generic; +using MediaBrowser.Model.Logging; namespace Emby.Drawing.Skia { @@ -11,11 +12,13 @@ public class StripCollageBuilder { private readonly IApplicationPaths _appPaths; private readonly IFileSystem _fileSystem; + private readonly ILogger _logger; - public StripCollageBuilder(IApplicationPaths appPaths, IFileSystem fileSystem) + public StripCollageBuilder(IApplicationPaths appPaths, IFileSystem fileSystem, ILogger logger) { _appPaths = appPaths; _fileSystem = fileSystem; + _logger = logger; } public static SKEncodedImageFormat GetEncodedFormat(string outputPath) @@ -173,7 +176,7 @@ private SKBitmap GetNextValidImage(string[] paths, int currentIndex, out int new } SKCodecOrigin origin; - bitmap = SkiaEncoder.Decode(paths[currentIndex], false, _fileSystem, null, out origin); + bitmap = SkiaEncoder.Decode(paths[currentIndex], false, _fileSystem, _logger, null, out origin); imagesTested[currentIndex] = 0;