From 61b9c3c25f47bf62d27abdff5902b45d5e4c6945 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 30 Aug 2017 22:41:58 +1000 Subject: [PATCH] Add Ycck and CMYK conversion These should be correct. I couldn't figure out how to test the values though as I can't remember what format each component array is in. Pretty sure in CMYK it's actually Ycc + inverted K. --- .../Decoder/JpegColorConverter.FromCmyk.cs | 46 +++++++++++++++++++ .../Decoder/JpegColorConverter.FromYccK.cs | 46 +++++++++++++++++++ .../Jpeg/Common/Decoder/JpegColorConverter.cs | 2 +- 3 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorConverter.FromCmyk.cs create mode 100644 src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorConverter.FromYccK.cs diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorConverter.FromCmyk.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorConverter.FromCmyk.cs new file mode 100644 index 0000000000..524cc76df1 --- /dev/null +++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorConverter.FromCmyk.cs @@ -0,0 +1,46 @@ +using System; +using System.Numerics; + +namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder +{ + internal abstract partial class JpegColorConverter + { + private class FromCmyk : JpegColorConverter + { + public FromCmyk() + : base(JpegColorSpace.Cmyk) + { + } + + public override void ConvertToRGBA(ComponentValues values, Span result) + { + // TODO: We can optimize a lot here with Vector and SRCS.Unsafe()! + ReadOnlySpan cVals = values.Component0; + ReadOnlySpan mVals = values.Component1; + ReadOnlySpan yVals = values.Component2; + ReadOnlySpan kVals = values.Component3; + + var v = new Vector4(0, 0, 0, 1F); + + var scale = new Vector4(1 / 255F, 1 / 255F, 1 / 255F, 1F); + + for (int i = 0; i < result.Length; i++) + { + float c = cVals[i]; + float m = mVals[i]; + float y = yVals[i]; + float k = kVals[i] / 255F; + + v.X = c * k; + v.Y = m * k; + v.Z = y * k; + v.W = 1F; + + v *= scale; + + result[i] = v; + } + } + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorConverter.FromYccK.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorConverter.FromYccK.cs new file mode 100644 index 0000000000..3449cc6b17 --- /dev/null +++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorConverter.FromYccK.cs @@ -0,0 +1,46 @@ +using System; +using System.Numerics; + +namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder +{ + internal abstract partial class JpegColorConverter + { + private class FromYccK : JpegColorConverter + { + public FromYccK() + : base(JpegColorSpace.Ycck) + { + } + + public override void ConvertToRGBA(ComponentValues values, Span result) + { + // TODO: We can optimize a lot here with Vector and SRCS.Unsafe()! + ReadOnlySpan yVals = values.Component0; + ReadOnlySpan cbVals = values.Component1; + ReadOnlySpan crVals = values.Component2; + ReadOnlySpan kVals = values.Component3; + + var v = new Vector4(0, 0, 0, 1F); + + var scale = new Vector4(1 / 255F, 1 / 255F, 1 / 255F, 1F); + + for (int i = 0; i < result.Length; i++) + { + float y = yVals[i]; + float cb = cbVals[i] - 128F; + float cr = crVals[i] - 128F; + float k = kVals[i] / 255F; + + v.X = (255F - MathF.Round(y + (1.402F * cr), MidpointRounding.AwayFromZero)) * k; + v.Y = (255F - MathF.Round(y - (0.344136F * cb) - (0.714136F * cr), MidpointRounding.AwayFromZero)) * k; + v.Z = (255F - MathF.Round(y + (1.772F * cb), MidpointRounding.AwayFromZero)) * k; + v.W = 1F; + + v *= scale; + + result[i] = v; + } + } + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorConverter.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorConverter.cs index 2ff0f7a10a..aaee7bcd14 100644 --- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorConverter.cs +++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegColorConverter.cs @@ -9,7 +9,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder { internal abstract partial class JpegColorConverter { - private static readonly JpegColorConverter[] Converters = { new FromYCbCr(), }; + private static readonly JpegColorConverter[] Converters = { new FromYCbCr(), new FromYccK(), new FromCmyk() }; protected JpegColorConverter(JpegColorSpace colorSpace) {