//
// 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;
}
}
}