diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/RgbToYCbCrTables.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/RgbToYCbCrTables.cs
index 3c1d666850..01fe51c8d1 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/RgbToYCbCrTables.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/RgbToYCbCrTables.cs
@@ -2,6 +2,10 @@
// Licensed under the Apache License, Version 2.0.
using System.Runtime.CompilerServices;
+using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.Formats.Jpeg.Common;
+using SixLabors.ImageSharp.Memory;
+using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Encoder
{
@@ -95,16 +99,16 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Encoder
/// TODO: Replace this logic with SIMD conversion (similar to the one in the decoder)!
/// Optimized method to allocates the correct y, cb, and cr values to the DCT blocks from the given r, g, b values.
///
+ /// The reference to the tables instance.
/// The The luminance block.
/// The red chroma block.
/// The blue chroma block.
- /// The reference to the tables instance.
/// The current index.
/// The red value.
/// The green value.
/// The blue value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void Rgb2YCbCr(float* yBlockRaw, float* cbBlockRaw, float* crBlockRaw, ref RgbToYCbCrTables* tables, int index, int r, int g, int b)
+ public static void Rgb2YCbCr(RgbToYCbCrTables* tables, float* yBlockRaw, float* cbBlockRaw, float* crBlockRaw, int index, int r, int g, int b)
{
// float y = (0.299F * r) + (0.587F * g) + (0.114F * b);
yBlockRaw[index] = (tables->YRTable[r] + tables->YGTable[g] + tables->YBTable[b]) >> ScaleBits;
@@ -116,6 +120,27 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Encoder
crBlockRaw[index] = (tables->CbBTable[r] + tables->CrGTable[g] + tables->CrBTable[b]) >> ScaleBits;
}
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void ConvertPixelInto(int r, int g, int b, ref float yResult, ref float cbResult, ref float crResult)
+ {
+ ref int start = ref Unsafe.As(ref this);
+
+ ref int yR = ref start;
+ ref int yG = ref Unsafe.Add(ref start, 256 * 1);
+ ref int yB = ref Unsafe.Add(ref start, 256 * 2);
+
+ ref int cbR = ref Unsafe.Add(ref start, 256 * 3);
+ ref int cbG = ref Unsafe.Add(ref start, 256 * 4);
+ ref int cbB = ref Unsafe.Add(ref start, 256 * 5);
+
+ ref int crG = ref Unsafe.Add(ref start, 256 * 6);
+ ref int crB = ref Unsafe.Add(ref start, 256 * 7);
+
+ yResult = (Unsafe.Add(ref yR, r) + Unsafe.Add(ref yG, g) + Unsafe.Add(ref yB, b)) >> ScaleBits;
+ cbResult = (Unsafe.Add(ref cbR, r) + Unsafe.Add(ref cbG, g) + Unsafe.Add(ref cbB, b)) >> ScaleBits;
+ crResult = (Unsafe.Add(ref cbB, r) + Unsafe.Add(ref crG, g) + Unsafe.Add(ref crB, b)) >> ScaleBits;
+ }
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static int Fix(float x)
{
@@ -128,4 +153,33 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Encoder
return x >> ScaleBits;
}
}
+
+ // TODO!
+ internal struct YCbCrForwardConverter
+ where TPixel : struct, IPixel
+ {
+ public Block8x8F Y;
+
+ public Block8x8F Cb;
+
+ public Block8x8F Cr;
+
+ private RgbToYCbCrTables colorTables;
+
+ private GenericBlock8x8 pixelBlock;
+
+ private GenericBlock8x8 rgbBlock;
+
+ public static YCbCrForwardConverter Create()
+ {
+ var result = default(YCbCrForwardConverter);
+ result.colorTables = RgbToYCbCrTables.Create();
+ return result;
+ }
+
+ public void Convert(IPixelSource pixels, int x, int y)
+ {
+
+ }
+ }
}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/JpegEncoderCore.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/JpegEncoderCore.cs
index b03b0b5341..fcac30a2c8 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/JpegEncoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/JpegEncoderCore.cs
@@ -303,15 +303,19 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
RgbToYCbCrTables* tables,
int x,
int y,
- Block8x8F* yBlock,
- Block8x8F* cbBlock,
- Block8x8F* crBlock,
+ ref Block8x8F yBlock,
+ ref Block8x8F cbBlock,
+ ref Block8x8F crBlock,
PixelArea rgbBytes)
where TPixel : struct, IPixel
{
- float* yBlockRaw = (float*)yBlock;
- float* cbBlockRaw = (float*)cbBlock;
- float* crBlockRaw = (float*)crBlock;
+ ref float yBlockStart = ref Unsafe.As(ref yBlock);
+ ref float cbBlockStart = ref Unsafe.As(ref cbBlock);
+ ref float crBlockStart = ref Unsafe.As(ref crBlock);
+
+ float* yBlockRaw = (float*) Unsafe.AsPointer(ref yBlock);
+ float* cbBlockRaw = (float*)Unsafe.AsPointer(ref cbBlock);
+ float* crBlockRaw = (float*)Unsafe.AsPointer(ref crBlock);
rgbBytes.Reset();
pixels.CopyRGBBytesStretchedTo(rgbBytes, y, x);
@@ -331,7 +335,14 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
int index = j8 + i;
- RgbToYCbCrTables.Rgb2YCbCr(yBlockRaw, cbBlockRaw, crBlockRaw, ref tables, index, r, g, b);
+ RgbToYCbCrTables.Rgb2YCbCr(tables, yBlockRaw, cbBlockRaw, crBlockRaw, index, r, g, b);
+ //tables->ConvertPixelInto(
+ // r,
+ // g,
+ // b,
+ // ref Unsafe.Add(ref yBlockRaw, index),
+ // ref Unsafe.Add(ref cbBlockRaw, index),
+ // ref Unsafe.Add(ref crBlockRaw, index));
dataIdx += 3;
}
@@ -460,7 +471,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
{
for (int x = 0; x < pixels.Width; x += 8)
{
- ToYCbCr(pixels, tables, x, y, &b, &cb, &cr, rgbBytes);
+ ToYCbCr(pixels, tables, x, y, ref b, ref cb, ref cr, rgbBytes);
prevDCY = this.WriteBlock(
QuantIndex.Luminance,
@@ -920,7 +931,15 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
int xOff = (i & 1) * 8;
int yOff = (i & 2) * 4;
- ToYCbCr(pixels, tables, x + xOff, y + yOff, &b, cbPtr + i, crPtr + i, rgbBytes);
+ ToYCbCr(
+ pixels,
+ tables,
+ x + xOff,
+ y + yOff,
+ ref b,
+ ref Unsafe.AsRef(cbPtr + i),
+ ref Unsafe.AsRef(crPtr + i),
+ rgbBytes);
prevDCY = this.WriteBlock(
QuantIndex.Luminance,
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Utils/OrigJpegUtils.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Utils/OrigJpegUtils.cs
index 42a7d56e3b..caa7014a4b 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Utils/OrigJpegUtils.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Utils/OrigJpegUtils.cs
@@ -7,11 +7,22 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Utils
{
+ using SixLabors.ImageSharp.Formats.Jpeg.Common;
+
///
/// Jpeg specific utilities and extension methods
///
internal static class OrigJpegUtils
{
+ ///
+ /// Stack only TPixel -> Rgb24 conversion method on 8x8 blocks.
+ ///
+ public static void ConvertToRgbUnsafe(ref GenericBlock8x8 source, ref GenericBlock8x8 dest)
+ where TPixel : struct, IPixel
+ {
+ PixelOperations.Instance.ToRgb24(source.AsSpanUnsafe(), dest.AsSpanUnsafe(), 64);
+ }
+
///
/// Copy a region of an image into dest. De "outlier" area will be stretched out with pixels on the right and bottom of the image.
///