// Decompiled with JetBrains decompiler // Type: SFXProductions.GradientTool.Utils // Assembly: GradientTool, Version=0.8.2.1, Culture=neutral, PublicKeyToken=null // MVID: 818AB9B3-796A-4A49-8B90-C00D066A321B // Assembly location: C:\Users\aless\Downloads\gradient-tool-v0.8.2.1\GradientTool.exe using SFXProductions.GradientTool.HDMA; using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Windows.Forms; #nullable disable namespace SFXProductions.GradientTool; internal static class Utils { private static Dictionary s_records = new Dictionary(); private static SaveFileDialog s_saveDialog = new SaveFileDialog(); internal static int IndexOfGradientStop(this IList gradientStopList, ulong id) { for (int index = 0; index < gradientStopList.Count; ++index) { if ((long) gradientStopList[index].Id == (long) id) return index; } return -1; } internal static Decimal Clamp(this Decimal value, Decimal max = 100M, Decimal min = 0M) { if (value < min) value = min; else if (value > max) value = max; return value; } internal static double Clamp(this double value, double max = 1.0, double min = 0.0) { if (value < min) value = min; else if (value > max) value = max; return value; } internal static int Clamp(this int value, int max, int min = 0) { if (value < min) value = min; else if (value > max) value = max; return value; } internal static bool HasFlag(this ChannelType chType, ChannelType flag) { return (chType & flag) == flag; } internal static bool EditGradientStop( IWin32Window owner, ref GradientStop gradientStop, string title = null) { using (ColourSelector colourSelector = new ColourSelector()) { colourSelector.SetColour(gradientStop.Colour); colourSelector.SetOffset(gradientStop.Position); if (title != null) colourSelector.Text = title; if (colourSelector.ShowDialog(owner) == DialogResult.OK) { gradientStop.Colour = colourSelector.GetColour(); gradientStop.Position = colourSelector.GetOffset(); return true; } } return false; } internal static unsafe string PromptForFilename( IWin32Window owner, string filter, string defaultExt, string defaultName = null, string typeId = null) { string defaultName1 = defaultName; string typeId1 = typeId; return Utils.PromptForFilename(owner, filter, defaultExt, (int*) null, defaultName1, typeId1); } internal static unsafe string PromptForFilename( IWin32Window owner, string filter, string defaultExt, int* pFilterIndex, string defaultName = null, string typeId = null) { string str = string.Empty; string key = typeId ?? filter; if (!Utils.s_records.ContainsKey(key)) Utils.s_records.Add(key, str); else str = Utils.s_records[key]; Utils.s_saveDialog.InitialDirectory = str; Utils.s_saveDialog.FileName = defaultName ?? string.Empty; Utils.s_saveDialog.DefaultExt = defaultExt; Utils.s_saveDialog.Filter = filter; if ((IntPtr) pFilterIndex != IntPtr.Zero && *pFilterIndex > 0) Utils.s_saveDialog.FilterIndex = *pFilterIndex; if (Utils.s_saveDialog.ShowDialog(owner) != DialogResult.OK) return (string) null; if ((IntPtr) pFilterIndex != IntPtr.Zero) *pFilterIndex = Utils.s_saveDialog.FilterIndex; Utils.s_records[filter] = Path.GetDirectoryName(Utils.s_saveDialog.FileName); return Utils.s_saveDialog.FileName; } internal static ushort RoundToWord(double v) { return (ushort) Math.Min(v + 0.5, (double) ushort.MaxValue); } internal static byte RoundToByte(double v) => (byte) Math.Min(v + 0.5, (double) byte.MaxValue); internal static void Get5BitChannels( this Color colour, out byte red, out byte green, out byte blue) { red = Utils.RoundToByte((double) colour.R * ((double) byte.MaxValue / 31.0)); green = Utils.RoundToByte((double) colour.G * ((double) byte.MaxValue / 31.0)); blue = Utils.RoundToByte((double) colour.B * ((double) byte.MaxValue / 31.0)); } internal static Vector ToColourspace(this Color colour, GradientColourspace colourspace) { switch (colourspace) { case GradientColourspace.RGB: return new Vector() { X = (double) colour.R / (double) byte.MaxValue, Y = (double) colour.G / (double) byte.MaxValue, Z = (double) colour.B / (double) byte.MaxValue }; case GradientColourspace.HSV: case GradientColourspace.HSL: case GradientColourspace.HSY: return new Vector() { X = ((double) colour.R / (double) byte.MaxValue), Y = ((double) colour.G / (double) byte.MaxValue), Z = ((double) colour.B / (double) byte.MaxValue) }.HDRToColourspace(colourspace); default: throw new ArgumentException("Invalid colourspace."); } } internal static Vector HDRToColourspace(this Vector vector, GradientColourspace toColourspace) { switch (toColourspace) { case GradientColourspace.RGB: case GradientColourspace.RGBV: case GradientColourspace.RGBB: case GradientColourspace.RGBL: return vector; case GradientColourspace.HSV: case GradientColourspace.HSL: case GradientColourspace.HSY: double num1 = Math.Max(vector.X, Math.Max(vector.Y, vector.Z)); double num2 = Math.Min(vector.X, Math.Min(vector.Y, vector.Z)); if (num1 <= 0.0) return new Vector() { X = double.NaN, Y = double.NaN, Z = 0.0 }; double num3 = num1 - num2; double num4 = double.NaN; if (num3 > 0.0) { if (num1 == vector.X) num4 = (vector.Y - vector.Z) / num3 % 6.0; else if (num1 == vector.Y) num4 = (vector.Z - vector.X) / num3 + 2.0; else if (num1 == vector.Z) num4 = (vector.X - vector.Y) / num3 + 4.0; } double d = num4 / 6.0; double num5 = d - Math.Floor(d); switch (toColourspace) { case GradientColourspace.HSV: return new Vector() { X = num5, Y = num3 / num1, Z = num1 }; case GradientColourspace.HSL: double num6 = (num1 + num2) / 2.0; return new Vector() { X = num5, Y = num3 / (num6 <= 0.5 ? 2.0 * num6 : 2.0 - 2.0 * num6), Z = num6 }; default: double num7 = (vector.X + vector.Y + vector.Z) / 3.0; return new Vector() { X = num5, Y = 1.0 - 3.0 / (vector.X + vector.Y + vector.Z) * num2, Z = num7 }; } default: throw new ArgumentException("Invalid colourspace."); } } internal static double GetRGBValue(this Vector vector) { return Math.Max(vector.X, Math.Max(vector.Y, vector.Z)); } internal static double GetRGBBrightness(this Vector vector) { return (vector.X + vector.Y + vector.Z) / 3.0; } internal static double GetRGBLightness(this Vector vector) { return (Math.Max(vector.X, Math.Max(vector.Y, vector.Z)) + Math.Min(vector.X, Math.Min(vector.Y, vector.Z))) / 2.0; } internal static Vector Adjust(this Vector vector, double orig, double @new) { if (orig == 0.0) return new Vector(); double num = @new / orig; vector.X *= num; vector.Y *= num; vector.Z *= num; return vector; } private static void GetR1G1B1( double hue, double chroma, out double r1, out double g1, out double b1) { hue = (hue - Math.Floor(hue)) * 6.0; if (double.IsNaN(hue)) hue = 0.0; double num = chroma * (1.0 - Math.Abs(hue % 2.0 - 1.0)); if (double.IsNaN(hue) || double.IsNaN(chroma) || chroma <= 0.0) r1 = g1 = b1 = 0.0; else if (hue < 1.0) { r1 = chroma; g1 = num; b1 = 0.0; } else if (hue < 2.0) { r1 = num; g1 = chroma; b1 = 0.0; } else if (hue < 3.0) { r1 = 0.0; g1 = chroma; b1 = num; } else if (hue < 4.0) { r1 = 0.0; g1 = num; b1 = chroma; } else if (hue < 5.0) { r1 = num; g1 = 0.0; b1 = chroma; } else { r1 = chroma; g1 = 0.0; b1 = num; } } internal static Vector ToHDR(this Vector vector, GradientColourspace fromColourspace) { switch (fromColourspace) { case GradientColourspace.RGB: case GradientColourspace.RGBV: case GradientColourspace.RGBB: case GradientColourspace.RGBL: return vector; case GradientColourspace.HSV: double chroma = vector.Y * vector.Z; double r1_1; double g1_1; double b1_1; Utils.GetR1G1B1(vector.X, chroma, out r1_1, out g1_1, out b1_1); double num1 = vector.Z - chroma; r1_1 += num1; double num2 = g1_1 + num1; double num3 = b1_1 + num1; return new Vector() { X = r1_1, Y = num2, Z = num3 }; case GradientColourspace.HSL: double num4 = (1.0 - Math.Abs(2.0 * vector.Z - 1.0)) * vector.Y; if (double.IsNaN(num4)) num4 = 0.0; double r1_2; double g1_2; double b1_2; Utils.GetR1G1B1(vector.X, num4, out r1_2, out g1_2, out b1_2); double num5 = vector.Z - num4 * 0.5; r1_2 += num5; g1_2 += num5; double num6 = b1_2 + num5; return new Vector() { X = r1_2, Y = g1_2, Z = num6 }; case GradientColourspace.HSY: return Utils.HSYToRGB(vector); default: throw new ArgumentException("Invalid colourspace."); } } private static Vector HSYToRGB(Vector v) { v.X -= Math.Floor(v.X); v.X *= 360.0; Vector rgb = new Vector(); if (0.0 < v.X && v.X <= 120.0) { rgb.Z = 1.0 / 3.0 * (1.0 - v.Y); rgb.X = 1.0 / 3.0 * (1.0 + v.Y * Math.Cos(v.X) / Math.Cos(60.0 - v.X)); rgb.Y = 1.0 - (rgb.X + rgb.Z); } else if (120.0 < v.X && v.X <= 240.0) { v.X -= 120.0; rgb.X = 1.0 / 3.0 * (1.0 - v.Y); rgb.Y = 1.0 / 3.0 * (1.0 + v.Y * Math.Cos(v.X) / Math.Cos(60.0 - v.X)); rgb.Z = 1.0 - (rgb.X + rgb.Y); } else { v.X -= 240.0; rgb.Y = 1.0 / 3.0 * (1.0 - v.Y); rgb.Z = 1.0 / 3.0 * (1.0 + v.Y * Math.Cos(v.X) / Math.Cos(60.0 - v.X)); rgb.X = 1.0 - (rgb.Y + rgb.Z); } return rgb; } internal static Color ToRGB(this Vector vector, GradientColourspace fromColourspace) { switch (fromColourspace) { case GradientColourspace.RGB: return Color.FromArgb((int) Utils.RoundToByte(vector.X * (double) byte.MaxValue), (int) Utils.RoundToByte(vector.Y * (double) byte.MaxValue), (int) Utils.RoundToByte(vector.Z * (double) byte.MaxValue)); case GradientColourspace.HSV: case GradientColourspace.HSL: case GradientColourspace.HSY: vector = vector.ToHDR(fromColourspace); return Color.FromArgb((int) Utils.RoundToByte(vector.X * (double) byte.MaxValue), (int) Utils.RoundToByte(vector.Y * (double) byte.MaxValue), (int) Utils.RoundToByte(vector.Z * (double) byte.MaxValue)); default: throw new ArgumentException("Invalid colourspace."); } } }