Browse Source

Processed review comments and did similar refactoring to the PNG decoding.

pull/548/head
woutware 8 years ago
parent
commit
12ec82b25f
  1. 53
      src/ImageSharp/Formats/Png/Filters/AverageFilter.cs
  2. 38
      src/ImageSharp/Formats/Png/Filters/PaethFilter.cs
  3. 47
      src/ImageSharp/Formats/Png/Filters/SubFilter.cs
  4. 15
      src/ImageSharp/Formats/Png/Filters/UpFilter.cs

53
src/ImageSharp/Formats/Png/Filters/AverageFilter.cs

@ -29,21 +29,19 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
ref byte prevBaseRef = ref MemoryMarshal.GetReference(previousScanline);
// Average(x) + floor((Raw(x-bpp)+Prior(x))/2)
for (int x = 1; x < scanline.Length; x++)
int x = 1;
for (; x <= bytesPerPixel /* Note the <= because x starts at 1 */; ++x) {
ref byte scan = ref Unsafe.Add(ref scanBaseRef, x);
byte above = Unsafe.Add(ref prevBaseRef, x);
scan = (byte)(scan + (above >> 1));
}
for (; x < scanline.Length; ++x)
{
if (x - bytesPerPixel < 1)
{
ref byte scan = ref Unsafe.Add(ref scanBaseRef, x);
byte above = Unsafe.Add(ref prevBaseRef, x);
scan = (byte)((scan + (above >> 1)) % 256);
}
else
{
ref byte scan = ref Unsafe.Add(ref scanBaseRef, x);
byte left = Unsafe.Add(ref scanBaseRef, x - bytesPerPixel);
byte above = Unsafe.Add(ref prevBaseRef, x);
scan = (byte)((scan + Average(left, above)) % 256);
}
ref byte scan = ref Unsafe.Add(ref scanBaseRef, x);
byte left = Unsafe.Add(ref scanBaseRef, x - bytesPerPixel);
byte above = Unsafe.Add(ref prevBaseRef, x);
scan = (byte)(scan + Average(left, above));
}
}
@ -69,30 +67,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
// Average(x) = Raw(x) - floor((Raw(x-bpp)+Prior(x))/2)
resultBaseRef = 3;
#if OLD_AND_SLOW
for (int x = 0; x < scanline.Length; x++)
{
if (x - bytesPerPixel < 0)
{
byte scan = Unsafe.Add(ref scanBaseRef, x);
byte above = Unsafe.Add(ref prevBaseRef, x);
ref byte res = ref Unsafe.Add(ref resultBaseRef, x + 1);
res = (byte)((scan - (above >> 1)) % 256);
sum += res < 128 ? res : 256 - res;
}
else
{
byte scan = Unsafe.Add(ref scanBaseRef, x);
byte left = Unsafe.Add(ref scanBaseRef, x - bytesPerPixel);
byte above = Unsafe.Add(ref prevBaseRef, x);
ref byte res = ref Unsafe.Add(ref resultBaseRef, x + 1);
res = (byte)((scan - Average(left, above)) % 256);
sum += res < 128 ? res : 256 - res;
}
}
#else
int x = 0;
for (; x < bytesPerPixel;) {
for (; x < bytesPerPixel; /* Note: ++x happens in the body to avoid one add operation */) {
byte scan = Unsafe.Add(ref scanBaseRef, x);
byte above = Unsafe.Add(ref prevBaseRef, x);
++x;
@ -101,7 +77,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
sum += ImageMaths.FastAbs(unchecked((sbyte)res));
}
for (int xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft) {
for (int xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft /* Note: ++x happens in the body to avoid one add operation */) {
byte scan = Unsafe.Add(ref scanBaseRef, x);
byte left = Unsafe.Add(ref scanBaseRef, xLeft);
byte above = Unsafe.Add(ref prevBaseRef, x);
@ -110,7 +86,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
res = (byte)(scan - Average(left, above));
sum += ImageMaths.FastAbs(unchecked((sbyte)res));
}
#endif
sum -= 3;
}

38
src/ImageSharp/Formats/Png/Filters/PaethFilter.cs

@ -30,15 +30,16 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
ref byte prevBaseRef = ref MemoryMarshal.GetReference(previousScanline);
// Paeth(x) + PaethPredictor(Raw(x-bpp), Prior(x), Prior(x-bpp))
int offset = bytesPerPixel + 1;
for (int x = 1; x < offset; x++)
int offset = bytesPerPixel + 1; // Add one bcause x starts at one.
int x = 1;
for (; x < offset; x++)
{
ref byte scan = ref Unsafe.Add(ref scanBaseRef, x);
byte above = Unsafe.Add(ref prevBaseRef, x);
scan = (byte)(scan + above);
}
for (int x = offset; x < scanline.Length; x++)
for (; x < scanline.Length; x++)
{
ref byte scan = ref Unsafe.Add(ref scanBaseRef, x);
byte left = Unsafe.Add(ref scanBaseRef, x - bytesPerPixel);
@ -70,39 +71,17 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
// Paeth(x) = Raw(x) - PaethPredictor(Raw(x-bpp), Prior(x), Prior(x - bpp))
resultBaseRef = 4;
#if OLD_AND_SLOW
for (int x = 0; x < scanline.Length; x++)
{
if (x - bytesPerPixel < 0)
{
byte scan = Unsafe.Add(ref scanBaseRef, x);
byte above = Unsafe.Add(ref prevBaseRef, x);
ref byte res = ref Unsafe.Add(ref resultBaseRef, x + 1);
res = (byte)((scan - PaethPredicator(0, above, 0)) % 256);
sum += res < 128 ? res : 256 - res;
}
else
{
byte scan = Unsafe.Add(ref scanBaseRef, x);
byte left = Unsafe.Add(ref scanBaseRef, x - bytesPerPixel);
byte above = Unsafe.Add(ref prevBaseRef, x);
byte upperLeft = Unsafe.Add(ref prevBaseRef, x - bytesPerPixel);
ref byte res = ref Unsafe.Add(ref resultBaseRef, x + 1);
res = (byte)((scan - PaethPredicator(left, above, upperLeft)) % 256);
sum += res < 128 ? res : 256 - res;
}
}
#else
int x = 0;
for (; x < bytesPerPixel; ++x) {
for (; x < bytesPerPixel; /* Note: ++x happens in the body to avoid one add operation */) {
byte scan = Unsafe.Add(ref scanBaseRef, x);
byte above = Unsafe.Add(ref prevBaseRef, x);
ref byte res = ref Unsafe.Add(ref resultBaseRef, x + 1);
++x;
ref byte res = ref Unsafe.Add(ref resultBaseRef, x);
res = (byte)(scan - PaethPredictor(0, above, 0));
sum += ImageMaths.FastAbs(unchecked((sbyte)res));
}
for (int xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft) {
for (int xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft /* Note: ++x happens in the body to avoid one add operation */) {
byte scan = Unsafe.Add(ref scanBaseRef, x);
byte left = Unsafe.Add(ref scanBaseRef, xLeft);
byte above = Unsafe.Add(ref prevBaseRef, x);
@ -112,7 +91,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
res = (byte)(scan - PaethPredictor(left, above, upperLeft));
sum += ImageMaths.FastAbs(unchecked((sbyte)res));
}
#endif
sum -= 4;
}

47
src/ImageSharp/Formats/Png/Filters/SubFilter.cs

@ -25,19 +25,17 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
ref byte scanBaseRef = ref MemoryMarshal.GetReference(scanline);
// Sub(x) + Raw(x-bpp)
for (int x = 1; x < scanline.Length; x++)
int x = 1;
for (; x <= bytesPerPixel /* Note the <= because x starts at 1 */; ++x)
{
if (x - bytesPerPixel < 1)
{
ref byte scan = ref Unsafe.Add(ref scanBaseRef, x);
scan = (byte)(scan % 256);
}
else
{
ref byte scan = ref Unsafe.Add(ref scanBaseRef, x);
byte prev = Unsafe.Add(ref scanBaseRef, x - bytesPerPixel);
scan = (byte)((scan + prev) % 256);
}
ref byte scan = ref Unsafe.Add(ref scanBaseRef, x);
}
for (; x < scanline.Length; ++x)
{
ref byte scan = ref Unsafe.Add(ref scanBaseRef, x);
byte prev = Unsafe.Add(ref scanBaseRef, x - bytesPerPixel);
scan = (byte)(scan + prev);
}
}
@ -60,28 +58,8 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
// Sub(x) = Raw(x) - Raw(x-bpp)
resultBaseRef = 1;
#if OLD_AND_SLOW
for (int x = 0; x < scanline.Length; x++)
{
if (x - bytesPerPixel < 0)
{
byte scan = Unsafe.Add(ref scanBaseRef, x);
ref byte res = ref Unsafe.Add(ref resultBaseRef, x + 1);
res = (byte)(scan % 256);
sum += res < 128 ? res : 256 - res;
}
else
{
byte scan = Unsafe.Add(ref scanBaseRef, x);
byte prev = Unsafe.Add(ref scanBaseRef, x - bytesPerPixel);
ref byte res = ref Unsafe.Add(ref resultBaseRef, x + 1);
res = (byte)((scan - prev) % 256);
sum += res < 128 ? res : 256 - res;
}
}
#else
int x = 0;
for (; x < bytesPerPixel;) {
for (; x < bytesPerPixel; /* Note: ++x happens in the body to avoid one add operation */) {
byte scan = Unsafe.Add(ref scanBaseRef, x);
++x;
ref byte res = ref Unsafe.Add(ref resultBaseRef, x);
@ -89,7 +67,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
sum += ImageMaths.FastAbs(unchecked((sbyte)res));
}
for (int xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft) {
for (int xLeft = x - bytesPerPixel; x < scanline.Length; ++xLeft /* Note: ++x happens in the body to avoid one add operation */) {
byte scan = Unsafe.Add(ref scanBaseRef, x);
byte prev = Unsafe.Add(ref scanBaseRef, xLeft);
++x;
@ -97,7 +75,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
res = (byte)(scan - prev);
sum += ImageMaths.FastAbs(unchecked((sbyte)res));
}
#endif
sum -= 1;
}

15
src/ImageSharp/Formats/Png/Filters/UpFilter.cs

@ -32,7 +32,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
{
ref byte scan = ref Unsafe.Add(ref scanBaseRef, x);
byte above = Unsafe.Add(ref prevBaseRef, x);
scan = (byte)((scan + above) % 256);
scan = (byte)(scan + above);
}
}
@ -57,17 +57,7 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
// Up(x) = Raw(x) - Prior(x)
resultBaseRef = 2;
#if OLD_AND_SLOW
for (int x = 0; x < scanline.Length; x++)
{
byte scan = Unsafe.Add(ref scanBaseRef, x);
byte above = Unsafe.Add(ref prevBaseRef, x);
ref byte res = ref Unsafe.Add(ref resultBaseRef, x + 1);
res = (byte)((scan - above) % 256);
sum += res < 128 ? res : 256 - res;
}
#else
for (int x = 0; x < scanline.Length;) {
for (int x = 0; x < scanline.Length; /* Note: ++x happens in the body to avoid one add operation */) {
byte scan = Unsafe.Add(ref scanBaseRef, x);
byte above = Unsafe.Add(ref prevBaseRef, x);
++x;
@ -75,7 +65,6 @@ namespace SixLabors.ImageSharp.Formats.Png.Filters
res = (byte)(scan - above);
sum += ImageMaths.FastAbs(unchecked((sbyte)res));
}
#endif
sum -= 2;
}

Loading…
Cancel
Save