diff --git a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs
index 26d3e0dbb3..b7835d6706 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Block8x8F.cs
@@ -376,16 +376,16 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
/// Source block
/// Destination block
/// The quantization table
- /// Pointer to elements of
+ /// The 8x8 Unzig block.
public static unsafe void Quantize(
ref Block8x8F block,
ref Block8x8F dest,
ref Block8x8F qt,
- byte* unzigPtr)
+ ref ZigZag unZig)
{
for (int zig = 0; zig < Size; zig++)
{
- dest[zig] = block[unzigPtr[zig]];
+ dest[zig] = block[unZig[zig]];
}
DivideRoundAll(ref dest, ref qt);
@@ -396,12 +396,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components
///
/// The destination block.
/// The source block.
- public static unsafe void Scale16X16To8X8(ref Block8x8F destination, Block8x8F* source)
+ public static unsafe void Scale16X16To8X8(ref Block8x8F destination, ReadOnlySpan source)
{
for (int i = 0; i < 4; i++)
{
int dstOff = ((i & 2) << 4) | ((i & 1) << 2);
- float* iSource = (float*)(source + i);
+ Block8x8F iSource = source[i];
for (int y = 0; y < 4; y++)
{
diff --git a/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
index 08ffd53343..26e804b923 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegEncoderCore.cs
@@ -431,7 +431,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
ref temp1,
ref temp2,
ref onStackLuminanceQuantTable,
- unzig.Data);
+ ref unzig);
prevDCCb = this.WriteBlock(
QuantIndex.Chrominance,
prevDCCb,
@@ -439,7 +439,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
ref temp1,
ref temp2,
ref onStackChrominanceQuantTable,
- unzig.Data);
+ ref unzig);
prevDCCr = this.WriteBlock(
QuantIndex.Chrominance,
prevDCCr,
@@ -447,7 +447,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
ref temp1,
ref temp2,
ref onStackChrominanceQuantTable,
- unzig.Data);
+ ref unzig);
}
}
}
@@ -512,7 +512,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
/// Temporal block to be used as FDCT Destination
/// Temporal block 2
/// Quantization table
- /// The 8x8 Unzig block pointer
+ /// The 8x8 Unzig block.
///
/// The
///
@@ -523,11 +523,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
ref Block8x8F tempDest1,
ref Block8x8F tempDest2,
ref Block8x8F quant,
- byte* unzigPtr)
+ ref ZigZag unZig)
{
FastFloatingPointDCT.TransformFDCT(ref src, ref tempDest1, ref tempDest2);
- Block8x8F.Quantize(ref tempDest1, ref tempDest2, ref quant, unzigPtr);
+ Block8x8F.Quantize(ref tempDest1, ref tempDest2, ref quant, ref unZig);
int dc = (int)tempDest2[0];
@@ -974,11 +974,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
{
// TODO: Need a JpegScanEncoder class or struct that encapsulates the scan-encoding implementation. (Similar to JpegScanDecoder.)
Block8x8F b = default;
-
- BlockQuad cb = default;
- BlockQuad cr = default;
- var cbPtr = (Block8x8F*)cb.Data;
- var crPtr = (Block8x8F*)cr.Data;
+ Span cb = stackalloc Block8x8F[4];
+ Span cr = stackalloc Block8x8F[4];
Block8x8F temp1 = default;
Block8x8F temp2 = default;
@@ -1009,8 +1006,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
pixelConverter.Convert(frame, x + xOff, y + yOff, currentRows);
- cbPtr[i] = pixelConverter.Cb;
- crPtr[i] = pixelConverter.Cr;
+ cb[i] = pixelConverter.Cb;
+ cr[i] = pixelConverter.Cr;
prevDCY = this.WriteBlock(
QuantIndex.Luminance,
@@ -1019,10 +1016,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
ref temp1,
ref temp2,
ref onStackLuminanceQuantTable,
- unzig.Data);
+ ref unzig);
}
- Block8x8F.Scale16X16To8X8(ref b, cbPtr);
+ Block8x8F.Scale16X16To8X8(ref b, cb);
prevDCCb = this.WriteBlock(
QuantIndex.Chrominance,
prevDCCb,
@@ -1030,9 +1027,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
ref temp1,
ref temp2,
ref onStackChrominanceQuantTable,
- unzig.Data);
+ ref unzig);
- Block8x8F.Scale16X16To8X8(ref b, crPtr);
+ Block8x8F.Scale16X16To8X8(ref b, cr);
prevDCCr = this.WriteBlock(
QuantIndex.Chrominance,
prevDCCr,
@@ -1040,7 +1037,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg
ref temp1,
ref temp2,
ref onStackChrominanceQuantTable,
- unzig.Data);
+ ref unzig);
}
}
}
diff --git a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/EncodeJpeg.cs b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/EncodeJpeg.cs
index 0a1fe977f8..b5be18189e 100644
--- a/tests/ImageSharp.Benchmarks/Codecs/Jpeg/EncodeJpeg.cs
+++ b/tests/ImageSharp.Benchmarks/Codecs/Jpeg/EncodeJpeg.cs
@@ -10,6 +10,7 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
+ using SixLabors.ImageSharp.Tests;
using CoreImage = SixLabors.ImageSharp.Image;
public class EncodeJpeg : BenchmarkBase
@@ -24,7 +25,8 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg
{
if (this.bmpStream == null)
{
- this.bmpStream = File.OpenRead("../ImageSharp.Tests/TestImages/Formats/Bmp/Car.bmp");
+ const string TestImage = TestImages.Bmp.Car;
+ this.bmpStream = File.OpenRead(Path.Combine(TestEnvironment.InputImagesDirectoryFullPath, TestImage));
this.bmpCore = CoreImage.Load(this.bmpStream);
this.bmpStream.Position = 0;
this.bmpDrawing = Image.FromStream(this.bmpStream);
@@ -58,3 +60,18 @@ namespace SixLabors.ImageSharp.Benchmarks.Codecs.Jpeg
}
}
}
+
+/*
+BenchmarkDotNet=v0.12.1, OS=Windows 10.0.18363.959 (1909/November2018Update/19H2)
+Intel Core i7-8650U CPU 1.90GHz(Kaby Lake R), 1 CPU, 8 logical and 4 physical cores
+.NET Core SDK = 3.1.302
+
+ [Host] : .NET Core 3.1.6 (CoreCLR 4.700.20.26901, CoreFX 4.700.20.31603), X64 RyuJIT
+ DefaultJob : .NET Core 3.1.6 (CoreCLR 4.700.20.26901, CoreFX 4.700.20.31603), X64 RyuJIT
+
+
+| Method | Mean | Error | StdDev | Median | Ratio | RatioSD |
+|---------------------- |---------:|----------:|----------:|---------:|------:|--------:|
+| 'System.Drawing Jpeg' | 4.473 ms | 0.0847 ms | 0.2012 ms | 4.408 ms | 1.00 | 0.00 |
+| 'ImageSharp Jpeg' | 5.409 ms | 0.0379 ms | 0.0316 ms | 5.412 ms | 1.19 | 0.05 |
+*/
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs
index 4c7277e5bc..722521f98d 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs
@@ -282,7 +282,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Jpg
var actualResults = default(Block8x8F);
- Block8x8F.Quantize(ref block, ref actualResults, ref qt, unzig.Data);
+ Block8x8F.Quantize(ref block, ref actualResults, ref qt, ref unzig);
for (int i = 0; i < Block8x8F.Size; i++)
{