diff --git a/.travis.yml b/.travis.yml
index 54e4dee2f8..deb8621971 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -6,7 +6,7 @@ matrix:
- os: linux # Ubuntu 14.04
dist: trusty
sudo: required
- dotnet: 2.1.4
+ dotnet: 2.1.300-rc1-008673
mono: latest
# - os: osx # OSX 10.11
# osx_image: xcode7.3.1
@@ -21,7 +21,7 @@ branches:
script:
- git submodule -q update --init
- dotnet restore
- - dotnet test tests/ImageSharp.Tests/ImageSharp.Tests.csproj -c Release -f "netcoreapp2.0"
+ - dotnet test tests/ImageSharp.Tests/ImageSharp.Tests.csproj -c Release -f "netcoreapp2.1"
env:
global:
diff --git a/ImageSharp.ruleset b/ImageSharp.ruleset
index 3567dc4b9e..d318b75c2e 100644
--- a/ImageSharp.ruleset
+++ b/ImageSharp.ruleset
@@ -9,5 +9,7 @@
+
+
\ No newline at end of file
diff --git a/README.md b/README.md
index b351b57716..b54a9b2075 100644
--- a/README.md
+++ b/README.md
@@ -115,17 +115,21 @@ For more examples check out:
### Manual build
-If you prefer, you can compile ImageSharp yourself (please do and help!), you'll need:
+If you prefer, you can compile ImageSharp yourself (please do and help!)
-- [Visual Studio 2017 (or above)](https://www.visualstudio.com/en-us/news/releasenotes/vs2017-relnotes)
-- The [.NET Core SDK Installer](https://www.microsoft.com/net/core#windows) - Non VSCode link.
+- Using [Visual Studio 2017 Preview](https://docs.microsoft.com/en-us/visualstudio/releasenotes/vs2017-preview-relnotes)
+ - Make sure you have the latest version installed
+ - Make sure you have [the newest 2.1 RC1 SDK installed](https://www.microsoft.com/net/core#windows)
-Alternatively on Linux you can use:
+- Using [Visual Studio 2017](https://www.visualstudio.com/en-us/news/releasenotes/vs2017-relnotes)
+ - If you are unable and/or don't want to build ImageSharp.Tests against 2.1 RC, remove the `netcoreapp2.1` target [from TargetFrameworks](https://github.com/SixLabors/ImageSharp/blob/master/tests/ImageSharp.Tests/ImageSharp.Tests.csproj#L3) locally
+
+Alternatively, you can work from command line and/or with a lightweight editor on **both Linux/Unix and Windows**:
- [Visual Studio Code](https://code.visualstudio.com/) with [C# Extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.csharp)
- [.Net Core](https://www.microsoft.com/net/core#linuxubuntu)
-To clone it locally click the "Clone in Windows" button above or run the following git commands.
+To clone ImageSharp locally click the "Clone in Windows" button above or run the following git commands.
```bash
git clone https://github.com/SixLabors/ImageSharp
diff --git a/appveyor.yml b/appveyor.yml
index f784ef2876..d98fa9c6a8 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,21 +1,34 @@
version: 1.0.0.{build}
-image: Visual Studio 2017
+image: Visual Studio 2017 Preview
# prevent the double build when a branch has an active PR
skip_branch_with_pr: true
environment:
matrix:
+ ### TODO: Enable the netcoreapp2.1 target when RC2 has been released!
+
+ #- target_framework: netcoreapp2.1
+ # is_32bit: False
+
+ #- target_framework: netcoreapp2.1
+ # is_32bit: True
+
+ - target_framework: netcoreapp2.0
+ is_32bit: False
+
+ - target_framework: net471
+ is_32bit: False
+
- target_framework: net471
is_32bit: True
+
- target_framework: net462
is_32bit: False
+
- target_framework: net462
is_32bit: True
- - target_framework: net471
- is_32bit: False
- - target_framework: netcoreapp2.0
- is_32bit: False
+
#- target_framework: netcoreapp2.0 # As far as I understand, 32 bit test execution is not supported by "dotnet xunit"
# is_32bit: True
#- target_framework: mono
@@ -39,7 +52,7 @@ install:
before_build:
- git submodule -q update --init
- - cmd: dotnet --version
+ - cmd: dotnet --info
build_script:
- cmd: build.cmd
@@ -60,4 +73,4 @@ deploy:
secure: V/lEHP0UeMWIpWd0fiNlY2IgbCnJKQlGdRksECdJbOBdaE20Fl0RNL7WyqHe02o4
artifact: /.*\.nupkg/
on:
- branch: master
+ branch: master
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
index a732d1da2c..30ca57b596 100644
--- a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
+++ b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
@@ -38,10 +38,9 @@
-
-
-
+
+
All
diff --git a/src/ImageSharp.Drawing/Processing/Drawing/Brushes/BrushApplicator.cs b/src/ImageSharp.Drawing/Processing/Drawing/Brushes/BrushApplicator.cs
index f665e8408c..c546663353 100644
--- a/src/ImageSharp.Drawing/Processing/Drawing/Brushes/BrushApplicator.cs
+++ b/src/ImageSharp.Drawing/Processing/Drawing/Brushes/BrushApplicator.cs
@@ -79,6 +79,10 @@ namespace SixLabors.ImageSharp.Processing.Drawing.Brushes
{
amountSpan[i] = scanline[i] * this.Options.BlendPercentage;
}
+ else
+ {
+ amountSpan[i] = scanline[i];
+ }
overlaySpan[i] = this[x + i, y];
}
diff --git a/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/ColorStop{TPixel}.cs b/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/ColorStop{TPixel}.cs
new file mode 100644
index 0000000000..298af5cb56
--- /dev/null
+++ b/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/ColorStop{TPixel}.cs
@@ -0,0 +1,36 @@
+using System.Diagnostics;
+
+using SixLabors.ImageSharp.PixelFormats;
+
+namespace SixLabors.ImageSharp.Processing.Drawing.Brushes.GradientBrushes
+{
+ ///
+ /// A struct that defines a single color stop.
+ ///
+ /// The pixel format.
+ [DebuggerDisplay("ColorStop({Ratio} -> {Color}")]
+ public struct ColorStop
+ where TPixel : struct, IPixel
+ {
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// Where should it be? 0 is at the start, 1 at the end of the Gradient.
+ /// What color should be used at that point?
+ public ColorStop(float ratio, TPixel color)
+ {
+ this.Ratio = ratio;
+ this.Color = color;
+ }
+
+ ///
+ /// Gets the point along the defined gradient axis.
+ ///
+ public float Ratio { get; }
+
+ ///
+ /// Gets the color to be used.
+ ///
+ public TPixel Color { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/EllipticGradientBrush{TPixel}.cs b/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/EllipticGradientBrush{TPixel}.cs
new file mode 100644
index 0000000000..43f7fe04e9
--- /dev/null
+++ b/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/EllipticGradientBrush{TPixel}.cs
@@ -0,0 +1,167 @@
+using System;
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.Primitives;
+
+namespace SixLabors.ImageSharp.Processing.Drawing.Brushes.GradientBrushes
+{
+ ///
+ /// Gradient Brush with elliptic shape.
+ /// The ellipse is defined by a center point,
+ /// a point on the longest extension of the ellipse and
+ /// the ratio between longest and shortest extension.
+ ///
+ /// The Pixel format that is used.
+ public sealed class EllipticGradientBrush : GradientBrushBase
+ where TPixel : struct, IPixel
+ {
+ private readonly Point center;
+
+ private readonly Point referenceAxisEnd;
+
+ private readonly float axisRatio;
+
+ ///
+ /// The center of the elliptical gradient and 0 for the color stops.
+ /// The end point of the reference axis of the ellipse.
+ ///
+ /// The ratio of the axis widths.
+ /// The second axis' is perpendicular to the reference axis and
+ /// it's length is the reference axis' length multiplied by this factor.
+ ///
+ /// Defines how the colors of the gradients are repeated.
+ /// the color stops as defined in base class.
+ public EllipticGradientBrush(
+ Point center,
+ Point referenceAxisEnd,
+ float axisRatio,
+ GradientRepetitionMode repetitionMode,
+ params ColorStop[] colorStops)
+ : base(repetitionMode, colorStops)
+ {
+ this.center = center;
+ this.referenceAxisEnd = referenceAxisEnd;
+ this.axisRatio = axisRatio;
+ }
+
+ ///
+ public override BrushApplicator CreateApplicator(
+ ImageFrame source,
+ RectangleF region,
+ GraphicsOptions options) =>
+ new RadialGradientBrushApplicator(
+ source,
+ options,
+ this.center,
+ this.referenceAxisEnd,
+ this.axisRatio,
+ this.ColorStops,
+ this.RepetitionMode);
+
+ ///
+ private sealed class RadialGradientBrushApplicator : GradientBrushApplicatorBase
+ {
+ private readonly Point center;
+
+ private readonly Point referenceAxisEnd;
+
+ private readonly float axisRatio;
+
+ private readonly double rotation;
+
+ private readonly float referenceRadius;
+
+ private readonly float secondRadius;
+
+ private readonly float cosRotation;
+
+ private readonly float sinRotation;
+
+ private readonly float secondRadiusSquared;
+
+ private readonly float referenceRadiusSquared;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The target image
+ /// The options
+ /// Center of the ellipse
+ /// Point on one angular points of the ellipse.
+ ///
+ /// Ratio of the axis length's. Used to determine the length of the second axis,
+ /// the first is defined by and .
+ /// Definition of colors
+ /// Defines how the gradient colors are repeated.
+ public RadialGradientBrushApplicator(
+ ImageFrame target,
+ GraphicsOptions options,
+ Point center,
+ Point referenceAxisEnd,
+ float axisRatio,
+ ColorStop[] colorStops,
+ GradientRepetitionMode repetitionMode)
+ : base(target, options, colorStops, repetitionMode)
+ {
+ this.center = center;
+ this.referenceAxisEnd = referenceAxisEnd;
+ this.axisRatio = axisRatio;
+ this.rotation = this.AngleBetween(
+ this.center,
+ new PointF(this.center.X + 1, this.center.Y),
+ this.referenceAxisEnd);
+ this.referenceRadius = this.DistanceBetween(this.center, this.referenceAxisEnd);
+ this.secondRadius = this.referenceRadius * this.axisRatio;
+
+ this.referenceRadiusSquared = this.referenceRadius * this.referenceRadius;
+ this.secondRadiusSquared = this.secondRadius * this.secondRadius;
+
+ this.sinRotation = (float)Math.Sin(this.rotation);
+ this.cosRotation = (float)Math.Cos(this.rotation);
+ }
+
+ ///
+ public override void Dispose()
+ {
+ }
+
+ ///
+ protected override float PositionOnGradient(int xt, int yt)
+ {
+ float x0 = xt - this.center.X;
+ float y0 = yt - this.center.Y;
+
+ float x = (x0 * this.cosRotation) - (y0 * this.sinRotation);
+ float y = (x0 * this.sinRotation) + (y0 * this.cosRotation);
+
+ float xSquared = x * x;
+ float ySquared = y * y;
+
+ var inBoundaryChecker = (xSquared / this.referenceRadiusSquared)
+ + (ySquared / this.secondRadiusSquared);
+
+ return inBoundaryChecker;
+ }
+
+ private float AngleBetween(PointF junction, PointF a, PointF b)
+ {
+ var vA = a - junction;
+ var vB = b - junction;
+ return (float)(Math.Atan2(vB.Y, vB.X)
+ - Math.Atan2(vA.Y, vA.X));
+ }
+
+ private float DistanceBetween(
+ PointF p1,
+ PointF p2)
+ {
+ float dX = p1.X - p2.X;
+ float dXsquared = dX * dX;
+
+ float dY = p1.Y - p2.Y;
+ float dYsquared = dY * dY;
+ return (float)Math.Sqrt(dXsquared + dYsquared);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/GradientBrushBase{TPixel}.cs b/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/GradientBrushBase{TPixel}.cs
new file mode 100644
index 0000000000..d0a1ef1c24
--- /dev/null
+++ b/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/GradientBrushBase{TPixel}.cs
@@ -0,0 +1,174 @@
+using System;
+using System.Numerics;
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.PixelFormats.PixelBlenders;
+using SixLabors.Primitives;
+
+namespace SixLabors.ImageSharp.Processing.Drawing.Brushes.GradientBrushes
+{
+ ///
+ /// Base class for Gradient brushes
+ ///
+ /// The pixel format
+ public abstract class GradientBrushBase : IBrush
+ where TPixel : struct, IPixel
+ {
+ ///
+ /// Defines how the colors are repeated beyond the interval [0..1]
+ /// The gradient colors.
+ protected GradientBrushBase(
+ GradientRepetitionMode repetitionMode,
+ params ColorStop[] colorStops)
+ {
+ this.RepetitionMode = repetitionMode;
+ this.ColorStops = colorStops;
+ }
+
+ ///
+ /// Gets how the colors are repeated beyond the interval [0..1].
+ ///
+ protected GradientRepetitionMode RepetitionMode { get; }
+
+ ///
+ /// Gets the list of color stops for this gradient.
+ ///
+ protected ColorStop[] ColorStops { get; }
+
+ ///
+ public abstract BrushApplicator CreateApplicator(
+ ImageFrame source,
+ RectangleF region,
+ GraphicsOptions options);
+
+ ///
+ /// Base class for gradient brush applicators
+ ///
+ protected abstract class GradientBrushApplicatorBase : BrushApplicator
+ {
+ private readonly ColorStop[] colorStops;
+
+ private readonly GradientRepetitionMode repetitionMode;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The target.
+ /// The options.
+ /// An array of color stops sorted by their position.
+ /// Defines if and how the gradient should be repeated.
+ protected GradientBrushApplicatorBase(
+ ImageFrame target,
+ GraphicsOptions options,
+ ColorStop[] colorStops,
+ GradientRepetitionMode repetitionMode)
+ : base(target, options)
+ {
+ this.colorStops = colorStops; // TODO: requires colorStops to be sorted by position - should that be checked?
+ this.repetitionMode = repetitionMode;
+ }
+
+ ///
+ /// Base implementation of the indexer for gradients
+ /// (follows the facade pattern, using abstract methods)
+ ///
+ /// X coordinate of the Pixel.
+ /// Y coordinate of the Pixel.
+ internal override TPixel this[int x, int y]
+ {
+ get
+ {
+ float positionOnCompleteGradient = this.PositionOnGradient(x, y);
+
+ switch (this.repetitionMode)
+ {
+ case GradientRepetitionMode.None:
+ // do nothing. The following could be done, but is not necessary:
+ // onLocalGradient = Math.Min(0, Math.Max(1, onLocalGradient));
+ break;
+ case GradientRepetitionMode.Repeat:
+ positionOnCompleteGradient = positionOnCompleteGradient % 1;
+ break;
+ case GradientRepetitionMode.Reflect:
+ positionOnCompleteGradient = positionOnCompleteGradient % 2;
+ if (positionOnCompleteGradient > 1)
+ {
+ positionOnCompleteGradient = 2 - positionOnCompleteGradient;
+ }
+
+ break;
+ case GradientRepetitionMode.DontFill:
+ if (positionOnCompleteGradient > 1 || positionOnCompleteGradient < 0)
+ {
+ return NamedColors.Transparent;
+ }
+
+ break;
+ default:
+ throw new ArgumentOutOfRangeException();
+ }
+
+ var (from, to) = this.GetGradientSegment(positionOnCompleteGradient);
+
+ if (from.Color.Equals(to.Color))
+ {
+ return from.Color;
+ }
+ else
+ {
+ var fromAsVector = from.Color.ToVector4();
+ var toAsVector = to.Color.ToVector4();
+ float onLocalGradient = (positionOnCompleteGradient - from.Ratio) / to.Ratio;
+
+ // TODO: this should be changeble for different gradienting functions
+ Vector4 result = PorterDuffFunctions.Normal(
+ fromAsVector,
+ toAsVector,
+ onLocalGradient);
+
+ TPixel resultColor = default;
+ resultColor.PackFromVector4(result);
+ return resultColor;
+ }
+ }
+ }
+
+ ///
+ /// calculates the position on the gradient for a given pixel.
+ /// This method is abstract as it's content depends on the shape of the gradient.
+ ///
+ /// The x coordinate of the pixel
+ /// The y coordinate of the pixel
+ ///
+ /// The position the given pixel has on the gradient.
+ /// The position is not bound to the [0..1] interval.
+ /// Values outside of that interval may be treated differently,
+ /// e.g. for the enum.
+ ///
+ protected abstract float PositionOnGradient(int x, int y);
+
+ private (ColorStop from, ColorStop to) GetGradientSegment(
+ float positionOnCompleteGradient)
+ {
+ var localGradientFrom = this.colorStops[0];
+ ColorStop localGradientTo = default;
+
+ // TODO: ensure colorStops has at least 2 items (technically 1 would be okay, but that's no gradient)
+ foreach (var colorStop in this.colorStops)
+ {
+ localGradientTo = colorStop;
+
+ if (colorStop.Ratio > positionOnCompleteGradient)
+ {
+ // we're done here, so break it!
+ break;
+ }
+
+ localGradientFrom = localGradientTo;
+ }
+
+ return (localGradientFrom, localGradientTo);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/GradientRepetitionMode.cs b/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/GradientRepetitionMode.cs
new file mode 100644
index 0000000000..adbc26ed43
--- /dev/null
+++ b/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/GradientRepetitionMode.cs
@@ -0,0 +1,34 @@
+namespace SixLabors.ImageSharp.Processing.Drawing.Brushes.GradientBrushes
+{
+ ///
+ /// Modes to repeat a gradient.
+ ///
+ public enum GradientRepetitionMode
+ {
+ ///
+ /// don't repeat, keep the color of start and end beyond those points stable.
+ ///
+ None,
+
+ ///
+ /// Repeat the gradient.
+ /// If it's a black-white gradient, with Repeat it will be Black->{gray}->White|Black->{gray}->White|...
+ ///
+ Repeat,
+
+ ///
+ /// Reflect the gradient.
+ /// Similar to , but each other repetition uses inverse order of s.
+ /// Used on a Black-White gradient, Reflect leads to Black->{gray}->White->{gray}->White...
+ ///
+ Reflect,
+
+ ///
+ /// With DontFill a gradient does not touch any pixel beyond it's borders.
+ /// For the this is beyond the orthogonal through start and end,
+ /// TODO For the cref="PolygonalGradientBrush" it's outside the polygon,
+ /// For and it's beyond 1.0.
+ ///
+ DontFill
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/LinearGradientBrush{TPixel}.cs b/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/LinearGradientBrush{TPixel}.cs
new file mode 100644
index 0000000000..09f816dd97
--- /dev/null
+++ b/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/LinearGradientBrush{TPixel}.cs
@@ -0,0 +1,152 @@
+using System;
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.Primitives;
+
+namespace SixLabors.ImageSharp.Processing.Drawing.Brushes.GradientBrushes
+{
+ ///
+ /// Provides an implementation of a brush for painting linear gradients within areas.
+ /// Supported right now:
+ /// - a set of colors in relative distances to each other.
+ ///
+ /// The pixel format
+ public sealed class LinearGradientBrush : GradientBrushBase
+ where TPixel : struct, IPixel
+ {
+ private readonly Point p1;
+
+ private readonly Point p2;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Start point
+ /// End point
+ /// defines how colors are repeated.
+ ///
+ public LinearGradientBrush(
+ Point p1,
+ Point p2,
+ GradientRepetitionMode repetitionMode,
+ params ColorStop[] colorStops)
+ : base(repetitionMode, colorStops)
+ {
+ this.p1 = p1;
+ this.p2 = p2;
+ }
+
+ ///
+ public override BrushApplicator CreateApplicator(ImageFrame source, RectangleF region, GraphicsOptions options)
+ => new LinearGradientBrushApplicator(source, this.p1, this.p2, this.ColorStops, this.RepetitionMode, options);
+
+ ///
+ /// The linear gradient brush applicator.
+ ///
+ private sealed class LinearGradientBrushApplicator : GradientBrushApplicatorBase
+ {
+ private readonly Point start;
+
+ private readonly Point end;
+
+ ///
+ /// the vector along the gradient, x component
+ ///
+ private readonly float alongX;
+
+ ///
+ /// the vector along the gradient, y component
+ ///
+ private readonly float alongY;
+
+ ///
+ /// the vector perpendicular to the gradient, y component
+ ///
+ private readonly float acrossY;
+
+ ///
+ /// the vector perpendicular to the gradient, x component
+ ///
+ private readonly float acrossX;
+
+ ///
+ /// the result of ^2 + ^2
+ ///
+ private readonly float alongsSquared;
+
+ ///
+ /// the length of the defined gradient (between source and end)
+ ///
+ private readonly float length;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The source
+ /// start point of the gradient
+ /// end point of the gradient
+ /// tuple list of colors and their respective position between 0 and 1 on the line
+ /// defines how the gradient colors are repeated.
+ /// the graphics options
+ public LinearGradientBrushApplicator(
+ ImageFrame source,
+ Point start,
+ Point end,
+ ColorStop[] colorStops,
+ GradientRepetitionMode repetitionMode,
+ GraphicsOptions options)
+ : base(source, options, colorStops, repetitionMode)
+ {
+ this.start = start;
+ this.end = end;
+
+ // the along vector:
+ this.alongX = this.end.X - this.start.X;
+ this.alongY = this.end.Y - this.start.Y;
+
+ // the cross vector:
+ this.acrossX = this.alongY;
+ this.acrossY = -this.alongX;
+
+ // some helpers:
+ this.alongsSquared = (this.alongX * this.alongX) + (this.alongY * this.alongY);
+ this.length = (float)Math.Sqrt(this.alongsSquared);
+ }
+
+ protected override float PositionOnGradient(int x, int y)
+ {
+ if (this.acrossX == 0)
+ {
+ return (x - this.start.X) / (float)(this.end.X - this.start.X);
+ }
+ else if (this.acrossY == 0)
+ {
+ return (y - this.start.Y) / (float)(this.end.Y - this.start.Y);
+ }
+ else
+ {
+ float deltaX = x - this.start.X;
+ float deltaY = y - this.start.Y;
+ float k = ((this.alongY * deltaX) - (this.alongX * deltaY)) / this.alongsSquared;
+
+ // point on the line:
+ float x4 = x - (k * this.alongY);
+ float y4 = y + (k * this.alongX);
+
+ // get distance from (x4,y4) to start
+ float distance = (float)Math.Sqrt(
+ Math.Pow(x4 - this.start.X, 2)
+ + Math.Pow(y4 - this.start.Y, 2));
+
+ // get and return ratio
+ float ratio = distance / this.length;
+ return ratio;
+ }
+ }
+
+ public override void Dispose()
+ {
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/RadialGradientBrush{TPixel}.cs b/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/RadialGradientBrush{TPixel}.cs
new file mode 100644
index 0000000000..5c0d8051ca
--- /dev/null
+++ b/src/ImageSharp.Drawing/Processing/Drawing/Brushes/GradientBrushes/RadialGradientBrush{TPixel}.cs
@@ -0,0 +1,102 @@
+using System;
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.Primitives;
+
+namespace SixLabors.ImageSharp.Processing.Drawing.Brushes.GradientBrushes
+{
+ ///
+ /// A Circular Gradient Brush, defined by center point and radius.
+ ///
+ /// The pixel format.
+ public sealed class RadialGradientBrush : GradientBrushBase
+ where TPixel : struct, IPixel
+ {
+ private readonly Point center;
+
+ private readonly float radius;
+
+ ///
+ /// The center of the circular gradient and 0 for the color stops.
+ /// The radius of the circular gradient and 1 for the color stops.
+ /// Defines how the colors in the gradient are repeated.
+ /// the color stops as defined in base class.
+ public RadialGradientBrush(
+ Point center,
+ float radius,
+ GradientRepetitionMode repetitionMode,
+ params ColorStop[] colorStops)
+ : base(repetitionMode, colorStops)
+ {
+ this.center = center;
+ this.radius = radius;
+ }
+
+ ///
+ public override BrushApplicator CreateApplicator(
+ ImageFrame source,
+ RectangleF region,
+ GraphicsOptions options) =>
+ new RadialGradientBrushApplicator(
+ source,
+ options,
+ this.center,
+ this.radius,
+ this.ColorStops,
+ this.RepetitionMode);
+
+ ///
+ private sealed class RadialGradientBrushApplicator : GradientBrushApplicatorBase
+ {
+ private readonly Point center;
+
+ private readonly float radius;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The target image
+ /// The options.
+ /// Center point of the gradient.
+ /// Radius of the gradient.
+ /// Definition of colors.
+ /// How the colors are repeated beyond the first gradient.
+ public RadialGradientBrushApplicator(
+ ImageFrame target,
+ GraphicsOptions options,
+ Point center,
+ float radius,
+ ColorStop[] colorStops,
+ GradientRepetitionMode repetitionMode)
+ : base(target, options, colorStops, repetitionMode)
+ {
+ this.center = center;
+ this.radius = radius;
+ }
+
+ ///
+ public override void Dispose()
+ {
+ }
+
+ ///
+ /// As this is a circular gradient, the position on the gradient is based on
+ /// the distance of the point to the center.
+ ///
+ /// The X coordinate of the target pixel.
+ /// The Y coordinate of the target pixel.
+ /// the position on the color gradient.
+ protected override float PositionOnGradient(int x, int y)
+ {
+ float distance = (float)Math.Sqrt(Math.Pow(this.center.X - x, 2) + Math.Pow(this.center.Y - y, 2));
+ return distance / this.radius;
+ }
+
+ internal override void Apply(Span scanline, int x, int y)
+ {
+ // TODO: each row is symmetric across center, so we can calculate half of it and mirror it to improve performance.
+ base.Apply(scanline, x, y);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Processing/Drawing/FillPathExtensions.cs b/src/ImageSharp.Drawing/Processing/Drawing/FillPathExtensions.cs
index 36eef8d638..4273fd8bee 100644
--- a/src/ImageSharp.Drawing/Processing/Drawing/FillPathExtensions.cs
+++ b/src/ImageSharp.Drawing/Processing/Drawing/FillPathExtensions.cs
@@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.Processing.Drawing
public static class FillPathExtensions
{
///
- /// Flood fills the image in the shape of the provided polygon with the specified brush..
+ /// Flood fills the image in the shape of the provided polygon with the specified brush.
///
/// The type of the color.
/// The image this method extends.
diff --git a/src/ImageSharp/Advanced/IConfigurable.cs b/src/ImageSharp/Advanced/IConfigurable.cs
index fd97ae921a..38fc83ae1d 100644
--- a/src/ImageSharp/Advanced/IConfigurable.cs
+++ b/src/ImageSharp/Advanced/IConfigurable.cs
@@ -4,7 +4,7 @@
namespace SixLabors.ImageSharp.Advanced
{
///
- /// Encapsulates the properties for configuration
+ /// Encapsulates the properties for configuration.
///
internal interface IConfigurable
{
diff --git a/src/ImageSharp/Common/Extensions/ByteExtensions.cs b/src/ImageSharp/Common/Extensions/ByteExtensions.cs
deleted file mode 100644
index b5b868deaa..0000000000
--- a/src/ImageSharp/Common/Extensions/ByteExtensions.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using System;
-using System.Runtime.CompilerServices;
-using SixLabors.ImageSharp.PixelFormats;
-
-namespace SixLabors.ImageSharp
-{
- ///
- /// Extension methods for the struct buffers.
- ///
- internal static class ByteExtensions
- {
- ///
- /// Returns a reference to the given position of the array unsafe casted to .
- ///
- /// The byte array.
- /// The offset in bytes.
- /// The reference at the given offset.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ref Rgb24 GetRgb24(this byte[] bytes, int offset)
- {
- DebugGuard.MustBeLessThan(offset + 2, bytes.Length, nameof(offset));
-
- return ref Unsafe.As(ref bytes[offset]);
- }
-
- ///
- /// Returns a reference to the given position of the span unsafe casted to .
- ///
- /// The byte span.
- /// The offset in bytes.
- /// The reference at the given offset.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ref Rgb24 GetRgb24(this Span bytes, int offset)
- {
- DebugGuard.MustBeLessThan(offset + 2, bytes.Length, nameof(offset));
-
- return ref Unsafe.As(ref bytes[offset]);
- }
-
- ///
- /// Returns a reference to the given position of the buffer pointed by `baseRef` unsafe casted to .
- ///
- /// A reference to the beginning of the buffer
- /// The offset in bytes.
- /// The reference at the given offset.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static ref Rgb24 GetRgb24(ref byte baseRef, int offset)
- {
- return ref Unsafe.As(ref Unsafe.Add(ref baseRef, offset));
- }
- }
-}
\ No newline at end of file
diff --git a/src/ImageSharp/Common/Helpers/DebugGuard.cs b/src/ImageSharp/Common/Helpers/DebugGuard.cs
index e64075db7a..6dcd0fd270 100644
--- a/src/ImageSharp/Common/Helpers/DebugGuard.cs
+++ b/src/ImageSharp/Common/Helpers/DebugGuard.cs
@@ -189,7 +189,7 @@ namespace SixLabors.ImageSharp
/// The 'other' span to compare 'target' to.
/// The name of the parameter that is to be checked.
///
- /// is true
+ /// has a different size than
///
[Conditional("DEBUG")]
public static void MustBeSameSized(Span target, Span other, string parameterName)
@@ -209,7 +209,7 @@ namespace SixLabors.ImageSharp
/// The 'minSpan' span to compare 'target' to.
/// The name of the parameter that is to be checked.
///
- /// is true
+ /// has less items than
///
[Conditional("DEBUG")]
public static void MustBeSizedAtLeast(Span target, Span minSpan, string parameterName)
diff --git a/src/ImageSharp/Common/Helpers/Guard.cs b/src/ImageSharp/Common/Helpers/Guard.cs
index 9f0a46f80c..011d7fdaac 100644
--- a/src/ImageSharp/Common/Helpers/Guard.cs
+++ b/src/ImageSharp/Common/Helpers/Guard.cs
@@ -4,7 +4,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
-using System.Linq;
namespace SixLabors.ImageSharp
{
@@ -15,78 +14,62 @@ namespace SixLabors.ImageSharp
internal static class Guard
{
///
- /// Verifies, that the method parameter with specified object value is not null
- /// and throws an exception if it is found to be so.
+ /// Ensures that the value is not null.
///
- /// The target object, which cannot be null.
+ /// The target object, which cannot be null.
/// The name of the parameter that is to be checked.
- /// The error message, if any to add to the exception.
- /// is null
- public static void NotNull(object target, string parameterName, string message = "")
+ /// is null
+ public static void NotNull(object value, string parameterName)
{
- if (target == null)
+ if (value == null)
{
- if (!string.IsNullOrWhiteSpace(message))
- {
- throw new ArgumentNullException(parameterName, message);
- }
-
throw new ArgumentNullException(parameterName);
}
}
///
- /// Verifies, that the string method parameter with specified object value and message
- /// is not null, not empty and does not contain only blanks and throws an exception
- /// if the object is null.
+ /// Ensures that the target value is not null, empty, or whitespace.
///
- /// The target string, which should be checked against being null or empty.
+ /// The target string, which should be checked against being null or empty.
/// Name of the parameter.
- /// The error message, if any to add to the exception.
- /// is null.
- /// is empty or contains only blanks.
- public static void NotNullOrEmpty(string target, string parameterName, string message = "")
+ /// is null.
+ /// is empty or contains only blanks.
+ public static void NotNullOrWhiteSpace(string value, string parameterName)
{
- NotNull(target, parameterName, message);
-
- if (string.IsNullOrWhiteSpace(target))
+ if (value == null)
{
- if (!string.IsNullOrWhiteSpace(message))
- {
- throw new ArgumentException(message, parameterName);
- }
+ throw new ArgumentNullException(parameterName);
+ }
- throw new ArgumentException("Value cannot be null or empty and cannot contain only blanks.", parameterName);
+ if (string.IsNullOrWhiteSpace(value))
+ {
+ throw new ArgumentException("Must not be empty or whitespace.", parameterName);
}
}
///
- /// Verifies, that the enumeration is not null and not empty.
+ /// Ensures that the enumeration is not null or empty.
///
- /// The type of objects in the
- /// The target enumeration, which should be checked against being null or empty.
+ /// The type of objects in the
+ /// The target enumeration, which should be checked against being null or empty.
/// Name of the parameter.
- /// The error message, if any to add to the exception.
- /// is null.
- /// is empty.
- public static void NotNullOrEmpty(IEnumerable target, string parameterName, string message = "")
+ /// is null.
+ /// is empty.
+ public static void NotNullOrEmpty(ICollection value, string parameterName)
{
- NotNull(target, parameterName, message);
-
- if (!target.Any())
+ if (value == null)
{
- if (!string.IsNullOrWhiteSpace(message))
- {
- throw new ArgumentException(message, parameterName);
- }
+ throw new ArgumentNullException(parameterName);
+ }
- throw new ArgumentException("Value cannot be empty.", parameterName);
+ if (value.Count == 0)
+ {
+ throw new ArgumentException("Must not be empty.", parameterName);
}
}
///
- /// Verifies that the specified value is less than a maximum value
- /// and throws an exception if it is not.
+ /// Ensures that the specified value is less than a maximum value.
///
/// The target value, which should be validated.
/// The maximum value.
@@ -191,15 +174,9 @@ namespace SixLabors.ImageSharp
/// Verifies, that the method parameter with specified target value is true
/// and throws an exception if it is found to be so.
///
- ///
- /// The target value, which cannot be false.
- ///
- ///
- /// The name of the parameter that is to be checked.
- ///
- ///
- /// The error message, if any to add to the exception.
- ///
+ /// The target value, which cannot be false.
+ /// The name of the parameter that is to be checked.
+ /// The error message, if any to add to the exception.
///
/// is false
///
@@ -230,14 +207,14 @@ namespace SixLabors.ImageSharp
}
///
- /// Verifies, that the `source` span has the length of 'minSpan', or longer.
+ /// Verifies, that the `source` span has the length of 'minLength', or longer.
///
/// The element type of the spans
/// The source span.
/// The minimum length.
/// The name of the parameter that is to be checked.
///
- /// is true
+ /// has less than items
///
public static void MustBeSizedAtLeast(ReadOnlySpan source, int minLength, string parameterName)
{
@@ -248,14 +225,14 @@ namespace SixLabors.ImageSharp
}
///
- /// Verifies, that the `source` span has the length of 'minSpan', or longer.
+ /// Verifies, that the `source` span has the length of 'minLength', or longer.
///
/// The element type of the spans
/// The target span.
/// The minimum length.
/// The name of the parameter that is to be checked.
///
- /// is true
+ /// has less than items
///
public static void MustBeSizedAtLeast(Span source, int minLength, string parameterName)
{
diff --git a/src/ImageSharp/Configuration.cs b/src/ImageSharp/Configuration.cs
index 06c588af33..eb08bc579c 100644
--- a/src/ImageSharp/Configuration.cs
+++ b/src/ImageSharp/Configuration.cs
@@ -18,7 +18,7 @@ using SixLabors.ImageSharp.Processing;
namespace SixLabors.ImageSharp
{
///
- /// Provides initialization code which allows extending the library.
+ /// Provides configuration code which allows altering default behaviour or extending the library.
///
public sealed class Configuration
{
diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
index 1900d0df05..4fbd4baf51 100644
--- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
+++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
@@ -39,11 +39,6 @@ namespace SixLabors.ImageSharp.Formats.Gif
///
private IManagedByteBuffer globalColorTable;
- ///
- /// The global color table length
- ///
- private int globalColorTableLength;
-
///
/// The area to restore.
///
@@ -333,8 +328,8 @@ namespace SixLabors.ImageSharp.Formats.Gif
indices = this.configuration.MemoryManager.AllocateManagedByteBuffer(imageDescriptor.Width * imageDescriptor.Height, true);
this.ReadFrameIndices(imageDescriptor, indices.Span);
- IManagedByteBuffer colorTable = localColorTable ?? this.globalColorTable;
- this.ReadFrameColors(ref image, ref previousFrame, indices.Span, colorTable.Span, imageDescriptor);
+ ReadOnlySpan colorTable = MemoryMarshal.Cast((localColorTable ?? this.globalColorTable).Span);
+ this.ReadFrameColors(ref image, ref previousFrame, indices.Span, colorTable, imageDescriptor);
// Skip any remaining blocks
this.Skip(0);
@@ -370,7 +365,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// The indexed pixels.
/// The color table containing the available colors.
/// The
- private void ReadFrameColors(ref Image image, ref ImageFrame previousFrame, Span indices, Span colorTable, in GifImageDescriptor descriptor)
+ private void ReadFrameColors(ref Image image, ref ImageFrame previousFrame, Span indices, ReadOnlySpan colorTable, in GifImageDescriptor descriptor)
where TPixel : struct, IPixel
{
ref byte indicesRef = ref MemoryMarshal.GetReference(indices);
@@ -458,11 +453,8 @@ namespace SixLabors.ImageSharp.Formats.Gif
if (this.graphicsControlExtension.TransparencyFlag == false ||
this.graphicsControlExtension.TransparencyIndex != index)
{
- int indexOffset = index * 3;
-
ref TPixel pixel = ref Unsafe.Add(ref rowRef, x);
- rgba.Rgb = colorTable.GetRgb24(indexOffset);
-
+ rgba.Rgb = colorTable[index];
pixel.PackFromRgba32(rgba);
}
@@ -534,12 +526,12 @@ namespace SixLabors.ImageSharp.Formats.Gif
if (this.logicalScreenDescriptor.GlobalColorTableFlag)
{
- this.globalColorTableLength = this.logicalScreenDescriptor.GlobalColorTableSize * 3;
+ int globalColorTableLength = this.logicalScreenDescriptor.GlobalColorTableSize * 3;
- this.globalColorTable = this.MemoryManager.AllocateManagedByteBuffer(this.globalColorTableLength, true);
+ this.globalColorTable = this.MemoryManager.AllocateManagedByteBuffer(globalColorTableLength, true);
- // Read the global color table from the stream
- stream.Read(this.globalColorTable.Array, 0, this.globalColorTableLength);
+ // Read the global color table data from the stream
+ stream.Read(this.globalColorTable.Array, 0, globalColorTableLength);
}
}
}
diff --git a/src/ImageSharp/Formats/ImageFormatManager.cs b/src/ImageSharp/Formats/ImageFormatManager.cs
index 67ba111474..4e33a0445c 100644
--- a/src/ImageSharp/Formats/ImageFormatManager.cs
+++ b/src/ImageSharp/Formats/ImageFormatManager.cs
@@ -85,6 +85,13 @@ namespace SixLabors.ImageSharp.Formats
/// The if found otherwise null
public IImageFormat FindFormatByFileExtension(string extension)
{
+ Guard.NotNullOrWhiteSpace(extension, nameof(extension));
+
+ if (extension[0] == '.')
+ {
+ extension = extension.Substring(1);
+ }
+
return this.imageFormats.FirstOrDefault(x => x.FileExtensions.Contains(extension, StringComparer.OrdinalIgnoreCase));
}
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Block8x8.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs
similarity index 99%
rename from src/ImageSharp/Formats/Jpeg/Common/Block8x8.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs
index efaa0b4a48..cb73ee9478 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Block8x8.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8.cs
@@ -7,7 +7,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components
{
///
/// Represents a Jpeg block with coefficiens.
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.CopyTo.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs
similarity index 99%
rename from src/ImageSharp/Formats/Jpeg/Common/Block8x8F.CopyTo.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs
index d8963a8b60..43cc3e9dba 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.CopyTo.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.CopyTo.cs
@@ -3,10 +3,11 @@
using System.Numerics;
using System.Runtime.CompilerServices;
+
using SixLabors.ImageSharp.Memory;
// ReSharper disable InconsistentNaming
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components
{
internal partial struct Block8x8F
{
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.Generated.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs
similarity index 99%
rename from src/ImageSharp/Formats/Jpeg/Common/Block8x8F.Generated.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs
index 93e9e03885..e83896f587 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.Generated.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.cs
@@ -5,7 +5,7 @@ using System.Numerics;
using System.Runtime.CompilerServices;
//
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components
{
internal partial struct Block8x8F
{
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.Generated.tt b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt
similarity index 98%
rename from src/ImageSharp/Formats/Jpeg/Common/Block8x8F.Generated.tt
rename to src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt
index dc0996b65d..82d82ef0c2 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.Generated.tt
+++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.Generated.tt
@@ -18,7 +18,7 @@ using System.Runtime.CompilerServices;
<#
char[] coordz = {'X', 'Y', 'Z', 'W'};
#>
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components
{
internal partial struct Block8x8F
{
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs
similarity index 98%
rename from src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs
index 53297ab550..38974cc76b 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Block8x8F.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs
@@ -9,7 +9,7 @@ using System.Runtime.InteropServices;
using System.Text;
// ReSharper disable InconsistentNaming
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components
{
///
/// Represents a Jpeg block with coefficients.
@@ -100,7 +100,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common
{
float val = result[i];
val /= value;
- result[i] = (float)val;
+ result[i] = val;
}
return result;
@@ -113,7 +113,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common
{
float val = result[i];
val += value;
- result[i] = (float)val;
+ result[i] = val;
}
return result;
@@ -126,7 +126,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common
{
float val = result[i];
val -= value;
- result[i] = (float)val;
+ result[i] = val;
}
return result;
@@ -153,7 +153,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common
public void Clear()
{
// The cheapest way to do this in C#:
- this = default(Block8x8F);
+ this = default;
}
///
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/AdobeMarker.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/AdobeMarker.cs
similarity index 97%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/AdobeMarker.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/AdobeMarker.cs
index 40059c5a0f..af0938d302 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/AdobeMarker.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/AdobeMarker.cs
@@ -4,7 +4,7 @@
using System;
// ReSharper disable InconsistentNaming
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{
///
/// Provides information about the Adobe marker segment.
@@ -78,7 +78,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
return true;
}
- marker = default(AdobeMarker);
+ marker = default;
return false;
}
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromCmyk.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmyk.cs
similarity index 86%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromCmyk.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmyk.cs
index 86d5957846..bac77f905e 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromCmyk.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmyk.cs
@@ -4,18 +4,18 @@
using System;
using System.Numerics;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
internal abstract partial class JpegColorConverter
{
- internal class FromCmyk : ColorConverters.JpegColorConverter
+ internal class FromCmyk : JpegColorConverter
{
public FromCmyk()
: base(JpegColorSpace.Cmyk)
{
}
- public override void ConvertToRGBA(ComponentValues values, Span result)
+ public override void ConvertToRgba(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/Common/Decoder/ColorConverters/JpegColorConverter.FromGrayScale.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScale.cs
similarity index 81%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromGrayScale.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScale.cs
index 4769bef1d7..b07e57e170 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromGrayScale.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromGrayScale.cs
@@ -4,18 +4,18 @@
using System;
using System.Numerics;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
internal abstract partial class JpegColorConverter
{
- internal class FromGrayscale : ColorConverters.JpegColorConverter
+ internal class FromGrayscale : JpegColorConverter
{
public FromGrayscale()
: base(JpegColorSpace.Grayscale)
{
}
- public override void ConvertToRGBA(ComponentValues values, Span result)
+ public override void ConvertToRgba(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/Common/Decoder/ColorConverters/JpegColorConverter.FromRgb.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgb.cs
similarity index 84%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromRgb.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgb.cs
index 7f01eedadb..6b7e77e148 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromRgb.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromRgb.cs
@@ -4,18 +4,18 @@
using System;
using System.Numerics;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
internal abstract partial class JpegColorConverter
{
- internal class FromRgb : ColorConverters.JpegColorConverter
+ internal class FromRgb : JpegColorConverter
{
public FromRgb()
: base(JpegColorSpace.RGB)
{
}
- public override void ConvertToRGBA(ComponentValues values, Span result)
+ public override void ConvertToRgba(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/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrBasic.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrBasic.cs
similarity index 87%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrBasic.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrBasic.cs
index ddd2197d4a..35700ea312 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrBasic.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrBasic.cs
@@ -4,18 +4,18 @@
using System;
using System.Numerics;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
internal abstract partial class JpegColorConverter
{
- internal class FromYCbCrBasic : ColorConverters.JpegColorConverter
+ internal class FromYCbCrBasic : JpegColorConverter
{
public FromYCbCrBasic()
: base(JpegColorSpace.YCbCr)
{
}
- public override void ConvertToRGBA(ComponentValues values, Span result)
+ public override void ConvertToRgba(ComponentValues values, Span result)
{
ConvertCore(values, result);
}
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs
similarity index 95%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs
index 2f214f88a9..fd2f17da9e 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimd.cs
@@ -5,20 +5,21 @@ using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+
using SixLabors.ImageSharp.Common.Tuples;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
internal abstract partial class JpegColorConverter
{
- internal class FromYCbCrSimd : ColorConverters.JpegColorConverter
+ internal class FromYCbCrSimd : JpegColorConverter
{
public FromYCbCrSimd()
: base(JpegColorSpace.YCbCr)
{
}
- public override void ConvertToRGBA(ComponentValues values, Span result)
+ public override void ConvertToRgba(ComponentValues values, Span result)
{
int remainder = result.Length % 8;
int simdCount = result.Length - remainder;
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs
similarity index 95%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs
index f8a4514221..c43713bf4c 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYCbCrSimdAvx2.cs
@@ -5,14 +5,15 @@ using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+
using SixLabors.ImageSharp.Common.Tuples;
// ReSharper disable ImpureMethodCallOnReadonlyValueField
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
internal abstract partial class JpegColorConverter
{
- internal class FromYCbCrSimdAvx2 : ColorConverters.JpegColorConverter
+ internal class FromYCbCrSimdAvx2 : JpegColorConverter
{
public FromYCbCrSimdAvx2()
: base(JpegColorSpace.YCbCr)
@@ -21,7 +22,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters
public static bool IsAvailable => Vector.IsHardwareAccelerated && SimdUtils.IsAvx2CompatibleArchitecture;
- public override void ConvertToRGBA(ComponentValues values, Span result)
+ public override void ConvertToRgba(ComponentValues values, Span result)
{
int remainder = result.Length % 8;
int simdCount = result.Length - remainder;
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYccK.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccK.cs
similarity index 91%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYccK.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccK.cs
index 6d8e6ef5a9..83feefa94a 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.FromYccK.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromYccK.cs
@@ -4,7 +4,7 @@
using System;
using System.Numerics;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
internal abstract partial class JpegColorConverter
{
@@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters
{
}
- public override void ConvertToRGBA(ComponentValues values, Span result)
+ public override void ConvertToRgba(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/Common/Decoder/ColorConverters/JpegColorConverter.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs
similarity index 95%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs
index 4391be5484..080bf83338 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ColorConverters/JpegColorConverter.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.cs
@@ -5,10 +5,11 @@ using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
+
using SixLabors.ImageSharp.Common.Tuples;
using SixLabors.ImageSharp.Memory;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
///
/// Encapsulates the conversion of Jpeg channels to RGBA values packed in buffer.
@@ -55,13 +56,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.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(ComponentValues values, Span result);
///
/// Returns the for the YCbCr colorspace that matches the current CPU architecture.
///
private static JpegColorConverter GetYCbCrConverter() =>
- FromYCbCrSimdAvx2.IsAvailable ? (JpegColorConverter)new FromYCbCrSimdAvx2() : new FromYCbCrSimd();
+ JpegColorConverter.FromYCbCrSimdAvx2.IsAvailable ? (JpegColorConverter)new JpegColorConverter.FromYCbCrSimdAvx2() : new JpegColorConverter.FromYCbCrSimd();
///
/// A stack-only struct to reference the input buffers using -s.
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/IJpegComponent.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/IJpegComponent.cs
similarity index 92%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/IJpegComponent.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/IJpegComponent.cs
index de9f75dc1f..efa746819d 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/IJpegComponent.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/IJpegComponent.cs
@@ -1,7 +1,10 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
using SixLabors.ImageSharp.Memory;
using SixLabors.Primitives;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{
///
/// Common interface to represent raw Jpeg components.
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/IRawJpegData.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/IRawJpegData.cs
similarity index 81%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/IRawJpegData.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/IRawJpegData.cs
index 3873656a4e..dace78b337 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/IRawJpegData.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/IRawJpegData.cs
@@ -1,13 +1,16 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
using System;
using System.Collections.Generic;
using SixLabors.Primitives;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{
///
///
- /// Represents decompressed, unprocessed jpeg data with spectral space -s.
+ /// Represents decompressed, unprocessed jpeg data with spectral space -s.
///
internal interface IRawJpegData : IDisposable
{
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JFifMarker.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs
similarity index 98%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/JFifMarker.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs
index afe4794a23..591af63442 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JFifMarker.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JFifMarker.cs
@@ -3,7 +3,7 @@
using System;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{
///
/// Provides information about the JFIF marker segment
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegBlockPostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockPostProcessor.cs
similarity index 97%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegBlockPostProcessor.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockPostProcessor.cs
index 2f59bcb822..b586d520a6 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegBlockPostProcessor.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegBlockPostProcessor.cs
@@ -2,10 +2,11 @@
// Licensed under the Apache License, Version 2.0.
using System.Runtime.InteropServices;
+
using SixLabors.ImageSharp.Memory;
using SixLabors.Primitives;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{
///
/// Encapsulates the implementation of processing "raw" -s into Jpeg image channels.
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorSpace.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegColorSpace.cs
similarity index 59%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorSpace.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegColorSpace.cs
index abc93727e1..2861a2c2e9 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorSpace.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegColorSpace.cs
@@ -1,4 +1,7 @@
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{
///
/// Identifies the colorspace of a Jpeg image
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegComponentPostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentPostProcessor.cs
similarity index 95%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegComponentPostProcessor.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentPostProcessor.cs
index 1be637b6df..fe18f8438c 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegComponentPostProcessor.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegComponentPostProcessor.cs
@@ -1,8 +1,12 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
using System;
+
using SixLabors.ImageSharp.Memory;
using SixLabors.Primitives;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{
///
/// Encapsulates postprocessing data for one component for .
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs
similarity index 89%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs
index 483242c768..38340b2380 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/JpegImagePostProcessor.cs
@@ -1,12 +1,18 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
using System;
using System.Linq;
using System.Numerics;
+
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Primitives;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
+using JpegColorConverter = SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters.JpegColorConverter;
+
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{
///
/// Encapsulates the execution od post-processing algorithms to be applied on a to produce a valid :
@@ -36,9 +42,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
private readonly IBuffer rgbaBuffer;
///
- /// The corresponding to the current determined by .
+ /// The corresponding to the current determined by .
///
- private ColorConverters.JpegColorConverter colorConverter;
+ private readonly JpegColorConverter colorConverter;
///
/// Initializes a new instance of the class.
@@ -54,7 +60,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
this.ComponentProcessors = rawJpeg.Components.Select(c => new JpegComponentPostProcessor(memoryManager, this, c)).ToArray();
this.rgbaBuffer = memoryManager.Allocate(rawJpeg.ImageSizeInPixels.Width);
- this.colorConverter = ColorConverters.JpegColorConverter.GetConverter(rawJpeg.ColorSpace);
+ this.colorConverter = JpegColorConverter.GetConverter(rawJpeg.ColorSpace);
}
///
@@ -148,8 +154,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
{
int y = yy - this.PixelRowCounter;
- var values = new ColorConverters.JpegColorConverter.ComponentValues(buffers, y);
- this.colorConverter.ConvertToRGBA(values, this.rgbaBuffer.Span);
+ var values = new JpegColorConverter.ComponentValues(buffers, y);
+ this.colorConverter.ConvertToRgba(values, this.rgbaBuffer.Span);
Span destRow = destination.GetPixelRowSpan(yy);
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ProfileResolver.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs
similarity index 96%
rename from src/ImageSharp/Formats/Jpeg/Common/Decoder/ProfileResolver.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs
index 2030ad71b1..e5de4441c2 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/ProfileResolver.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/ProfileResolver.cs
@@ -4,7 +4,7 @@
using System;
using System.Text;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder
{
///
/// Provides methods for identifying metadata and color profiles within jpeg images.
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/BlockQuad.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/BlockQuad.cs
similarity index 66%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/Components/BlockQuad.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Encoder/BlockQuad.cs
index 6b16ea824e..7a312138d0 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/BlockQuad.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/BlockQuad.cs
@@ -1,18 +1,16 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-using Block8x8F = SixLabors.ImageSharp.Formats.Jpeg.Common.Block8x8F;
-
-namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
{
///
- /// Poor man's stackalloc: Contains a value-type buffer sized for 4 instances.
+ /// Poor man's stackalloc: Contains a value-type buffer sized for 4 instances.
/// Useful for decoder/encoder operations allocating a block for each Jpeg component.
///
internal unsafe struct BlockQuad
{
///
- /// The value-type buffer sized for 4 instances.
+ /// The value-type buffer sized for 4 instances.
///
public fixed float Data[4 * Block8x8F.Size];
}
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffIndex.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffIndex.cs
similarity index 91%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffIndex.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffIndex.cs
index 23fcda2964..633d7ea80f 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffIndex.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffIndex.cs
@@ -1,7 +1,7 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Encoder
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
{
///
/// Enumerates the Huffman tables
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffmanLut.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanLut.cs
similarity index 96%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffmanLut.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanLut.cs
index 7756a7e3ba..a31c4bf2f4 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffmanLut.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanLut.cs
@@ -1,7 +1,7 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Encoder
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
{
///
/// A compiled look-up table representation of a huffmanSpec.
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffmanSpec.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs
similarity index 98%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffmanSpec.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs
index 1c8228aaa2..2e2ee9575c 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/HuffmanSpec.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/HuffmanSpec.cs
@@ -1,7 +1,7 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Encoder
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
{
///
/// The Huffman encoding specifications.
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/QuantIndex.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/QuantIndex.cs
similarity index 86%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/QuantIndex.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Encoder/QuantIndex.cs
index 459d29f91f..d0933af0c4 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/QuantIndex.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/QuantIndex.cs
@@ -1,7 +1,7 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Encoder
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
{
///
/// Enumerates the quantization tables
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/RgbToYCbCrTables.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbToYCbCrTables.cs
similarity index 93%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/RgbToYCbCrTables.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbToYCbCrTables.cs
index 923fe244eb..a0cc9ee8e5 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/RgbToYCbCrTables.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/RgbToYCbCrTables.cs
@@ -3,9 +3,7 @@
using System.Runtime.CompilerServices;
-using SixLabors.ImageSharp.Memory;
-
-namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Encoder
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
{
///
/// Provides 8-bit lookup tables for converting from Rgb to YCbCr colorspace.
@@ -68,7 +66,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Encoder
/// The intialized
public static RgbToYCbCrTables Create()
{
- RgbToYCbCrTables tables = default(RgbToYCbCrTables);
+ RgbToYCbCrTables tables = default;
for (int i = 0; i <= 255; i++)
{
@@ -123,11 +121,5 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Encoder
{
return (int)((x * (1L << ScaleBits)) + 0.5F);
}
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static int RightShift(int x)
- {
- return x >> ScaleBits;
- }
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/YCbCrForwardConverter{TPixel}.cs b/src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrForwardConverter{TPixel}.cs
similarity index 95%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/YCbCrForwardConverter{TPixel}.cs
rename to src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrForwardConverter{TPixel}.cs
index 3c95a85080..311ffed24b 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/YCbCrForwardConverter{TPixel}.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Encoder/YCbCrForwardConverter{TPixel}.cs
@@ -1,10 +1,10 @@
using System;
using System.Runtime.CompilerServices;
+
using SixLabors.ImageSharp.Advanced;
-using SixLabors.ImageSharp.Formats.Jpeg.Common;
using SixLabors.ImageSharp.PixelFormats;
-namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Encoder
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder
{
///
/// On-stack worker struct to efficiently encapsulate the TPixel -> Rgb24 -> YCbCr conversion chain of 8x8 pixel blocks.
diff --git a/src/ImageSharp/Formats/Jpeg/Common/FastFloatingPointDCT.cs b/src/ImageSharp/Formats/Jpeg/Components/FastFloatingPointDCT.cs
similarity index 99%
rename from src/ImageSharp/Formats/Jpeg/Common/FastFloatingPointDCT.cs
rename to src/ImageSharp/Formats/Jpeg/Components/FastFloatingPointDCT.cs
index 3ee6e72c5d..dcdc7e9ba7 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/FastFloatingPointDCT.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/FastFloatingPointDCT.cs
@@ -5,7 +5,7 @@ using System.Numerics;
using System.Runtime.CompilerServices;
// ReSharper disable InconsistentNaming
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components
{
///
/// Contains inaccurate, but fast forward and inverse DCT implementations.
diff --git a/src/ImageSharp/Formats/Jpeg/Common/GenericBlock8x8.Generated.cs b/src/ImageSharp/Formats/Jpeg/Components/GenericBlock8x8.Generated.cs
similarity index 89%
rename from src/ImageSharp/Formats/Jpeg/Common/GenericBlock8x8.Generated.cs
rename to src/ImageSharp/Formats/Jpeg/Components/GenericBlock8x8.Generated.cs
index 1bb37a7d32..0cc729371f 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/GenericBlock8x8.Generated.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/GenericBlock8x8.Generated.cs
@@ -1,11 +1,8 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-using System.Numerics;
-using System.Runtime.CompilerServices;
-
//
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components
{
internal unsafe partial struct GenericBlock8x8
{
diff --git a/src/ImageSharp/Formats/Jpeg/Common/GenericBlock8x8.Generated.tt b/src/ImageSharp/Formats/Jpeg/Components/GenericBlock8x8.Generated.tt
similarity index 90%
rename from src/ImageSharp/Formats/Jpeg/Common/GenericBlock8x8.Generated.tt
rename to src/ImageSharp/Formats/Jpeg/Components/GenericBlock8x8.Generated.tt
index d9b15b34fa..28bcea791b 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/GenericBlock8x8.Generated.tt
+++ b/src/ImageSharp/Formats/Jpeg/Components/GenericBlock8x8.Generated.tt
@@ -11,11 +11,8 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-using System.Numerics;
-using System.Runtime.CompilerServices;
-
//
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components
{
internal unsafe partial struct GenericBlock8x8
{
diff --git a/src/ImageSharp/Formats/Jpeg/Common/GenericBlock8x8.cs b/src/ImageSharp/Formats/Jpeg/Components/GenericBlock8x8.cs
similarity index 96%
rename from src/ImageSharp/Formats/Jpeg/Common/GenericBlock8x8.cs
rename to src/ImageSharp/Formats/Jpeg/Components/GenericBlock8x8.cs
index 09a7eb73aa..9aceb78b2a 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/GenericBlock8x8.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/GenericBlock8x8.cs
@@ -1,13 +1,16 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.Primitives;
// ReSharper disable InconsistentNaming
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components
{
///
/// A generic 8x8 block implementation, useful for manipulating custom 8x8 pixel data.
@@ -18,8 +21,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common
{
public const int Size = 64;
- public const int SizeInBytes = Size * 3;
-
///
/// FOR TESTING ONLY!
/// Gets or sets a value at the given index
diff --git a/src/ImageSharp/Formats/Jpeg/Common/SizeExtensions.cs b/src/ImageSharp/Formats/Jpeg/Components/SizeExtensions.cs
similarity index 97%
rename from src/ImageSharp/Formats/Jpeg/Common/SizeExtensions.cs
rename to src/ImageSharp/Formats/Jpeg/Components/SizeExtensions.cs
index 978688673f..48ad188561 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/SizeExtensions.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/SizeExtensions.cs
@@ -3,9 +3,10 @@
using System;
using System.Numerics;
+
using SixLabors.Primitives;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components
{
///
/// Extension methods for
diff --git a/src/ImageSharp/Formats/Jpeg/Common/ZigZag.cs b/src/ImageSharp/Formats/Jpeg/Components/ZigZag.cs
similarity index 98%
rename from src/ImageSharp/Formats/Jpeg/Common/ZigZag.cs
rename to src/ImageSharp/Formats/Jpeg/Components/ZigZag.cs
index cb035a8d3d..a3701f2c1b 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/ZigZag.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/ZigZag.cs
@@ -1,10 +1,11 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
+
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-namespace SixLabors.ImageSharp.Formats.Jpeg.Common
+namespace SixLabors.ImageSharp.Formats.Jpeg.Components
{
///
/// Holds the Jpeg UnZig array in a value/stack type.
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/Bits.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/Bits.cs
index 05bde78e65..353eb01fe2 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/Bits.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/Bits.cs
@@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void EnsureNBits(int n, ref InputProcessor inputProcessor)
{
- OrigDecoderErrorCode errorCode = this.EnsureNBitsUnsafe(n, ref inputProcessor);
+ GolangDecoderErrorCode errorCode = this.EnsureNBitsUnsafe(n, ref inputProcessor);
errorCode.EnsureNoError();
}
@@ -46,17 +46,17 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// Reads bytes from the byte buffer to ensure that bits.UnreadBits is at
/// least n. For best performance (avoiding function calls inside hot loops),
/// the caller is the one responsible for first checking that bits.UnreadBits < n.
- /// This method does not throw. Returns instead.
+ /// This method does not throw. Returns instead.
///
/// The number of bits to ensure.
/// The
/// Error code
- public OrigDecoderErrorCode EnsureNBitsUnsafe(int n, ref InputProcessor inputProcessor)
+ public GolangDecoderErrorCode EnsureNBitsUnsafe(int n, ref InputProcessor inputProcessor)
{
while (true)
{
- OrigDecoderErrorCode errorCode = this.EnsureBitsStepImpl(ref inputProcessor);
- if (errorCode != OrigDecoderErrorCode.NoError || this.UnreadBits >= n)
+ GolangDecoderErrorCode errorCode = this.EnsureBitsStepImpl(ref inputProcessor);
+ if (errorCode != GolangDecoderErrorCode.NoError || this.UnreadBits >= n)
{
return errorCode;
}
@@ -67,8 +67,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// Unrolled version of for n==8
///
/// The
- /// A
- public OrigDecoderErrorCode Ensure8BitsUnsafe(ref InputProcessor inputProcessor)
+ /// A
+ public GolangDecoderErrorCode Ensure8BitsUnsafe(ref InputProcessor inputProcessor)
{
return this.EnsureBitsStepImpl(ref inputProcessor);
}
@@ -77,8 +77,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// Unrolled version of for n==1
///
/// The
- /// A
- public OrigDecoderErrorCode Ensure1BitUnsafe(ref InputProcessor inputProcessor)
+ /// A
+ public GolangDecoderErrorCode Ensure1BitUnsafe(ref InputProcessor inputProcessor)
{
return this.EnsureBitsStepImpl(ref inputProcessor);
}
@@ -92,7 +92,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int ReceiveExtend(int t, ref InputProcessor inputProcessor)
{
- OrigDecoderErrorCode errorCode = this.ReceiveExtendUnsafe(t, ref inputProcessor, out int x);
+ GolangDecoderErrorCode errorCode = this.ReceiveExtendUnsafe(t, ref inputProcessor, out int x);
errorCode.EnsureNoError();
return x;
}
@@ -103,13 +103,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// Byte
/// The
/// Read bits value
- /// The
- public OrigDecoderErrorCode ReceiveExtendUnsafe(int t, ref InputProcessor inputProcessor, out int x)
+ /// The
+ public GolangDecoderErrorCode ReceiveExtendUnsafe(int t, ref InputProcessor inputProcessor, out int x)
{
if (this.UnreadBits < t)
{
- OrigDecoderErrorCode errorCode = this.EnsureNBitsUnsafe(t, ref inputProcessor);
- if (errorCode != OrigDecoderErrorCode.NoError)
+ GolangDecoderErrorCode errorCode = this.EnsureNBitsUnsafe(t, ref inputProcessor);
+ if (errorCode != GolangDecoderErrorCode.NoError)
{
x = int.MaxValue;
return errorCode;
@@ -126,14 +126,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
x += ((-1) << t) + 1;
}
- return OrigDecoderErrorCode.NoError;
+ return GolangDecoderErrorCode.NoError;
}
- private OrigDecoderErrorCode EnsureBitsStepImpl(ref InputProcessor inputProcessor)
+ private GolangDecoderErrorCode EnsureBitsStepImpl(ref InputProcessor inputProcessor)
{
- OrigDecoderErrorCode errorCode = inputProcessor.Bytes.ReadByteStuffedByteUnsafe(inputProcessor.InputStream, out int c);
+ GolangDecoderErrorCode errorCode = inputProcessor.Bytes.ReadByteStuffedByteUnsafe(inputProcessor.InputStream, out int c);
- if (errorCode != OrigDecoderErrorCode.NoError)
+ if (errorCode != GolangDecoderErrorCode.NoError)
{
return errorCode;
}
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/Bytes.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/Bytes.cs
index 2a3817400c..c8c68aa7ea 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/Bytes.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/Bytes.cs
@@ -77,8 +77,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
/// Input stream
/// The result byte as
- /// The
- public OrigDecoderErrorCode ReadByteStuffedByteUnsafe(Stream inputStream, out int x)
+ /// The
+ public GolangDecoderErrorCode ReadByteStuffedByteUnsafe(Stream inputStream, out int x)
{
// Take the fast path if bytes.buf contains at least two bytes.
if (this.I + 2 <= this.J)
@@ -86,50 +86,50 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
x = this.BufferAsInt[this.I];
this.I++;
this.UnreadableBytes = 1;
- if (x != OrigJpegConstants.Markers.XFFInt)
+ if (x != JpegConstants.Markers.XFFInt)
{
- return OrigDecoderErrorCode.NoError;
+ return GolangDecoderErrorCode.NoError;
}
if (this.BufferAsInt[this.I] != 0x00)
{
- return OrigDecoderErrorCode.MissingFF00;
+ return GolangDecoderErrorCode.MissingFF00;
}
this.I++;
this.UnreadableBytes = 2;
- x = OrigJpegConstants.Markers.XFF;
- return OrigDecoderErrorCode.NoError;
+ x = JpegConstants.Markers.XFF;
+ return GolangDecoderErrorCode.NoError;
}
this.UnreadableBytes = 0;
- OrigDecoderErrorCode errorCode = this.ReadByteAsIntUnsafe(inputStream, out x);
+ GolangDecoderErrorCode errorCode = this.ReadByteAsIntUnsafe(inputStream, out x);
this.UnreadableBytes = 1;
- if (errorCode != OrigDecoderErrorCode.NoError)
+ if (errorCode != GolangDecoderErrorCode.NoError)
{
return errorCode;
}
- if (x != OrigJpegConstants.Markers.XFF)
+ if (x != JpegConstants.Markers.XFF)
{
- return OrigDecoderErrorCode.NoError;
+ return GolangDecoderErrorCode.NoError;
}
errorCode = this.ReadByteAsIntUnsafe(inputStream, out x);
this.UnreadableBytes = 2;
- if (errorCode != OrigDecoderErrorCode.NoError)
+ if (errorCode != GolangDecoderErrorCode.NoError)
{
return errorCode;
}
if (x != 0x00)
{
- return OrigDecoderErrorCode.MissingFF00;
+ return GolangDecoderErrorCode.MissingFF00;
}
- x = OrigJpegConstants.Markers.XFF;
- return OrigDecoderErrorCode.NoError;
+ x = JpegConstants.Markers.XFF;
+ return GolangDecoderErrorCode.NoError;
}
///
@@ -140,25 +140,25 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public byte ReadByte(Stream inputStream)
{
- OrigDecoderErrorCode errorCode = this.ReadByteUnsafe(inputStream, out byte result);
+ GolangDecoderErrorCode errorCode = this.ReadByteUnsafe(inputStream, out byte result);
errorCode.EnsureNoError();
return result;
}
///
/// Extracts the next byte, whether buffered or not buffered into the result out parameter. It does not care about byte stuffing.
- /// This method does not throw on format error, it returns a instead.
+ /// This method does not throw on format error, it returns a instead.
///
/// Input stream
/// The result as out parameter
- /// The
- public OrigDecoderErrorCode ReadByteUnsafe(Stream inputStream, out byte result)
+ /// The
+ public GolangDecoderErrorCode ReadByteUnsafe(Stream inputStream, out byte result)
{
- OrigDecoderErrorCode errorCode = OrigDecoderErrorCode.NoError;
+ GolangDecoderErrorCode errorCode = GolangDecoderErrorCode.NoError;
while (this.I == this.J)
{
errorCode = this.FillUnsafe(inputStream);
- if (errorCode != OrigDecoderErrorCode.NoError)
+ if (errorCode != GolangDecoderErrorCode.NoError)
{
result = 0;
return errorCode;
@@ -176,15 +176,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
/// The input stream
/// The result
- /// A
+ /// A
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public OrigDecoderErrorCode ReadByteAsIntUnsafe(Stream inputStream, out int result)
+ public GolangDecoderErrorCode ReadByteAsIntUnsafe(Stream inputStream, out int result)
{
- OrigDecoderErrorCode errorCode = OrigDecoderErrorCode.NoError;
+ GolangDecoderErrorCode errorCode = GolangDecoderErrorCode.NoError;
while (this.I == this.J)
{
errorCode = this.FillUnsafe(inputStream);
- if (errorCode != OrigDecoderErrorCode.NoError)
+ if (errorCode != GolangDecoderErrorCode.NoError)
{
result = 0;
return errorCode;
@@ -206,18 +206,18 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Fill(Stream inputStream)
{
- OrigDecoderErrorCode errorCode = this.FillUnsafe(inputStream);
+ GolangDecoderErrorCode errorCode = this.FillUnsafe(inputStream);
errorCode.EnsureNoError();
}
///
/// Fills up the bytes buffer from the underlying stream.
/// It should only be called when there are no unread bytes in bytes.
- /// This method does not throw , returns a instead!
+ /// This method does not throw , returns a instead!
///
/// Input stream
- /// The
- public OrigDecoderErrorCode FillUnsafe(Stream inputStream)
+ /// The
+ public GolangDecoderErrorCode FillUnsafe(Stream inputStream)
{
if (this.I != this.J)
{
@@ -239,7 +239,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
int n = inputStream.Read(this.Buffer, this.J, this.Buffer.Length - this.J);
if (n == 0)
{
- return OrigDecoderErrorCode.UnexpectedEndOfStream;
+ return GolangDecoderErrorCode.UnexpectedEndOfStream;
}
this.J += n;
@@ -249,7 +249,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
this.BufferAsInt[i] = this.Buffer[i];
}
- return OrigDecoderErrorCode.NoError;
+ return GolangDecoderErrorCode.NoError;
}
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/DecoderThrowHelper.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/DecoderThrowHelper.cs
index 904ce00dde..2b2bc61ba8 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/DecoderThrowHelper.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/DecoderThrowHelper.cs
@@ -12,22 +12,22 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
internal static class DecoderThrowHelper
{
///
- /// Throws an exception that belongs to the given
+ /// Throws an exception that belongs to the given
///
- /// The
+ /// The
[MethodImpl(MethodImplOptions.NoInlining)]
- public static void ThrowExceptionForErrorCode(this OrigDecoderErrorCode errorCode)
+ public static void ThrowExceptionForErrorCode(this GolangDecoderErrorCode errorCode)
{
// REMARK: If this method throws for an image that is expected to be decodable,
// consider using the ***Unsafe variant of the parsing method that asks for ThrowExceptionForErrorCode()
// then verify the error code + implement fallback logic manually!
switch (errorCode)
{
- case OrigDecoderErrorCode.NoError:
+ case GolangDecoderErrorCode.NoError:
throw new ArgumentException("ThrowExceptionForErrorCode() called with NoError!", nameof(errorCode));
- case OrigDecoderErrorCode.MissingFF00:
+ case GolangDecoderErrorCode.MissingFF00:
throw new MissingFF00Exception();
- case OrigDecoderErrorCode.UnexpectedEndOfStream:
+ case GolangDecoderErrorCode.UnexpectedEndOfStream:
throw new EOFException();
default:
throw new ArgumentOutOfRangeException(nameof(errorCode), errorCode, null);
@@ -35,26 +35,26 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
}
///
- /// Throws an exception if the given defines an error.
+ /// Throws an exception if the given defines an error.
///
- /// The
+ /// The
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void EnsureNoError(this OrigDecoderErrorCode errorCode)
+ public static void EnsureNoError(this GolangDecoderErrorCode errorCode)
{
- if (errorCode != OrigDecoderErrorCode.NoError)
+ if (errorCode != GolangDecoderErrorCode.NoError)
{
ThrowExceptionForErrorCode(errorCode);
}
}
///
- /// Throws an exception if the given is .
+ /// Throws an exception if the given is .
///
- /// The
+ /// The
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void EnsureNoEOF(this OrigDecoderErrorCode errorCode)
+ public static void EnsureNoEOF(this GolangDecoderErrorCode errorCode)
{
- if (errorCode == OrigDecoderErrorCode.UnexpectedEndOfStream)
+ if (errorCode == GolangDecoderErrorCode.UnexpectedEndOfStream)
{
errorCode.ThrowExceptionForErrorCode();
}
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangComponent.cs
similarity index 93%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs
rename to src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangComponent.cs
index e2b72db057..bb3bd01aa3 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponent.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangComponent.cs
@@ -3,8 +3,9 @@
using System;
using System.Runtime.CompilerServices;
-using SixLabors.ImageSharp.Formats.Jpeg.Common;
-using SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder;
+
+using SixLabors.ImageSharp.Formats.Jpeg.Components;
+using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder;
using SixLabors.ImageSharp.Memory;
using SixLabors.Primitives;
@@ -14,9 +15,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
/// Represents a single color component
///
- internal class OrigComponent : IDisposable, IJpegComponent
+ internal class GolangComponent : IDisposable, IJpegComponent
{
- public OrigComponent(byte identifier, int index)
+ public GolangComponent(byte identifier, int index)
{
this.Identifier = identifier;
this.Index = index;
@@ -56,8 +57,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// Initializes
///
/// The to use for buffer allocations.
- /// The instance
- public void InitializeDerivedData(MemoryManager memoryManager, OrigJpegDecoderCore decoder)
+ /// The instance
+ public void InitializeDerivedData(MemoryManager memoryManager, GolangJpegDecoderCore decoder)
{
// For 4-component images (either CMYK or YCbCrK), we only support two
// hv vectors: [0x11 0x11 0x11 0x11] and [0x22 0x11 0x11 0x22].
@@ -76,7 +77,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
}
else
{
- OrigComponent c0 = decoder.Components[0];
+ GolangComponent c0 = decoder.Components[0];
this.SubSamplingDivisors = c0.SamplingFactors.DivideBy(this.SamplingFactors);
}
@@ -86,8 +87,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
/// Initializes all component data except .
///
- /// The instance
- public void InitializeCoreData(OrigJpegDecoderCore decoder)
+ /// The instance
+ public void InitializeCoreData(GolangJpegDecoderCore decoder)
{
// Section B.2.2 states that "the value of C_i shall be different from
// the values of C_1 through C_(i-1)".
@@ -102,7 +103,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
}
this.QuantizationTableIndex = decoder.Temp[8 + (3 * i)];
- if (this.QuantizationTableIndex > OrigJpegDecoderCore.MaxTq)
+ if (this.QuantizationTableIndex > GolangJpegDecoderCore.MaxTq)
{
throw new ImageFormatException("Bad Tq value");
}
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponentScan.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangComponentScan.cs
similarity index 94%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponentScan.cs
rename to src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangComponentScan.cs
index 0d98044045..6752768ffa 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigComponentScan.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangComponentScan.cs
@@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// Represents a component scan
///
[StructLayout(LayoutKind.Sequential)]
- internal struct OrigComponentScan
+ internal struct GolangComponentScan
{
///
/// Gets or sets the component index.
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigDecoderErrorCode.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangDecoderErrorCode.cs
similarity index 93%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigDecoderErrorCode.cs
rename to src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangDecoderErrorCode.cs
index 02a8ea55e0..fa3364527c 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigDecoderErrorCode.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangDecoderErrorCode.cs
@@ -6,7 +6,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
/// Represents "recoverable" decoder errors.
///
- internal enum OrigDecoderErrorCode
+ internal enum GolangDecoderErrorCode
{
///
/// NoError
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigHuffmanTree.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangHuffmanTree.cs
similarity index 95%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigHuffmanTree.cs
rename to src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangHuffmanTree.cs
index dbc7bb0f7f..dccce2aaa8 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigHuffmanTree.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangHuffmanTree.cs
@@ -1,8 +1,6 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-using System;
-using System.Buffers;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
@@ -12,7 +10,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// Represents a Huffman tree
///
[StructLayout(LayoutKind.Sequential)]
- internal unsafe struct OrigHuffmanTree
+ internal unsafe struct GolangHuffmanTree
{
///
/// The index of the AC table row
@@ -95,12 +93,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
public FixedInt32Buffer16 Indices;
///
- /// Creates and initializes an array of instances of size
+ /// Creates and initializes an array of instances of size
///
- /// An array of instances representing the Huffman tables
- public static OrigHuffmanTree[] CreateHuffmanTrees()
+ /// An array of instances representing the Huffman tables
+ public static GolangHuffmanTree[] CreateHuffmanTrees()
{
- return new OrigHuffmanTree[NumberOfTrees];
+ return new GolangHuffmanTree[NumberOfTrees];
}
///
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.ComputationData.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangJpegScanDecoder.ComputationData.cs
similarity index 79%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.ComputationData.cs
rename to src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangJpegScanDecoder.ComputationData.cs
index c9bb898aa5..f1dd2526ae 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.ComputationData.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangJpegScanDecoder.ComputationData.cs
@@ -2,14 +2,15 @@
// Licensed under the Apache License, Version 2.0.
using System.Runtime.InteropServices;
-using SixLabors.ImageSharp.Formats.Jpeg.Common;
+
+using SixLabors.ImageSharp.Formats.Jpeg.Components;
namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
{
///
/// Conains the definition of
///
- internal unsafe partial struct OrigJpegScanDecoder
+ internal unsafe partial struct GolangJpegScanDecoder
{
///
/// Holds the "large" data blocks needed for computations.
@@ -28,14 +29,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
public ZigZag Unzig;
///
- /// The buffer storing the -s for each component
+ /// The buffer storing the -s for each component
///
- public fixed byte ScanData[3 * OrigJpegDecoderCore.MaxComponents];
+ public fixed byte ScanData[3 * GolangJpegDecoderCore.MaxComponents];
///
/// The DC values for each component
///
- public fixed int Dc[OrigJpegDecoderCore.MaxComponents];
+ public fixed int Dc[GolangJpegDecoderCore.MaxComponents];
///
/// Creates and initializes a new instance
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.DataPointers.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangJpegScanDecoder.DataPointers.cs
similarity index 86%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.DataPointers.cs
rename to src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangJpegScanDecoder.DataPointers.cs
index 0207280e3e..a00da6fcaf 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.DataPointers.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangJpegScanDecoder.DataPointers.cs
@@ -1,14 +1,14 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-using SixLabors.ImageSharp.Formats.Jpeg.Common;
+using SixLabors.ImageSharp.Formats.Jpeg.Components;
namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
{
///
/// Conains the definition of
///
- internal unsafe partial struct OrigJpegScanDecoder
+ internal unsafe partial struct GolangJpegScanDecoder
{
///
/// Contains pointers to the memory regions of so they can be easily passed around to pointer based utility methods of
@@ -28,7 +28,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
/// Pointer to as Scan*
///
- public OrigComponentScan* ComponentScan;
+ public GolangComponentScan* ComponentScan;
///
/// Pointer to
@@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
{
this.Block = &basePtr->Block;
this.Unzig = basePtr->Unzig.Data;
- this.ComponentScan = (OrigComponentScan*)basePtr->ScanData;
+ this.ComponentScan = (GolangComponentScan*)basePtr->ScanData;
this.Dc = basePtr->Dc;
}
}
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangJpegScanDecoder.cs
similarity index 89%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs
rename to src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangJpegScanDecoder.cs
index d10def3ce7..3a88cfad4b 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OrigJpegScanDecoder.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/GolangJpegScanDecoder.cs
@@ -3,9 +3,8 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-using SixLabors.ImageSharp.Formats.Jpeg.Common;
-using SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder;
-using SixLabors.ImageSharp.Memory;
+
+using SixLabors.ImageSharp.Formats.Jpeg.Components;
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
@@ -29,7 +28,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// For baseline JPEGs, these parameters are hard-coded to 0/63/0/0.
///
[StructLayout(LayoutKind.Sequential)]
- internal unsafe partial struct OrigJpegScanDecoder
+ internal unsafe partial struct GolangJpegScanDecoder
{
// The JpegScanDecoder members should be ordered in a way that results in optimal memory layout.
#pragma warning disable SA1202 // ElementsMustBeOrderedByAccess
@@ -110,12 +109,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
private byte expectedRst;
///
- /// Initializes a default-constructed instance for reading data from -s stream.
+ /// Initializes a default-constructed instance for reading data from -s stream.
///
- /// Pointer to on the stack
- /// The instance
+ /// Pointer to on the stack
+ /// The instance
/// The remaining bytes in the segment block.
- public static void InitStreamReading(OrigJpegScanDecoder* p, OrigJpegDecoderCore decoder, int remaining)
+ public static void InitStreamReading(GolangJpegScanDecoder* p, GolangJpegDecoderCore decoder, int remaining)
{
p->data = ComputationData.Create();
p->pointers = new DataPointers(&p->data);
@@ -123,8 +122,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
}
///
- /// Read Huffman data from Jpeg scans in ,
- /// and decode it as into .
+ /// Read Huffman data from Jpeg scans in ,
+ /// and decode it as into .
///
/// The blocks are traversed one MCU at a time. For 4:2:0 chroma
/// subsampling, there are four Y 8x8 blocks in every 16x16 MCU.
@@ -149,14 +148,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// 0 1 2
/// 3 4 5
///
- /// The instance
- public void DecodeBlocks(OrigJpegDecoderCore decoder)
+ /// The instance
+ public void DecodeBlocks(GolangJpegDecoderCore decoder)
{
decoder.InputProcessor.ResetErrorState();
this.blockCounter = 0;
this.mcuCounter = 0;
- this.expectedRst = OrigJpegConstants.Markers.RST0;
+ this.expectedRst = JpegConstants.Markers.RST0;
for (int my = 0; my < decoder.MCUCountY; my++)
{
@@ -177,12 +176,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
}
}
- private void DecodeBlocksAtMcuIndex(OrigJpegDecoderCore decoder, int mx, int my)
+ private void DecodeBlocksAtMcuIndex(GolangJpegDecoderCore decoder, int mx, int my)
{
for (int scanIndex = 0; scanIndex < this.componentScanCount; scanIndex++)
{
this.ComponentIndex = this.pointers.ComponentScan[scanIndex].ComponentIndex;
- OrigComponent component = decoder.Components[this.ComponentIndex];
+ GolangComponent component = decoder.Components[this.ComponentIndex];
this.hi = component.HorizontalSamplingFactor;
int vi = component.VerticalSamplingFactor;
@@ -223,7 +222,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
}
}
- private void ProcessRSTMarker(OrigJpegDecoderCore decoder)
+ private void ProcessRSTMarker(GolangJpegDecoderCore decoder)
{
// Attempt to look for RST[0-7] markers to resynchronize from corrupt input.
if (!decoder.InputProcessor.ReachedEOF)
@@ -262,15 +261,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
}
this.expectedRst++;
- if (this.expectedRst == OrigJpegConstants.Markers.RST7 + 1)
+ if (this.expectedRst == JpegConstants.Markers.RST7 + 1)
{
- this.expectedRst = OrigJpegConstants.Markers.RST0;
+ this.expectedRst = JpegConstants.Markers.RST0;
}
}
}
}
- private void Reset(OrigJpegDecoderCore decoder)
+ private void Reset(GolangJpegDecoderCore decoder)
{
decoder.InputProcessor.ResetHuffmanDecoder();
@@ -285,15 +284,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
private void ResetDcValues()
{
- Unsafe.InitBlock(this.pointers.Dc, default(byte), sizeof(int) * OrigJpegDecoderCore.MaxComponents);
+ Unsafe.InitBlock(this.pointers.Dc, default, sizeof(int) * GolangJpegDecoderCore.MaxComponents);
}
///
/// The implementation part of as an instance method.
///
- /// The
+ /// The
/// The remaining bytes
- private void InitStreamReadingImpl(OrigJpegDecoderCore decoder, int remaining)
+ private void InitStreamReadingImpl(GolangJpegDecoderCore decoder, int remaining)
{
if (decoder.ComponentCount == 0)
{
@@ -360,10 +359,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
/// The decoder
/// The index of the scan
- private void DecodeBlock(OrigJpegDecoderCore decoder, int scanIndex)
+ private void DecodeBlock(GolangJpegDecoderCore decoder, int scanIndex)
{
Block8x8* b = this.pointers.Block;
- int huffmannIdx = (OrigHuffmanTree.AcTableIndex * OrigHuffmanTree.ThRowSize) + this.pointers.ComponentScan[scanIndex].AcTableSelector;
+ int huffmannIdx = (GolangHuffmanTree.AcTableIndex * GolangHuffmanTree.ThRowSize) + this.pointers.ComponentScan[scanIndex].AcTableSelector;
if (this.ah != 0)
{
this.Refine(ref decoder.InputProcessor, ref decoder.HuffmanTrees[huffmannIdx], 1 << this.al);
@@ -377,7 +376,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
zig++;
// Decode the DC coefficient, as specified in section F.2.2.1.
- int huffmanIndex = (OrigHuffmanTree.DcTableIndex * OrigHuffmanTree.ThRowSize) + this.pointers.ComponentScan[scanIndex].DcTableSelector;
+ int huffmanIndex = (GolangHuffmanTree.DcTableIndex * GolangHuffmanTree.ThRowSize) + this.pointers.ComponentScan[scanIndex].DcTableSelector;
decoder.InputProcessor.DecodeHuffmanUnsafe(
ref decoder.HuffmanTrees[huffmanIndex],
out int value);
@@ -467,7 +466,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
private void DecodeEobRun(int count, ref InputProcessor processor)
{
processor.DecodeBitsUnsafe(count, out int bitsResult);
- if (processor.LastErrorCode != OrigDecoderErrorCode.NoError)
+ if (processor.LastErrorCode != GolangDecoderErrorCode.NoError)
{
return;
}
@@ -475,7 +474,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
this.eobRun |= bitsResult;
}
- private void InitComponentScan(OrigJpegDecoderCore decoder, int i, ref OrigComponentScan currentComponentScan, ref int totalHv)
+ private void InitComponentScan(GolangJpegDecoderCore decoder, int i, ref GolangComponentScan currentComponentScan, ref int totalHv)
{
// Component selector.
int cs = decoder.Temp[1 + (2 * i)];
@@ -500,11 +499,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
}
private void ProcessComponentImpl(
- OrigJpegDecoderCore decoder,
+ GolangJpegDecoderCore decoder,
int i,
- ref OrigComponentScan currentComponentScan,
+ ref GolangComponentScan currentComponentScan,
ref int totalHv,
- OrigComponent currentComponent)
+ GolangComponent currentComponent)
{
// Section B.2.3 states that "the value of Cs_j shall be different from
// the values of Cs_1 through Cs_(j-1)". Since we have previously
@@ -522,13 +521,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
totalHv += currentComponent.HorizontalSamplingFactor * currentComponent.VerticalSamplingFactor;
currentComponentScan.DcTableSelector = (byte)(decoder.Temp[2 + (2 * i)] >> 4);
- if (currentComponentScan.DcTableSelector > OrigHuffmanTree.MaxTh)
+ if (currentComponentScan.DcTableSelector > GolangHuffmanTree.MaxTh)
{
throw new ImageFormatException("Bad DC table selector value");
}
currentComponentScan.AcTableSelector = (byte)(decoder.Temp[2 + (2 * i)] & 0x0f);
- if (currentComponentScan.AcTableSelector > OrigHuffmanTree.MaxTh)
+ if (currentComponentScan.AcTableSelector > GolangHuffmanTree.MaxTh)
{
throw new ImageFormatException("Bad AC table selector value");
}
@@ -540,7 +539,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// The instance
/// The Huffman tree
/// The low transform offset
- private void Refine(ref InputProcessor bp, ref OrigHuffmanTree h, int delta)
+ private void Refine(ref InputProcessor bp, ref GolangHuffmanTree h, int delta)
{
Block8x8* b = this.pointers.Block;
@@ -560,7 +559,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
if (bit)
{
- int stuff = (int)Block8x8.GetScalarAt(b, 0);
+ int stuff = Block8x8.GetScalarAt(b, 0);
// int stuff = (int)b[0];
stuff |= delta;
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/InputProcessor.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/InputProcessor.cs
index cb4b63cffd..c7e14ee4f2 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/InputProcessor.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/InputProcessor.cs
@@ -8,7 +8,7 @@ using System.Runtime.CompilerServices;
namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
{
///
- /// Encapsulates stream reading and processing data and operations for .
+ /// Encapsulates stream reading and processing data and operations for .
/// It's a value type for imporved data locality, and reduced number of CALLVIRT-s
///
internal struct InputProcessor : IDisposable
@@ -27,14 +27,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// Initializes a new instance of the struct.
///
/// The input
- /// Temporal buffer, same as
+ /// Temporal buffer, same as
public InputProcessor(Stream inputStream, byte[] temp)
{
- this.Bits = default(Bits);
+ this.Bits = default;
this.Bytes = Bytes.Create();
this.InputStream = inputStream;
this.Temp = temp;
- this.LastErrorCode = OrigDecoderErrorCode.NoError;
+ this.LastErrorCode = GolangDecoderErrorCode.NoError;
}
///
@@ -43,20 +43,20 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
public Stream InputStream { get; }
///
- /// Gets the temporary buffer, same instance as
+ /// Gets the temporary buffer, same instance as
///
public byte[] Temp { get; }
///
/// Gets a value indicating whether an unexpected EOF reached in .
///
- public bool ReachedEOF => this.LastErrorCode == OrigDecoderErrorCode.UnexpectedEndOfStream;
+ public bool ReachedEOF => this.LastErrorCode == GolangDecoderErrorCode.UnexpectedEndOfStream;
- public bool HasError => this.LastErrorCode != OrigDecoderErrorCode.NoError;
+ public bool HasError => this.LastErrorCode != GolangDecoderErrorCode.NoError;
- public OrigDecoderErrorCode LastErrorCode { get; private set; }
+ public GolangDecoderErrorCode LastErrorCode { get; private set; }
- public void ResetErrorState() => this.LastErrorCode = OrigDecoderErrorCode.NoError;
+ public void ResetErrorState() => this.LastErrorCode = GolangDecoderErrorCode.NoError;
///
/// If errorCode indicates unexpected EOF, sets to true and returns false.
@@ -65,7 +65,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// A indicating whether EOF reached
public bool CheckEOFEnsureNoError()
{
- if (this.LastErrorCode == OrigDecoderErrorCode.UnexpectedEndOfStream)
+ if (this.LastErrorCode == GolangDecoderErrorCode.UnexpectedEndOfStream)
{
return false;
}
@@ -81,7 +81,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// A indicating whether EOF reached
public bool CheckEOF()
{
- if (this.LastErrorCode == OrigDecoderErrorCode.UnexpectedEndOfStream)
+ if (this.LastErrorCode == GolangDecoderErrorCode.UnexpectedEndOfStream)
{
return false;
}
@@ -106,7 +106,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public OrigDecoderErrorCode ReadByteUnsafe(out byte result)
+ public GolangDecoderErrorCode ReadByteUnsafe(out byte result)
{
this.LastErrorCode = this.Bytes.ReadByteUnsafe(this.InputStream, out result);
return this.LastErrorCode;
@@ -117,13 +117,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// TODO: This method (and also the usages) could be optimized by batching!
///
/// The decoded bit as a
- /// The
- public OrigDecoderErrorCode DecodeBitUnsafe(out bool result)
+ /// The
+ public GolangDecoderErrorCode DecodeBitUnsafe(out bool result)
{
if (this.Bits.UnreadBits == 0)
{
this.LastErrorCode = this.Bits.Ensure1BitUnsafe(ref this);
- if (this.LastErrorCode != OrigDecoderErrorCode.NoError)
+ if (this.LastErrorCode != GolangDecoderErrorCode.NoError)
{
result = false;
return this.LastErrorCode;
@@ -133,18 +133,18 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
result = (this.Bits.Accumulator & this.Bits.Mask) != 0;
this.Bits.UnreadBits--;
this.Bits.Mask >>= 1;
- return this.LastErrorCode = OrigDecoderErrorCode.NoError;
+ return this.LastErrorCode = GolangDecoderErrorCode.NoError;
}
///
/// Reads exactly length bytes into data. It does not care about byte stuffing.
- /// Does not throw on errors, returns instead!
+ /// Does not throw on errors, returns instead!
///
/// The data to write to.
/// The offset in the source buffer
/// The number of bytes to read
- /// The
- public OrigDecoderErrorCode ReadFullUnsafe(byte[] data, int offset, int length)
+ /// The
+ public GolangDecoderErrorCode ReadFullUnsafe(byte[] data, int offset, int length)
{
// Unread the overshot bytes, if any.
if (this.Bytes.UnreadableBytes != 0)
@@ -157,8 +157,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
this.Bytes.UnreadableBytes = 0;
}
- this.LastErrorCode = OrigDecoderErrorCode.NoError;
- while (length > 0 && this.LastErrorCode == OrigDecoderErrorCode.NoError)
+ this.LastErrorCode = GolangDecoderErrorCode.NoError;
+ while (length > 0 && this.LastErrorCode == GolangDecoderErrorCode.NoError)
{
if (this.Bytes.J - this.Bytes.I >= length)
{
@@ -185,13 +185,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
/// The number of bits to decode.
/// The result
- /// The
- public OrigDecoderErrorCode DecodeBitsUnsafe(int count, out int result)
+ /// The
+ public GolangDecoderErrorCode DecodeBitsUnsafe(int count, out int result)
{
if (this.Bits.UnreadBits < count)
{
this.LastErrorCode = this.Bits.EnsureNBitsUnsafe(count, ref this);
- if (this.LastErrorCode != OrigDecoderErrorCode.NoError)
+ if (this.LastErrorCode != GolangDecoderErrorCode.NoError)
{
result = 0;
return this.LastErrorCode;
@@ -202,7 +202,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
result = result & ((1 << count) - 1);
this.Bits.UnreadBits -= count;
this.Bits.Mask >>= count;
- return this.LastErrorCode = OrigDecoderErrorCode.NoError;
+ return this.LastErrorCode = GolangDecoderErrorCode.NoError;
}
///
@@ -210,8 +210,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
/// The huffman value
/// The decoded
- /// The
- public OrigDecoderErrorCode DecodeHuffmanUnsafe(ref OrigHuffmanTree huffmanTree, out int result)
+ /// The
+ public GolangDecoderErrorCode DecodeHuffmanUnsafe(ref GolangHuffmanTree huffmanTree, out int result)
{
result = 0;
@@ -224,9 +224,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
{
this.LastErrorCode = this.Bits.Ensure8BitsUnsafe(ref this);
- if (this.LastErrorCode == OrigDecoderErrorCode.NoError)
+ if (this.LastErrorCode == GolangDecoderErrorCode.NoError)
{
- int lutIndex = (this.Bits.Accumulator >> (this.Bits.UnreadBits - OrigHuffmanTree.LutSizeLog2)) & 0xFF;
+ int lutIndex = (this.Bits.Accumulator >> (this.Bits.UnreadBits - GolangHuffmanTree.LutSizeLog2)) & 0xFF;
int v = huffmanTree.Lut[lutIndex];
if (v != 0)
@@ -246,7 +246,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
}
int code = 0;
- for (int i = 0; i < OrigHuffmanTree.MaxCodeLength; i++)
+ for (int i = 0; i < GolangHuffmanTree.MaxCodeLength; i++)
{
if (this.Bits.UnreadBits == 0)
{
@@ -269,7 +269,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
if (code <= huffmanTree.MaxCodes[i])
{
result = huffmanTree.GetValue(code, i);
- return this.LastErrorCode = OrigDecoderErrorCode.NoError;
+ return this.LastErrorCode = GolangDecoderErrorCode.NoError;
}
code <<= 1;
@@ -279,7 +279,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
DecoderThrowHelper.ThrowImageFormatException.BadHuffmanCode();
// DUMMY RETURN! C# doesn't know we have thrown an exception!
- return OrigDecoderErrorCode.NoError;
+ return GolangDecoderErrorCode.NoError;
}
///
@@ -295,11 +295,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
/// Skips the next n bytes.
- /// Does not throw, returns instead!
+ /// Does not throw, returns instead!
///
/// The number of bytes to ignore.
- /// The
- public OrigDecoderErrorCode SkipUnsafe(int count)
+ /// The
+ public GolangDecoderErrorCode SkipUnsafe(int count)
{
// Unread the overshot bytes, if any.
if (this.Bytes.UnreadableBytes != 0)
@@ -328,13 +328,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
}
this.LastErrorCode = this.Bytes.FillUnsafe(this.InputStream);
- if (this.LastErrorCode != OrigDecoderErrorCode.NoError)
+ if (this.LastErrorCode != GolangDecoderErrorCode.NoError)
{
return this.LastErrorCode;
}
}
- return this.LastErrorCode = OrigDecoderErrorCode.NoError;
+ return this.LastErrorCode = GolangDecoderErrorCode.NoError;
}
///
@@ -374,8 +374,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
/// Byte
/// Read bits value
- /// The
- public OrigDecoderErrorCode ReceiveExtendUnsafe(int t, out int x)
+ /// The
+ public GolangDecoderErrorCode ReceiveExtendUnsafe(int t, out int x)
{
this.LastErrorCode = this.Bits.ReceiveExtendUnsafe(t, ref this, out x);
return this.LastErrorCode;
@@ -386,7 +386,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
public void ResetHuffmanDecoder()
{
- this.Bits = default(Bits);
+ this.Bits = default;
}
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoder.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/GolangJpegDecoder.cs
similarity index 80%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoder.cs
rename to src/ImageSharp/Formats/Jpeg/GolangPort/GolangJpegDecoder.cs
index bf2f64b349..29255204b4 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoder.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/GolangJpegDecoder.cs
@@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
///
/// Image decoder for generating an image out of a jpg stream.
///
- internal sealed class OrigJpegDecoder : IImageDecoder, IJpegDecoderOptions, IImageInfoDetector
+ internal sealed class GolangJpegDecoder : IImageDecoder, IJpegDecoderOptions, IImageInfoDetector
{
///
/// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded.
@@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
{
Guard.NotNull(stream, nameof(stream));
- using (var decoder = new OrigJpegDecoderCore(configuration, this))
+ using (var decoder = new GolangJpegDecoderCore(configuration, this))
{
return decoder.Decode(stream);
}
@@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
{
Guard.NotNull(stream, nameof(stream));
- using (var decoder = new OrigJpegDecoderCore(configuration, this))
+ using (var decoder = new GolangJpegDecoderCore(configuration, this))
{
return decoder.Identify(stream);
}
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/GolangJpegDecoderCore.cs
similarity index 91%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs
rename to src/ImageSharp/Formats/Jpeg/GolangPort/GolangJpegDecoderCore.cs
index 875f16ec2e..86f97d2248 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/GolangJpegDecoderCore.cs
@@ -3,8 +3,9 @@
using System.Collections.Generic;
using System.IO;
-using SixLabors.ImageSharp.Formats.Jpeg.Common;
-using SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder;
+
+using SixLabors.ImageSharp.Formats.Jpeg.Components;
+using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder;
using SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder;
using SixLabors.ImageSharp.MetaData;
using SixLabors.ImageSharp.MetaData.Profiles.Exif;
@@ -19,7 +20,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
///
/// Performs the jpeg decoding operation.
///
- internal sealed unsafe class OrigJpegDecoderCore : IRawJpegData
+ internal sealed unsafe class GolangJpegDecoderCore : IRawJpegData
{
///
/// The maximum number of color components
@@ -40,7 +41,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
#pragma warning disable SA1401 // FieldsMustBePrivate
///
- /// Encapsulates stream reading and processing data and operations for .
+ /// Encapsulates stream reading and processing data and operations for .
/// It's a value type for improved data locality, and reduced number of CALLVIRT-s
///
public InputProcessor InputProcessor;
@@ -79,11 +80,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
private AdobeMarker adobe;
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
/// The configuration.
/// The options.
- public OrigJpegDecoderCore(Configuration configuration, IJpegDecoderOptions options)
+ public GolangJpegDecoderCore(Configuration configuration, IJpegDecoderOptions options)
{
this.IgnoreMetadata = options.IgnoreMetadata;
this.configuration = configuration ?? Configuration.Default;
@@ -96,12 +97,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
///
/// Gets the component array
///
- public OrigComponent[] Components { get; private set; }
+ public GolangComponent[] Components { get; private set; }
///
/// Gets the huffman trees
///
- public OrigHuffmanTree[] HuffmanTrees { get; private set; }
+ public GolangHuffmanTree[] HuffmanTrees { get; private set; }
///
public Block8x8F[] QuantizationTables { get; private set; }
@@ -209,7 +210,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
{
if (this.Components != null)
{
- foreach (OrigComponent component in this.Components)
+ foreach (GolangComponent component in this.Components)
{
component?.Dispose();
}
@@ -219,7 +220,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
///
- /// Read metadata from stream and read the blocks in the scans into .
+ /// Read metadata from stream and read the blocks in the scans into .
///
/// The stream
/// Whether to decode metadata only.
@@ -231,14 +232,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
if (!metadataOnly)
{
- this.HuffmanTrees = OrigHuffmanTree.CreateHuffmanTrees();
+ this.HuffmanTrees = GolangHuffmanTree.CreateHuffmanTrees();
this.QuantizationTables = new Block8x8F[MaxTq + 1];
}
// Check for the Start Of Image marker.
this.InputProcessor.ReadFull(this.Temp, 0, 2);
- if (this.Temp[0] != OrigJpegConstants.Markers.XFF || this.Temp[1] != OrigJpegConstants.Markers.SOI)
+ if (this.Temp[0] != JpegConstants.Markers.XFF || this.Temp[1] != JpegConstants.Markers.SOI)
{
throw new ImageFormatException("Missing SOI marker.");
}
@@ -302,12 +303,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
// End Of Image.
- if (marker == OrigJpegConstants.Markers.EOI)
+ if (marker == JpegConstants.Markers.EOI)
{
break;
}
- if (marker >= OrigJpegConstants.Markers.RST0 && marker <= OrigJpegConstants.Markers.RST7)
+ if (marker >= JpegConstants.Markers.RST0 && marker <= JpegConstants.Markers.RST7)
{
// Figures B.2 and B.16 of the specification suggest that restart markers should
// only occur between Entropy Coded Segments and not after the final ECS.
@@ -329,14 +330,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
switch (marker)
{
- case OrigJpegConstants.Markers.SOF0:
- case OrigJpegConstants.Markers.SOF1:
- case OrigJpegConstants.Markers.SOF2:
- this.IsProgressive = marker == OrigJpegConstants.Markers.SOF2;
+ case JpegConstants.Markers.SOF0:
+ case JpegConstants.Markers.SOF1:
+ case JpegConstants.Markers.SOF2:
+ this.IsProgressive = marker == JpegConstants.Markers.SOF2;
this.ProcessStartOfFrameMarker(remaining, metadataOnly);
break;
- case OrigJpegConstants.Markers.DHT:
+ case JpegConstants.Markers.DHT:
if (metadataOnly)
{
this.InputProcessor.Skip(remaining);
@@ -347,7 +348,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
break;
- case OrigJpegConstants.Markers.DQT:
+ case JpegConstants.Markers.DQT:
if (metadataOnly)
{
this.InputProcessor.Skip(remaining);
@@ -358,7 +359,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
break;
- case OrigJpegConstants.Markers.SOS:
+ case JpegConstants.Markers.SOS:
if (!metadataOnly)
{
this.ProcessStartOfScanMarker(remaining);
@@ -377,7 +378,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
break;
- case OrigJpegConstants.Markers.DRI:
+ case JpegConstants.Markers.DRI:
if (metadataOnly)
{
this.InputProcessor.Skip(remaining);
@@ -388,21 +389,21 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
break;
- case OrigJpegConstants.Markers.APP0:
+ case JpegConstants.Markers.APP0:
this.ProcessApplicationHeaderMarker(remaining);
break;
- case OrigJpegConstants.Markers.APP1:
+ case JpegConstants.Markers.APP1:
this.ProcessApp1Marker(remaining);
break;
- case OrigJpegConstants.Markers.APP2:
+ case JpegConstants.Markers.APP2:
this.ProcessApp2Marker(remaining);
break;
- case OrigJpegConstants.Markers.APP14:
+ case JpegConstants.Markers.APP14:
this.ProcessApp14Marker(remaining);
break;
default:
- if ((marker >= OrigJpegConstants.Markers.APP0 && marker <= OrigJpegConstants.Markers.APP15)
- || marker == OrigJpegConstants.Markers.COM)
+ if ((marker >= JpegConstants.Markers.APP0 && marker <= JpegConstants.Markers.APP15)
+ || marker == JpegConstants.Markers.COM)
{
this.InputProcessor.Skip(remaining);
}
@@ -449,6 +450,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
this.MetaData.VerticalResolution = verticalValue;
}
}
+
+ if (this.MetaData.IccProfile?.CheckIsValid() == false)
+ {
+ this.MetaData.IccProfile = null;
+ }
}
///
@@ -680,12 +686,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
if (!metadataOnly)
{
- this.Components = new OrigComponent[this.ComponentCount];
+ this.Components = new GolangComponent[this.ComponentCount];
for (int i = 0; i < this.ComponentCount; i++)
{
byte componentIdentifier = this.Temp[6 + (3 * i)];
- var component = new OrigComponent(componentIdentifier, i);
+ var component = new GolangComponent(componentIdentifier, i);
component.InitializeCoreData(this);
this.Components[i] = component;
}
@@ -697,7 +703,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
this.ColorSpace = this.DeduceJpegColorSpace();
- foreach (OrigComponent component in this.Components)
+ foreach (GolangComponent component in this.Components)
{
component.InitializeDerivedData(this.configuration.MemoryManager, this);
}
@@ -721,18 +727,18 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
this.InputProcessor.ReadFull(this.Temp, 0, 17);
int tc = this.Temp[0] >> 4;
- if (tc > OrigHuffmanTree.MaxTc)
+ if (tc > GolangHuffmanTree.MaxTc)
{
throw new ImageFormatException("Bad Tc value");
}
int th = this.Temp[0] & 0x0f;
- if (th > OrigHuffmanTree.MaxTh)
+ if (th > GolangHuffmanTree.MaxTh)
{
throw new ImageFormatException("Bad Th value");
}
- int huffTreeIndex = (tc * OrigHuffmanTree.ThRowSize) + th;
+ int huffTreeIndex = (tc * GolangHuffmanTree.ThRowSize) + th;
this.HuffmanTrees[huffTreeIndex].ProcessDefineHuffmanTablesMarkerLoop(
ref this.InputProcessor,
this.Temp,
@@ -766,9 +772,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
///
private void ProcessStartOfScanMarker(int remaining)
{
- var scan = default(OrigJpegScanDecoder);
- OrigJpegScanDecoder.InitStreamReading(&scan, this, remaining);
- this.InputProcessor.Bits = default(Bits);
+ var scan = default(GolangJpegScanDecoder);
+ GolangJpegScanDecoder.InitStreamReading(&scan, this, remaining);
+ this.InputProcessor.Bits = default;
scan.DecodeBlocks(this);
}
@@ -779,19 +785,19 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
case 1:
return JpegColorSpace.Grayscale;
case 3:
- if (!this.isAdobe || this.adobe.ColorTransform == OrigJpegConstants.Adobe.ColorTransformYCbCr)
+ if (!this.isAdobe || this.adobe.ColorTransform == JpegConstants.Adobe.ColorTransformYCbCr)
{
return JpegColorSpace.YCbCr;
}
- if (this.adobe.ColorTransform == OrigJpegConstants.Adobe.ColorTransformUnknown)
+ if (this.adobe.ColorTransform == JpegConstants.Adobe.ColorTransformUnknown)
{
return JpegColorSpace.RGB;
}
break;
case 4:
- if (this.adobe.ColorTransform == OrigJpegConstants.Adobe.ColorTransformYcck)
+ if (this.adobe.ColorTransform == JpegConstants.Adobe.ColorTransformYcck)
{
return JpegColorSpace.Ycck;
}
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegConstants.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegConstants.cs
deleted file mode 100644
index be383d2120..0000000000
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegConstants.cs
+++ /dev/null
@@ -1,189 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using System.Collections.Generic;
-
-namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
-{
- ///
- /// Defines jpeg constants defined in the specification.
- ///
- internal static class OrigJpegConstants
- {
- ///
- /// The maximum allowable length in each dimension of a jpeg image.
- ///
- public const ushort MaxLength = 65535;
-
- ///
- /// The list of mimetypes that equate to a jpeg.
- ///
- public static readonly IEnumerable MimeTypes = new[] { "image/jpeg", "image/pjpeg" };
-
- ///
- /// The list of file extensions that equate to a jpeg.
- ///
- public static readonly IEnumerable FileExtensions = new[] { "jpg", "jpeg", "jfif" };
-
- ///
- /// Describes common Jpeg markers
- ///
- internal static class Markers
- {
- ///
- /// Marker prefix. Next byte is a marker.
- ///
- public const byte XFF = 0xff;
-
- ///
- /// Same as but of type
- ///
- public const int XFFInt = XFF;
-
- ///
- /// Start of Image
- ///
- public const byte SOI = 0xd8;
-
- ///
- /// Start of Frame (baseline DCT)
- ///
- /// Indicates that this is a baseline DCT-based JPEG, and specifies the width, height, number of components,
- /// and component subsampling (e.g., 4:2:0).
- ///
- ///
- public const byte SOF0 = 0xc0;
-
- ///
- /// Start Of Frame (Extended Sequential DCT)
- ///
- /// Indicates that this is a progressive DCT-based JPEG, and specifies the width, height, number of components,
- /// and component subsampling (e.g., 4:2:0).
- ///
- ///
- public const byte SOF1 = 0xc1;
-
- ///
- /// Start Of Frame (progressive DCT)
- ///
- /// Indicates that this is a progressive DCT-based JPEG, and specifies the width, height, number of components,
- /// and component subsampling (e.g., 4:2:0).
- ///
- ///
- public const byte SOF2 = 0xc2;
-
- ///
- /// Define Huffman Table(s)
- ///
- /// Specifies one or more Huffman tables.
- ///
- ///
- public const byte DHT = 0xc4;
-
- ///
- /// Define Quantization Table(s)
- ///
- /// Specifies one or more quantization tables.
- ///
- ///
- public const byte DQT = 0xdb;
-
- ///
- /// Define Restart Interval
- ///
- /// Specifies the interval between RSTn markers, in macroblocks. This marker is followed by two bytes
- /// indicating the fixed size so it can be treated like any other variable size segment.
- ///
- ///
- public const byte DRI = 0xdd;
-
- ///
- /// Define First Restart
- ///
- /// Inserted every r macroblocks, where r is the restart interval set by a DRI marker.
- /// Not used if there was no DRI marker. The low three bits of the marker code cycle in value from 0 to 7.
- ///
- ///
- public const byte RST0 = 0xd0;
-
- ///
- /// Define Eigth Restart
- ///
- /// Inserted every r macroblocks, where r is the restart interval set by a DRI marker.
- /// Not used if there was no DRI marker. The low three bits of the marker code cycle in value from 0 to 7.
- ///
- ///
- public const byte RST7 = 0xd7;
-
- ///
- /// Start of Scan
- ///
- /// Begins a top-to-bottom scan of the image. In baseline DCT JPEG images, there is generally a single scan.
- /// Progressive DCT JPEG images usually contain multiple scans. This marker specifies which slice of data it
- /// will contain, and is immediately followed by entropy-coded data.
- ///
- ///
- public const byte SOS = 0xda;
-
- ///
- /// Comment
- ///
- /// Contains a text comment.
- ///
- ///
- public const byte COM = 0xfe;
-
- ///
- /// End of Image
- ///
- public const byte EOI = 0xd9;
-
- ///
- /// Application specific marker for marking the jpeg format.
- ///
- ///
- public const byte APP0 = 0xe0;
-
- ///
- /// Application specific marker for marking where to store metadata.
- ///
- public const byte APP1 = 0xe1;
-
- ///
- /// Application specific marker for marking where to store ICC profile information.
- ///
- public const byte APP2 = 0xe2;
-
- ///
- /// Application specific marker used by Adobe for storing encoding information for DCT filters.
- ///
- public const byte APP14 = 0xee;
-
- ///
- /// Application specific marker used by GraphicConverter to store JPEG quality.
- ///
- public const byte APP15 = 0xef;
- }
-
- ///
- /// Describes Adobe specific markers
- ///
- internal static class Adobe
- {
- ///
- /// The color transform is unknown.(RGB or CMYK)
- ///
- public const int ColorTransformUnknown = 0;
-
- ///
- /// The color transform is YCbCr (luminance, red chroma, blue chroma)
- ///
- public const int ColorTransformYCbCr = 1;
-
- ///
- /// The color transform is YCCK (luminance, red chroma, blue chroma, keyline)
- ///
- public const int ColorTransformYcck = 2;
- }
- }
-}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegConstants.cs b/src/ImageSharp/Formats/Jpeg/JpegConstants.cs
similarity index 78%
rename from src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegConstants.cs
rename to src/ImageSharp/Formats/Jpeg/JpegConstants.cs
index 437f772860..49e3b41704 100644
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegConstants.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegConstants.cs
@@ -1,23 +1,45 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-// ReSharper disable InconsistentNaming
-namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
+using System.Collections.Generic;
+
+namespace SixLabors.ImageSharp.Formats.Jpeg
{
///
- /// Contains jpeg constant values
+ /// Contains jpeg constant values defined in the specification.
///
- internal static class PdfJsJpegConstants
+ internal static class JpegConstants
{
+ ///
+ /// The maximum allowable length in each dimension of a jpeg image.
+ ///
+ public const ushort MaxLength = 65535;
+
+ ///
+ /// The list of mimetypes that equate to a jpeg.
+ ///
+ public static readonly IEnumerable MimeTypes = new[] { "image/jpeg", "image/pjpeg" };
+
+ ///
+ /// The list of file extensions that equate to a jpeg.
+ ///
+ public static readonly IEnumerable FileExtensions = new[] { "jpg", "jpeg", "jfif" };
+
///
/// Contains marker specific constants
///
- public static class Markers
+ // ReSharper disable InconsistentNaming
+ internal static class Markers
{
///
/// The prefix used for all markers.
///
- public const byte Prefix = 0xFF;
+ public const byte XFF = 0xFF;
+
+ ///
+ /// Same as but of type
+ ///
+ public const int XFFInt = XFF;
///
/// The Start of Image marker
@@ -161,7 +183,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
///
/// Define Restart Interval
///
- /// Specifies the interval between RSTn markers, in macroblocks.This marker is followed by two bytes indicating the fixed size so it can be treated like any other variable size segment.
+ /// Specifies the interval between RSTn markers, in macroblocks.This marker is followed by two bytes indicating the fixed size so
+ /// it can be treated like any other variable size segment.
///
///
public const byte DRI = 0xDD;
@@ -193,27 +216,27 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
///
///
public const byte RST7 = 0xD7;
+ }
+ ///
+ /// Contains Adobe specific constants
+ ///
+ internal static class Adobe
+ {
///
- /// Contains Adobe specific markers
+ /// The color transform is unknown.(RGB or CMYK)
///
- public static class Adobe
- {
- ///
- /// The color transform is unknown.(RGB or CMYK)
- ///
- public const byte ColorTransformUnknown = 0;
+ public const byte ColorTransformUnknown = 0;
- ///
- /// The color transform is YCbCr (luminance, red chroma, blue chroma)
- ///
- public const byte ColorTransformYCbCr = 1;
+ ///
+ /// The color transform is YCbCr (luminance, red chroma, blue chroma)
+ ///
+ public const byte ColorTransformYCbCr = 1;
- ///
- /// The color transform is YCCK (luminance, red chroma, blue chroma, keyline)
- ///
- public const byte ColorTransformYcck = 2;
- }
+ ///
+ /// The color transform is YCCK (luminance, red chroma, blue chroma, keyline)
+ ///
+ public const byte ColorTransformYcck = 2;
}
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs
index 91835b5d71..e738982cba 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegDecoder.cs
@@ -3,7 +3,7 @@
using System.IO;
-using SixLabors.ImageSharp.Formats.Jpeg.GolangPort;
+using SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats.Jpeg
@@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
{
Guard.NotNull(stream, nameof(stream));
- using (var decoder = new OrigJpegDecoderCore(configuration, this))
+ using (var decoder = new PdfJsJpegDecoderCore(configuration, this))
{
return decoder.Decode(stream);
}
@@ -35,7 +35,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
{
Guard.NotNull(stream, "stream");
- using (var decoder = new OrigJpegDecoderCore(configuration, this))
+ using (var decoder = new PdfJsJpegDecoderCore(configuration, this))
{
return decoder.Identify(stream);
}
diff --git a/src/ImageSharp/Formats/Jpeg/JpegEncoder.cs b/src/ImageSharp/Formats/Jpeg/JpegEncoder.cs
index 60b00c0f5b..0f389dee0f 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegEncoder.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegEncoder.cs
@@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0.
using System.IO;
-using SixLabors.ImageSharp.Formats.Jpeg.GolangPort;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats.Jpeg
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/JpegEncoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
similarity index 93%
rename from src/ImageSharp/Formats/Jpeg/GolangPort/JpegEncoderCore.cs
rename to src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
index 4fbb20ee82..37279d5263 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/JpegEncoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
@@ -1,19 +1,16 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-using System.Buffers;
using System.IO;
using System.Runtime.CompilerServices;
-using SixLabors.ImageSharp.Formats.Jpeg.Common;
-using SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components;
-using SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Encoder;
-using SixLabors.ImageSharp.Memory;
+
+using SixLabors.ImageSharp.Formats.Jpeg.Components;
+using SixLabors.ImageSharp.Formats.Jpeg.Components.Encoder;
using SixLabors.ImageSharp.MetaData.Profiles.Exif;
using SixLabors.ImageSharp.MetaData.Profiles.Icc;
using SixLabors.ImageSharp.PixelFormats;
-using Block8x8F = SixLabors.ImageSharp.Formats.Jpeg.Common.Block8x8F;
-namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
+namespace SixLabors.ImageSharp.Formats.Jpeg
{
///
/// Image encoder for writing an image to a stream as a jpeg.
@@ -58,7 +55,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
///
private static readonly byte[] SosHeaderYCbCr =
{
- OrigJpegConstants.Markers.XFF, OrigJpegConstants.Markers.SOS,
+ JpegConstants.Markers.XFF, JpegConstants.Markers.SOS,
// Marker
0x00, 0x0c,
@@ -104,11 +101,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
}
};
- ///
- /// Lookup tables for converting Rgb to YCbCr
- ///
- private static RgbToYCbCrTables rgbToYCbCrTables = RgbToYCbCrTables.Create();
-
///
/// A scratch buffer to reduce allocations.
///
@@ -190,7 +182,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
Guard.NotNull(image, nameof(image));
Guard.NotNull(stream, nameof(stream));
- ushort max = OrigJpegConstants.MaxLength;
+ ushort max = JpegConstants.MaxLength;
if (image.Width >= max || image.Height >= max)
{
throw new ImageFormatException($"Image is too large to encode at {image.Width}x{image.Height}.");
@@ -234,8 +226,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
this.WriteStartOfScan(image);
// Write the End Of Image marker.
- this.buffer[0] = OrigJpegConstants.Markers.XFF;
- this.buffer[1] = OrigJpegConstants.Markers.EOI;
+ this.buffer[0] = JpegConstants.Markers.XFF;
+ this.buffer[1] = JpegConstants.Markers.EOI;
stream.Write(this.buffer, 0, 2);
stream.Flush();
}
@@ -382,18 +374,18 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
{
// TODO: Need a JpegScanEncoder class or struct that encapsulates the scan-encoding implementation. (Similar to JpegScanDecoder.)
// (Partially done with YCbCrForwardConverter)
- Block8x8F temp1 = default(Block8x8F);
- Block8x8F temp2 = default(Block8x8F);
+ Block8x8F temp1 = default;
+ Block8x8F temp2 = default;
Block8x8F onStackLuminanceQuantTable = this.luminanceQuantTable;
Block8x8F onStackChrominanceQuantTable = this.chrominanceQuantTable;
- ZigZag unzig = ZigZag.CreateUnzigTable();
+ var unzig = ZigZag.CreateUnzigTable();
// ReSharper disable once InconsistentNaming
int prevDCY = 0, prevDCCb = 0, prevDCCr = 0;
- YCbCrForwardConverter pixelConverter = YCbCrForwardConverter.Create();
+ var pixelConverter = YCbCrForwardConverter.Create();
for (int y = 0; y < pixels.Height; y += 8)
{
@@ -437,12 +429,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
private void WriteApplicationHeader(short horizontalResolution, short verticalResolution)
{
// Write the start of image marker. Markers are always prefixed with with 0xff.
- this.buffer[0] = OrigJpegConstants.Markers.XFF;
- this.buffer[1] = OrigJpegConstants.Markers.SOI;
+ this.buffer[0] = JpegConstants.Markers.XFF;
+ this.buffer[1] = JpegConstants.Markers.SOI;
// Write the JFIF headers
- this.buffer[2] = OrigJpegConstants.Markers.XFF;
- this.buffer[3] = OrigJpegConstants.Markers.APP0; // Application Marker
+ this.buffer[2] = JpegConstants.Markers.XFF;
+ this.buffer[3] = JpegConstants.Markers.APP0; // Application Marker
this.buffer[4] = 0x00;
this.buffer[5] = 0x10;
this.buffer[6] = 0x4a; // J
@@ -502,7 +494,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
this.EmitHuffRLE((HuffIndex)((2 * (int)index) + 0), 0, dc - prevDC);
// Emit the AC components.
- HuffIndex h = (HuffIndex)((2 * (int)index) + 1);
+ var h = (HuffIndex)((2 * (int)index) + 1);
int runLength = 0;
for (int zig = 1; zig < Block8x8F.Size; zig++)
@@ -556,7 +548,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
markerlen += 1 + 16 + s.Values.Length;
}
- this.WriteMarkerHeader(OrigJpegConstants.Markers.DHT, markerlen);
+ this.WriteMarkerHeader(JpegConstants.Markers.DHT, markerlen);
for (int i = 0; i < specs.Length; i++)
{
HuffmanSpec spec = specs[i];
@@ -590,7 +582,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
{
// Marker + quantization table lengths
int markerlen = 2 + (QuantizationTableCount * (1 + Block8x8F.Size));
- this.WriteMarkerHeader(OrigJpegConstants.Markers.DQT, markerlen);
+ this.WriteMarkerHeader(JpegConstants.Markers.DQT, markerlen);
// Loop through and collect the tables as one array.
// This allows us to reduce the number of writes to the stream.
@@ -627,8 +619,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
int length = data.Length + 2;
- this.buffer[0] = OrigJpegConstants.Markers.XFF;
- this.buffer[1] = OrigJpegConstants.Markers.APP1; // Application Marker
+ this.buffer[0] = JpegConstants.Markers.XFF;
+ this.buffer[1] = JpegConstants.Markers.APP1; // Application Marker
this.buffer[2] = (byte)((length >> 8) & 0xFF);
this.buffer[3] = (byte)(length & 0xFF);
@@ -686,8 +678,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
dataLength -= length;
- this.buffer[0] = OrigJpegConstants.Markers.XFF;
- this.buffer[1] = OrigJpegConstants.Markers.APP2; // Application Marker
+ this.buffer[0] = JpegConstants.Markers.XFF;
+ this.buffer[1] = JpegConstants.Markers.APP2; // Application Marker
int markerLength = length + 16;
this.buffer[2] = (byte)((markerLength >> 8) & 0xFF);
this.buffer[3] = (byte)(markerLength & 0xFF);
@@ -759,7 +751,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
// Length (high byte, low byte), 8 + components * 3.
int markerlen = 8 + (3 * componentCount);
- this.WriteMarkerHeader(OrigJpegConstants.Markers.SOF0, markerlen);
+ this.WriteMarkerHeader(JpegConstants.Markers.SOF0, markerlen);
this.buffer[0] = 8; // Data Precision. 8 for now, 12 and 16 bit jpegs not supported
this.buffer[1] = (byte)(height >> 8);
this.buffer[2] = (byte)(height & 0xff); // (2 bytes, Hi-Lo), must be > 0 if DNL not supported
@@ -827,20 +819,20 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
where TPixel : struct, IPixel
{
// TODO: Need a JpegScanEncoder class or struct that encapsulates the scan-encoding implementation. (Similar to JpegScanDecoder.)
- Block8x8F b = default(Block8x8F);
+ Block8x8F b = default;
- BlockQuad cb = default(BlockQuad);
- BlockQuad cr = default(BlockQuad);
- Block8x8F* cbPtr = (Block8x8F*)cb.Data;
- Block8x8F* crPtr = (Block8x8F*)cr.Data;
+ BlockQuad cb = default;
+ BlockQuad cr = default;
+ var cbPtr = (Block8x8F*)cb.Data;
+ var crPtr = (Block8x8F*)cr.Data;
- Block8x8F temp1 = default(Block8x8F);
- Block8x8F temp2 = default(Block8x8F);
+ Block8x8F temp1 = default;
+ Block8x8F temp2 = default;
Block8x8F onStackLuminanceQuantTable = this.luminanceQuantTable;
Block8x8F onStackChrominanceQuantTable = this.chrominanceQuantTable;
- ZigZag unzig = ZigZag.CreateUnzigTable();
+ var unzig = ZigZag.CreateUnzigTable();
var pixelConverter = YCbCrForwardConverter.Create();
@@ -902,7 +894,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
private void WriteMarkerHeader(byte marker, int length)
{
// Markers are always prefixed with with 0xff.
- this.buffer[0] = OrigJpegConstants.Markers.XFF;
+ this.buffer[0] = JpegConstants.Markers.XFF;
this.buffer[1] = marker;
this.buffer[2] = (byte)(length >> 8);
this.buffer[3] = (byte)(length & 0xff);
diff --git a/src/ImageSharp/Formats/Jpeg/JpegFormat.cs b/src/ImageSharp/Formats/Jpeg/JpegFormat.cs
index 4f368dcdee..9a18f14d30 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegFormat.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegFormat.cs
@@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0.
using System.Collections.Generic;
-using SixLabors.ImageSharp.Formats.Jpeg.GolangPort;
namespace SixLabors.ImageSharp.Formats.Jpeg
{
@@ -18,9 +17,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
public string DefaultMimeType => "image/jpeg";
///
- public IEnumerable MimeTypes => OrigJpegConstants.MimeTypes;
+ public IEnumerable MimeTypes => JpegConstants.MimeTypes;
///
- public IEnumerable FileExtensions => OrigJpegConstants.FileExtensions;
+ public IEnumerable FileExtensions => JpegConstants.FileExtensions;
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs
index f063309eac..ccbb5c6c01 100644
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs
+++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsFrameComponent.cs
@@ -4,8 +4,9 @@
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-using SixLabors.ImageSharp.Formats.Jpeg.Common;
-using SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder;
+
+using SixLabors.ImageSharp.Formats.Jpeg.Components;
+using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder;
using SixLabors.ImageSharp.Memory;
using SixLabors.Primitives;
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsScanDecoder.cs
index 0736fd342b..69331e1ca9 100644
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsScanDecoder.cs
+++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsScanDecoder.cs
@@ -7,7 +7,8 @@ using System.Diagnostics;
#endif
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-using SixLabors.ImageSharp.Formats.Jpeg.Common;
+
+using SixLabors.ImageSharp.Formats.Jpeg.Components;
namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
{
@@ -136,7 +137,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
byte marker = fileMarker.Marker;
// RSTn - We've already read the bytes and altered the position so no need to skip
- if (marker >= PdfJsJpegConstants.Markers.RST0 && marker <= PdfJsJpegConstants.Markers.RST7)
+ if (marker >= JpegConstants.Markers.RST0 && marker <= JpegConstants.Markers.RST7)
{
continue;
}
@@ -452,7 +453,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
this.endOfStreamReached = true;
return false;
- case PdfJsJpegConstants.Markers.Prefix:
+ case JpegConstants.Markers.XFF:
int nextByte = stream.ReadByte();
if (nextByte == -0x1)
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs
index f1d1053881..05d9def681 100644
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs
@@ -7,8 +7,9 @@ using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
-using SixLabors.ImageSharp.Formats.Jpeg.Common;
-using SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder;
+
+using SixLabors.ImageSharp.Formats.Jpeg.Components;
+using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder;
using SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.MetaData;
@@ -98,15 +99,23 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
///
public PdfJsFrame Frame { get; private set; }
+ ///
+ public Size ImageSizeInPixels { get; private set; }
+
+ ///
+ /// Gets the number of MCU blocks in the image as .
+ ///
+ public Size ImageSizeInMCU { get; private set; }
+
///
/// Gets the image width
///
- public int ImageWidth { get; private set; }
+ public int ImageWidth => this.ImageSizeInPixels.Width;
///
/// Gets the image height
///
- public int ImageHeight { get; private set; }
+ public int ImageHeight => this.ImageSizeInPixels.Height;
///
/// Gets the color depth, in number of bits per pixel.
@@ -128,17 +137,19 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
///
public ImageMetaData MetaData { get; private set; }
- ///
- public Size ImageSizeInPixels => new Size(this.ImageWidth, this.ImageHeight);
-
///
public int ComponentCount { get; private set; }
///
public JpegColorSpace ColorSpace { get; private set; }
+ ///
+ /// Gets the components.
+ ///
+ public PdfJsFrameComponent[] Components => this.Frame.Components;
+
///
- public IEnumerable Components => this.Frame.Components;
+ IEnumerable IRawJpegData.Components => this.Components;
///
public Block8x8F[] QuantizationTables { get; private set; }
@@ -155,20 +166,20 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
if (value == 0)
{
- return new PdfJsFileMarker(PdfJsJpegConstants.Markers.EOI, stream.Length - 2);
+ return new PdfJsFileMarker(JpegConstants.Markers.EOI, stream.Length - 2);
}
- if (marker[0] == PdfJsJpegConstants.Markers.Prefix)
+ if (marker[0] == JpegConstants.Markers.XFF)
{
// According to Section B.1.1.2:
// "Any marker may optionally be preceded by any number of fill bytes, which are bytes assigned code 0xFF."
int m = marker[1];
- while (m == PdfJsJpegConstants.Markers.Prefix)
+ while (m == JpegConstants.Markers.XFF)
{
int suffix = stream.ReadByte();
if (suffix == -1)
{
- return new PdfJsFileMarker(PdfJsJpegConstants.Markers.EOI, stream.Length - 2);
+ return new PdfJsFileMarker(JpegConstants.Markers.EOI, stream.Length - 2);
}
m = suffix;
@@ -190,7 +201,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
where TPixel : struct, IPixel
{
this.ParseStream(stream);
- this.AssignResolution();
+ this.InitDerivedMetaDataProperties();
return this.PostProcessIntoImage();
}
@@ -201,7 +212,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
public IImageInfo Identify(Stream stream)
{
this.ParseStream(stream, true);
- this.AssignResolution();
+ this.InitDerivedMetaDataProperties();
return new ImageInfo(new PixelTypeInfo(this.BitsPerPixel), this.ImageWidth, this.ImageHeight, this.MetaData);
}
@@ -218,7 +229,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
// Check for the Start Of Image marker.
this.InputStream.Read(this.markerBuffer, 0, 2);
var fileMarker = new PdfJsFileMarker(this.markerBuffer[1], 0);
- if (fileMarker.Marker != PdfJsJpegConstants.Markers.SOI)
+ if (fileMarker.Marker != JpegConstants.Markers.SOI)
{
throw new ImageFormatException("Missing SOI marker.");
}
@@ -236,7 +247,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
this.fastACTables = new FastACTables(this.configuration.MemoryManager);
}
- while (fileMarker.Marker != PdfJsJpegConstants.Markers.EOI)
+ while (fileMarker.Marker != JpegConstants.Markers.EOI)
{
if (!fileMarker.Invalid)
{
@@ -245,13 +256,13 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
switch (fileMarker.Marker)
{
- case PdfJsJpegConstants.Markers.SOF0:
- case PdfJsJpegConstants.Markers.SOF1:
- case PdfJsJpegConstants.Markers.SOF2:
+ case JpegConstants.Markers.SOF0:
+ case JpegConstants.Markers.SOF1:
+ case JpegConstants.Markers.SOF2:
this.ProcessStartOfFrameMarker(remaining, fileMarker, metadataOnly);
break;
- case PdfJsJpegConstants.Markers.SOS:
+ case JpegConstants.Markers.SOS:
if (!metadataOnly)
{
this.ProcessStartOfScanMarker();
@@ -264,7 +275,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
return;
}
- case PdfJsJpegConstants.Markers.DHT:
+ case JpegConstants.Markers.DHT:
if (metadataOnly)
{
this.InputStream.Skip(remaining);
@@ -276,7 +287,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
break;
- case PdfJsJpegConstants.Markers.DQT:
+ case JpegConstants.Markers.DQT:
if (metadataOnly)
{
this.InputStream.Skip(remaining);
@@ -288,7 +299,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
break;
- case PdfJsJpegConstants.Markers.DRI:
+ case JpegConstants.Markers.DRI:
if (metadataOnly)
{
this.InputStream.Skip(remaining);
@@ -300,38 +311,38 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
break;
- case PdfJsJpegConstants.Markers.APP0:
+ case JpegConstants.Markers.APP0:
this.ProcessApplicationHeaderMarker(remaining);
break;
- case PdfJsJpegConstants.Markers.APP1:
+ case JpegConstants.Markers.APP1:
this.ProcessApp1Marker(remaining);
break;
- case PdfJsJpegConstants.Markers.APP2:
+ case JpegConstants.Markers.APP2:
this.ProcessApp2Marker(remaining);
break;
- case PdfJsJpegConstants.Markers.APP3:
- case PdfJsJpegConstants.Markers.APP4:
- case PdfJsJpegConstants.Markers.APP5:
- case PdfJsJpegConstants.Markers.APP6:
- case PdfJsJpegConstants.Markers.APP7:
- case PdfJsJpegConstants.Markers.APP8:
- case PdfJsJpegConstants.Markers.APP9:
- case PdfJsJpegConstants.Markers.APP10:
- case PdfJsJpegConstants.Markers.APP11:
- case PdfJsJpegConstants.Markers.APP12:
- case PdfJsJpegConstants.Markers.APP13:
+ case JpegConstants.Markers.APP3:
+ case JpegConstants.Markers.APP4:
+ case JpegConstants.Markers.APP5:
+ case JpegConstants.Markers.APP6:
+ case JpegConstants.Markers.APP7:
+ case JpegConstants.Markers.APP8:
+ case JpegConstants.Markers.APP9:
+ case JpegConstants.Markers.APP10:
+ case JpegConstants.Markers.APP11:
+ case JpegConstants.Markers.APP12:
+ case JpegConstants.Markers.APP13:
this.InputStream.Skip(remaining);
break;
- case PdfJsJpegConstants.Markers.APP14:
+ case JpegConstants.Markers.APP14:
this.ProcessApp14Marker(remaining);
break;
- case PdfJsJpegConstants.Markers.APP15:
- case PdfJsJpegConstants.Markers.COM:
+ case JpegConstants.Markers.APP15:
+ case JpegConstants.Markers.COM:
this.InputStream.Skip(remaining);
break;
}
@@ -370,11 +381,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
if (this.ComponentCount == 3)
{
- if (this.adobe.Equals(default) || this.adobe.ColorTransform == PdfJsJpegConstants.Markers.Adobe.ColorTransformYCbCr)
+ if (this.adobe.Equals(default) || this.adobe.ColorTransform == JpegConstants.Adobe.ColorTransformYCbCr)
{
return JpegColorSpace.YCbCr;
}
- else if (this.adobe.ColorTransform == PdfJsJpegConstants.Markers.Adobe.ColorTransformUnknown)
+
+ if (this.adobe.ColorTransform == JpegConstants.Adobe.ColorTransformUnknown)
{
return JpegColorSpace.RGB;
}
@@ -382,7 +394,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
if (this.ComponentCount == 4)
{
- return this.adobe.ColorTransform == PdfJsJpegConstants.Markers.Adobe.ColorTransformYcck
+ return this.adobe.ColorTransform == JpegConstants.Adobe.ColorTransformYcck
? JpegColorSpace.Ycck
: JpegColorSpace.Cmyk;
}
@@ -391,13 +403,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
}
///
- /// Assigns the horizontal and vertical resolution to the image if it has a JFIF header or EXIF metadata.
+ /// Assigns derived metadata properties to , eg. horizontal and vertical resolution if it has a JFIF header.
///
- private void AssignResolution()
+ private void InitDerivedMetaDataProperties()
{
- this.ImageWidth = this.Frame.SamplesPerLine;
- this.ImageHeight = this.Frame.Scanlines;
-
if (this.jFif.XDensity > 0 && this.jFif.YDensity > 0)
{
this.MetaData.HorizontalResolution = this.jFif.XDensity;
@@ -419,6 +428,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
this.MetaData.VerticalResolution = verticalValue;
}
}
+
+ if (this.MetaData.IccProfile?.CheckIsValid() == false)
+ {
+ this.MetaData.IccProfile = null;
+ }
}
///
@@ -630,59 +644,58 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
this.Frame = new PdfJsFrame
{
- Extended = frameMarker.Marker == PdfJsJpegConstants.Markers.SOF1,
- Progressive = frameMarker.Marker == PdfJsJpegConstants.Markers.SOF2,
+ Extended = frameMarker.Marker == JpegConstants.Markers.SOF1,
+ Progressive = frameMarker.Marker == JpegConstants.Markers.SOF2,
Precision = this.temp[0],
Scanlines = (short)((this.temp[1] << 8) | this.temp[2]),
SamplesPerLine = (short)((this.temp[3] << 8) | this.temp[4]),
ComponentCount = this.temp[5]
};
+ this.ImageSizeInPixels = new Size(this.Frame.SamplesPerLine, this.Frame.Scanlines);
+
int maxH = 0;
int maxV = 0;
int index = 6;
this.ComponentCount = this.Frame.ComponentCount;
+
if (!metadataOnly)
{
// No need to pool this. They max out at 4
this.Frame.ComponentIds = new byte[this.Frame.ComponentCount];
this.Frame.Components = new PdfJsFrameComponent[this.Frame.ComponentCount];
- }
-
- for (int i = 0; i < this.Frame.ComponentCount; i++)
- {
- byte hv = this.temp[index + 1];
- int h = hv >> 4;
- int v = hv & 15;
+ this.ColorSpace = this.DeduceJpegColorSpace();
- if (maxH < h)
+ for (int i = 0; i < this.Frame.ComponentCount; i++)
{
- maxH = h;
- }
+ byte hv = this.temp[index + 1];
+ int h = hv >> 4;
+ int v = hv & 15;
- if (maxV < v)
- {
- maxV = v;
- }
+ if (maxH < h)
+ {
+ maxH = h;
+ }
+
+ if (maxV < v)
+ {
+ maxV = v;
+ }
- if (!metadataOnly)
- {
var component = new PdfJsFrameComponent(this.configuration.MemoryManager, this.Frame, this.temp[index], h, v, this.temp[index + 2], i);
this.Frame.Components[i] = component;
this.Frame.ComponentIds[i] = component.Id;
- }
- index += 3;
- }
-
- this.Frame.MaxHorizontalFactor = maxH;
- this.Frame.MaxVerticalFactor = maxV;
+ index += 3;
+ }
- if (!metadataOnly)
- {
+ this.Frame.MaxHorizontalFactor = maxH;
+ this.Frame.MaxVerticalFactor = maxV;
+ this.ColorSpace = this.DeduceJpegColorSpace();
this.Frame.InitComponents();
+ this.ImageSizeInMCU = new Size(this.Frame.McusPerLine, this.Frame.McusPerColumn);
}
}
@@ -852,7 +865,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
private Image PostProcessIntoImage()
where TPixel : struct, IPixel
{
- this.ColorSpace = this.DeduceJpegColorSpace();
using (var postProcessor = new JpegImagePostProcessor(this.configuration.MemoryManager, this))
{
var image = new Image(this.configuration, this.ImageWidth, this.ImageHeight, this.MetaData);
diff --git a/src/ImageSharp/Formats/Png/Filters/NoneFilter.cs b/src/ImageSharp/Formats/Png/Filters/NoneFilter.cs
index 0164ceafaa..97e16ef233 100644
--- a/src/ImageSharp/Formats/Png/Filters/NoneFilter.cs
+++ b/src/ImageSharp/Formats/Png/Filters/NoneFilter.cs
@@ -3,7 +3,6 @@
using System;
using System.Runtime.CompilerServices;
-using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Png.Filters
{
@@ -20,12 +19,12 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
/// The scanline to encode
/// The filtered scanline result.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void Encode(Span scanline, Span result)
+ public static void Encode(ReadOnlySpan scanline, Span result)
{
// Insert a byte before the data.
result[0] = 0;
result = result.Slice(1);
- SpanHelper.Copy(scanline, result);
+ scanline.Slice(0, Math.Min(scanline.Length, result.Length)).CopyTo(result);
}
}
-}
+}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
index 8fefcb480c..cc98b8450b 100644
--- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
@@ -853,7 +853,7 @@ namespace SixLabors.ImageSharp.Formats.Png
where TPixel : struct, IPixel
{
ReadOnlySpan newScanline = ToArrayByBitsLength(defilteredScanline, this.bytesPerScanline, this.header.BitDepth);
- byte[] pal = this.palette;
+ ReadOnlySpan pal = MemoryMarshal.Cast(this.palette);
var color = default(TPixel);
var rgba = default(Rgba32);
@@ -865,10 +865,9 @@ namespace SixLabors.ImageSharp.Formats.Png
for (int x = 0; x < this.header.Width; x++)
{
int index = newScanline[x];
- int pixelOffset = index * 3;
rgba.A = this.paletteAlpha.Length > index ? this.paletteAlpha[index] : (byte)255;
- rgba.Rgb = pal.GetRgb24(pixelOffset);
+ rgba.Rgb = pal[index];
color.PackFromRgba32(rgba);
row[x] = color;
@@ -881,9 +880,8 @@ namespace SixLabors.ImageSharp.Formats.Png
for (int x = 0; x < this.header.Width; x++)
{
int index = newScanline[x];
- int pixelOffset = index * 3;
- rgba.Rgb = pal.GetRgb24(pixelOffset);
+ rgba.Rgb = pal[index];
color.PackFromRgba32(rgba);
row[x] = color;
@@ -946,6 +944,7 @@ namespace SixLabors.ImageSharp.Formats.Png
ReadOnlySpan newScanline = ToArrayByBitsLength(scanlineBuffer, this.bytesPerScanline, this.header.BitDepth);
var rgba = default(Rgba32);
+ Span pal = MemoryMarshal.Cast(this.palette);
if (this.paletteAlpha != null && this.paletteAlpha.Length > 0)
{
@@ -954,10 +953,9 @@ namespace SixLabors.ImageSharp.Formats.Png
for (int x = pixelOffset, o = 0; x < this.header.Width; x += increment, o++)
{
int index = newScanline[o];
- int offset = index * 3;
rgba.A = this.paletteAlpha.Length > index ? this.paletteAlpha[index] : (byte)255;
- rgba.Rgb = this.palette.GetRgb24(offset);
+ rgba.Rgb = pal[index];
color.PackFromRgba32(rgba);
rowSpan[x] = color;
@@ -970,10 +968,8 @@ namespace SixLabors.ImageSharp.Formats.Png
for (int x = pixelOffset, o = 0; x < this.header.Width; x += increment, o++)
{
int index = newScanline[o];
- int offset = index * 3;
-
- rgba.Rgb = this.palette.GetRgb24(offset);
+ rgba.Rgb = pal[index];
color.PackFromRgba32(rgba);
rowSpan[x] = color;
}
diff --git a/src/ImageSharp/Image.LoadPixelData.cs b/src/ImageSharp/Image.LoadPixelData.cs
index 0179e62acc..282f980865 100644
--- a/src/ImageSharp/Image.LoadPixelData.cs
+++ b/src/ImageSharp/Image.LoadPixelData.cs
@@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp
/// The height of the final image.
/// The pixel format.
/// A new .
- private static Image LoadPixelData(Span data, int width, int height)
+ public static Image LoadPixelData(ReadOnlySpan data, int width, int height)
where TPixel : struct, IPixel
=> LoadPixelData(Configuration.Default, data, width, height);
@@ -57,7 +57,7 @@ namespace SixLabors.ImageSharp
/// The height of the final image.
/// The pixel format.
/// A new .
- private static Image LoadPixelData(Span data, int width, int height)
+ public static Image LoadPixelData(ReadOnlySpan data, int width, int height)
where TPixel : struct, IPixel
=> LoadPixelData(Configuration.Default, data, width, height);
@@ -72,7 +72,7 @@ namespace SixLabors.ImageSharp
/// A new .
public static Image LoadPixelData(Configuration config, byte[] data, int width, int height)
where TPixel : struct, IPixel
- => LoadPixelData(config, MemoryMarshal.Cast(data.AsSpan()), width, height);
+ => LoadPixelData(config, MemoryMarshal.Cast(new ReadOnlySpan(data)), width, height);
///
/// Create a new instance of the class from the given byte array in format.
@@ -83,7 +83,7 @@ namespace SixLabors.ImageSharp
/// The height of the final image.
/// The pixel format.
/// A new .
- private static Image LoadPixelData(Configuration config, Span data, int width, int height)
+ public static Image LoadPixelData(Configuration config, ReadOnlySpan data, int width, int height)
where TPixel : struct, IPixel
=> LoadPixelData(config, MemoryMarshal.Cast(data), width, height);
@@ -99,7 +99,7 @@ namespace SixLabors.ImageSharp
public static Image LoadPixelData(Configuration config, TPixel[] data, int width, int height)
where TPixel : struct, IPixel
{
- return LoadPixelData(config, data.AsSpan(), width, height);
+ return LoadPixelData(config, new ReadOnlySpan(data), width, height);
}
///
@@ -111,7 +111,7 @@ namespace SixLabors.ImageSharp
/// The height of the final image.
/// The pixel format.
/// A new .
- private static Image LoadPixelData(Configuration config, Span data, int width, int height)
+ public static Image LoadPixelData(Configuration config, ReadOnlySpan data, int width, int height)
where TPixel : struct, IPixel
{
int count = width * height;
diff --git a/src/ImageSharp/ImageExtensions.cs b/src/ImageSharp/ImageExtensions.cs
index 2cdb71fc0e..d8cda2f8fc 100644
--- a/src/ImageSharp/ImageExtensions.cs
+++ b/src/ImageSharp/ImageExtensions.cs
@@ -4,13 +4,11 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.Primitives;
namespace SixLabors.ImageSharp
{
@@ -21,18 +19,18 @@ namespace SixLabors.ImageSharp
{
#if !NETSTANDARD1_1
///
- /// Saves the image to the given stream using the currently loaded image format.
+ /// Writes the image to the given stream using the currently loaded image format.
///
- /// The Pixel format.
- /// The source image
+ /// The pixel format.
+ /// The source image.
/// The file path to save the image to.
/// Thrown if the stream is null.
public static void Save(this Image source, string filePath)
where TPixel : struct, IPixel
{
- Guard.NotNullOrEmpty(filePath, nameof(filePath));
+ Guard.NotNullOrWhiteSpace(filePath, nameof(filePath));
- string ext = Path.GetExtension(filePath).Trim('.');
+ string ext = Path.GetExtension(filePath);
IImageFormat format = source.GetConfiguration().ImageFormatsManager.FindFormatByFileExtension(ext);
if (format == null)
{
@@ -64,13 +62,13 @@ namespace SixLabors.ImageSharp
}
///
- /// Saves the image to the given stream using the currently loaded image format.
+ /// Writes the image to the given stream using the currently loaded image format.
///
- /// The Pixel format.
- /// The source image
+ /// The pixel format.
+ /// The source image.
/// The file path to save the image to.
/// The encoder to save the image with.
- /// Thrown if the encoder is null.
+ /// Thrown if the encoder is null.
public static void Save(this Image source, string filePath, IImageEncoder encoder)
where TPixel : struct, IPixel
{
@@ -83,13 +81,13 @@ namespace SixLabors.ImageSharp
#endif
///
- /// Saves the image to the given stream using the currently loaded image format.
+ /// Writes the image to the given stream using the currently loaded image format.
///
/// The Pixel format.
- /// The source image
+ /// The source image.
/// The stream to save the image to.
- /// The format to save the image to.
- /// Thrown if the stream is null.
+ /// The format to save the image in.
+ /// Thrown if the stream is null.
public static void Save(this Image source, Stream stream, IImageFormat format)
where TPixel : struct, IPixel
{
@@ -113,67 +111,67 @@ namespace SixLabors.ImageSharp
}
///
- /// Saves the raw image pixels to a byte array in row-major order.
+ /// Returns the a copy of the image pixels as a byte array in row-major order.
///
- /// The Pixel format.
+ /// The pixel format.
/// The source image
/// A copy of the pixel data as bytes from this frame.
- /// Thrown if the stream is null.
+ /// Thrown if the stream is null.
public static byte[] SavePixelData(this ImageFrame source)
where TPixel : struct, IPixel
=> MemoryMarshal.AsBytes(source.GetPixelSpan()).ToArray();
///
- /// Saves the raw image pixels to the given byte array in row-major order.
+ /// Writes the raw image pixels to the given byte array in row-major order.
///
- /// The Pixel format.
- /// The source image
+ /// The pixel format.
+ /// The source image.
/// The buffer to save the raw pixel data to.
- /// Thrown if the stream is null.
+ /// Thrown if the stream is null.
public static void SavePixelData(this ImageFrame source, byte[] buffer)
where TPixel : struct, IPixel
=> SavePixelData(source, MemoryMarshal.Cast(buffer.AsSpan()));
///
- /// Saves the raw image pixels to the given TPixel array in row-major order.
+ /// Writes the raw image pixels to the given TPixel array in row-major order.
///
- /// The Pixel format.
+ /// The pixel format.
/// The source image
/// The buffer to save the raw pixel data to.
- /// Thrown if the stream is null.
+ /// Thrown if the stream is null.
public static void SavePixelData(this ImageFrame source, TPixel[] buffer)
where TPixel : struct, IPixel
=> SavePixelData(source, buffer.AsSpan());
///
- /// Saves the raw image pixels to a byte array in row-major order.
+ /// Returns a copy of the raw image pixels as a byte array in row-major order.
///
- /// The Pixel format.
- /// The source image
+ /// The pixel format.
+ /// The source image.
/// A copy of the pixel data from the first frame as bytes.
- /// Thrown if the stream is null.
+ /// Thrown if the stream is null.
public static byte[] SavePixelData(this Image source)
where TPixel : struct, IPixel
=> source.Frames.RootFrame.SavePixelData();
///
- /// Saves the raw image pixels to the given byte array in row-major order.
+ /// Writes the raw image pixels to the given byte array in row-major order.
///
- /// The Pixel format.
- /// The source image
+ /// The pixel format.
+ /// The source image.
/// The buffer to save the raw pixel data to.
- /// Thrown if the stream is null.
+ /// Thrown if the stream is null.
public static void SavePixelData(this Image source, byte[] buffer)
where TPixel : struct, IPixel
=> source.Frames.RootFrame.SavePixelData(buffer);
///
- /// Saves the raw image pixels to the given TPixel array in row-major order.
+ /// Writes the raw image pixels to the given TPixel array in row-major order.
///
- /// The Pixel format.
+ /// The pixel format.
/// The source image
/// The buffer to save the raw pixel data to.
- /// Thrown if the stream is null.
+ /// Thrown if the stream is null.
public static void SavePixelData(this Image source, TPixel[] buffer)
where TPixel : struct, IPixel
=> source.Frames.RootFrame.SavePixelData(buffer);
@@ -182,7 +180,7 @@ namespace SixLabors.ImageSharp
/// Returns a Base64 encoded string from the given image.
///
///
- /// The Pixel format.
+ /// The pixel format.
/// The source image
/// The format.
/// The
@@ -198,24 +196,24 @@ namespace SixLabors.ImageSharp
}
///
- /// Saves the raw image to the given bytes.
+ /// Writes the raw image bytes to the given byte span.
///
- /// The Pixel format.
+ /// The pixel format.
/// The source image
- /// The buffer to save the raw pixel data to.
+ /// The span to save the raw pixel data to.
/// Thrown if the stream is null.
- internal static void SavePixelData(this Image source, Span buffer)
+ public static void SavePixelData(this Image source, Span buffer)
where TPixel : struct, IPixel
=> source.Frames.RootFrame.SavePixelData(MemoryMarshal.Cast(buffer));
///
- /// Saves the raw image to the given bytes.
+ /// Writes the raw image pixels to the given TPixel span.
///
- /// The Pixel format.
+ /// The pixel format.
/// The source image
- /// The buffer to save the raw pixel data to.
+ /// The span to save the raw pixel data to.
/// Thrown if the stream is null.
- internal static void SavePixelData(this ImageFrame source, Span buffer)
+ public static void SavePixelData(this ImageFrame source, Span buffer)
where TPixel : struct, IPixel
{
Span sourceBuffer = source.GetPixelSpan();
@@ -224,4 +222,4 @@ namespace SixLabors.ImageSharp
sourceBuffer.CopyTo(buffer);
}
}
-}
+}
\ No newline at end of file
diff --git a/src/ImageSharp/ImageFrame.LoadPixelData.cs b/src/ImageSharp/ImageFrame.LoadPixelData.cs
index 1306c28367..33dbe31df7 100644
--- a/src/ImageSharp/ImageFrame.LoadPixelData.cs
+++ b/src/ImageSharp/ImageFrame.LoadPixelData.cs
@@ -4,7 +4,6 @@
using System;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Advanced;
-using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp
@@ -12,37 +11,37 @@ namespace SixLabors.ImageSharp
///
/// Adds static methods allowing the creation of new image from raw pixel data.
///
- internal static partial class ImageFrame
+ internal static class ImageFrame
{
///
/// Create a new instance of the class from the given byte array in format.
///
- /// The memory manager to use for allocations
+ /// The configuration which allows altering default behaviour or extending the library.
/// The byte array containing image data.
/// The width of the final image.
/// The height of the final image.
/// The pixel format.
/// A new .
- public static ImageFrame LoadPixelData(MemoryManager memoryManager, Span data, int width, int height)
+ public static ImageFrame LoadPixelData(Configuration configuration, ReadOnlySpan data, int width, int height)
where TPixel : struct, IPixel
- => LoadPixelData(memoryManager, MemoryMarshal.Cast(data), width, height);
+ => LoadPixelData(configuration, MemoryMarshal.Cast(data), width, height);
///
/// Create a new instance of the class from the raw data.
///
- /// The memory manager to use for allocations
+ /// The configuration which allows altering default behaviour or extending the library.
/// The Span containing the image Pixel data.
/// The width of the final image.
/// The height of the final image.
/// The pixel format.
/// A new .
- public static ImageFrame LoadPixelData(MemoryManager memoryManager, Span data, int width, int height)
+ public static ImageFrame LoadPixelData(Configuration configuration, ReadOnlySpan data, int width, int height)
where TPixel : struct, IPixel
{
int count = width * height;
Guard.MustBeGreaterThanOrEqualTo(data.Length, count, nameof(data));
- var image = new ImageFrame(memoryManager, width, height);
+ var image = new ImageFrame(configuration, width, height);
data.Slice(0, count).CopyTo(image.GetPixelSpan());
diff --git a/src/ImageSharp/ImageFrameCollection.cs b/src/ImageSharp/ImageFrameCollection.cs
index 0318a7068d..c101b48d30 100644
--- a/src/ImageSharp/ImageFrameCollection.cs
+++ b/src/ImageSharp/ImageFrameCollection.cs
@@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp
internal ImageFrameCollection(Image parent, IEnumerable> frames)
{
Guard.NotNull(parent, nameof(parent));
- Guard.NotNullOrEmpty(frames, nameof(frames));
+ Guard.NotNull(frames, nameof(frames));
this.parent = parent;
@@ -42,6 +42,12 @@ namespace SixLabors.ImageSharp
this.ValidateFrame(f);
this.frames.Add(f);
}
+
+ // Ensure at least 1 frame was added to the frames collection
+ if (this.frames.Count == 0)
+ {
+ throw new ArgumentException("Must not be empty.", nameof(frames));
+ }
}
///
@@ -110,8 +116,8 @@ namespace SixLabors.ImageSharp
Guard.NotNull(source, nameof(source));
var frame = ImageFrame.LoadPixelData(
- this.parent.GetMemoryManager(),
- new Span(source),
+ this.parent.GetConfiguration(),
+ new ReadOnlySpan(source),
this.RootFrame.Width,
this.RootFrame.Height);
this.frames.Add(frame);
diff --git a/src/ImageSharp/ImageFrame{TPixel}.cs b/src/ImageSharp/ImageFrame{TPixel}.cs
index c3955c1321..0caacd8a8d 100644
--- a/src/ImageSharp/ImageFrame{TPixel}.cs
+++ b/src/ImageSharp/ImageFrame{TPixel}.cs
@@ -4,7 +4,6 @@
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
using System.Threading.Tasks;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory;
@@ -19,53 +18,61 @@ namespace SixLabors.ImageSharp
///
/// The pixel format.
public sealed class ImageFrame : IPixelSource, IDisposable
- where TPixel : struct, IPixel {
+ where TPixel : struct, IPixel
+ {
+ private readonly Configuration configuration;
private bool isDisposed;
///
/// Initializes a new instance of the class.
///
- /// The to use for buffer allocations.
+ /// The configuration which allows altering default behaviour or extending the library.
/// The width of the image in pixels.
/// The height of the image in pixels.
- internal ImageFrame(MemoryManager memoryManager, int width, int height)
- : this(memoryManager, width, height, new ImageFrameMetaData()) {
+ internal ImageFrame(Configuration configuration, int width, int height)
+ : this(configuration, width, height, new ImageFrameMetaData())
+ {
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The configuration which allows altering default behaviour or extending the library.
+ /// The of the frame.
+ /// The meta data.
+ internal ImageFrame(Configuration configuration, Size size, ImageFrameMetaData metaData)
+ : this(configuration, size.Width, size.Height, metaData)
+ {
}
///
/// Initializes a new instance of the class.
///
- /// The to use for buffer allocations.
+ /// The configuration which allows altering default behaviour or extending the library.
/// The width of the image in pixels.
/// The height of the image in pixels.
/// The meta data.
- internal ImageFrame(MemoryManager memoryManager, int width, int height, ImageFrameMetaData metaData)
+ internal ImageFrame(Configuration configuration, int width, int height, ImageFrameMetaData metaData)
+ : this(configuration, width, height, default, metaData)
{
- Guard.NotNull(memoryManager, nameof(memoryManager));
- Guard.MustBeGreaterThan(width, 0, nameof(width));
- Guard.MustBeGreaterThan(height, 0, nameof(height));
- Guard.NotNull(metaData, nameof(metaData));
-
- this.MemoryManager = memoryManager;
- this.PixelBuffer = memoryManager.AllocateClean2D(width, height);
- this.MetaData = metaData;
}
///
/// Initializes a new instance of the class.
///
- /// The to use for buffer allocation and parallel options to clear the buffer with.
+ /// The configuration which allows altering default behaviour or extending the library.
/// The width of the image in pixels.
/// The height of the image in pixels.
/// The color to clear the image with.
internal ImageFrame(Configuration configuration, int width, int height, TPixel backgroundColor)
- : this(configuration, width, height, backgroundColor, new ImageFrameMetaData()) {
+ : this(configuration, width, height, backgroundColor, new ImageFrameMetaData())
+ {
}
///
/// Initializes a new instance of the class.
///
- /// The to use for buffer allocation and parallel options to clear the buffer with.
+ /// The configuration which allows altering default behaviour or extending the library.
/// The width of the image in pixels.
/// The height of the image in pixels.
/// The color to clear the image with.
@@ -77,31 +84,26 @@ namespace SixLabors.ImageSharp
Guard.MustBeGreaterThan(height, 0, nameof(height));
Guard.NotNull(metaData, nameof(metaData));
+ this.configuration = configuration;
this.MemoryManager = configuration.MemoryManager;
this.PixelBuffer = this.MemoryManager.Allocate2D(width, height, false);
- this.Clear(configuration.ParallelOptions, backgroundColor);
this.MetaData = metaData;
+ this.Clear(configuration.ParallelOptions, backgroundColor);
}
///
/// Initializes a new instance of the class.
///
- /// The to use for buffer allocations.
- /// The of the frame.
- /// The meta data.
- internal ImageFrame(MemoryManager memoryManager, Size size, ImageFrameMetaData metaData)
- : this(memoryManager, size.Width, size.Height, metaData) {
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The to use for buffer allocations.
+ /// The configuration which allows altering default behaviour or extending the library.
/// The source.
- internal ImageFrame(MemoryManager memoryManager, ImageFrame source)
+ internal ImageFrame(Configuration configuration, ImageFrame source)
{
- this.MemoryManager = memoryManager;
- this.PixelBuffer = memoryManager.Allocate2D(source.PixelBuffer.Width, source.PixelBuffer.Height);
+ Guard.NotNull(configuration, nameof(configuration));
+ Guard.NotNull(source, nameof(source));
+
+ this.configuration = configuration;
+ this.MemoryManager = configuration.MemoryManager;
+ this.PixelBuffer = this.MemoryManager.Allocate2D(source.PixelBuffer.Width, source.PixelBuffer.Height);
source.PixelBuffer.Span.CopyTo(this.PixelBuffer.Span);
this.MetaData = source.MetaData.Clone();
}
@@ -276,13 +278,12 @@ namespace SixLabors.ImageSharp
return this.Clone() as ImageFrame;
}
- var target = new ImageFrame(this.MemoryManager, this.Width, this.Height, this.MetaData.Clone());
+ var target = new ImageFrame(this.configuration, this.Width, this.Height, this.MetaData.Clone());
- // TODO: ImageFrame has no visibility of the current configuration. It should have.
ParallelFor.WithTemporaryBuffer(
0,
this.Height,
- Configuration.Default,
+ this.configuration,
this.Width,
(int y, IBuffer tempRowBuffer) =>
{
@@ -302,12 +303,13 @@ namespace SixLabors.ImageSharp
///
/// The parallel options.
/// The value to initialize the bitmap with.
- internal void Clear(ParallelOptions parallelOptions, TPixel value) {
+ internal void Clear(ParallelOptions parallelOptions, TPixel value)
+ {
Parallel.For(
0,
this.Height,
parallelOptions,
- (int y) =>
+ y =>
{
Span targetRow = this.GetPixelRowSpan(y);
targetRow.Fill(value);
@@ -320,7 +322,7 @@ namespace SixLabors.ImageSharp
/// The
internal ImageFrame Clone()
{
- return new ImageFrame(this.MemoryManager, this);
+ return new ImageFrame(this.configuration, this);
}
///
diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj
index 7cbe862835..b1934faa6f 100644
--- a/src/ImageSharp/ImageSharp.csproj
+++ b/src/ImageSharp/ImageSharp.csproj
@@ -37,17 +37,17 @@
-
+
All
-
-
-
+
+
+
-
+
..\..\ImageSharp.ruleset
@@ -57,11 +57,11 @@
true
-
+
TextTemplatingFileGenerator
Block8x8F.Generated.cs
-
+
TextTemplatingFileGenerator
GenericBlock8x8.Generated.cs
@@ -87,12 +87,12 @@
-
+
True
True
Block8x8F.Generated.tt
-
+
True
True
GenericBlock8x8.Generated.tt
@@ -123,4 +123,7 @@
PorterDuffFunctions.Generated.tt
+
+
+
\ No newline at end of file
diff --git a/src/ImageSharp/Image{TPixel}.cs b/src/ImageSharp/Image{TPixel}.cs
index 596dc9bcd0..324385601f 100644
--- a/src/ImageSharp/Image{TPixel}.cs
+++ b/src/ImageSharp/Image{TPixel}.cs
@@ -78,7 +78,7 @@ namespace SixLabors.ImageSharp
this.configuration = configuration ?? Configuration.Default;
this.PixelType = new PixelTypeInfo(Unsafe.SizeOf() * 8);
this.MetaData = metadata ?? new ImageMetaData();
- this.frames = new ImageFrameCollection(this, width, height, default(TPixel));
+ this.frames = new ImageFrameCollection(this, width, height, default);
}
///
diff --git a/src/ImageSharp/Memory/SpanHelper.cs b/src/ImageSharp/Memory/SpanHelper.cs
deleted file mode 100644
index 592e2a885b..0000000000
--- a/src/ImageSharp/Memory/SpanHelper.cs
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using System;
-using System.Runtime.CompilerServices;
-
-namespace SixLabors.ImageSharp.Memory
-{
- ///
- /// Utility methods for
- ///
- internal static class SpanHelper
- {
- ///
- /// Copy all elements of 'source' into 'destination'.
- ///
- /// The element type.
- /// The to copy elements from.
- /// The destination .
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void Copy(ReadOnlySpan source, Span destination)
- where T : struct
- {
- source.Slice(0, Math.Min(source.Length, destination.Length)).CopyTo(destination);
- }
-
- ///
- /// Gets the size of `count` elements in bytes.
- ///
- /// The element type.
- /// The count of the elements
- /// The size in bytes as int
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static int SizeOf(int count)
- where T : struct => Unsafe.SizeOf() * count;
-
- ///
- /// Gets the size of `count` elements in bytes as UInt32
- ///
- /// The element type.
- /// The count of the elements
- /// The size in bytes as UInt32
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static uint USizeOf(int count)
- where T : struct
- => (uint)SizeOf(count);
- }
-}
\ No newline at end of file
diff --git a/src/ImageSharp/MetaData/ImageProperty.cs b/src/ImageSharp/MetaData/ImageProperty.cs
index c67c1f3cf9..3e0cccd422 100644
--- a/src/ImageSharp/MetaData/ImageProperty.cs
+++ b/src/ImageSharp/MetaData/ImageProperty.cs
@@ -19,7 +19,7 @@ namespace SixLabors.ImageSharp.MetaData
/// The value of the property.
public ImageProperty(string name, string value)
{
- Guard.NotNullOrEmpty(name, nameof(name));
+ Guard.NotNullOrWhiteSpace(name, nameof(name));
this.Name = name;
this.Value = value;
diff --git a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs
index c00eec6010..4f28449d64 100644
--- a/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs
+++ b/src/ImageSharp/MetaData/Profiles/Exif/ExifReader.cs
@@ -387,7 +387,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Exif
value = this.ConvertValue(dataType, offsetBuffer, numberOfComponents);
}
- exifValue = new ExifValue(tag, dataType, value, isArray: value != null && numberOfComponents > 1);
+ exifValue = new ExifValue(tag, dataType, value, isArray: value != null && numberOfComponents != 1);
return true;
}
diff --git a/src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.cs b/src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.cs
index c4a6a9039a..d6df9e666c 100644
--- a/src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.cs
+++ b/src/ImageSharp/MetaData/Profiles/ICC/DataReader/IccDataReader.cs
@@ -1,7 +1,6 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-using System;
using System.Text;
namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
@@ -11,7 +10,6 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
///
internal sealed partial class IccDataReader
{
- private static readonly bool IsLittleEndian = BitConverter.IsLittleEndian;
private static readonly Encoding AsciiEncoding = Encoding.GetEncoding("ASCII");
///
@@ -34,6 +32,14 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
this.data = data;
}
+ ///
+ /// Gets the length in bytes of the raw data
+ ///
+ public int DataLength
+ {
+ get { return this.data.Length; }
+ }
+
///
/// Sets the reading position to the given value
///
diff --git a/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs b/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs
index df85b2ab8e..52b8e43dac 100644
--- a/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs
+++ b/src/ImageSharp/MetaData/Profiles/ICC/IccProfile.cs
@@ -52,17 +52,12 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
/// by making a copy from another ICC profile.
///
/// The other ICC profile, where the clone should be made from.
- /// is null.>
+ /// is null.>
public IccProfile(IccProfile other)
{
Guard.NotNull(other, nameof(other));
- // TODO: Do we need to copy anything else?
- if (other.data != null)
- {
- this.data = new byte[other.data.Length];
- Buffer.BlockCopy(other.data, 0, this.data, 0, other.data.Length);
- }
+ this.data = other.ToByteArray();
}
///
@@ -108,7 +103,7 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
#if !NETSTANDARD1_1
///
- /// Calculates the MD5 hash value of an ICC profile header
+ /// Calculates the MD5 hash value of an ICC profile
///
/// The data of which to calculate the hash value
/// The calculated hash
@@ -117,22 +112,38 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
Guard.NotNull(data, nameof(data));
Guard.IsTrue(data.Length >= 128, nameof(data), "Data length must be at least 128 to be a valid profile header");
- byte[] header = new byte[128];
- Buffer.BlockCopy(data, 0, header, 0, 128);
+ const int profileFlagPos = 44;
+ const int renderingIntentPos = 64;
+ const int profileIdPos = 84;
+
+ // need to copy some values because they need to be zero for the hashing
+ byte[] temp = new byte[24];
+ Buffer.BlockCopy(data, profileFlagPos, temp, 0, 4);
+ Buffer.BlockCopy(data, renderingIntentPos, temp, 4, 4);
+ Buffer.BlockCopy(data, profileIdPos, temp, 8, 16);
using (var md5 = MD5.Create())
{
- // Zero out some values
- Array.Clear(header, 44, 4); // Profile flags
- Array.Clear(header, 64, 4); // Rendering Intent
- Array.Clear(header, 84, 16); // Profile ID
-
- // Calculate hash
- byte[] hash = md5.ComputeHash(data);
-
- // Read values from hash
- var reader = new IccDataReader(hash);
- return reader.ReadProfileId();
+ try
+ {
+ // Zero out some values
+ Array.Clear(data, profileFlagPos, 4);
+ Array.Clear(data, renderingIntentPos, 4);
+ Array.Clear(data, profileIdPos, 16);
+
+ // Calculate hash
+ byte[] hash = md5.ComputeHash(data);
+
+ // Read values from hash
+ var reader = new IccDataReader(hash);
+ return reader.ReadProfileId();
+ }
+ finally
+ {
+ Buffer.BlockCopy(temp, 0, data, profileFlagPos, 4);
+ Buffer.BlockCopy(temp, 4, data, renderingIntentPos, 4);
+ Buffer.BlockCopy(temp, 8, data, profileIdPos, 16);
+ }
}
}
@@ -149,14 +160,37 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
Buffer.BlockCopy(bytes, 0, this.data, currentLength, bytes.Length);
}
+ ///
+ /// Checks for signs of a corrupt profile.
+ ///
+ /// This is not an absolute proof of validity but should weed out most corrupt data.
+ /// True if the profile is valid; False otherwise
+ public bool CheckIsValid()
+ {
+ return Enum.IsDefined(typeof(IccColorSpaceType), this.Header.DataColorSpace) &&
+ Enum.IsDefined(typeof(IccColorSpaceType), this.Header.ProfileConnectionSpace) &&
+ Enum.IsDefined(typeof(IccRenderingIntent), this.Header.RenderingIntent) &&
+ this.Header.Size >= 128 &&
+ this.Header.Size < 50_000_000; // it's unlikely there is a profile bigger than 50MB
+ }
+
///
/// Converts this instance to a byte array.
///
/// The
public byte[] ToByteArray()
{
- var writer = new IccWriter();
- return writer.Write(this);
+ if (this.data != null)
+ {
+ byte[] copy = new byte[this.data.Length];
+ Buffer.BlockCopy(this.data, 0, copy, 0, copy.Length);
+ return copy;
+ }
+ else
+ {
+ var writer = new IccWriter();
+ return writer.Write(this);
+ }
}
private void InitializeHeader()
diff --git a/src/ImageSharp/MetaData/Profiles/ICC/IccReader.cs b/src/ImageSharp/MetaData/Profiles/ICC/IccReader.cs
index ca7c73620a..f6ed9325ac 100644
--- a/src/ImageSharp/MetaData/Profiles/ICC/IccReader.cs
+++ b/src/ImageSharp/MetaData/Profiles/ICC/IccReader.cs
@@ -84,27 +84,36 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
private IccTagDataEntry[] ReadTagData(IccDataReader reader)
{
IccTagTableEntry[] tagTable = this.ReadTagTable(reader);
- var entries = new IccTagDataEntry[tagTable.Length];
+ var entries = new List(tagTable.Length);
var store = new Dictionary();
- for (int i = 0; i < tagTable.Length; i++)
+
+ foreach (IccTagTableEntry tag in tagTable)
{
IccTagDataEntry entry;
- uint offset = tagTable[i].Offset;
- if (store.ContainsKey(offset))
+ if (store.ContainsKey(tag.Offset))
{
- entry = store[offset];
+ entry = store[tag.Offset];
}
else
{
- entry = reader.ReadTagDataEntry(tagTable[i]);
- store.Add(offset, entry);
+ try
+ {
+ entry = reader.ReadTagDataEntry(tag);
+ }
+ catch
+ {
+ // Ignore tags that could not be read
+ continue;
+ }
+
+ store.Add(tag.Offset, entry);
}
- entry.TagSignature = tagTable[i].Signature;
- entries[i] = entry;
+ entry.TagSignature = tag.Signature;
+ entries.Add(entry);
}
- return entries;
+ return entries.ToArray();
}
private IccTagTableEntry[] ReadTagTable(IccDataReader reader)
@@ -112,17 +121,29 @@ namespace SixLabors.ImageSharp.MetaData.Profiles.Icc
reader.SetIndex(128); // An ICC header is 128 bytes long
uint tagCount = reader.ReadUInt32();
- var table = new IccTagTableEntry[tagCount];
+ // Prevent creating huge arrays because of corrupt profiles.
+ // A normal profile usually has 5-15 entries
+ if (tagCount > 100)
+ {
+ return new IccTagTableEntry[0];
+ }
+
+ var table = new List((int)tagCount);
for (int i = 0; i < tagCount; i++)
{
uint tagSignature = reader.ReadUInt32();
uint tagOffset = reader.ReadUInt32();
uint tagSize = reader.ReadUInt32();
- table[i] = new IccTagTableEntry((IccProfileTag)tagSignature, tagOffset, tagSize);
+
+ // Exclude entries that have nonsense values and could cause exceptions further on
+ if (tagOffset < reader.DataLength && tagSize < reader.DataLength - 128)
+ {
+ table.Add(new IccTagTableEntry((IccProfileTag)tagSignature, tagOffset, tagSize));
+ }
}
- return table;
+ return table.ToArray();
}
}
}
diff --git a/src/ImageSharp/PixelFormats/Bgr24.cs b/src/ImageSharp/PixelFormats/Bgr24.cs
index 955b5c1613..b099bab1ce 100644
--- a/src/ImageSharp/PixelFormats/Bgr24.cs
+++ b/src/ImageSharp/PixelFormats/Bgr24.cs
@@ -14,22 +14,25 @@ namespace SixLabors.ImageSharp.PixelFormats
/// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form.
///
///
- [StructLayout(LayoutKind.Sequential)]
+ [StructLayout(LayoutKind.Explicit)]
public struct Bgr24 : IPixel
{
///
/// The blue component.
///
+ [FieldOffset(0)]
public byte B;
///
/// The green component.
///
+ [FieldOffset(1)]
public byte G;
///
/// The red component.
///
+ [FieldOffset(2)]
public byte R;
///
diff --git a/src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs b/src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs
index 184928d0e4..c2c0277f9e 100644
--- a/src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs
+++ b/src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0.
using System;
+using System.Buffers.Binary;
using System.Globalization;
namespace SixLabors.ImageSharp.PixelFormats
@@ -23,21 +24,17 @@ namespace SixLabors.ImageSharp.PixelFormats
/// Returns a that represents the color defined by the provided RGBA heax string.
public static TPixel FromHex(string hex)
{
- Guard.NotNullOrEmpty(hex, nameof(hex));
+ Guard.NotNullOrWhiteSpace(hex, nameof(hex));
hex = ToRgbaHex(hex);
- uint packedValue;
- if (hex == null || !uint.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out packedValue))
+
+ if (hex == null || !uint.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out uint packedValue))
{
throw new ArgumentException("Hexadecimal string is not in the correct format.", nameof(hex));
}
TPixel result = default;
- var rgba = new Rgba32(
- (byte)(packedValue >> 24),
- (byte)(packedValue >> 16),
- (byte)(packedValue >> 8),
- (byte)(packedValue >> 0));
+ var rgba = new Rgba32(BinaryPrimitives.ReverseEndianness(packedValue));
result.PackFromRgba32(rgba);
return result;
@@ -76,7 +73,10 @@ namespace SixLabors.ImageSharp.PixelFormats
///
private static string ToRgbaHex(string hex)
{
- hex = hex.StartsWith("#") ? hex.Substring(1) : hex;
+ if (hex[0] == '#')
+ {
+ hex = hex.Substring(1);
+ }
if (hex.Length == 8)
{
@@ -93,12 +93,12 @@ namespace SixLabors.ImageSharp.PixelFormats
return null;
}
- string red = char.ToString(hex[0]);
- string green = char.ToString(hex[1]);
- string blue = char.ToString(hex[2]);
- string alpha = hex.Length == 3 ? "F" : char.ToString(hex[3]);
+ char r = hex[0];
+ char g = hex[1];
+ char b = hex[2];
+ char a = hex.Length == 3 ? 'F' : hex[3];
- return string.Concat(red, red, green, green, blue, blue, alpha, alpha);
+ return new string(new[] { r, r, g, g, b, b, a, a });
}
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/Rgb24.cs b/src/ImageSharp/PixelFormats/Rgb24.cs
index fa03683c69..c540a7d120 100644
--- a/src/ImageSharp/PixelFormats/Rgb24.cs
+++ b/src/ImageSharp/PixelFormats/Rgb24.cs
@@ -15,22 +15,25 @@ namespace SixLabors.ImageSharp.PixelFormats
/// Ranges from [0, 0, 0, 1] to [1, 1, 1, 1] in vector form.
///
///
- [StructLayout(LayoutKind.Sequential)]
+ [StructLayout(LayoutKind.Explicit)]
public struct Rgb24 : IPixel
{
///
/// The red component.
///
+ [FieldOffset(0)]
public byte R;
///
/// The green component.
///
+ [FieldOffset(1)]
public byte G;
///
/// The blue component.
///
+ [FieldOffset(2)]
public byte B;
///
diff --git a/src/ImageSharp/Processing/Quantization/FrameQuantizers/WuFrameQuantizer{TPixel}.cs b/src/ImageSharp/Processing/Quantization/FrameQuantizers/WuFrameQuantizer{TPixel}.cs
index fbc40dc8a1..bc7a2df715 100644
--- a/src/ImageSharp/Processing/Quantization/FrameQuantizers/WuFrameQuantizer{TPixel}.cs
+++ b/src/ImageSharp/Processing/Quantization/FrameQuantizers/WuFrameQuantizer{TPixel}.cs
@@ -157,13 +157,13 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
}
finally
{
- this.vwt.Dispose();
- this.vmr.Dispose();
- this.vmg.Dispose();
- this.vmb.Dispose();
- this.vma.Dispose();
- this.m2.Dispose();
- this.tag.Dispose();
+ this.vwt?.Dispose();
+ this.vmr?.Dispose();
+ this.vmg?.Dispose();
+ this.vmb?.Dispose();
+ this.vma?.Dispose();
+ this.m2?.Dispose();
+ this.tag?.Dispose();
}
}
diff --git a/src/ImageSharp/Processing/Transforms/Processors/AffineTransformProcessor.cs b/src/ImageSharp/Processing/Transforms/Processors/AffineTransformProcessor.cs
index 2d6083e55f..7c1a581b02 100644
--- a/src/ImageSharp/Processing/Transforms/Processors/AffineTransformProcessor.cs
+++ b/src/ImageSharp/Processing/Transforms/Processors/AffineTransformProcessor.cs
@@ -51,7 +51,7 @@ namespace SixLabors.ImageSharp.Processing.Transforms.Processors
{
// We will always be creating the clone even for mutate because we may need to resize the canvas
IEnumerable> frames =
- source.Frames.Select(x => new ImageFrame(source.GetMemoryManager(), this.TargetDimensions, x.MetaData.Clone()));
+ source.Frames.Select(x => new ImageFrame(source.GetConfiguration(), this.TargetDimensions, x.MetaData.Clone()));
// Use the overload to prevent an extra frame being added
return new Image(source.GetConfiguration(), source.MetaData.Clone(), frames);
diff --git a/src/ImageSharp/Processing/Transforms/Processors/CropProcessor.cs b/src/ImageSharp/Processing/Transforms/Processors/CropProcessor.cs
index bfbf349b52..848ea7b62e 100644
--- a/src/ImageSharp/Processing/Transforms/Processors/CropProcessor.cs
+++ b/src/ImageSharp/Processing/Transforms/Processors/CropProcessor.cs
@@ -37,7 +37,7 @@ namespace SixLabors.ImageSharp.Processing.Transforms.Processors
protected override Image CreateDestination(Image source, Rectangle sourceRectangle)
{
// We will always be creating the clone even for mutate because we may need to resize the canvas
- IEnumerable> frames = source.Frames.Select(x => new ImageFrame(source.GetMemoryManager(), this.CropRectangle.Width, this.CropRectangle.Height, x.MetaData.Clone()));
+ IEnumerable> frames = source.Frames.Select(x => new ImageFrame(source.GetConfiguration(), this.CropRectangle.Width, this.CropRectangle.Height, x.MetaData.Clone()));
// Use the overload to prevent an extra frame being added
return new Image(source.GetConfiguration(), source.MetaData.Clone(), frames);
diff --git a/src/ImageSharp/Processing/Transforms/Processors/ProjectiveTransformProcessor.cs b/src/ImageSharp/Processing/Transforms/Processors/ProjectiveTransformProcessor.cs
index 9f76540378..a55613decb 100644
--- a/src/ImageSharp/Processing/Transforms/Processors/ProjectiveTransformProcessor.cs
+++ b/src/ImageSharp/Processing/Transforms/Processors/ProjectiveTransformProcessor.cs
@@ -52,7 +52,7 @@ namespace SixLabors.ImageSharp.Processing.Transforms.Processors
{
// We will always be creating the clone even for mutate because we may need to resize the canvas
IEnumerable> frames =
- source.Frames.Select(x => new ImageFrame(source.GetMemoryManager(), this.TargetDimensions.Width, this.TargetDimensions.Height, x.MetaData.Clone()));
+ source.Frames.Select(x => new ImageFrame(source.GetConfiguration(), this.TargetDimensions.Width, this.TargetDimensions.Height, x.MetaData.Clone()));
// Use the overload to prevent an extra frame being added
return new Image(source.GetConfiguration(), source.MetaData.Clone(), frames);
diff --git a/src/ImageSharp/Processing/Transforms/Processors/ResizeProcessor.cs b/src/ImageSharp/Processing/Transforms/Processors/ResizeProcessor.cs
index 27dc39ef1e..773b16e73d 100644
--- a/src/ImageSharp/Processing/Transforms/Processors/ResizeProcessor.cs
+++ b/src/ImageSharp/Processing/Transforms/Processors/ResizeProcessor.cs
@@ -6,11 +6,11 @@ using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
using System.Threading.Tasks;
using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.ImageSharp.Processing.Processors;
using SixLabors.ImageSharp.Processing.Transforms.Resamplers;
using SixLabors.Primitives;
@@ -56,12 +56,12 @@ namespace SixLabors.ImageSharp.Processing.Transforms.Processors
Guard.MustBeGreaterThan(tempWidth, 0, nameof(tempWidth));
Guard.MustBeGreaterThan(tempHeight, 0, nameof(tempHeight));
- (Size size, Rectangle rectangle) locationBounds = ResizeHelper.CalculateTargetLocationAndBounds(sourceSize, options, tempWidth, tempHeight);
+ (Size size, Rectangle rectangle) = ResizeHelper.CalculateTargetLocationAndBounds(sourceSize, options, tempWidth, tempHeight);
this.Sampler = options.Sampler;
- this.Width = locationBounds.size.Width;
- this.Height = locationBounds.size.Height;
- this.ResizeRectangle = locationBounds.rectangle;
+ this.Width = size.Width;
+ this.Height = size.Height;
+ this.ResizeRectangle = rectangle;
this.Compand = options.Compand;
}
@@ -167,13 +167,13 @@ namespace SixLabors.ImageSharp.Processing.Transforms.Processors
float center = ((i + .5F) * ratio) - .5F;
// Keep inside bounds.
- int left = (int)Math.Ceiling(center - radius);
+ int left = (int)MathF.Ceiling(center - radius);
if (left < 0)
{
left = 0;
}
- int right = (int)Math.Floor(center + radius);
+ int right = (int)MathF.Floor(center + radius);
if (right > sourceSize - 1)
{
right = sourceSize - 1;
@@ -214,7 +214,7 @@ namespace SixLabors.ImageSharp.Processing.Transforms.Processors
protected override Image CreateDestination(Image source, Rectangle sourceRectangle)
{
// We will always be creating the clone even for mutate because we may need to resize the canvas
- IEnumerable> frames = source.Frames.Select(x => new ImageFrame(source.GetMemoryManager(), this.Width, this.Height, x.MetaData.Clone()));
+ IEnumerable> frames = source.Frames.Select(x => new ImageFrame(source.GetConfiguration(), this.Width, this.Height, x.MetaData.Clone()));
// Use the overload to prevent an extra frame being added
return new Image(source.GetConfiguration(), source.MetaData.Clone(), frames);
@@ -245,7 +245,7 @@ namespace SixLabors.ImageSharp.Processing.Transforms.Processors
// Handle resize dimensions identical to the original
if (source.Width == destination.Width && source.Height == destination.Height && sourceRectangle == this.ResizeRectangle)
{
- // the cloned will be blank here copy all the pixel data over
+ // The cloned will be blank here copy all the pixel data over
source.GetPixelSpan().CopyTo(destination.GetPixelSpan());
return;
}
@@ -306,7 +306,7 @@ namespace SixLabors.ImageSharp.Processing.Transforms.Processors
source.Width,
(int y, IBuffer tempRowBuffer) =>
{
- Span firstPassRow = firstPassPixels.GetRowSpan(y);
+ ref Vector4 firstPassRow = ref MemoryMarshal.GetReference(firstPassPixels.GetRowSpan(y));
Span sourceRow = source.GetPixelRowSpan(y);
Span tempRowSpan = tempRowBuffer.Span;
@@ -317,7 +317,7 @@ namespace SixLabors.ImageSharp.Processing.Transforms.Processors
for (int x = minX; x < maxX; x++)
{
WeightsWindow window = this.horizontalWeights.Weights[x - startX];
- firstPassRow[x] = window.ComputeExpandedWeightedRowSum(tempRowSpan, sourceX);
+ Unsafe.Add(ref firstPassRow, x) = window.ComputeExpandedWeightedRowSum(tempRowSpan, sourceX);
}
}
else
@@ -325,7 +325,7 @@ namespace SixLabors.ImageSharp.Processing.Transforms.Processors
for (int x = minX; x < maxX; x++)
{
WeightsWindow window = this.horizontalWeights.Weights[x - startX];
- firstPassRow[x] = window.ComputeWeightedRowSum(tempRowSpan, sourceX);
+ Unsafe.Add(ref firstPassRow, x) = window.ComputeWeightedRowSum(tempRowSpan, sourceX);
}
}
});
@@ -339,7 +339,7 @@ namespace SixLabors.ImageSharp.Processing.Transforms.Processors
{
// Ensure offsets are normalized for cropping and padding.
WeightsWindow window = this.verticalWeights.Weights[y - startY];
- Span targetRow = destination.GetPixelRowSpan(y);
+ ref TPixel targetRow = ref MemoryMarshal.GetReference(destination.GetPixelRowSpan(y));
if (this.Compand)
{
@@ -349,7 +349,7 @@ namespace SixLabors.ImageSharp.Processing.Transforms.Processors
Vector4 destinationVector = window.ComputeWeightedColumnSum(firstPassPixels, x, sourceY);
destinationVector = destinationVector.Compress();
- ref TPixel pixel = ref targetRow[x];
+ ref TPixel pixel = ref Unsafe.Add(ref targetRow, x);
pixel.PackFromVector4(destinationVector);
}
}
@@ -360,7 +360,7 @@ namespace SixLabors.ImageSharp.Processing.Transforms.Processors
// Destination color components
Vector4 destinationVector = window.ComputeWeightedColumnSum(firstPassPixels, x, sourceY);
- ref TPixel pixel = ref targetRow[x];
+ ref TPixel pixel = ref Unsafe.Add(ref targetRow, x);
pixel.PackFromVector4(destinationVector);
}
}
diff --git a/src/ImageSharp/Processing/Transforms/Processors/WeightsBuffer.cs b/src/ImageSharp/Processing/Transforms/Processors/WeightsBuffer.cs
index d633a3869f..42c95cd338 100644
--- a/src/ImageSharp/Processing/Transforms/Processors/WeightsBuffer.cs
+++ b/src/ImageSharp/Processing/Transforms/Processors/WeightsBuffer.cs
@@ -2,10 +2,9 @@
// Licensed under the Apache License, Version 2.0.
using System;
-
using SixLabors.ImageSharp.Memory;
-namespace SixLabors.ImageSharp.Processing.Processors
+namespace SixLabors.ImageSharp.Processing.Transforms.Processors
{
///
/// Holds the values in an optimized contigous memory region.
diff --git a/src/ImageSharp/Processing/Transforms/Processors/WeightsWindow.cs b/src/ImageSharp/Processing/Transforms/Processors/WeightsWindow.cs
index 26aaec502f..a211052728 100644
--- a/src/ImageSharp/Processing/Transforms/Processors/WeightsWindow.cs
+++ b/src/ImageSharp/Processing/Transforms/Processors/WeightsWindow.cs
@@ -7,7 +7,7 @@ using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Memory;
-namespace SixLabors.ImageSharp.Processing.Processors
+namespace SixLabors.ImageSharp.Processing.Transforms.Processors
{
///
/// Points to a collection of of weights allocated in .
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs
index 47325476cf..f86919dd15 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpeg.cs
@@ -49,7 +49,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg
{
using (var memoryStream = new MemoryStream(this.jpegBytes))
{
- using (var image = Image.Load(memoryStream, new OrigJpegDecoder()))
+ using (var image = Image.Load(memoryStream, new GolangJpegDecoder()))
{
return new CoreSize(image.Width, image.Height);
}
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs
index a1083e8ebf..c4ee732f5e 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/DecodeJpegMultiple.cs
@@ -24,7 +24,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg
[Benchmark(Description = "DecodeJpegMultiple - ImageSharp")]
public void DecodeJpegImageSharpOrig()
{
- this.ForEachStream(ms => Image.Load(ms, new OrigJpegDecoder()));
+ this.ForEachStream(ms => Image.Load(ms, new GolangJpegDecoder()));
}
[Benchmark(Description = "DecodeJpegMultiple - ImageSharp PDFJs")]
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/IdentifyJpeg.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/IdentifyJpeg.cs
index c3c1281001..b6ad20d128 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/IdentifyJpeg.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/IdentifyJpeg.cs
@@ -33,7 +33,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg
{
using (var memoryStream = new MemoryStream(this.jpegBytes))
{
- var decoder = new OrigJpegDecoder();
+ var decoder = new GolangJpegDecoder();
return decoder.Identify(Configuration.Default, memoryStream);
}
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YCbCrColorConversion.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YCbCrColorConversion.cs
index 5f902ff64d..ef0d55765a 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YCbCrColorConversion.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/YCbCrColorConversion.cs
@@ -1,14 +1,14 @@
-namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg
+using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters;
+
+namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg
{
using System;
using System.Numerics;
using BenchmarkDotNet.Attributes;
- using SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder;
- using SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder.ColorConverters;
using SixLabors.ImageSharp.Memory;
-
+
[Config(typeof(Config.ShortClr))]
public class YCbCrColorConversion
{
@@ -57,7 +57,7 @@
JpegColorConverter.FromYCbCrSimdAvx2.ConvertCore(values, this.output);
}
-
+
private static Buffer2D[] CreateRandomValues(
int componentCount,
int inputBufferLength,
@@ -81,6 +81,6 @@
return buffers;
}
-
+
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.cs b/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.cs
index c4a77acc26..07ae17d754 100644
--- a/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.cs
+++ b/tests/ImageSharp.Benchmarks/Color/RgbToYCbCr.cs
@@ -1,13 +1,12 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
-using System;
-using System.Buffers;
using System.Numerics;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
-using SixLabors.ImageSharp.Formats.Jpeg.Common;
+
+using SixLabors.ImageSharp.Formats.Jpeg.Components;
namespace SixLabors.ImageSharp.Benchmarks
{
@@ -104,14 +103,14 @@ namespace SixLabors.ImageSharp.Benchmarks
}
}
}
-
+
public struct Result
{
internal Block8x8F Y;
internal Block8x8F Cb;
internal Block8x8F Cr;
}
-
+
// The operation is defined as "RGBA -> YCbCr Transform a stream of bytes into a stream of floats"
// We need to benchmark the whole operation, to get true results, not missing any side effects!
private byte[] inputSourceRGB = null;
@@ -200,11 +199,11 @@ namespace SixLabors.ImageSharp.Benchmarks
float* cbPtr = (float*)&result.Cb;
float* crPtr = (float*)&result.Cr;
// end of code-bloat block :)
-
+
Vector yCoeffs = new Vector(ScaledCoeffs.Y);
Vector cbCoeffs = new Vector(ScaledCoeffs.Cb);
Vector crCoeffs = new Vector(ScaledCoeffs.Cr);
-
+
for (int i = 0; i < this.inputSourceRGB.Length; i++)
{
this.inputSourceRGBAsInteger[i] = this.inputSourceRGB[i];
@@ -217,7 +216,7 @@ namespace SixLabors.ImageSharp.Benchmarks
Vector y = yCoeffs * rgb;
Vector cb = cbCoeffs * rgb;
Vector cr = crCoeffs * rgb;
-
+
*yPtr++ = (y[0] + y[1] + y[2]) >> 10;
*cbPtr++ = 128 + ((cb[0] - cb[1] + cb[2]) >> 10);
*crPtr++ = 128 + ((cr[0] - cr[1] - cr[2]) >> 10);
@@ -335,7 +334,7 @@ namespace SixLabors.ImageSharp.Benchmarks
*crPtr++ = 128 + ((cr0 - cr1 - cr2) >> 10);
}
}
-
+
[Benchmark(Description = "Scaled Integer LUT Conversion")]
public unsafe void RgbaToYcbCrScaledIntegerLut()
{
diff --git a/tests/ImageSharp.Benchmarks/General/Block8x8F_DivideRound.cs b/tests/ImageSharp.Benchmarks/General/Block8x8F_DivideRound.cs
index bad87cc11a..fcc5f9a592 100644
--- a/tests/ImageSharp.Benchmarks/General/Block8x8F_DivideRound.cs
+++ b/tests/ImageSharp.Benchmarks/General/Block8x8F_DivideRound.cs
@@ -5,7 +5,9 @@ using System.Numerics;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
-using SixLabors.ImageSharp.Formats.Jpeg.Common;
+
+using SixLabors.ImageSharp.Formats.Jpeg.Components;
+
// ReSharper disable InconsistentNaming
namespace SixLabors.ImageSharp.Benchmarks.General
diff --git a/tests/ImageSharp.Benchmarks/General/Block8x8F_Round.cs b/tests/ImageSharp.Benchmarks/General/Block8x8F_Round.cs
index d101bf0509..200af64c25 100644
--- a/tests/ImageSharp.Benchmarks/General/Block8x8F_Round.cs
+++ b/tests/ImageSharp.Benchmarks/General/Block8x8F_Round.cs
@@ -6,8 +6,7 @@ using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
-using SixLabors.ImageSharp;
-using SixLabors.ImageSharp.Formats.Jpeg.Common;
+using SixLabors.ImageSharp.Formats.Jpeg.Components;
namespace SixLabors.ImageSharp.Benchmarks.General
{
diff --git a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj
index 9dbd680efd..9a58f350ac 100644
--- a/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj
+++ b/tests/ImageSharp.Benchmarks/ImageSharp.Benchmarks.csproj
@@ -16,9 +16,9 @@
-
-
-
+
+
+
diff --git a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj
index 266b905a04..245af5289c 100644
--- a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj
+++ b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj
@@ -20,7 +20,7 @@
-
+
diff --git a/tests/ImageSharp.Tests/ConfigurationTests.cs b/tests/ImageSharp.Tests/ConfigurationTests.cs
index 88aabfe337..d870b7bf78 100644
--- a/tests/ImageSharp.Tests/ConfigurationTests.cs
+++ b/tests/ImageSharp.Tests/ConfigurationTests.cs
@@ -1,95 +1,95 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using SixLabors.ImageSharp.Formats;
-using SixLabors.ImageSharp.IO;
-using SixLabors.ImageSharp.PixelFormats;
-using Moq;
-using Xunit;
-
-namespace SixLabors.ImageSharp.Tests
-{
- ///
- /// Tests the configuration class.
- ///
- public class ConfigurationTests
- {
- public Configuration ConfigurationEmpty { get; private set; }
- public Configuration DefaultConfiguration { get; private set; }
-
- public ConfigurationTests()
- {
- // the shallow copy of configuration should behave exactly like the default configuration,
- // so by using the copy, we test both the default and the copy.
- this.DefaultConfiguration = Configuration.CreateDefaultInstance().ShallowCopy();
- this.ConfigurationEmpty = new Configuration();
- }
-
- [Fact]
- public void DefaultsToLocalFileSystem()
- {
- Assert.IsType(this.DefaultConfiguration.FileSystem);
- Assert.IsType(this.ConfigurationEmpty.FileSystem);
- }
-
- ///
- /// Test that the default configuration is not null.
- ///
- [Fact]
- public void TestDefultConfigurationIsNotNull()
- {
- Assert.True(Configuration.Default != null);
- }
-
- ///
- /// Test that the default configuration parallel options is not null.
- ///
- [Fact]
- public void TestDefultConfigurationParallelOptionsIsNotNull()
- {
- Assert.True(Configuration.Default.ParallelOptions != null);
- }
-
- ///
- /// Test that the default configuration read origin options is set to begin.
- ///
- [Fact]
- public void TestDefultConfigurationReadOriginIsCurrent()
- {
- Assert.True(Configuration.Default.ReadOrigin == ReadOrigin.Current);
- }
-
- ///
- /// Test that the default configuration parallel options max degrees of parallelism matches the
- /// environment processor count.
- ///
- [Fact]
- public void TestDefultConfigurationMaxDegreeOfParallelism()
- {
- Assert.True(Configuration.Default.ParallelOptions.MaxDegreeOfParallelism == Environment.ProcessorCount);
- }
-
- [Fact]
- public void ConstructorCallConfigureOnFormatProvider()
- {
- var provider = new Mock();
- var config = new Configuration(provider.Object);
-
- provider.Verify(x => x.Configure(config));
- }
-
- [Fact]
- public void AddFormatCallsConfig()
- {
- var provider = new Mock();
- var config = new Configuration();
- config.Configure(provider.Object);
-
- provider.Verify(x => x.Configure(config));
- }
- }
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using SixLabors.ImageSharp.Formats;
+using SixLabors.ImageSharp.IO;
+using SixLabors.ImageSharp.PixelFormats;
+using Moq;
+using Xunit;
+
+namespace SixLabors.ImageSharp.Tests
+{
+ ///
+ /// Tests the configuration class.
+ ///
+ public class ConfigurationTests
+ {
+ public Configuration ConfigurationEmpty { get; private set; }
+ public Configuration DefaultConfiguration { get; private set; }
+
+ public ConfigurationTests()
+ {
+ // the shallow copy of configuration should behave exactly like the default configuration,
+ // so by using the copy, we test both the default and the copy.
+ this.DefaultConfiguration = Configuration.CreateDefaultInstance().ShallowCopy();
+ this.ConfigurationEmpty = new Configuration();
+ }
+
+ [Fact]
+ public void DefaultsToLocalFileSystem()
+ {
+ Assert.IsType(this.DefaultConfiguration.FileSystem);
+ Assert.IsType(this.ConfigurationEmpty.FileSystem);
+ }
+
+ ///
+ /// Test that the default configuration is not null.
+ ///
+ [Fact]
+ public void TestDefaultConfigurationIsNotNull()
+ {
+ Assert.True(Configuration.Default != null);
+ }
+
+ ///
+ /// Test that the default configuration parallel options is not null.
+ ///
+ [Fact]
+ public void TestDefaultConfigurationParallelOptionsIsNotNull()
+ {
+ Assert.True(Configuration.Default.ParallelOptions != null);
+ }
+
+ ///
+ /// Test that the default configuration read origin options is set to begin.
+ ///
+ [Fact]
+ public void TestDefaultConfigurationReadOriginIsCurrent()
+ {
+ Assert.True(Configuration.Default.ReadOrigin == ReadOrigin.Current);
+ }
+
+ ///
+ /// Test that the default configuration parallel options max degrees of parallelism matches the
+ /// environment processor count.
+ ///
+ [Fact]
+ public void TestDefaultConfigurationMaxDegreeOfParallelism()
+ {
+ Assert.True(Configuration.Default.ParallelOptions.MaxDegreeOfParallelism == Environment.ProcessorCount);
+ }
+
+ [Fact]
+ public void ConstructorCallConfigureOnFormatProvider()
+ {
+ var provider = new Mock();
+ var config = new Configuration(provider.Object);
+
+ provider.Verify(x => x.Configure(config));
+ }
+
+ [Fact]
+ public void AddFormatCallsConfig()
+ {
+ var provider = new Mock();
+ var config = new Configuration();
+ config.Configure(provider.Object);
+
+ provider.Verify(x => x.Configure(config));
+ }
+ }
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Drawing/FillEllipticGradientBrushTest.cs b/tests/ImageSharp.Tests/Drawing/FillEllipticGradientBrushTest.cs
new file mode 100644
index 0000000000..7c9fa20884
--- /dev/null
+++ b/tests/ImageSharp.Tests/Drawing/FillEllipticGradientBrushTest.cs
@@ -0,0 +1,149 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.ImageSharp.Processing;
+using SixLabors.ImageSharp.Processing.Drawing;
+using SixLabors.ImageSharp.Processing.Drawing.Brushes.GradientBrushes;
+
+using Xunit;
+
+namespace SixLabors.ImageSharp.Tests.Drawing
+{
+ using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
+
+ [GroupOutput("Drawing/GradientBrushes")]
+ public class FillEllipticGradientBrushTests
+ {
+ public static ImageComparer TolerantComparer = ImageComparer.TolerantPercentage(0.01f);
+
+ [Theory]
+ [WithBlankImages(10, 10, PixelTypes.Rgba32)]
+ public void WithEqualColorsReturnsUnicolorImage(
+ TestImageProvider provider)
+ where TPixel : struct, IPixel
+ {
+ TPixel red = NamedColors.Red;
+
+ using (Image image = provider.GetImage())
+ {
+ var unicolorLinearGradientBrush =
+ new EllipticGradientBrush(
+ new SixLabors.Primitives.Point(0, 0),
+ new SixLabors.Primitives.Point(10, 0),
+ 1.0f,
+ GradientRepetitionMode.None,
+ new ColorStop(0, red),
+ new ColorStop(1, red));
+
+ image.Mutate(x => x.Fill(unicolorLinearGradientBrush));
+
+ image.DebugSave(provider, appendPixelTypeToFileName: false, appendSourceFileOrDescription: false);
+
+ // no need for reference image in this test:
+ image.ComparePixelBufferTo(red);
+ }
+ }
+
+ [Theory]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 0.1)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 0.4)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 0.8)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 1.0)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 1.2)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 1.6)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 2.0)]
+ public void AxisParallelEllipsesWithDifferentRatio(
+ TestImageProvider provider,
+ float ratio)
+ where TPixel : struct, IPixel
+ {
+ TPixel yellow = NamedColors.Yellow;
+ TPixel red = NamedColors.Red;
+ TPixel black = NamedColors.Black;
+
+ provider.VerifyOperation(
+ TolerantComparer,
+ image =>
+ {
+ var unicolorLinearGradientBrush = new EllipticGradientBrush(
+ new SixLabors.Primitives.Point(image.Width / 2, image.Height / 2),
+ new SixLabors.Primitives.Point(image.Width / 2, (image.Width * 2) / 3),
+ ratio,
+ GradientRepetitionMode.None,
+ new ColorStop(0, yellow),
+ new ColorStop(1, red),
+ new ColorStop(1, black));
+
+ image.Mutate(x => x.Fill(unicolorLinearGradientBrush));
+ },
+ $"{ratio:F2}",
+ false,
+ false);
+ }
+
+ [Theory]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 0.1, 0)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 0.4, 0)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 0.8, 0)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 1.0, 0)]
+
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 0.1, 45)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 0.4, 45)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 0.8, 45)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 1.0, 45)]
+
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 0.1, 90)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 0.4, 90)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 0.8, 90)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 1.0, 90)]
+
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 0.1, 30)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 0.4, 30)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 0.8, 30)]
+ [WithBlankImages(200, 200, PixelTypes.Rgba32, 1.0, 30)]
+ public void RotatedEllipsesWithDifferentRatio(
+ TestImageProvider provider,
+ float ratio,
+ float rotationInDegree)
+ where TPixel: struct, IPixel
+ {
+ FormattableString variant = $"{ratio:F2}_AT_{rotationInDegree:00}deg";
+
+ provider.VerifyOperation(
+ TolerantComparer,
+ image =>
+ {
+ TPixel yellow = NamedColors.Yellow;
+ TPixel red = NamedColors.Red;
+ TPixel black = NamedColors.Black;
+
+ var center = new SixLabors.Primitives.Point(image.Width / 2, image.Height / 2);
+
+ double rotation = (Math.PI * rotationInDegree) / 180.0;
+ double cos = Math.Cos(rotation);
+ double sin = Math.Sin(rotation);
+
+ int offsetY = image.Height / 6;
+ int axisX = center.X + (int)-(offsetY * sin);
+ int axisY = center.Y + (int)(offsetY * cos);
+
+ var unicolorLinearGradientBrush = new EllipticGradientBrush(
+ center,
+ new SixLabors.Primitives.Point(axisX, axisY),
+ ratio,
+ GradientRepetitionMode.None,
+ new ColorStop(0, yellow),
+ new ColorStop