Browse Source

Drawing: make SkiaEncoder more robust when reading image dimensions (#14481)

queukat 3 days ago
parent
commit
aa77dfb92d
1 changed files with 31 additions and 2 deletions
  1. 31 2
      src/Jellyfin.Drawing.Skia/SkiaEncoder.cs

+ 31 - 2
src/Jellyfin.Drawing.Skia/SkiaEncoder.cs

@@ -202,18 +202,47 @@ public class SkiaEncoder : IImageEncoder
             }
         }
 
-        using var codec = SKCodec.Create(path, out SKCodecResult result);
+        var safePath = NormalizePath(path);
+        if (new FileInfo(safePath).Length == 0)
+        {
+            _logger.LogDebug("Skip zero‑byte image {FilePath}", path);
+            return default;
+        }
+
+        using var codec = SKCodec.Create(safePath, out var result);
+
         switch (result)
         {
             case SKCodecResult.Success:
+            // Skia/SkiaSharp edge‑case: when the image header is parsed but the actual pixel
+            // decode fails (truncated JPEG/PNG, exotic ICC/EXIF, CMYK without color‑transform, etc.)
+            // `SKCodec.Create` returns a *non‑null* codec together with
+            // SKCodecResult.InternalError.  The header still contains valid dimensions,
+            // which is all we need here – so we fall back to them instead of aborting.
+            // See e.g. Skia bugs #4139, #6092.
+            case SKCodecResult.InternalError when codec is not null:
                 var info = codec.Info;
                 return new ImageDimensions(info.Width, info.Height);
+
             case SKCodecResult.Unimplemented:
                 _logger.LogDebug("Image format not supported: {FilePath}", path);
                 return default;
+
             default:
-                _logger.LogError("Unable to determine image dimensions for {FilePath}: {SkCodecResult}", path, result);
+            {
+                var boundsInfo = SKBitmap.DecodeBounds(safePath);
+
+                if (boundsInfo.Width > 0 && boundsInfo.Height > 0)
+                {
+                    return new ImageDimensions(boundsInfo.Width, boundsInfo.Height);
+                }
+
+                _logger.LogWarning(
+                    "Unable to determine image dimensions for {FilePath}: {SkCodecResult}",
+                    path,
+                    result);
                 return default;
+            }
         }
     }