// // Copyright (c) James South and contributors. // Licensed under the Apache License, Version 2.0. // namespace ImageProcessor { using System; using System.Numerics; /// /// Performs per-pixel operations. /// public static class PixelOperations { /// /// Converts an pixel from an sRGB color-space to the equivalent linear color-space. /// /// /// The to convert. /// /// /// The . /// public static Color ToLinear(Color composite) { // TODO: Figure out a way to either cache these values quickly or perform the calcuations together. composite.R = SrgbToLinear(composite.R); composite.G = SrgbToLinear(composite.G); composite.B = SrgbToLinear(composite.B); return composite; } /// /// Converts a pixel from a linear color-space to the equivalent sRGB color-space. /// /// /// The to convert. /// /// /// The . /// public static Color ToSrgb(Color linear) { // TODO: Figure out a way to either cache these values quickly or perform the calcuations together. linear.R = LinearToSrgb(linear.R); linear.G = LinearToSrgb(linear.G); linear.B = LinearToSrgb(linear.B); return linear; } /// /// Gets the correct linear value from an sRGB signal. /// /// /// /// The signal value to convert. /// /// The . /// private static float SrgbToLinear(float signal) { if (signal <= 0.04045f) { return signal / 12.92f; } return (float)Math.Pow((signal + 0.055f) / 1.055f, 2.4f); } /// /// Gets the correct sRGB value from an linear signal. /// /// /// /// The signal value to convert. /// /// The . /// private static float LinearToSrgb(float signal) { if (signal <= 0.0031308f) { return signal * 12.92f; } return (1.055f * (float)Math.Pow(signal, 0.41666666f)) - 0.055f; } } }