Browse Source

Improve ApplyCgbiTransform

pull/3136/head
Erik White 5 days ago
parent
commit
4f85600cb8
  1. 31
      src/ImageSharp/Formats/Png/PngDecoderCore.cs

31
src/ImageSharp/Formats/Png/PngDecoderCore.cs

@ -2509,33 +2509,34 @@ internal sealed class PngDecoderCore : ImageDecoderCore
{
if (colorType == PngColorType.RgbWithAlpha)
{
for (int i = 0; i + 3 < scanline.Length; i += 4)
Span<Rgba32> pixels = MemoryMarshal.Cast<byte, Rgba32>(scanline);
for (int i = 0; i < pixels.Length; i++)
{
byte b = scanline[i];
byte g = scanline[i + 1];
byte r = scanline[i + 2];
byte a = scanline[i + 3];
ref Rgba32 p = ref pixels[i];
byte r = p.B;
byte g = p.G;
byte b = p.R;
byte a = p.A;
if (a is not 0 and not 255)
if (a is not 0 and not byte.MaxValue)
{
// Reverse: c' = c * a / 255 => c = round(c' * 255 / a)
int half = a >> 1;
r = (byte)Math.Min(255, ((r * 255) + half) / a);
g = (byte)Math.Min(255, ((g * 255) + half) / a);
b = (byte)Math.Min(255, ((b * 255) + half) / a);
r = (byte)Math.Min(byte.MaxValue, ((r * byte.MaxValue) + half) / a);
g = (byte)Math.Min(byte.MaxValue, ((g * byte.MaxValue) + half) / a);
b = (byte)Math.Min(byte.MaxValue, ((b * byte.MaxValue) + half) / a);
}
scanline[i] = r;
scanline[i + 1] = g;
scanline[i + 2] = b;
scanline[i + 3] = a;
p = new Rgba32(r, g, b, a);
}
}
else if (colorType == PngColorType.Rgb)
{
for (int i = 0; i + 2 < scanline.Length; i += 3)
Span<Rgb24> pixels = MemoryMarshal.Cast<byte, Rgb24>(scanline);
for (int i = 0; i < pixels.Length; i++)
{
(scanline[i], scanline[i + 2]) = (scanline[i + 2], scanline[i]);
ref Rgb24 p = ref pixels[i];
(p.R, p.B) = (p.B, p.R);
}
}
}

Loading…
Cancel
Save