Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swapped sRGB linearization implementations #6

Open
domyd opened this issue May 9, 2024 · 1 comment
Open

Swapped sRGB linearization implementations #6

domyd opened this issue May 9, 2024 · 1 comment

Comments

@domyd
Copy link

domyd commented May 9, 2024

Hello! In color_converter.dart, linearize and normalize are each doing the opposite of what they're supposed to do. normalize turns the color into a linear space, and linearize turns it into gamma-compressed sRGB. See https://en.wikipedia.org/wiki/SRGB#Transformation.

I noticed this since OklabColor was seemingly giving me the wrong colors, and I tracked it down to this :)

If you want, I can submit a PR to fix this.

@timmaffett
Copy link

timmaffett commented Sep 8, 2024

@domyd is correct - the math in the map() functions of the linearize() and normalize() functions are indeed swapped.

linearize() should be REVERSING the gamma correct of the sRGB color and instead it is GAMMA CORRECTING it (a second time because the sRGB color is already gamma corrected (and 'non-linear'))
normalize() should be gamma correcting the linear RGB color and returning a non-linear sRGB color, and instead it is REVERSING the gamma correction of a NON-gamma corrected linear RGB color.

PR#12 includes the following fix for this issue.

(@james-alex does not seem to be monitoring this repo any more so I will place the corrected versions here for anyone interested in patching it themselves.)

at end of file color_models/lib/src/helpers/color_converter.dart replace with CORRECTED CODE:

/// A linearized RGB color (as opposed to a Gamma corrected sRGB non-linear color)
class _LinearRgbColor {
  const _LinearRgbColor(
    this.red,
    this.green,
    this.blue,
  );

  /// Constructs a linear RGB color from a list of [values].
  factory _LinearRgbColor.fromList(List<double> values) {
    assert(values.length == 3);
    return _LinearRgbColor(values[0], values[1], values[2]);
  }

  final double red, green, blue;

  /// Returns this linear RGB color as a list of values.
  List<double> toList() => <double>[red, green, blue];

  /// This is to gamma correct 'non-linear' RGB values to transform them into
  /// sRGB color space.
  /// https://en.wikipedia.org/wiki/SRGB#Transformation
  /// 
  /// Converts this linear RGB color back to a gamma
  /// corrected non-linear (sRGB space) [RgbColor].
  RgbColor normalize() => RgbColor.fromList(
        toList()
            .map<double>((value) => value >= 0.0031308
                ? (1.055 * math.pow(value, 1.0 / 2.4)) - 0.055
                : 12.92 * value)
            .toList(),
      );
}

timmaffett added a commit to timmaffett/color_models that referenced this issue Jan 8, 2025
Support Flutter 3.x wide gamut changes, Fix okLab<->RGB conversions (gamma correction math was swapped), Fixes james-alex#9, Fixes james-alex#6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants