Browse Source

Use fixed on filter loops

pull/23/head
James Jackson-South 9 years ago
parent
commit
502fa2c6f4
  1. 1
      Settings.StyleCop
  2. 41
      src/ImageSharp/Formats/Png/Filters/AverageFilter.cs
  3. 8
      src/ImageSharp/Formats/Png/Filters/NoneFilter.cs
  4. 39
      src/ImageSharp/Formats/Png/Filters/PaethFilter.cs
  5. 29
      src/ImageSharp/Formats/Png/Filters/SubFilter.cs
  6. 31
      src/ImageSharp/Formats/Png/Filters/UpFilter.cs

1
Settings.StyleCop

@ -32,6 +32,7 @@
<Value>Vol</Value>
<Value>pp</Value>
<Value>cmyk</Value>
<Value>Paeth</Value>
</CollectionProperty>
</GlobalSettings>
<Analyzers>

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

@ -12,7 +12,7 @@ namespace ImageSharp.Formats
/// the value of a pixel.
/// <see href="https://www.w3.org/TR/PNG-Filters.html"/>
/// </summary>
internal static class AverageFilter
internal static unsafe class AverageFilter
{
/// <summary>
/// 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;
}
/// <summary>
@ -73,7 +82,7 @@ namespace ImageSharp.Formats
/// <returns>The <see cref="int"/></returns>
private static int Average(byte left, byte above)
{
return Convert.ToInt32(Math.Floor((left + above) / 2.0D));
return (left + above) >> 1;
}
}
}
}

8
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;
}
}
}

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

@ -13,7 +13,7 @@ namespace ImageSharp.Formats
/// This technique is due to Alan W. Paeth.
/// <see href="https://www.w3.org/TR/PNG-Filters.html"/>
/// </summary>
internal static class PaethFilter
internal static unsafe class PaethFilter
{
/// <summary>
/// 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;
}
/// <summary>

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

@ -10,7 +10,7 @@ namespace ImageSharp.Formats
/// of the prior pixel.
/// <see href="https://www.w3.org/TR/PNG-Filters.html"/>
/// </summary>
internal static class SubFilter
internal static unsafe class SubFilter
{
/// <summary>
/// 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;
}
}
}

31
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.
/// <see href="https://www.w3.org/TR/PNG-Filters.html"/>
/// </summary>
internal static class UpFilter
internal static unsafe class UpFilter
{
/// <summary>
/// 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;
}
}
}

Loading…
Cancel
Save