diff --git a/Settings.StyleCop b/Settings.StyleCop
index b7a5355e0..4403974d3 100644
--- a/Settings.StyleCop
+++ b/Settings.StyleCop
@@ -32,6 +32,7 @@
Vol
pp
cmyk
+ Paeth
diff --git a/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs b/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs
index bef124541..6fe2175d9 100644
--- a/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs
+++ b/src/ImageSharp/Formats/Png/Filters/AverageFilter.cs
@@ -12,7 +12,7 @@ namespace ImageSharp.Formats
/// the value of a pixel.
///
///
- internal static class AverageFilter
+ internal static unsafe class AverageFilter
{
///
/// Decodes the scanline
@@ -28,12 +28,17 @@ namespace ImageSharp.Formats
// Average(x) + floor((Raw(x-bpp)+Prior(x))/2)
byte[] result = new byte[scanline.Length];
- for (int x = 1; x < scanline.Length; x++)
+ fixed (byte* scan = scanline)
+ fixed (byte* prev = previousScanline)
+ fixed (byte* res = result)
{
- byte left = (x - bytesPerPixel < 1) ? (byte)0 : result[x - bytesPerPixel];
- byte above = previousScanline[x];
+ for (int x = 1; x < scanline.Length; x++)
+ {
+ byte left = (x - bytesPerPixel < 1) ? (byte)0 : res[x - bytesPerPixel];
+ byte above = prev[x];
- result[x] = (byte)((scanline[x] + Average(left, above)) % 256);
+ res[x] = (byte)((scan[x] + Average(left, above)) % 256);
+ }
}
return result;
@@ -50,19 +55,23 @@ namespace ImageSharp.Formats
public static byte[] Encode(byte[] scanline, byte[] previousScanline, int bytesPerPixel, int bytesPerScanline)
{
// Average(x) = Raw(x) - floor((Raw(x-bpp)+Prior(x))/2)
- byte[] encodedScanline = new byte[bytesPerScanline + 1];
-
- encodedScanline[0] = (byte)FilterType.Average;
-
- for (int x = 0; x < bytesPerScanline; x++)
+ byte[] result = new byte[bytesPerScanline + 1];
+ fixed (byte* scan = scanline)
+ fixed (byte* prev = previousScanline)
+ fixed (byte* res = result)
{
- byte left = (x - bytesPerPixel < 0) ? (byte)0 : scanline[x - bytesPerPixel];
- byte above = previousScanline[x];
+ res[0] = 3;
- encodedScanline[x + 1] = (byte)((scanline[x] - Average(left, above)) % 256);
+ for (int x = 0; x < bytesPerScanline; x++)
+ {
+ byte left = (x - bytesPerPixel < 0) ? (byte)0 : scan[x - bytesPerPixel];
+ byte above = prev[x];
+
+ res[x + 1] = (byte)((scan[x] - Average(left, above)) % 256);
+ }
}
- return encodedScanline;
+ return result;
}
///
@@ -73,7 +82,7 @@ namespace ImageSharp.Formats
/// The
private static int Average(byte left, byte above)
{
- return Convert.ToInt32(Math.Floor((left + above) / 2.0D));
+ return (left + above) >> 1;
}
}
-}
+}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Png/Filters/NoneFilter.cs b/src/ImageSharp/Formats/Png/Filters/NoneFilter.cs
index 175e5affa..068e57ad0 100644
--- a/src/ImageSharp/Formats/Png/Filters/NoneFilter.cs
+++ b/src/ImageSharp/Formats/Png/Filters/NoneFilter.cs
@@ -34,11 +34,11 @@ namespace ImageSharp.Formats
public static byte[] Encode(byte[] scanline, int bytesPerScanline)
{
// Insert a byte before the data.
- byte[] encodedScanline = new byte[bytesPerScanline + 1];
- encodedScanline[0] = (byte)FilterType.None;
- Buffer.BlockCopy(scanline, 0, encodedScanline, 1, bytesPerScanline);
+ byte[] result = new byte[bytesPerScanline + 1];
+ result[0] = 0;
+ Buffer.BlockCopy(scanline, 0, result, 1, bytesPerScanline);
- return encodedScanline;
+ return result;
}
}
}
diff --git a/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs b/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs
index 232d7cc3d..55f7a36b0 100644
--- a/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs
+++ b/src/ImageSharp/Formats/Png/Filters/PaethFilter.cs
@@ -13,7 +13,7 @@ namespace ImageSharp.Formats
/// This technique is due to Alan W. Paeth.
///
///
- internal static class PaethFilter
+ internal static unsafe class PaethFilter
{
///
/// Decodes the scanline
@@ -27,13 +27,18 @@ namespace ImageSharp.Formats
// Paeth(x) + PaethPredictor(Raw(x-bpp), Prior(x), Prior(x-bpp))
byte[] result = new byte[scanline.Length];
- for (int x = 1; x < scanline.Length; x++)
+ fixed (byte* scan = scanline)
+ fixed (byte* prev = previousScanline)
+ fixed (byte* res = result)
{
- byte left = (x - bytesPerPixel < 1) ? (byte)0 : result[x - bytesPerPixel];
- byte above = previousScanline[x];
- byte upperLeft = (x - bytesPerPixel < 1) ? (byte)0 : previousScanline[x - bytesPerPixel];
+ for (int x = 1; x < scanline.Length; x++)
+ {
+ byte left = (x - bytesPerPixel < 1) ? (byte)0 : res[x - bytesPerPixel];
+ byte above = prev[x];
+ byte upperLeft = (x - bytesPerPixel < 1) ? (byte)0 : prev[x - bytesPerPixel];
- result[x] = (byte)((scanline[x] + PaethPredicator(left, above, upperLeft)) % 256);
+ res[x] = (byte)((scan[x] + PaethPredicator(left, above, upperLeft)) % 256);
+ }
}
return result;
@@ -50,19 +55,25 @@ namespace ImageSharp.Formats
public static byte[] Encode(byte[] scanline, byte[] previousScanline, int bytesPerPixel, int bytesPerScanline)
{
// Paeth(x) = Raw(x) - PaethPredictor(Raw(x-bpp), Prior(x), Prior(x - bpp))
- byte[] encodedScanline = new byte[bytesPerScanline + 1];
- encodedScanline[0] = (byte)FilterType.Paeth;
+ byte[] result = new byte[bytesPerScanline + 1];
- for (int x = 0; x < bytesPerScanline; x++)
+ fixed (byte* scan = scanline)
+ fixed (byte* prev = previousScanline)
+ fixed (byte* res = result)
{
- byte left = (x - bytesPerPixel < 0) ? (byte)0 : scanline[x - bytesPerPixel];
- byte above = previousScanline[x];
- byte upperLeft = (x - bytesPerPixel < 0) ? (byte)0 : previousScanline[x - bytesPerPixel];
+ res[0] = 4;
- encodedScanline[x + 1] = (byte)((scanline[x] - PaethPredicator(left, above, upperLeft)) % 256);
+ for (int x = 0; x < bytesPerScanline; x++)
+ {
+ byte left = (x - bytesPerPixel < 0) ? (byte)0 : scan[x - bytesPerPixel];
+ byte above = prev[x];
+ byte upperLeft = (x - bytesPerPixel < 0) ? (byte)0 : prev[x - bytesPerPixel];
+
+ res[x + 1] = (byte)((scan[x] - PaethPredicator(left, above, upperLeft)) % 256);
+ }
}
- return encodedScanline;
+ return result;
}
///
diff --git a/src/ImageSharp/Formats/Png/Filters/SubFilter.cs b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs
index c4fbe3e51..79ebcf835 100644
--- a/src/ImageSharp/Formats/Png/Filters/SubFilter.cs
+++ b/src/ImageSharp/Formats/Png/Filters/SubFilter.cs
@@ -10,7 +10,7 @@ namespace ImageSharp.Formats
/// of the prior pixel.
///
///
- internal static class SubFilter
+ internal static unsafe class SubFilter
{
///
/// Decodes the scanline
@@ -23,11 +23,15 @@ namespace ImageSharp.Formats
// Sub(x) + Raw(x-bpp)
byte[] result = new byte[scanline.Length];
- for (int x = 1; x < scanline.Length; x++)
+ fixed (byte* scan = scanline)
+ fixed (byte* res = result)
{
- byte priorRawByte = (x - bytesPerPixel < 1) ? (byte)0 : result[x - bytesPerPixel];
+ for (int x = 1; x < scanline.Length; x++)
+ {
+ byte priorRawByte = (x - bytesPerPixel < 1) ? (byte)0 : res[x - bytesPerPixel];
- result[x] = (byte)((scanline[x] + priorRawByte) % 256);
+ res[x] = (byte)((scan[x] + priorRawByte) % 256);
+ }
}
return result;
@@ -43,17 +47,22 @@ namespace ImageSharp.Formats
public static byte[] Encode(byte[] scanline, int bytesPerPixel, int bytesPerScanline)
{
// Sub(x) = Raw(x) - Raw(x-bpp)
- byte[] encodedScanline = new byte[bytesPerScanline + 1];
- encodedScanline[0] = (byte)FilterType.Sub;
+ byte[] result = new byte[bytesPerScanline + 1];
- for (int x = 0; x < bytesPerScanline; x++)
+ fixed (byte* scan = scanline)
+ fixed (byte* res = result)
{
- byte priorRawByte = (x - bytesPerPixel < 0) ? (byte)0 : scanline[x - bytesPerPixel];
+ res[0] = 1;
- encodedScanline[x + 1] = (byte)((scanline[x] - priorRawByte) % 256);
+ for (int x = 0; x < bytesPerScanline; x++)
+ {
+ byte priorRawByte = (x - bytesPerPixel < 0) ? (byte)0 : scan[x - bytesPerPixel];
+
+ res[x + 1] = (byte)((scan[x] - priorRawByte) % 256);
+ }
}
- return encodedScanline;
+ return result;
}
}
}
diff --git a/src/ImageSharp/Formats/Png/Filters/UpFilter.cs b/src/ImageSharp/Formats/Png/Filters/UpFilter.cs
index 026070421..7f162fae1 100644
--- a/src/ImageSharp/Formats/Png/Filters/UpFilter.cs
+++ b/src/ImageSharp/Formats/Png/Filters/UpFilter.cs
@@ -10,7 +10,7 @@ namespace ImageSharp.Formats
/// rather than just to its left, is used as the predictor.
///
///
- internal static class UpFilter
+ internal static unsafe class UpFilter
{
///
/// Decodes the scanline
@@ -23,11 +23,16 @@ namespace ImageSharp.Formats
// Up(x) + Prior(x)
byte[] result = new byte[scanline.Length];
- for (int x = 1; x < scanline.Length; x++)
+ fixed (byte* scan = scanline)
+ fixed (byte* prev = previousScanline)
+ fixed (byte* res = result)
{
- byte above = previousScanline[x];
+ for (int x = 1; x < scanline.Length; x++)
+ {
+ byte above = prev[x];
- result[x] = (byte)((scanline[x] + above) % 256);
+ res[x] = (byte)((scan[x] + above) % 256);
+ }
}
return result;
@@ -43,17 +48,23 @@ namespace ImageSharp.Formats
public static byte[] Encode(byte[] scanline, int bytesPerScanline, byte[] previousScanline)
{
// Up(x) = Raw(x) - Prior(x)
- byte[] encodedScanline = new byte[bytesPerScanline + 1];
- encodedScanline[0] = (byte)FilterType.Up;
+ byte[] result = new byte[bytesPerScanline + 1];
- for (int x = 0; x < bytesPerScanline; x++)
+ fixed (byte* scan = scanline)
+ fixed (byte* prev = previousScanline)
+ fixed (byte* res = result)
{
- byte above = previousScanline[x];
+ res[0] = 2;
- encodedScanline[x + 1] = (byte)((scanline[x] - above) % 256);
+ for (int x = 0; x < bytesPerScanline; x++)
+ {
+ byte above = prev[x];
+
+ res[x + 1] = (byte)((scan[x] - above) % 256);
+ }
}
- return encodedScanline;
+ return result;
}
}
}