aboutsummaryrefslogtreecommitdiff
path: root/Jellyfin.Drawing.Skia
diff options
context:
space:
mode:
Diffstat (limited to 'Jellyfin.Drawing.Skia')
-rw-r--r--Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj16
-rw-r--r--Jellyfin.Drawing.Skia/SkiaEncoder.cs98
2 files changed, 18 insertions, 96 deletions
diff --git a/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj b/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj
index 466a12e67..ee43c2159 100644
--- a/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj
+++ b/Jellyfin.Drawing.Skia/Jellyfin.Drawing.Skia.csproj
@@ -11,6 +11,8 @@
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<Nullable>enable</Nullable>
+ <AnalysisMode>AllEnabledByDefault</AnalysisMode>
+ <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
@@ -18,8 +20,8 @@
</ItemGroup>
<ItemGroup>
- <PackageReference Include="BlurHashSharp" Version="1.1.1" />
- <PackageReference Include="BlurHashSharp.SkiaSharp" Version="1.1.1" />
+ <PackageReference Include="BlurHashSharp" Version="1.2.0" />
+ <PackageReference Include="BlurHashSharp.SkiaSharp" Version="1.2.0" />
<PackageReference Include="SkiaSharp" Version="2.80.2" />
<PackageReference Include="SkiaSharp.NativeAssets.Linux" Version="2.80.2" />
</ItemGroup>
@@ -30,16 +32,16 @@
<ProjectReference Include="..\MediaBrowser.Common\MediaBrowser.Common.csproj" />
</ItemGroup>
+ <ItemGroup>
+ <!-- Needed for https://github.com/dotnet/roslyn-analyzers/issues/4382 which is in the SDK yet -->
+ <PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.3" PrivateAssets="All" />
+ </ItemGroup>
+
<!-- Code analysers-->
<ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
- <PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" />
<PackageReference Include="SerilogAnalyzer" Version="0.15.0" PrivateAssets="All" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118" PrivateAssets="All" />
<PackageReference Include="SmartAnalyzers.MultithreadingAnalyzer" Version="1.1.31" PrivateAssets="All" />
</ItemGroup>
- <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
- <CodeAnalysisRuleSet>../jellyfin.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
-
</Project>
diff --git a/Jellyfin.Drawing.Skia/SkiaEncoder.cs b/Jellyfin.Drawing.Skia/SkiaEncoder.cs
index eab5777d5..8f0fae3be 100644
--- a/Jellyfin.Drawing.Skia/SkiaEncoder.cs
+++ b/Jellyfin.Drawing.Skia/SkiaEncoder.cs
@@ -91,9 +91,6 @@ namespace Jellyfin.Drawing.Skia
}
}
- private static bool IsTransparent(SKColor color)
- => (color.Red == 255 && color.Green == 255 && color.Blue == 255) || color.Alpha == 0;
-
/// <summary>
/// Convert a <see cref="ImageFormat"/> to a <see cref="SKEncodedImageFormat"/>.
/// </summary>
@@ -111,65 +108,6 @@ namespace Jellyfin.Drawing.Skia
};
}
- private static bool IsTransparentRow(SKBitmap bmp, int row)
- {
- for (var i = 0; i < bmp.Width; ++i)
- {
- if (!IsTransparent(bmp.GetPixel(i, row)))
- {
- return false;
- }
- }
-
- return true;
- }
-
- private static bool IsTransparentColumn(SKBitmap bmp, int col)
- {
- for (var i = 0; i < bmp.Height; ++i)
- {
- if (!IsTransparent(bmp.GetPixel(col, i)))
- {
- return false;
- }
- }
-
- return true;
- }
-
- private SKBitmap CropWhiteSpace(SKBitmap bitmap)
- {
- var topmost = 0;
- while (topmost < bitmap.Height && IsTransparentRow(bitmap, topmost))
- {
- topmost++;
- }
-
- int bottommost = bitmap.Height;
- while (bottommost >= 0 && IsTransparentRow(bitmap, bottommost - 1))
- {
- bottommost--;
- }
-
- var leftmost = 0;
- while (leftmost < bitmap.Width && IsTransparentColumn(bitmap, leftmost))
- {
- leftmost++;
- }
-
- var rightmost = bitmap.Width;
- while (rightmost >= 0 && IsTransparentColumn(bitmap, rightmost - 1))
- {
- rightmost--;
- }
-
- var newRect = SKRectI.Create(leftmost, topmost, rightmost - leftmost, bottommost - topmost);
-
- using var image = SKImage.FromBitmap(bitmap);
- using var subset = image.Subset(newRect);
- return SKBitmap.FromImage(subset);
- }
-
/// <inheritdoc />
/// <exception cref="ArgumentNullException">The path is null.</exception>
/// <exception cref="FileNotFoundException">The path is not valid.</exception>
@@ -274,8 +212,8 @@ namespace Jellyfin.Drawing.Skia
if (requiresTransparencyHack || forceCleanBitmap)
{
- using var codec = SKCodec.Create(NormalizePath(path));
- if (codec == null)
+ using SKCodec codec = SKCodec.Create(NormalizePath(path), out SKCodecResult res);
+ if (res != SKCodecResult.Success)
{
origin = GetSKEncodedOrigin(orientation);
return null;
@@ -312,22 +250,11 @@ namespace Jellyfin.Drawing.Skia
return resultBitmap;
}
- private SKBitmap? GetBitmap(string path, bool cropWhitespace, bool forceAnalyzeBitmap, ImageOrientation? orientation, out SKEncodedOrigin origin)
- {
- if (cropWhitespace)
- {
- using var bitmap = Decode(path, forceAnalyzeBitmap, orientation, out origin);
- return bitmap == null ? null : CropWhiteSpace(bitmap);
- }
-
- return Decode(path, forceAnalyzeBitmap, orientation, out origin);
- }
-
- private SKBitmap? GetBitmap(string path, bool cropWhitespace, bool autoOrient, ImageOrientation? orientation)
+ private SKBitmap? GetBitmap(string path, bool autoOrient, ImageOrientation? orientation)
{
if (autoOrient)
{
- var bitmap = GetBitmap(path, cropWhitespace, true, orientation, out var origin);
+ var bitmap = Decode(path, true, orientation, out var origin);
if (bitmap != null && origin != SKEncodedOrigin.TopLeft)
{
@@ -340,16 +267,11 @@ namespace Jellyfin.Drawing.Skia
return bitmap;
}
- return GetBitmap(path, cropWhitespace, false, orientation, out _);
+ return Decode(path, false, orientation, out _);
}
private SKBitmap OrientImage(SKBitmap bitmap, SKEncodedOrigin origin)
{
- if (origin == SKEncodedOrigin.Default)
- {
- return bitmap;
- }
-
var needsFlip = origin == SKEncodedOrigin.LeftBottom
|| origin == SKEncodedOrigin.LeftTop
|| origin == SKEncodedOrigin.RightBottom
@@ -447,7 +369,7 @@ namespace Jellyfin.Drawing.Skia
}
/// <inheritdoc/>
- public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation? orientation, int quality, ImageProcessingOptions options, ImageFormat selectedOutputFormat)
+ public string EncodeImage(string inputPath, DateTime dateModified, string outputPath, bool autoOrient, ImageOrientation? orientation, int quality, ImageProcessingOptions options, ImageFormat outputFormat)
{
if (inputPath.Length == 0)
{
@@ -459,14 +381,14 @@ namespace Jellyfin.Drawing.Skia
throw new ArgumentException("String can't be empty.", nameof(outputPath));
}
- var skiaOutputFormat = GetImageFormat(selectedOutputFormat);
+ var skiaOutputFormat = GetImageFormat(outputFormat);
var hasBackgroundColor = !string.IsNullOrWhiteSpace(options.BackgroundColor);
var hasForegroundColor = !string.IsNullOrWhiteSpace(options.ForegroundLayer);
var blur = options.Blur ?? 0;
var hasIndicator = options.AddPlayedIndicator || options.UnplayedCount.HasValue || !options.PercentPlayed.Equals(0);
- using var bitmap = GetBitmap(inputPath, options.CropWhiteSpace, autoOrient, orientation);
+ using var bitmap = GetBitmap(inputPath, autoOrient, orientation);
if (bitmap == null)
{
throw new InvalidDataException($"Skia unable to read image {inputPath}");
@@ -474,9 +396,7 @@ namespace Jellyfin.Drawing.Skia
var originalImageSize = new ImageDimensions(bitmap.Width, bitmap.Height);
- if (!options.CropWhiteSpace
- && options.HasDefaultOptions(inputPath, originalImageSize)
- && !autoOrient)
+ if (options.HasDefaultOptions(inputPath, originalImageSize) && !autoOrient)
{
// Just spit out the original file if all the options are default
return inputPath;