From 38a13de46623ef8ccb35524e5aa41ba49cbf0bc2 Mon Sep 17 00:00:00 2001 From: Jason Nelson Date: Sat, 29 Sep 2018 15:51:40 -0700 Subject: [PATCH] Breakout Adam7 constants and methods --- src/ImageSharp/Formats/Png/Adam7.cs | 56 ++++++++++++++++++++ src/ImageSharp/Formats/Png/PngDecoderCore.cs | 52 ++---------------- 2 files changed, 61 insertions(+), 47 deletions(-) create mode 100644 src/ImageSharp/Formats/Png/Adam7.cs diff --git a/src/ImageSharp/Formats/Png/Adam7.cs b/src/ImageSharp/Formats/Png/Adam7.cs new file mode 100644 index 000000000..4e6485b55 --- /dev/null +++ b/src/ImageSharp/Formats/Png/Adam7.cs @@ -0,0 +1,56 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +using System; +using System.Runtime.CompilerServices; + +namespace SixLabors.ImageSharp.Formats.Png +{ + /// + /// Constants and helper methods for the Adam7 interlacing algorithm. + /// + internal static class Adam7 + { + /// + /// The amount to increment when processing each column per scanline for each interlaced pass. + /// + public static readonly int[] ColumnIncrement = { 8, 8, 4, 4, 2, 2, 1 }; + + /// + /// The index to start at when processing each column per scanline for each interlaced pass. + /// + public static readonly int[] FirstColumn = { 0, 4, 0, 2, 0, 1, 0 }; + + /// + /// The index to start at when processing each row per scanline for each interlaced pass. + /// + public static readonly int[] FirstRow = { 0, 0, 4, 0, 2, 0, 1 }; + + /// + /// The amount to increment when processing each row per scanline for each interlaced pass. + /// + public static readonly int[] RowIncrement = { 8, 8, 8, 4, 4, 2, 2 }; + + /// + /// Returns the correct number of columns for each interlaced pass. + /// + /// The line width. + /// The current pass index. + /// The + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int ComputeColumns(int width, int passIndex) + { + switch (passIndex) + { + case 0: return (width + 7) / 8; + case 1: return (width + 3) / 8; + case 2: return (width + 3) / 4; + case 3: return (width + 1) / 4; + case 4: return (width + 1) / 2; + case 5: return width / 2; + case 6: return width; + default: throw new ArgumentException($"Not a valid pass index: {passIndex}"); + } + } + } +} \ No newline at end of file diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs index 28898bfbd..a728bb296 100644 --- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs +++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs @@ -37,26 +37,6 @@ namespace SixLabors.ImageSharp.Formats.Png [PngColorType.RgbWithAlpha] = new byte[] { 8, 16 } }; - /// - /// The amount to increment when processing each column per scanline for each interlaced pass - /// - private static readonly int[] Adam7ColumnIncrement = { 8, 8, 4, 4, 2, 2, 1 }; - - /// - /// The index to start at when processing each column per scanline for each interlaced pass - /// - private static readonly int[] Adam7FirstColumn = { 0, 4, 0, 2, 0, 1, 0 }; - - /// - /// The index to start at when processing each row per scanline for each interlaced pass - /// - private static readonly int[] Adam7FirstRow = { 0, 0, 4, 0, 2, 0, 1 }; - - /// - /// The amount to increment when processing each row per scanline for each interlaced pass - /// - private static readonly int[] Adam7RowIncrement = { 8, 8, 8, 4, 4, 2, 2 }; - /// /// Reusable buffer for reading chunk types. /// @@ -150,7 +130,7 @@ namespace SixLabors.ImageSharp.Formats.Png /// /// The index of the current scanline being processed /// - private int currentRow = Adam7FirstRow[0]; + private int currentRow = Adam7.FirstRow[0]; /// /// The current pass for an interlaced PNG @@ -635,7 +615,7 @@ namespace SixLabors.ImageSharp.Formats.Png { while (true) { - int numColumns = this.ComputeColumnsAdam7(this.pass); + int numColumns = Adam7.ComputeColumns(this.header.Width, this.pass); if (numColumns == 0) { @@ -691,11 +671,11 @@ namespace SixLabors.ImageSharp.Formats.Png } Span rowSpan = image.GetPixelRowSpan(this.currentRow); - this.ProcessInterlacedDefilteredScanline(this.scanline.GetSpan(), rowSpan, Adam7FirstColumn[this.pass], Adam7ColumnIncrement[this.pass]); + this.ProcessInterlacedDefilteredScanline(this.scanline.GetSpan(), rowSpan, Adam7.FirstColumn[this.pass], Adam7.ColumnIncrement[this.pass]); this.SwapBuffers(); - this.currentRow += Adam7RowIncrement[this.pass]; + this.currentRow += Adam7.RowIncrement[this.pass]; } this.pass++; @@ -703,7 +683,7 @@ namespace SixLabors.ImageSharp.Formats.Png if (this.pass < 7) { - this.currentRow = Adam7FirstRow[this.pass]; + this.currentRow = Adam7.FirstRow[this.pass]; } else { @@ -1198,28 +1178,6 @@ namespace SixLabors.ImageSharp.Formats.Png return false; } - /// - /// Returns the correct number of columns for each interlaced pass. - /// - /// Th current pass index - /// The - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private int ComputeColumnsAdam7(int passIndex) - { - int width = this.header.Width; - switch (passIndex) - { - case 0: return (width + 7) / 8; - case 1: return (width + 3) / 8; - case 2: return (width + 3) / 4; - case 3: return (width + 1) / 4; - case 4: return (width + 1) / 2; - case 5: return width / 2; - case 6: return width; - default: throw new ArgumentException($"Not a valid pass index: {passIndex}"); - } - } - private void SwapBuffers() { IManagedByteBuffer temp = this.previousScanline;