From 47926752d3db062ac008f7031ce5307fc28efd9b Mon Sep 17 00:00:00 2001 From: Brian Popow Date: Tue, 10 Dec 2019 20:58:08 +0100 Subject: [PATCH] Implemented ColorSpaceInverseTransform --- src/ImageSharp/Formats/WebP/LosslessUtils.cs | 78 ++++++++++++++----- .../Formats/WebP/WebPLosslessDecoder.cs | 9 ++- 2 files changed, 65 insertions(+), 22 deletions(-) diff --git a/src/ImageSharp/Formats/WebP/LosslessUtils.cs b/src/ImageSharp/Formats/WebP/LosslessUtils.cs index 2ba749dc3..20e502ef6 100644 --- a/src/ImageSharp/Formats/WebP/LosslessUtils.cs +++ b/src/ImageSharp/Formats/WebP/LosslessUtils.cs @@ -22,46 +22,65 @@ namespace SixLabors.ImageSharp.Formats.WebP } } - public static void ColorSpaceInverseTransform(Vp8LTransform transform, uint[] pixelData, int yEnd) + public static void ColorSpaceInverseTransform(Vp8LTransform transform, uint[] pixelData) { int width = transform.XSize; + int yEnd = transform.YSize; int tileWidth = 1 << transform.Bits; int mask = tileWidth - 1; int safeWidth = width & ~mask; int remainingWidth = width - safeWidth; int tilesPerRow = SubSampleSize(width, transform.Bits); int y = 0; + uint predRow = transform.Data[(y >> transform.Bits) * tilesPerRow]; - /*uint[] predRow = transform.Data + (y >> transform.Bits) * tilesPerRow; - + int pixelPos = 0; while (y < yEnd) { - uint[] pred = predRow; - VP8LMultipliers m = { 0, 0, 0 }; - const uint32_t* const src_safe_end = src + safeWidth; - const uint32_t* const src_end = src + width; - while (src> 8); + uint red = argb >> 16; + int newRed = (int)(red & 0xff); + int newBlue = (int)argb & 0xff; + newRed += ColorTransformDelta(m.GreenToRed, (sbyte)green); + newRed &= 0xff; + newBlue += ColorTransformDelta(m.GreenToBlue, (sbyte)green); + newBlue += ColorTransformDelta(m.RedToBlue, (sbyte)newRed); + newBlue &= 0xff; + var pixelValue = (uint)((argb & 0xff00ff00u) | (newRed << 16) | newBlue); + pixelData[i] = (uint)((argb & 0xff00ff00u) | (newRed << 16) | newBlue); + } } /// @@ -71,5 +90,26 @@ namespace SixLabors.ImageSharp.Formats.WebP { return (size + (1 << samplingBits) - 1) >> samplingBits; } + + private static int ColorTransformDelta(sbyte colorPred, sbyte color) + { + return ((int)colorPred * color) >> 5; + } + + private static void ColorCodeToMultipliers(uint colorCode, ref Vp8LMultipliers m) + { + m.GreenToRed = (sbyte)(colorCode & 0xff); + m.GreenToBlue = (sbyte)((colorCode >> 8) & 0xff); + m.RedToBlue = (sbyte)((colorCode >> 16) & 0xff); + } + + internal struct Vp8LMultipliers + { + public sbyte GreenToRed; + + public sbyte GreenToBlue; + + public sbyte RedToBlue; + } } } diff --git a/src/ImageSharp/Formats/WebP/WebPLosslessDecoder.cs b/src/ImageSharp/Formats/WebP/WebPLosslessDecoder.cs index d12325f38..341af8843 100644 --- a/src/ImageSharp/Formats/WebP/WebPLosslessDecoder.cs +++ b/src/ImageSharp/Formats/WebP/WebPLosslessDecoder.cs @@ -630,14 +630,17 @@ namespace SixLabors.ImageSharp.Formats.WebP private void ApplyInverseTransforms(Vp8LDecoder decoder, uint[] pixelData) { List transforms = decoder.Transforms; - for (int i = transforms.Count; i > 0; i--) + for (int i = transforms.Count - 1; i >= 0; i--) { - Vp8LTransformType transform = transforms[0].TransformType; - switch (transform) + Vp8LTransformType transformType = transforms[i].TransformType; + switch (transformType) { case Vp8LTransformType.SubtractGreen: LosslessUtils.AddGreenToBlueAndRed(pixelData); break; + case Vp8LTransformType.CrossColorTransform: + LosslessUtils.ColorSpaceInverseTransform(transforms[i], pixelData); + break; } } }