Browse Source

Implemented cmyk encoding

pull/2120/head
Dmitry Pentin 4 years ago
parent
commit
ccf664c150
  1. 43
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykAvx.cs
  2. 41
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykScalar.cs
  3. 47
      src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykVector.cs

43
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykAvx.cs

@ -18,8 +18,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
{
}
public override void ConvertFromRgbInplace(in ComponentValues values) => throw new System.NotImplementedException();
public override void ConvertToRgbInplace(in ComponentValues values)
{
ref Vector256<float> c0Base =
@ -48,6 +46,47 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
y = Avx.Multiply(y, k);
}
}
public override void ConvertFromRgbInplace(in ComponentValues values)
{
ref Vector256<float> c0Base =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component0));
ref Vector256<float> c1Base =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component1));
ref Vector256<float> c2Base =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component2));
ref Vector256<float> c3Base =
ref Unsafe.As<float, Vector256<float>>(ref MemoryMarshal.GetReference(values.Component3));
// Used for the color conversion
var scale = Vector256.Create(this.MaximumValue);
var one = Vector256.Create(1f);
nint n = values.Component0.Length / Vector256<float>.Count;
for (nint i = 0; i < n; i++)
{
ref Vector256<float> c0 = ref Unsafe.Add(ref c0Base, i);
ref Vector256<float> c1 = ref Unsafe.Add(ref c1Base, i);
ref Vector256<float> c2 = ref Unsafe.Add(ref c2Base, i);
ref Vector256<float> c3 = ref Unsafe.Add(ref c3Base, i);
Vector256<float> ctmp = Avx.Subtract(one, c0);
Vector256<float> mtmp = Avx.Subtract(one, c1);
Vector256<float> ytmp = Avx.Subtract(one, c2);
Vector256<float> ktmp = Avx.Min(ctmp, Avx.Min(mtmp, ytmp));
Vector256<float> kMask = Avx.CompareNotEqual(ktmp, one);
ctmp = Avx.And(Avx.Divide(Avx.Subtract(ctmp, ktmp), Avx.Subtract(one, ktmp)), kMask);
mtmp = Avx.And(Avx.Divide(Avx.Subtract(mtmp, ktmp), Avx.Subtract(one, ktmp)), kMask);
ytmp = Avx.And(Avx.Divide(Avx.Subtract(ytmp, ktmp), Avx.Subtract(one, ktmp)), kMask);
c0 = Avx.Subtract(scale, Avx.Multiply(ctmp, scale));
c1 = Avx.Subtract(scale, Avx.Multiply(mtmp, scale));
c2 = Avx.Subtract(scale, Avx.Multiply(ytmp, scale));
c3 = Avx.Subtract(scale, Avx.Multiply(ktmp, scale));
}
}
}
}
}

41
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykScalar.cs

@ -15,9 +15,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
}
public override void ConvertToRgbInplace(in ComponentValues values) =>
ConvertCoreInplace(values, this.MaximumValue);
ConvertToRgbInplace(values, this.MaximumValue);
internal static void ConvertCoreInplace(in ComponentValues values, float maxValue)
public override void ConvertFromRgbInplace(in ComponentValues values)
=> ConvertFromRgbInplace(values, this.MaximumValue);
public static void ConvertToRgbInplace(in ComponentValues values, float maxValue)
{
Span<float> c0 = values.Component0;
Span<float> c1 = values.Component1;
@ -39,7 +42,39 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
}
}
public override void ConvertFromRgbInplace(in ComponentValues values) => throw new NotImplementedException();
public static void ConvertFromRgbInplace(in ComponentValues values, float maxValue)
{
Span<float> c0 = values.Component0;
Span<float> c1 = values.Component1;
Span<float> c2 = values.Component2;
Span<float> c3 = values.Component3;
for (int i = 0; i < c0.Length; i++)
{
float ctmp = 1f - c0[i];
float mtmp = 1f - c1[i];
float ytmp = 1f - c2[i];
float ktmp = MathF.Min(MathF.Min(ctmp, mtmp), ytmp);
if (1f - ktmp <= float.Epsilon)
{
ctmp = 0f;
mtmp = 0f;
ytmp = 0f;
}
else
{
ctmp = (ctmp - ktmp) / (1f - ktmp);
mtmp = (mtmp - ktmp) / (1f - ktmp);
ytmp = (ytmp - ktmp) / (1f - ktmp);
}
c0[i] = maxValue - (ctmp * maxValue);
c1[i] = maxValue - (mtmp * maxValue);
c2[i] = maxValue - (ytmp * maxValue);
c3[i] = maxValue - (ktmp * maxValue);
}
}
}
}
}

47
src/ImageSharp/Formats/Jpeg/Components/Decoder/ColorConverters/JpegColorConverter.FromCmykVector.cs

@ -44,12 +44,51 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder.ColorConverters
}
}
protected override void ConvertCoreInplaceToRgb(in ComponentValues values) =>
FromCmykScalar.ConvertCoreInplace(values, this.MaximumValue);
protected override void ConvertCoreInplaceToRgb(in ComponentValues values)
=> FromCmykScalar.ConvertToRgbInplace(values, this.MaximumValue);
protected override void ConvertCoreVectorizedInplaceFromRgb(in ComponentValues values) => throw new System.NotImplementedException();
protected override void ConvertCoreVectorizedInplaceFromRgb(in ComponentValues values)
{
ref Vector<float> c0Base =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component0));
ref Vector<float> c1Base =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component1));
ref Vector<float> c2Base =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component2));
ref Vector<float> c3Base =
ref Unsafe.As<float, Vector<float>>(ref MemoryMarshal.GetReference(values.Component3));
// Used for the color conversion
var scale = new Vector<float>(this.MaximumValue);
var one = new Vector<float>(1f);
nint n = values.Component0.Length / Vector<float>.Count;
for (nint i = 0; i < n; i++)
{
ref Vector<float> c0 = ref Unsafe.Add(ref c0Base, i);
ref Vector<float> c1 = ref Unsafe.Add(ref c1Base, i);
ref Vector<float> c2 = ref Unsafe.Add(ref c2Base, i);
ref Vector<float> c3 = ref Unsafe.Add(ref c3Base, i);
Vector<float> ctmp = one - c0;
Vector<float> mtmp = one - c1;
Vector<float> ytmp = one - c2;
Vector<float> ktmp = Vector.Min(ctmp, Vector.Min(mtmp, ytmp));
var kMask = Vector.Equals(ktmp, Vector<float>.One);
ctmp = Vector.AndNot((ctmp - ktmp) / (one - ktmp), kMask.As<int, float>());
mtmp = Vector.AndNot((mtmp - ktmp) / (one - ktmp), kMask.As<int, float>());
ytmp = Vector.AndNot((ytmp - ktmp) / (one - ktmp), kMask.As<int, float>());
c0 = scale - (ctmp * scale);
c1 = scale - (mtmp * scale);
c2 = scale - (ytmp * scale);
c3 = scale - (ktmp * scale);
}
}
protected override void ConvertCoreInplaceFromRgb(in ComponentValues values) => throw new System.NotImplementedException();
protected override void ConvertCoreInplaceFromRgb(in ComponentValues values)
=> FromCmykScalar.ConvertFromRgbInplace(values, this.MaximumValue);
}
}
}

Loading…
Cancel
Save