Browse Source

Revert "Color is now linear by default."

This reverts commit c4114b2ef1 [formerly 144be0509d7ce2e2702b13b1ea60f708083e4912] [formerly 549f0ac778eb8b1a12d7b7e38280f360aa71ad59] [formerly 3869ebe4d426df2fba1e2996c2fed464a0a55357].


Former-commit-id: a6e0888c25d48a7982a297bfda0ecbc90e20a3d0
Former-commit-id: e404d156c276660e88d0524cce840205c0bb7214
Former-commit-id: ea32434d8dc919a710f521f358ad939a98ada9fe
af/merge-core
James Jackson-South 10 years ago
parent
commit
94cd3d7411
  1. 2
      src/ImageProcessor/Colors/Color.cs
  2. 2
      src/ImageProcessor/Colors/ColorDefinitions.cs
  3. 2
      src/ImageProcessor/Colors/ColorTransforms.cs
  4. 6
      src/ImageProcessor/Colors/ColorspaceTransforms.cs
  5. 2
      src/ImageProcessor/Colors/Colorspaces/CieLab.cs
  6. 2
      src/ImageProcessor/Colors/Colorspaces/CieXyz.cs
  7. 4
      src/ImageProcessor/Filters/Brightness.cs
  8. 6
      src/ImageProcessor/Filters/ColorMatrix/ColorMatrixFilter.cs
  9. 2
      src/ImageProcessor/Filters/ColorMatrix/Hue.cs
  10. 2
      src/ImageProcessor/Filters/ColorMatrix/Sepia.cs
  11. 4
      src/ImageProcessor/Filters/Contrast.cs
  12. 50
      src/ImageProcessor/Formats/Bmp/BmpDecoderCore.cs
  13. 4
      src/ImageProcessor/Formats/Bmp/BmpEncoder.cs
  14. 25
      src/ImageProcessor/Formats/Jpg/JpegDecoder.cs
  15. 3
      src/ImageProcessor/Formats/Jpg/JpegEncoder.cs
  16. 6
      src/ImageProcessor/Samplers/Resampler.cs

2
src/ImageProcessor/Colors/Color.cs

@ -11,7 +11,7 @@ namespace ImageProcessor
/// <summary>
/// Represents a four-component color using red, green, blue, and alpha data.
/// Each component is stored in a linear premultiplied format multiplied by the alpha component.
/// Each component is stored in premultiplied format multiplied by the alpha component.
/// </summary>
/// <remarks>
/// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,

2
src/ImageProcessor/Colors/ColorDefinitions.cs

@ -7,7 +7,7 @@ namespace ImageProcessor
{
/// <summary>
/// Represents a four-component color using red, green, blue, and alpha data.
/// Each component is stored in a linear premultiplied format multiplied by the alpha component.
/// Each component is stored in premultiplied format multiplied by the alpha component.
/// </summary>
/// <remarks>
/// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,

2
src/ImageProcessor/Colors/ColorTransforms.cs

@ -9,7 +9,7 @@ namespace ImageProcessor
/// <summary>
/// Represents a four-component color using red, green, blue, and alpha data.
/// Each component is stored in a linear premultiplied format multiplied by the alpha component.
/// Each component is stored in premultiplied format multiplied by the alpha component.
/// </summary>
/// <remarks>
/// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,

6
src/ImageProcessor/Colors/ColorspaceTransforms.cs

@ -9,7 +9,7 @@ namespace ImageProcessor
/// <summary>
/// Represents a four-component color using red, green, blue, and alpha data.
/// Each component is stored in a linear premultiplied format multiplied by the alpha component.
/// Each component is stored in premultiplied format multiplied by the alpha component.
/// </summary>
/// <remarks>
/// This struct is fully mutable. This is done (against the guidelines) for the sake of performance,
@ -86,7 +86,7 @@ namespace ImageProcessor
float g = (x * -0.9689F) + (y * 1.8758F) + (z * 0.0415F);
float b = (x * 0.0557F) + (y * -0.2040F) + (z * 1.0570F);
return new Color(r, g, b);
return Color.Compress(new Color(r, g, b));
}
/// <summary>
@ -226,7 +226,7 @@ namespace ImageProcessor
float g = (x * -0.9689F) + (y * 1.8758F) + (z * 0.0415F);
float b = (x * 0.0557F) + (y * -0.2040F) + (z * 1.0570F);
return new Color(r, g, b);
return Color.Compress(new Color(r, g, b));
}
/// <summary>

2
src/ImageProcessor/Colors/Colorspaces/CieLab.cs

@ -79,6 +79,8 @@ namespace ImageProcessor
public static implicit operator CieLab(Color color)
{
// First convert to CIE XYZ
color = Color.Expand(color);
float x = (color.R * 0.4124F) + (color.G * 0.3576F) + (color.B * 0.1805F);
float y = (color.R * 0.2126F) + (color.G * 0.7152F) + (color.B * 0.0722F);
float z = (color.R * 0.0193F) + (color.G * 0.1192F) + (color.B * 0.9505F);

2
src/ImageProcessor/Colors/Colorspaces/CieXyz.cs

@ -79,6 +79,8 @@ namespace ImageProcessor
/// </returns>
public static implicit operator CieXyz(Color color)
{
color = Color.Expand(color);
float x = (color.R * 0.4124F) + (color.G * 0.3576F) + (color.B * 0.1805F);
float y = (color.R * 0.2126F) + (color.G * 0.7152F) + (color.B * 0.0722F);
float z = (color.R * 0.0193F) + (color.G * 0.1192F) + (color.B * 0.9505F);

4
src/ImageProcessor/Filters/Brightness.cs

@ -50,12 +50,12 @@ namespace ImageProcessor.Filters
{
for (int x = startX; x < endX; x++)
{
Color color = source[x, y];
Color color = Color.Expand(source[x, y]);
Vector3 vector3 = color.ToVector3();
vector3 += new Vector3(brightness);
target[x, y] = new Color(vector3, color.A);
target[x, y] = Color.Compress(new Color(vector3, color.A));
}
}
});

6
src/ImageProcessor/Filters/ColorMatrix/ColorMatrixFilter.cs

@ -17,7 +17,7 @@ namespace ImageProcessor.Filters
public abstract Matrix4x4 Matrix { get; }
/// <inheritdoc/>
public virtual bool Compand => false;
public virtual bool Compand => true;
/// <inheritdoc/>
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
@ -57,11 +57,11 @@ namespace ImageProcessor.Filters
if (compand)
{
color = Color.Compress(color);
color = Color.Expand(color);
}
Vector3 transformed = Vector3.Transform(color.ToVector3(), matrix);
return compand ? Color.Expand(new Color(transformed, color.A)) : new Color(transformed, color.A);
return compand ? Color.Compress(new Color(transformed, color.A)) : new Color(transformed, color.A);
}
}
}

2
src/ImageProcessor/Filters/ColorMatrix/Hue.cs

@ -37,7 +37,7 @@
public override Matrix4x4 Matrix => this.matrix;
/// <inheritdoc/>
public override bool Compand => true;
public override bool Compand => false;
/// <inheritdoc/>
protected override void OnApply(ImageBase source, ImageBase target, Rectangle targetRectangle, Rectangle sourceRectangle)

2
src/ImageProcessor/Filters/ColorMatrix/Sepia.cs

@ -28,6 +28,6 @@ namespace ImageProcessor.Filters
};
/// <inheritdoc/>
public override bool Compand => true;
public override bool Compand => false;
}
}

4
src/ImageProcessor/Filters/Contrast.cs

@ -51,11 +51,11 @@ namespace ImageProcessor.Filters
{
for (int x = startX; x < endX; x++)
{
Vector4 color = source[x, y].ToVector4();
Vector4 color = Color.Expand(source[x, y]).ToVector4();
color -= shiftVector;
color *= contrastVector;
color += shiftVector;
target[x, y] = new Color(color);
target[x, y] = Color.Compress(new Color(color));
}
}
});

50
src/ImageProcessor/Formats/Bmp/BmpDecoderCore.cs

@ -7,7 +7,6 @@ namespace ImageProcessor.Formats
{
using System;
using System.IO;
using System.Numerics;
using System.Threading.Tasks;
/// <summary>
@ -224,17 +223,11 @@ namespace ImageProcessor.Formats
int arrayOffset = ((row * width) + (colOffset + shift)) * 4;
// We divide by 255 as we will store the colors in our floating point format.
// Default colorspace is sRGB TODO: Check if we can detect this.
// Stored in r-> g-> b-> a order.
// Expand from sRGB to linear RGB
Color color =
Color.Expand(
new Color(new Vector3(colors[colorIndex + 2], colors[colorIndex + 1], colors[colorIndex]) / 255f));
imageData[arrayOffset] = color.R; // r
imageData[arrayOffset + 1] = color.G; // g
imageData[arrayOffset + 2] = color.B; // b
imageData[arrayOffset + 3] = color.A; // a
imageData[arrayOffset] = colors[colorIndex + 2] / 255f; // r
imageData[arrayOffset + 1] = colors[colorIndex + 1] / 255f; // g
imageData[arrayOffset + 2] = colors[colorIndex] / 255f; // b
imageData[arrayOffset + 3] = 1; // a
}
}
});
@ -277,14 +270,11 @@ namespace ImageProcessor.Formats
int arrayOffset = ((row * width) + x) * 4;
// Expand from sRGB to linear RGB
Color color = Color.Expand(new Color(r, g, b, 1));
// Stored in r-> g-> b-> a order.
imageData[arrayOffset] = color.R;
imageData[arrayOffset + 1] = color.G;
imageData[arrayOffset + 2] = color.B;
imageData[arrayOffset + 3] = color.A;
imageData[arrayOffset] = r;
imageData[arrayOffset + 1] = g;
imageData[arrayOffset + 2] = b;
imageData[arrayOffset + 3] = 1;
}
});
}
@ -315,15 +305,12 @@ namespace ImageProcessor.Formats
int offset = rowOffset + (x * 3);
int arrayOffset = ((row * width) + x) * 4;
// Expand from sRGB to linear RGB
Color color = Color.Expand(new Color(new Vector3(data[offset + 2], data[offset + 1], data[offset]) / 255f, 1));
// We divide by 255 as we will store the colors in our floating point format.
// Stored in r-> g-> b-> a order.
imageData[arrayOffset] = color.R;
imageData[arrayOffset + 1] = color.G;
imageData[arrayOffset + 2] = color.B;
imageData[arrayOffset + 3] = color.A;
imageData[arrayOffset] = data[offset + 2] / 255f;
imageData[arrayOffset + 1] = data[offset + 1] / 255f;
imageData[arrayOffset + 2] = data[offset] / 255f;
imageData[arrayOffset + 3] = 1;
}
});
}
@ -356,15 +343,10 @@ namespace ImageProcessor.Formats
// We divide by 255 as we will store the colors in our floating point format.
// Stored in r-> g-> b-> a order.
// Expand from sRGB to linear RGB
// TODO: Can we use our real alpha here?
Color color = Color.Expand(new Color(new Vector3(data[offset + 2], data[offset + 1], data[offset]) / 255f, 1));
imageData[arrayOffset] = color.R;
imageData[arrayOffset + 1] = color.G;
imageData[arrayOffset + 2] = color.B;
imageData[arrayOffset + 3] = color.A;
imageData[arrayOffset] = data[offset + 2] / 255f;
imageData[arrayOffset + 1] = data[offset + 1] / 255f;
imageData[arrayOffset + 2] = data[offset] / 255f;
imageData[arrayOffset + 3] = 1; // TODO: Can we use our real alpha here?
}
});
}

4
src/ImageProcessor/Formats/Bmp/BmpEncoder.cs

@ -110,13 +110,13 @@ namespace ImageProcessor.Formats
// Limit the output range and multiply out from our floating point.
// Convert back to b-> g-> r-> a order.
// Convert to non-premultiplied sRGB color.
// Convert to non-premultiplied color.
float r = data[offset];
float g = data[offset + 1];
float b = data[offset + 2];
float a = data[offset + 3];
Bgra32 color = Color.ToNonPremultiplied(Color.Compress(new Color(r, g, b, a)));
Bgra32 color = Color.ToNonPremultiplied(new Color(r, g, b, a));
writer.Write(color.B);
writer.Write(color.G);

25
src/ImageProcessor/Formats/Jpg/JpegDecoder.cs

@ -7,7 +7,6 @@ namespace ImageProcessor.Formats
{
using System;
using System.IO;
using System.Numerics;
using System.Threading.Tasks;
using BitMiracle.LibJpeg;
@ -118,14 +117,10 @@ namespace ImageProcessor.Formats
int offset = ((y * pixelWidth) + x) * 4;
// Expand from sRGB to linear RGB
Color color =
Color.Expand(new Color(new Vector3(sample[0], sample[1], sample[2]) / 255f));
pixels[offset + 0] = color.R;
pixels[offset + 1] = color.G;
pixels[offset + 2] = color.B;
pixels[offset + 3] = color.A;
pixels[offset + 0] = sample[0] / 255f;
pixels[offset + 1] = sample[1] / 255f;
pixels[offset + 2] = sample[2] / 255f;
pixels[offset + 3] = 1;
}
});
}
@ -144,14 +139,10 @@ namespace ImageProcessor.Formats
int offset = ((y * pixelWidth) + x) * 4;
// Expand from sRGB to linear RGB
Color color =
Color.Expand(new Color(new Vector3(sample[0], sample[0], sample[0]) / 255f));
pixels[offset + 0] = color.R;
pixels[offset + 1] = color.G;
pixels[offset + 2] = color.B;
pixels[offset + 3] = color.A;
pixels[offset + 0] = sample[0] / 255f;
pixels[offset + 1] = sample[0] / 255f;
pixels[offset + 2] = sample[0] / 255f;
pixels[offset + 3] = 1;
}
});
}

3
src/ImageProcessor/Formats/Jpg/JpegEncoder.cs

@ -111,8 +111,7 @@ namespace ImageProcessor.Formats
float b = sourcePixels[source + 2];
float a = sourcePixels[source + 3];
// Compress back to sRGB
Bgra32 color = Color.ToNonPremultiplied(Color.Compress(new Color(r, g, b, a)));
Bgra32 color = Color.ToNonPremultiplied(new Color(r, g, b, a));
samples[start] = color.R;
samples[start + 1] = color.G;

6
src/ImageProcessor/Samplers/Resampler.cs

@ -193,11 +193,12 @@ namespace ImageProcessor.Samplers
foreach (Weight xw in horizontalValues)
{
int originX = xw.Index;
Color sourceColor = source[originX, originY];
Color sourceColor = Color.Expand(source[originX, originY]);
destination += sourceColor * yw.Value * xw.Value;
}
}
destination = Color.Compress(destination);
target[x, y] = destination;
}
}
@ -301,12 +302,13 @@ namespace ImageProcessor.Samplers
if (sourceRectangle.Contains(rotated.X, rotated.Y))
{
Color sourceColor = source[rotated.X, rotated.Y];
Color sourceColor = Color.Expand(source[rotated.X, rotated.Y]);
destination += sourceColor * yw.Value * xw.Value;
}
}
}
destination = Color.Compress(destination);
target[x, y] = destination;
}
}

Loading…
Cancel
Save