Browse Source

YCbCrForwardConverter<TPixel> WIP

af/merge-core
Anton Firszov 8 years ago
parent
commit
8c15954391
  1. 58
      src/ImageSharp/Formats/Jpeg/GolangPort/Components/Encoder/RgbToYCbCrTables.cs
  2. 37
      src/ImageSharp/Formats/Jpeg/GolangPort/JpegEncoderCore.cs
  3. 11
      src/ImageSharp/Formats/Jpeg/GolangPort/Utils/OrigJpegUtils.cs

58
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.
/// </summary>
/// <param name="tables">The reference to the tables instance.</param>
/// <param name="yBlockRaw">The The luminance block.</param>
/// <param name="cbBlockRaw">The red chroma block.</param>
/// <param name="crBlockRaw">The blue chroma block.</param>
/// <param name="tables">The reference to the tables instance.</param>
/// <param name="index">The current index.</param>
/// <param name="r">The red value.</param>
/// <param name="g">The green value.</param>
/// <param name="b">The blue value.</param>
[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<RgbToYCbCrTables, int>(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<TPixel>
where TPixel : struct, IPixel<TPixel>
{
public Block8x8F Y;
public Block8x8F Cb;
public Block8x8F Cr;
private RgbToYCbCrTables colorTables;
private GenericBlock8x8<TPixel> pixelBlock;
private GenericBlock8x8<Rgb24> rgbBlock;
public static YCbCrForwardConverter<TPixel> Create()
{
var result = default(YCbCrForwardConverter<TPixel>);
result.colorTables = RgbToYCbCrTables.Create();
return result;
}
public void Convert(IPixelSource<TPixel> pixels, int x, int y)
{
}
}
}

37
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<TPixel> rgbBytes)
where TPixel : struct, IPixel<TPixel>
{
float* yBlockRaw = (float*)yBlock;
float* cbBlockRaw = (float*)cbBlock;
float* crBlockRaw = (float*)crBlock;
ref float yBlockStart = ref Unsafe.As<Block8x8F, float>(ref yBlock);
ref float cbBlockStart = ref Unsafe.As<Block8x8F, float>(ref cbBlock);
ref float crBlockStart = ref Unsafe.As<Block8x8F, float>(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<Block8x8F>(cbPtr + i),
ref Unsafe.AsRef<Block8x8F>(crPtr + i),
rgbBytes);
prevDCY = this.WriteBlock(
QuantIndex.Luminance,

11
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;
/// <summary>
/// Jpeg specific utilities and extension methods
/// </summary>
internal static class OrigJpegUtils
{
/// <summary>
/// Stack only TPixel -> Rgb24 conversion method on 8x8 blocks.
/// </summary>
public static void ConvertToRgbUnsafe<TPixel>(ref GenericBlock8x8<TPixel> source, ref GenericBlock8x8<Rgb24> dest)
where TPixel : struct, IPixel<TPixel>
{
PixelOperations<TPixel>.Instance.ToRgb24(source.AsSpanUnsafe(), dest.AsSpanUnsafe(), 64);
}
/// <summary>
/// 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.
/// </summary>

Loading…
Cancel
Save