diff --git a/.github/ISSUE_TEMPLATE/ask-question.md b/.github/ISSUE_TEMPLATE/ask-question.md
new file mode 100644
index 0000000000..c8313fba9f
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/ask-question.md
@@ -0,0 +1,13 @@
+---
+name: Ask question
+about: Ask a question about this project.
+
+---
+
+You should not create an issue but use Gitter instead: https://gitter.im/ImageSharp/General
+
+You should not create an issue but use Gitter instead: https://gitter.im/ImageSharp/General
+
+You should not create an issue but use Gitter instead: https://gitter.im/ImageSharp/General
+
+You should not create an issue but use Gitter instead: https://gitter.im/ImageSharp/General
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE/bug-report.md
similarity index 93%
rename from .github/ISSUE_TEMPLATE.md
rename to .github/ISSUE_TEMPLATE/bug-report.md
index a172605e64..58a31246a9 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE/bug-report.md
@@ -1,3 +1,9 @@
+---
+name: Bug report
+about: Create a report to help us improve
+
+---
+
### Prerequisites
- [ ] I have written a descriptive issue title
diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md
new file mode 100644
index 0000000000..be1e593be4
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature-request.md
@@ -0,0 +1,13 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+
+---
+
+You should first discuss the feature on Gitter: https://gitter.im/ImageSharp/General
+
+You should first discuss the feature on Gitter: https://gitter.im/ImageSharp/General
+
+You should first discuss the feature on Gitter: https://gitter.im/ImageSharp/General
+
+You should first discuss the feature on Gitter: https://gitter.im/ImageSharp/General
\ No newline at end of file
diff --git a/ImageSharp.sln b/ImageSharp.sln
index 0291d9f93a..8f3bc68602 100644
--- a/ImageSharp.sln
+++ b/ImageSharp.sln
@@ -8,13 +8,15 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionIt
.editorconfig = .editorconfig
.travis.yml = .travis.yml
appveyor.yml = appveyor.yml
+ .github\ISSUE_TEMPLATE\ask-question.md = .github\ISSUE_TEMPLATE\ask-question.md
+ .github\ISSUE_TEMPLATE\bug-report.md = .github\ISSUE_TEMPLATE\bug-report.md
codecov.yml = codecov.yml
CodeCoverage.runsettings = CodeCoverage.runsettings
.github\CONTRIBUTING.md = .github\CONTRIBUTING.md
+ .github\ISSUE_TEMPLATE\feature-request.md = .github\ISSUE_TEMPLATE\feature-request.md
features.md = features.md
ImageSharp.ruleset = ImageSharp.ruleset
ImageSharp.sln.DotSettings = ImageSharp.sln.DotSettings
- .github\ISSUE_TEMPLATE.md = .github\ISSUE_TEMPLATE.md
NuGet.config = NuGet.config
.github\PULL_REQUEST_TEMPLATE.md = .github\PULL_REQUEST_TEMPLATE.md
README.md = README.md
diff --git a/appveyor.yml b/appveyor.yml
index fccac0c44d..821fd427c8 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,5 +1,5 @@
version: 1.0.0.{build}
-image: Previous Visual Studio 2017
+image: Visual Studio 2017
# prevent the double build when a branch has an active PR
skip_branch_with_pr: true
diff --git a/build.ps1 b/build.ps1
index 35b8344dcc..215b551170 100644
--- a/build.ps1
+++ b/build.ps1
@@ -94,7 +94,7 @@ if("$env:APPVEYOR_API_URL" -ne ""){
}
Write-Host "Building version '${version}'"
-dotnet restore /p:packageversion=$version
+dotnet restore /p:packageversion=$version /p:DisableImplicitNuGetFallbackFolder=true
Write-Host "Building projects"
dotnet build -c Release /p:packageversion=$version
diff --git a/src/ImageSharp.Drawing/Processing/DrawImageExtensions.cs b/src/ImageSharp.Drawing/Processing/DrawImageExtensions.cs
index 8ccbe22acb..a8ee4d90bc 100644
--- a/src/ImageSharp.Drawing/Processing/DrawImageExtensions.cs
+++ b/src/ImageSharp.Drawing/Processing/DrawImageExtensions.cs
@@ -1,121 +1,137 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.ImageSharp.Processing.Processors.Drawing;
-using SixLabors.Primitives;
-
-namespace SixLabors.ImageSharp.Processing
-{
- ///
- /// Adds extensions that allow the drawing of images to the type.
- ///
- public static class DrawImageExtensions
- {
- ///
- /// Draws the given image together with the current one by blending their pixels.
- ///
- /// The pixel format.
- /// The image this method extends.
- /// The image to blend with the currently processing image.
- /// The opacity of the image to blend. Must be between 0 and 1.
- /// The .
- public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, float opacity)
- where TPixel : struct, IPixel
- => source.ApplyProcessor(new DrawImageProcessor(image, Point.Empty, GraphicsOptions.Default.ColorBlendingMode, GraphicsOptions.Default.AlphaCompositionMode, opacity));
-
- ///
- /// Draws the given image together with the current one by blending their pixels.
- ///
- /// The pixel format.
- /// The image this method extends.
- /// The image to blend with the currently processing image.
- /// The blending mode.
- /// The opacity of the image to blend. Must be between 0 and 1.
- /// The .
- public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, PixelColorBlendingMode colorBlending, float opacity)
- where TPixel : struct, IPixel
- => source.ApplyProcessor(new DrawImageProcessor(image, Point.Empty, colorBlending, GraphicsOptions.Default.AlphaCompositionMode, opacity));
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
- ///
- /// Draws the given image together with the current one by blending their pixels.
- ///
- /// The pixel format.
- /// The image this method extends.
- /// The image to blend with the currently processing image.
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing.Processors.Drawing;
+using SixLabors.Primitives;
+
+namespace SixLabors.ImageSharp.Processing
+{
+ ///
+ /// Adds extensions that allow the drawing of images to the type.
+ ///
+ public static class DrawImageExtensions
+ {
+ ///
+ /// Draws the given image together with the current one by blending their pixels.
+ ///
+ /// The pixel format of the destination image.
+ /// The pixel format of the source image.
+ /// The image this method extends.
+ /// The image to blend with the currently processing image.
+ /// The opacity of the image to blend. Must be between 0 and 1.
+ /// The .
+ public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, float opacity)
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
+ => source.ApplyProcessor(new DrawImageProcessor(image, Point.Empty, GraphicsOptions.Default.ColorBlendingMode, GraphicsOptions.Default.AlphaCompositionMode, opacity));
+
+ ///
+ /// Draws the given image together with the current one by blending their pixels.
+ ///
+ /// The pixel format of the destination image.
+ /// The pixel format of the source image.
+ /// The image this method extends.
+ /// The image to blend with the currently processing image.
+ /// The blending mode.
+ /// The opacity of the image to blend. Must be between 0 and 1.
+ /// The .
+ public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, PixelColorBlendingMode colorBlending, float opacity)
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
+ => source.ApplyProcessor(new DrawImageProcessor(image, Point.Empty, colorBlending, GraphicsOptions.Default.AlphaCompositionMode, opacity));
+
+ ///
+ /// Draws the given image together with the current one by blending their pixels.
+ ///
+ /// The pixel format of the destination image.
+ /// The pixel format of the source image.
+ /// The image this method extends.
+ /// The image to blend with the currently processing image.
/// The color blending mode.
- /// The alpha composition mode.
- /// The opacity of the image to blend. Must be between 0 and 1.
- /// The .
- public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, PixelColorBlendingMode colorBlending, PixelAlphaCompositionMode alphaComposition, float opacity)
- where TPixel : struct, IPixel
- => source.ApplyProcessor(new DrawImageProcessor(image, Point.Empty, colorBlending, alphaComposition, opacity));
+ /// The alpha composition mode.
+ /// The opacity of the image to blend. Must be between 0 and 1.
+ /// The .
+ public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, PixelColorBlendingMode colorBlending, PixelAlphaCompositionMode alphaComposition, float opacity)
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
+ => source.ApplyProcessor(new DrawImageProcessor(image, Point.Empty, colorBlending, alphaComposition, opacity));
- ///
- /// Draws the given image together with the current one by blending their pixels.
- ///
- /// The pixel format.
+ ///
+ /// Draws the given image together with the current one by blending their pixels.
+ ///
+ /// The pixel format of the destination image.
+ /// The pixel format of the source image.
/// The image this method extends.
- /// The image to blend with the currently processing image.
+ /// The image to blend with the currently processing image.
/// The options, including the blending type and blending amount.
- /// The .
- public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, GraphicsOptions options)
- where TPixel : struct, IPixel
- => source.ApplyProcessor(new DrawImageProcessor(image, Point.Empty, options.ColorBlendingMode, options.AlphaCompositionMode, options.BlendPercentage));
+ /// The .
+ public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, GraphicsOptions options)
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
+ => source.ApplyProcessor(new DrawImageProcessor(image, Point.Empty, options.ColorBlendingMode, options.AlphaCompositionMode, options.BlendPercentage));
- ///
- /// Draws the given image together with the current one by blending their pixels.
+ ///
+ /// Draws the given image together with the current one by blending their pixels.
///
- /// The pixel format.
- /// The image this method extends.
+ /// The pixel format of the destination image.
+ /// The pixel format of the source image.
+ /// The image this method extends.
/// The image to blend with the currently processing image.
- /// The location to draw the blended image.
+ /// The location to draw the blended image.
/// The opacity of the image to blend. Must be between 0 and 1.
- /// The .
- public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, Point location, float opacity)
- where TPixel : struct, IPixel
- => source.ApplyProcessor(new DrawImageProcessor(image, location, GraphicsOptions.Default.ColorBlendingMode, GraphicsOptions.Default.AlphaCompositionMode, opacity));
+ /// The .
+ public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, Point location, float opacity)
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
+ => source.ApplyProcessor(new DrawImageProcessor(image, location, GraphicsOptions.Default.ColorBlendingMode, GraphicsOptions.Default.AlphaCompositionMode, opacity));
- ///
- /// Draws the given image together with the current one by blending their pixels.
+ ///
+ /// Draws the given image together with the current one by blending their pixels.
///
- /// The pixel format.
- /// The image this method extends.
+ /// The pixel format of the destination image.
+ /// The pixel format of the source image.
+ /// The image this method extends.
/// The image to blend with the currently processing image.
- /// The location to draw the blended image.
- /// The color blending to apply.
+ /// The location to draw the blended image.
+ /// The color blending to apply.
/// The opacity of the image to blend. Must be between 0 and 1.
- /// The .
- public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, Point location, PixelColorBlendingMode colorBlending, float opacity)
- where TPixel : struct, IPixel
- => source.ApplyProcessor(new DrawImageProcessor(image, location, colorBlending, GraphicsOptions.Default.AlphaCompositionMode, opacity));
+ /// The .
+ public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, Point location, PixelColorBlendingMode colorBlending, float opacity)
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
+ => source.ApplyProcessor(new DrawImageProcessor(image, location, colorBlending, GraphicsOptions.Default.AlphaCompositionMode, opacity));
- ///
- /// Draws the given image together with the current one by blending their pixels.
+ ///
+ /// Draws the given image together with the current one by blending their pixels.
///
- /// The pixel format.
- /// The image this method extends.
+ /// The pixel format of the destination image.
+ /// The pixel format of the source image.
+ /// The image this method extends.
/// The image to blend with the currently processing image.
- /// The location to draw the blended image.
+ /// The location to draw the blended image.
/// The color blending to apply.
- /// The alpha composition mode.
+ /// The alpha composition mode.
/// The opacity of the image to blend. Must be between 0 and 1.
- /// The .
- public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, Point location, PixelColorBlendingMode colorBlending, PixelAlphaCompositionMode alphaComposition, float opacity)
- where TPixel : struct, IPixel
- => source.ApplyProcessor(new DrawImageProcessor(image, location, colorBlending, alphaComposition, opacity));
+ /// The .
+ public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, Point location, PixelColorBlendingMode colorBlending, PixelAlphaCompositionMode alphaComposition, float opacity)
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
+ => source.ApplyProcessor(new DrawImageProcessor(image, location, colorBlending, alphaComposition, opacity));
- ///
- /// Draws the given image together with the current one by blending their pixels.
+ ///
+ /// Draws the given image together with the current one by blending their pixels.
///
- /// The pixel format.
+ /// The pixel format of the destination image.
+ /// The pixel format of the source image.
/// The image this method extends.
/// The image to blend with the currently processing image.
/// The location to draw the blended image.
- /// The options containing the blend mode and opacity.
- /// The .
- public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, Point location, GraphicsOptions options)
- where TPixel : struct, IPixel
- => source.ApplyProcessor(new DrawImageProcessor(image, location, options.ColorBlendingMode, options.AlphaCompositionMode, options.BlendPercentage));
- }
+ /// The options containing the blend mode and opacity.
+ /// The .
+ public static IImageProcessingContext DrawImage(this IImageProcessingContext source, Image image, Point location, GraphicsOptions options)
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
+ => source.ApplyProcessor(new DrawImageProcessor(image, location, options.ColorBlendingMode, options.AlphaCompositionMode, options.BlendPercentage));
+ }
}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Processing/Processors/Drawing/DrawImageProcessor.cs b/src/ImageSharp.Drawing/Processing/Processors/Drawing/DrawImageProcessor.cs
index 324d25e097..4e6018e07a 100644
--- a/src/ImageSharp.Drawing/Processing/Processors/Drawing/DrawImageProcessor.cs
+++ b/src/ImageSharp.Drawing/Processing/Processors/Drawing/DrawImageProcessor.cs
@@ -15,32 +15,34 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
///
/// Combines two images together by blending the pixels.
///
- /// The pixel format.
- internal class DrawImageProcessor : ImageProcessor
- where TPixel : struct, IPixel
+ /// The pixel format of destination image.
+ /// The pixel format os source image.
+ internal class DrawImageProcessor : ImageProcessor
+ where TPixelDst : struct, IPixel
+ where TPixelSrc : struct, IPixel
{
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The image to blend with the currently processing image.
/// The location to draw the blended image.
/// The blending mode to use when drawing the image.
/// The Alpha blending mode to use when drawing the image.
/// The opacity of the image to blend. Must be between 0 and 1.
- public DrawImageProcessor(Image image, Point location, PixelColorBlendingMode colorBlendingMode, PixelAlphaCompositionMode alphaCompositionMode, float opacity)
+ public DrawImageProcessor(Image image, Point location, PixelColorBlendingMode colorBlendingMode, PixelAlphaCompositionMode alphaCompositionMode, float opacity)
{
Guard.MustBeBetweenOrEqualTo(opacity, 0, 1, nameof(opacity));
this.Image = image;
this.Opacity = opacity;
- this.Blender = PixelOperations.Instance.GetPixelBlender(colorBlendingMode, alphaCompositionMode);
+ this.Blender = PixelOperations.Instance.GetPixelBlender(colorBlendingMode, alphaCompositionMode);
this.Location = location;
}
///
/// Gets the image to blend
///
- public Image Image { get; }
+ public Image Image { get; }
///
/// Gets the opacity of the image to blend
@@ -50,7 +52,7 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
///
/// Gets the pixel blender
///
- public PixelBlender Blender { get; }
+ public PixelBlender Blender { get; }
///
/// Gets the location to draw the blended image
@@ -58,10 +60,10 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
public Point Location { get; }
///
- protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration)
+ protected override void OnFrameApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration)
{
- Image targetImage = this.Image;
- PixelBlender blender = this.Blender;
+ Image targetImage = this.Image;
+ PixelBlender blender = this.Blender;
int locationY = this.Location.Y;
// Align start/end positions.
@@ -76,23 +78,18 @@ namespace SixLabors.ImageSharp.Processing.Processors.Drawing
int width = maxX - minX;
- MemoryAllocator memoryAllocator = this.Image.GetConfiguration().MemoryAllocator;
-
- using (IMemoryOwner amount = memoryAllocator.Allocate(width))
- {
- amount.GetSpan().Fill(this.Opacity);
-
- ParallelFor.WithConfiguration(
- minY,
- maxY,
- configuration,
- y =>
- {
- Span background = source.GetPixelRowSpan(y).Slice(minX, width);
- Span foreground = targetImage.GetPixelRowSpan(y - locationY).Slice(targetX, width);
- blender.Blend(memoryAllocator, background, background, foreground, amount.GetSpan());
- });
- }
+ MemoryAllocator memoryAllocator = this.Image.GetConfiguration().MemoryAllocator;
+
+ ParallelFor.WithConfiguration(
+ minY,
+ maxY,
+ configuration,
+ y =>
+ {
+ Span background = source.GetPixelRowSpan(y).Slice(minX, width);
+ Span foreground = targetImage.GetPixelRowSpan(y - locationY).Slice(targetX, width);
+ blender.Blend(memoryAllocator, background, background, foreground, this.Opacity);
+ });
}
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs
index bebc13f6de..b7dd125a88 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs
@@ -5,7 +5,6 @@ using System.Numerics;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Memory;
-using SixLabors.Memory;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Formats.Jpeg.Components
@@ -15,7 +14,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
///
/// Copy block data into the destination color buffer pixel area with the provided horizontal and vertical.
///
- public void CopyTo(BufferArea area, int horizontalScale, int verticalScale)
+ public void CopyTo(in BufferArea area, int horizontalScale, int verticalScale)
{
if (horizontalScale == 1 && verticalScale == 1)
{
@@ -57,7 +56,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
}
// [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void CopyTo(BufferArea area)
+ public void CopyTo(in BufferArea area)
{
ref byte selfBase = ref Unsafe.As(ref this);
ref byte destBase = ref Unsafe.As(ref area.GetReferenceToOrigin());
@@ -81,7 +80,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
Unsafe.CopyBlock(ref d, ref s, 8 * sizeof(float));
}
- private void CopyTo2x2(BufferArea area)
+ private void CopyTo2x2(in BufferArea area)
{
ref float destBase = ref area.GetReferenceToOrigin();
int destStride = area.Stride;
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmyk.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmyk.cs
index bac77f905e..7a14d072e6 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmyk.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmyk.cs
@@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
- public override void ConvertToRgba(ComponentValues values, Span result)
+ public override void ConvertToRgba(in ComponentValues values, Span result)
{
// TODO: We can optimize a lot here with Vector and SRCS.Unsafe()!
ReadOnlySpan cVals = values.Component0;
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScale.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScale.cs
index b07e57e170..5d7a31a12b 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScale.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScale.cs
@@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
- public override void ConvertToRgba(ComponentValues values, Span result)
+ public override void ConvertToRgba(in ComponentValues values, Span result)
{
// TODO: We can optimize a lot here with Vector and SRCS.Unsafe()!
ReadOnlySpan yVals = values.Component0;
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgb.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgb.cs
index 6b7e77e148..7cd97c4140 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgb.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgb.cs
@@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
- public override void ConvertToRgba(ComponentValues values, Span result)
+ public override void ConvertToRgba(in ComponentValues values, Span result)
{
// TODO: We can optimize a lot here with Vector and SRCS.Unsafe()!
ReadOnlySpan rVals = values.Component0;
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrBasic.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrBasic.cs
index 35700ea312..cb71889bc5 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrBasic.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrBasic.cs
@@ -15,12 +15,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
- public override void ConvertToRgba(ComponentValues values, Span result)
+ public override void ConvertToRgba(in ComponentValues values, Span result)
{
ConvertCore(values, result);
}
- internal static void ConvertCore(ComponentValues values, Span result)
+ internal static void ConvertCore(in ComponentValues values, Span result)
{
// TODO: We can optimize a lot here with Vector and SRCS.Unsafe()!
ReadOnlySpan yVals = values.Component0;
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs
index fd2f17da9e..4b2626c582 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs
@@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
- public override void ConvertToRgba(ComponentValues values, Span result)
+ public override void ConvertToRgba(in ComponentValues values, Span result)
{
int remainder = result.Length % 8;
int simdCount = result.Length - remainder;
@@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
///
/// SIMD convert using buffers of sizes divisable by 8.
///
- internal static void ConvertCore(ComponentValues values, Span result)
+ internal static void ConvertCore(in ComponentValues values, Span result)
{
DebugGuard.IsTrue(result.Length % 8 == 0, nameof(result), "result.Length should be divisable by 8!");
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs
index 25342f4d67..ab4947e65c 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs
@@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
public static bool IsAvailable => Vector.IsHardwareAccelerated && SimdUtils.IsAvx2CompatibleArchitecture;
- public override void ConvertToRgba(ComponentValues values, Span result)
+ public override void ConvertToRgba(in ComponentValues values, Span result)
{
int remainder = result.Length % 8;
int simdCount = result.Length - remainder;
@@ -37,7 +37,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
///
/// SIMD convert using buffers of sizes divisable by 8.
///
- internal static void ConvertCore(ComponentValues values, Span result)
+ internal static void ConvertCore(in ComponentValues values, Span result)
{
// This implementation is actually AVX specific.
// An AVX register is capable of storing 8 float-s.
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccK.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccK.cs
index 83feefa94a..6f940f62f9 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccK.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccK.cs
@@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
- public override void ConvertToRgba(ComponentValues values, Span result)
+ public override void ConvertToRgba(in ComponentValues values, Span result)
{
// TODO: We can optimize a lot here with Vector and SRCS.Unsafe()!
ReadOnlySpan yVals = values.Component0;
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs
index 8aeb01d7f0..60abb7fb2c 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs
@@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
///
/// The input as a stack-only struct
/// The destination buffer of values
- public abstract void ConvertToRgba(ComponentValues values, Span result);
+ public abstract void ConvertToRgba(in ComponentValues values, Span result);
///
/// Returns the for the YCbCr colorspace that matches the current CPU architecture.
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockPostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockPostProcessor.cs
index 900dd3bc89..0108e30815 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockPostProcessor.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockPostProcessor.cs
@@ -2,9 +2,7 @@
// Licensed under the Apache License, Version 2.0.
using System.Runtime.InteropServices;
-
using SixLabors.ImageSharp.Memory;
-using SixLabors.Memory;
using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
@@ -43,6 +41,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
///
/// Initializes a new instance of the struct.
///
+ /// The raw jpeg data.
+ /// The raw component.
public JpegBlockPostProcessor(IRawJpegData decoder, IJpegComponent component)
{
int qtIndex = component.QuantizationTableIndex;
@@ -61,9 +61,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
/// - Level shift by +128, clip to [0, 255]
/// - Copy the resultin color values into 'destArea' scaling up the block by amount defined in
///
+ /// The source block.
+ /// The destination buffer area.
public void ProcessBlockColorsInto(
ref Block8x8 sourceBlock,
- BufferArea destArea)
+ in BufferArea destArea)
{
ref Block8x8F b = ref this.SourceBlock;
b.LoadFrom(ref sourceBlock);
diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
index 7561afa1ef..b46b4b6042 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
@@ -268,7 +268,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
this.fastACTables = new FastACTables(this.configuration.MemoryAllocator);
}
- while (fileMarker.Marker != JpegConstants.Markers.EOI)
+ // Break only when we discover a valid EOI marker.
+ // https://github.com/SixLabors/ImageSharp/issues/695
+ while (fileMarker.Marker != JpegConstants.Markers.EOI
+ || (fileMarker.Marker == JpegConstants.Markers.EOI && fileMarker.Invalid))
{
if (!fileMarker.Invalid)
{
@@ -463,13 +466,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
}
else if (this.isExif)
{
- double horizontalValue = this.MetaData.ExifProfile.TryGetValue(ExifTag.XResolution, out ExifValue horizontalTag)
- ? ((Rational)horizontalTag.Value).ToDouble()
- : 0;
-
- double verticalValue = this.MetaData.ExifProfile.TryGetValue(ExifTag.YResolution, out ExifValue verticalTag)
- ? ((Rational)verticalTag.Value).ToDouble()
- : 0;
+ double horizontalValue = this.GetExifResolutionValue(ExifTag.XResolution);
+ double verticalValue = this.GetExifResolutionValue(ExifTag.YResolution);
if (horizontalValue > 0 && verticalValue > 0)
{
@@ -480,6 +478,26 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
}
}
+ private double GetExifResolutionValue(ExifTag tag)
+ {
+ if (!this.MetaData.ExifProfile.TryGetValue(tag, out ExifValue exifValue))
+ {
+ return 0;
+ }
+
+ switch (exifValue.DataType)
+ {
+ case ExifDataType.Rational:
+ return ((Rational)exifValue.Value).ToDouble();
+ case ExifDataType.Long:
+ return (uint)exifValue.Value;
+ case ExifDataType.DoubleFloat:
+ return (double)exifValue.Value;
+ default:
+ return 0;
+ }
+ }
+
///
/// Extends the profile with additional data.
///
@@ -899,9 +917,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// The values
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void BuildHuffmanTable(HuffmanTables tables, int index, ReadOnlySpan codeLengths, ReadOnlySpan values)
- {
- tables[index] = new HuffmanTable(this.configuration.MemoryAllocator, codeLengths, values);
- }
+ => tables[index] = new HuffmanTable(this.configuration.MemoryAllocator, codeLengths, values);
///
/// Reads a from the stream advancing it by two bytes
diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs
index 72db6305dd..549cb3fe09 100644
--- a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs
+++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs
@@ -88,19 +88,19 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif
}
uint ifdOffset = this.ReadUInt32();
- this.AddValues(values, (int)ifdOffset);
+ this.AddValues(values, ifdOffset);
uint thumbnailOffset = this.ReadUInt32();
- this.GetThumbnail((int)thumbnailOffset);
+ this.GetThumbnail(thumbnailOffset);
if (this.exifOffset != 0)
{
- this.AddValues(values, (int)this.exifOffset);
+ this.AddValues(values, this.exifOffset);
}
if (this.gpsOffset != 0)
{
- this.AddValues(values, (int)this.gpsOffset);
+ this.AddValues(values, this.gpsOffset);
}
return values;
@@ -153,9 +153,14 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif
///
/// The values.
/// The index.
- private void AddValues(List values, int index)
+ private void AddValues(List values, uint index)
{
- this.position = index;
+ if (index > (uint)this.exifData.Length)
+ {
+ return;
+ }
+
+ this.position = (int)index;
int count = this.ReadUInt16();
for (int i = 0; i < count; i++)
@@ -431,7 +436,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif
return null;
}
- private void GetThumbnail(int offset)
+ private void GetThumbnail(uint offset)
{
var values = new List();
this.AddValues(values, offset);
@@ -515,10 +520,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif
return new Rational(numerator, denominator, false);
}
- private sbyte ConvertToSignedByte(ReadOnlySpan buffer)
- {
- return unchecked((sbyte)buffer[0]);
- }
+ private sbyte ConvertToSignedByte(ReadOnlySpan buffer) => unchecked((sbyte)buffer[0]);
private int ConvertToInt32(ReadOnlySpan buffer) // SignedLong in Exif Specification
{
diff --git a/src/ImageSharp/MetaData/Profiles/ICC/DataWriter/IccDataWriter.Matrix.cs b/src/ImageSharp/MetaData/Profiles/ICC/DataWriter/IccDataWriter.Matrix.cs
index 5d7d729b2c..79b9132192 100644
--- a/src/ImageSharp/MetaData/Profiles/ICC/DataWriter/IccDataWriter.Matrix.cs
+++ b/src/ImageSharp/MetaData/Profiles/ICC/DataWriter/IccDataWriter.Matrix.cs
@@ -59,7 +59,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// The matrix to write
/// True if the values are encoded as Single; false if encoded as Fix16
/// The number of bytes written
- public int WriteMatrix(DenseMatrix value, bool isSingle)
+ public int WriteMatrix(in DenseMatrix value, bool isSingle)
{
int count = 0;
for (int y = 0; y < value.Rows; y++)
diff --git a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs b/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs
index 9b1e29db81..19d1c5dad1 100644
--- a/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs
+++ b/src/ImageSharp/PixelFormats/PixelBlenders/DefaultPixelBlenders.Generated.cs
@@ -1,4242 +1,3926 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-//
-using System;
-using System.Numerics;
-using System.Buffers;
-
-using SixLabors.ImageSharp.Memory;
-using SixLabors.Memory;
-
-namespace SixLabors.ImageSharp.PixelFormats.PixelBlenders
-{
- ///
- /// Collection of Porter Duff alpha blending functions applying different composition models.
- ///
- ///
- /// These functions are designed to be a general solution for all color cases,
- /// that is, they take in account the alpha value of both the backdrop
- /// and source, and there's no need to alpha-premultiply neither the backdrop
- /// nor the source.
- /// Note there are faster functions for when the backdrop color is known
- /// to be opaque
- ///
- internal static class DefaultPixelBlenders
- where TPixel : struct, IPixel
- {
-
- internal class NormalSrc : PixelBlender
- {
- ///
- /// Gets the static instance of this blender.
- ///
- public static NormalSrc Instance { get; } = new NormalSrc();
-
- ///
- public override TPixel Blend(TPixel background, TPixel source, float amount)
- {
- return PorterDuffFunctions.NormalSrc(background, source, amount);
- }
-
- ///
- public override void Blend(MemoryAllocator memoryManager, Span destination, Span background, Span source, Span amount)
- {
- Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
- Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
- Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
-
- using (IMemoryOwner buffer = memoryManager.Allocate(destination.Length * 3))
- {
- Span destinationSpan = buffer.Slice(0, destination.Length);
- Span backgroundSpan = buffer.Slice(destination.Length, destination.Length);
- Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
-
- PixelOperations.Instance.ToVector4(background, backgroundSpan, destination.Length);
- PixelOperations.Instance.ToVector4(source, sourceSpan, destination.Length);
-
- for (int i = 0; i < destination.Length; i++)
- {
- destinationSpan[i] = PorterDuffFunctions.NormalSrc(backgroundSpan[i], sourceSpan[i], amount[i]);
- }
-
- PixelOperations.Instance.PackFromVector4(destinationSpan, destination, destination.Length);
- }
- }
- }
-
- internal class MultiplySrc : PixelBlender
- {
- ///
- /// Gets the static instance of this blender.
- ///
- public static MultiplySrc Instance { get; } = new MultiplySrc();
-
- ///
- public override TPixel Blend(TPixel background, TPixel source, float amount)
- {
- return PorterDuffFunctions.MultiplySrc(background, source, amount);
- }
-
- ///
- public override void Blend(MemoryAllocator memoryManager, Span destination, Span background, Span source, Span amount)
- {
- Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
- Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
- Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
-
- using (IMemoryOwner buffer = memoryManager.Allocate(destination.Length * 3))
- {
- Span destinationSpan = buffer.Slice(0, destination.Length);
- Span backgroundSpan = buffer.Slice(destination.Length, destination.Length);
- Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
-
- PixelOperations.Instance.ToVector4(background, backgroundSpan, destination.Length);
- PixelOperations.Instance.ToVector4(source, sourceSpan, destination.Length);
-
- for (int i = 0; i < destination.Length; i++)
- {
- destinationSpan[i] = PorterDuffFunctions.MultiplySrc(backgroundSpan[i], sourceSpan[i], amount[i]);
- }
-
- PixelOperations.Instance.PackFromVector4(destinationSpan, destination, destination.Length);
- }
- }
- }
-
- internal class AddSrc : PixelBlender
- {
- ///
- /// Gets the static instance of this blender.
- ///
- public static AddSrc Instance { get; } = new AddSrc();
-
- ///
- public override TPixel Blend(TPixel background, TPixel source, float amount)
- {
- return PorterDuffFunctions.AddSrc(background, source, amount);
- }
-
- ///
- public override void Blend(MemoryAllocator memoryManager, Span destination, Span background, Span source, Span amount)
- {
- Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
- Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
- Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
-
- using (IMemoryOwner buffer = memoryManager.Allocate(destination.Length * 3))
- {
- Span destinationSpan = buffer.Slice(0, destination.Length);
- Span backgroundSpan = buffer.Slice(destination.Length, destination.Length);
- Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
-
- PixelOperations.Instance.ToVector4(background, backgroundSpan, destination.Length);
- PixelOperations.Instance.ToVector4(source, sourceSpan, destination.Length);
-
- for (int i = 0; i < destination.Length; i++)
- {
- destinationSpan[i] = PorterDuffFunctions.AddSrc(backgroundSpan[i], sourceSpan[i], amount[i]);
- }
-
- PixelOperations.Instance.PackFromVector4(destinationSpan, destination, destination.Length);
- }
- }
- }
-
- internal class SubtractSrc : PixelBlender
- {
- ///
- /// Gets the static instance of this blender.
- ///
- public static SubtractSrc Instance { get; } = new SubtractSrc();
-
- ///
- public override TPixel Blend(TPixel background, TPixel source, float amount)
- {
- return PorterDuffFunctions.SubtractSrc(background, source, amount);
- }
-
- ///
- public override void Blend(MemoryAllocator memoryManager, Span destination, Span background, Span source, Span amount)
- {
- Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
- Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
- Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
-
- using (IMemoryOwner buffer = memoryManager.Allocate(destination.Length * 3))
- {
- Span destinationSpan = buffer.Slice(0, destination.Length);
- Span backgroundSpan = buffer.Slice(destination.Length, destination.Length);
- Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
-
- PixelOperations.Instance.ToVector4(background, backgroundSpan, destination.Length);
- PixelOperations.Instance.ToVector4(source, sourceSpan, destination.Length);
-
- for (int i = 0; i < destination.Length; i++)
- {
- destinationSpan[i] = PorterDuffFunctions.SubtractSrc(backgroundSpan[i], sourceSpan[i], amount[i]);
- }
-
- PixelOperations.Instance.PackFromVector4(destinationSpan, destination, destination.Length);
- }
- }
- }
-
- internal class ScreenSrc : PixelBlender
- {
- ///
- /// Gets the static instance of this blender.
- ///
- public static ScreenSrc Instance { get; } = new ScreenSrc();
-
- ///
- public override TPixel Blend(TPixel background, TPixel source, float amount)
- {
- return PorterDuffFunctions.ScreenSrc(background, source, amount);
- }
-
- ///
- public override void Blend(MemoryAllocator memoryManager, Span destination, Span background, Span source, Span amount)
- {
- Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
- Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
- Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
-
- using (IMemoryOwner buffer = memoryManager.Allocate(destination.Length * 3))
- {
- Span destinationSpan = buffer.Slice(0, destination.Length);
- Span backgroundSpan = buffer.Slice(destination.Length, destination.Length);
- Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
-
- PixelOperations.Instance.ToVector4(background, backgroundSpan, destination.Length);
- PixelOperations.Instance.ToVector4(source, sourceSpan, destination.Length);
-
- for (int i = 0; i < destination.Length; i++)
- {
- destinationSpan[i] = PorterDuffFunctions.ScreenSrc(backgroundSpan[i], sourceSpan[i], amount[i]);
- }
-
- PixelOperations.Instance.PackFromVector4(destinationSpan, destination, destination.Length);
- }
- }
- }
-
- internal class DarkenSrc : PixelBlender
- {
- ///
- /// Gets the static instance of this blender.
- ///
- public static DarkenSrc Instance { get; } = new DarkenSrc();
-
- ///
- public override TPixel Blend(TPixel background, TPixel source, float amount)
- {
- return PorterDuffFunctions.DarkenSrc(background, source, amount);
- }
-
- ///
- public override void Blend(MemoryAllocator memoryManager, Span destination, Span background, Span source, Span amount)
- {
- Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
- Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
- Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
-
- using (IMemoryOwner buffer = memoryManager.Allocate(destination.Length * 3))
- {
- Span destinationSpan = buffer.Slice(0, destination.Length);
- Span backgroundSpan = buffer.Slice(destination.Length, destination.Length);
- Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
-
- PixelOperations.Instance.ToVector4(background, backgroundSpan, destination.Length);
- PixelOperations.Instance.ToVector4(source, sourceSpan, destination.Length);
-
- for (int i = 0; i < destination.Length; i++)
- {
- destinationSpan[i] = PorterDuffFunctions.DarkenSrc(backgroundSpan[i], sourceSpan[i], amount[i]);
- }
-
- PixelOperations.Instance.PackFromVector4(destinationSpan, destination, destination.Length);
- }
- }
- }
-
- internal class LightenSrc : PixelBlender
- {
- ///
- /// Gets the static instance of this blender.
- ///
- public static LightenSrc Instance { get; } = new LightenSrc();
-
- ///
- public override TPixel Blend(TPixel background, TPixel source, float amount)
- {
- return PorterDuffFunctions.LightenSrc(background, source, amount);
- }
-
- ///
- public override void Blend(MemoryAllocator memoryManager, Span destination, Span background, Span source, Span amount)
- {
- Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
- Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
- Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
-
- using (IMemoryOwner buffer = memoryManager.Allocate(destination.Length * 3))
- {
- Span destinationSpan = buffer.Slice(0, destination.Length);
- Span backgroundSpan = buffer.Slice(destination.Length, destination.Length);
- Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
-
- PixelOperations.Instance.ToVector4(background, backgroundSpan, destination.Length);
- PixelOperations.Instance.ToVector4(source, sourceSpan, destination.Length);
-
- for (int i = 0; i < destination.Length; i++)
- {
- destinationSpan[i] = PorterDuffFunctions.LightenSrc(backgroundSpan[i], sourceSpan[i], amount[i]);
- }
-
- PixelOperations.Instance.PackFromVector4(destinationSpan, destination, destination.Length);
- }
- }
- }
-
- internal class OverlaySrc : PixelBlender
- {
- ///
- /// Gets the static instance of this blender.
- ///
- public static OverlaySrc Instance { get; } = new OverlaySrc();
-
- ///
- public override TPixel Blend(TPixel background, TPixel source, float amount)
- {
- return PorterDuffFunctions.OverlaySrc(background, source, amount);
- }
-
- ///
- public override void Blend(MemoryAllocator memoryManager, Span destination, Span background, Span source, Span amount)
- {
- Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
- Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
- Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
-
- using (IMemoryOwner buffer = memoryManager.Allocate(destination.Length * 3))
- {
- Span destinationSpan = buffer.Slice(0, destination.Length);
- Span backgroundSpan = buffer.Slice(destination.Length, destination.Length);
- Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
-
- PixelOperations.Instance.ToVector4(background, backgroundSpan, destination.Length);
- PixelOperations.Instance.ToVector4(source, sourceSpan, destination.Length);
-
- for (int i = 0; i < destination.Length; i++)
- {
- destinationSpan[i] = PorterDuffFunctions.OverlaySrc(backgroundSpan[i], sourceSpan[i], amount[i]);
- }
-
- PixelOperations.Instance.PackFromVector4(destinationSpan, destination, destination.Length);
- }
- }
- }
-
- internal class HardLightSrc : PixelBlender
- {
- ///
- /// Gets the static instance of this blender.
- ///
- public static HardLightSrc Instance { get; } = new HardLightSrc();
-
- ///
- public override TPixel Blend(TPixel background, TPixel source, float amount)
- {
- return PorterDuffFunctions.HardLightSrc(background, source, amount);
- }
-
- ///
- public override void Blend(MemoryAllocator memoryManager, Span destination, Span background, Span source, Span amount)
- {
- Guard.MustBeGreaterThanOrEqualTo(background.Length, destination.Length, nameof(background.Length));
- Guard.MustBeGreaterThanOrEqualTo(source.Length, destination.Length, nameof(source.Length));
- Guard.MustBeGreaterThanOrEqualTo(amount.Length, destination.Length, nameof(amount.Length));
-
- using (IMemoryOwner buffer = memoryManager.Allocate(destination.Length * 3))
- {
- Span destinationSpan = buffer.Slice(0, destination.Length);
- Span backgroundSpan = buffer.Slice(destination.Length, destination.Length);
- Span sourceSpan = buffer.Slice(destination.Length * 2, destination.Length);
-
- PixelOperations