diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Color.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Color.cs index 33ba356c225..e9f39258468 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Color.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Color.cs @@ -431,7 +431,7 @@ public float[] GetNativeColorValues() c2.context = new ColorContext(PixelFormats.Bgra32); ColorTransform colorTransform = new ColorTransform(c1.context, c2.context); - float[] sRGBValue = new float[3]; + Span sRGBValue = stackalloc float[3]; colorTransform.Translate(c1.nativeColorValue, sRGBValue); @@ -550,7 +550,7 @@ public static Color Add(Color color1, Color color2) c2.context = new ColorContext(PixelFormats.Bgra32); ColorTransform colorTransform = new ColorTransform(c1.context, c2.context); - float[] sRGBValue = new float[3]; + Span sRGBValue = stackalloc float[3]; colorTransform.Translate(c1.nativeColorValue, sRGBValue); @@ -1097,7 +1097,7 @@ private void ComputeScRgbValues() c2.context = new ColorContext(PixelFormats.Bgra32); ColorTransform colorTransform = new ColorTransform(this.context, c2.context); - float[] scRGBValue = new float[3]; + Span scRGBValue = stackalloc float[3]; colorTransform.Translate(this.nativeColorValue, scRGBValue); @@ -1110,16 +1110,11 @@ private void ComputeScRgbValues() private void ComputeNativeValues(int numChannels) { this.nativeColorValue = new float[numChannels]; - if (this.nativeColorValue.GetLength(0) > 0) + if (this.nativeColorValue.Length > 0) { - float[] sRGBValue = new float[3]; - - sRGBValue[0] = this.sRgbColor.r / 255.0f; - sRGBValue[1] = this.sRgbColor.g / 255.0f; - sRGBValue[2] = this.sRgbColor.b / 255.0f; + Span sRGBValue = [this.sRgbColor.r / 255.0f, this.sRgbColor.g / 255.0f, this.sRgbColor.b / 255.0f]; ColorTransform colorTransform = new ColorTransform(this.context, new ColorContext(PixelFormats.Bgra32)); - colorTransform.Translate(sRGBValue, this.nativeColorValue); } } diff --git a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/ColorTransform.cs b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/ColorTransform.cs index fb8c00ee6c1..42e423e632e 100644 --- a/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/ColorTransform.cs +++ b/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/ColorTransform.cs @@ -106,52 +106,30 @@ internal ColorTransform(SafeMILHandle bitmapSource, ColorContext srcContext, Col #region Internal Methods - internal void Translate(float[] srcValue, float[] dstValue) + internal unsafe void Translate(Span srcValue, Span dstValue) { - // 3. create Win32 unmanaged profile handle from memory source profile using OpenColorProfileW - IntPtr[] pProfiles = new IntPtr[2]; + // Transform colors using TranslateColors + const UInt32 NumColors = 1; - IntPtr paInputColors = IntPtr.Zero; - IntPtr paOutputColors = IntPtr.Zero; + // There's no SkipLocalsInit, will be all zeroes + long* paInputColors = stackalloc long[64 / sizeof(long)]; + long* paOutputColors = stackalloc long[64 / sizeof(long)]; - try - { - // 6. transform colors using TranslateColors - UInt32 numColors = 1; - long inputColor = ICM2Color(srcValue); - paInputColors = Marshal.AllocHGlobal(64); - - Marshal.WriteInt64(paInputColors, inputColor); - - paOutputColors = Marshal.AllocHGlobal(64); - long outputColor = 0; - - Marshal.WriteInt64(paOutputColors, outputColor); - - _colorTransformHelper.TranslateColors( - (IntPtr)paInputColors, - numColors, - _inputColorType, - (IntPtr)paOutputColors, - _outputColorType - ); + long inputColor = ICM2Color(srcValue); + paInputColors[0] = inputColor; - outputColor = Marshal.ReadInt64(paOutputColors); - for (int i = 0; i < dstValue.GetLength(0); i++) - { - UInt32 result = 0x0000ffff & (UInt32)(outputColor >> (16 * i)); - float a = (result & 0x7fffffff) / (float)(0x10000); + _colorTransformHelper.TranslateColors((nint)paInputColors, NumColors, _inputColorType, (nint)paOutputColors, _outputColorType); - if (result < 0) - dstValue[i] = -a; - else - dstValue[i] = a; - } - } - finally + long outputColor = paOutputColors[0]; + for (int i = 0; i < dstValue.Length; i++) { - Marshal.FreeHGlobal(paInputColors); - Marshal.FreeHGlobal(paOutputColors); + UInt32 result = 0x0000ffff & (UInt32)(outputColor >> (16 * i)); + float a = (result & 0x7fffffff) / (float)0x10000; + + if (result < 0) + dstValue[i] = -a; + else + dstValue[i] = a; } } @@ -170,21 +148,20 @@ private void InitializeICM() _colorTransformHelper = new ColorTransformHelper(); } - private long ICM2Color(float[] srcValue) + private long ICM2Color(Span srcValue) { long colorValue; - if (srcValue.GetLength(0) < 3 || srcValue.GetLength(0) > 8) + if (srcValue.Length < 3 || srcValue.Length > 8) { throw new NotSupportedException(); // Only support color spaces with 3,4,5,6,7,8 channels } - if (srcValue.GetLength(0) <= 4) + if (srcValue.Length <= 4) { - UInt16[] channel = new UInt16[4]; + Span channel = stackalloc UInt16[4]; - channel[0] = channel[1] = channel[2] = channel[3] = 0; - for (int i = 0; i < srcValue.GetLength(0); i++) + for (int i = 0; i < srcValue.Length; i++) { if (srcValue[i] >= 1.0)// this fails for values above 1.0 and below 0.0 { @@ -204,11 +181,9 @@ private long ICM2Color(float[] srcValue) } else { - byte[] channel = new byte[8]; + Span channel = stackalloc byte[8]; - channel[0] = channel[1] = channel[2] = channel[3] = - channel[4] = channel[5] = channel[6] = channel[7] = 0; - for (int i = 0; i < srcValue.GetLength(0); i++) + for (int i = 0; i < srcValue.Length; i++) { if (srcValue[i] >= 1.0)// this fails for values above 1.0 and below 0.0 { @@ -244,9 +219,9 @@ private long ICM2Color(float[] srcValue) private ColorTransformHelper _colorTransformHelper; - private UInt32 _inputColorType; + private readonly UInt32 _inputColorType; - private UInt32 _outputColorType; + private readonly UInt32 _outputColorType; #endregion }