From 436a105af70148e819b4d27fcc0768560a1a2cca Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Mon, 24 Oct 2016 20:11:12 +1100 Subject: [PATCH] Png stylecop Former-commit-id: 7d13b3c396b75143108bb9e5df6b03bbc0085095 Former-commit-id: 40f802aea39d038f8908e50c364fe161b4978b44 Former-commit-id: af2b3ed36a98b84eea71484582b718dea2f240cb --- Settings.StyleCop | 3 + .../Formats/Png/PngDecoderCore.cs | 73 +++++------ .../Formats/Png/PngEncoderCore.cs | 119 +++++++++--------- 3 files changed, 97 insertions(+), 98 deletions(-) diff --git a/Settings.StyleCop b/Settings.StyleCop index 90469053cf..28a91bcbec 100644 --- a/Settings.StyleCop +++ b/Settings.StyleCop @@ -16,6 +16,9 @@ Scharr rrggbb rrggbbaa + scanline + scanlines + png's diff --git a/src/ImageProcessorCore/Formats/Png/PngDecoderCore.cs b/src/ImageProcessorCore/Formats/Png/PngDecoderCore.cs index c449b72d99..d68bec5118 100644 --- a/src/ImageProcessorCore/Formats/Png/PngDecoderCore.cs +++ b/src/ImageProcessorCore/Formats/Png/PngDecoderCore.cs @@ -2,15 +2,13 @@ // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // - -using System.Numerics; - namespace ImageProcessorCore.Formats { using System; using System.Collections.Generic; using System.IO; using System.Linq; + using System.Numerics; using System.Text; /// @@ -18,9 +16,9 @@ namespace ImageProcessorCore.Formats /// internal class PngDecoderCore { - ///// - ///// The dictionary of available color types. - ///// + /// + /// The dictionary of available color types. + /// private static readonly Dictionary ColorTypes = new Dictionary(); /// @@ -49,20 +47,15 @@ namespace ImageProcessorCore.Formats private int bytesPerScanline; /// - /// The palette containing color information for indexed pngs + /// The palette containing color information for indexed png's /// private byte[] palette; /// - /// The palette containing alpha channel color information for indexed pngs + /// The palette containing alpha channel color information for indexed png's /// private byte[] paletteAlpha; - /// - /// Gets or sets the png color type - /// - public PngColorType PngColorType { get; set; } - /// /// Initializes static members of the class. /// @@ -79,6 +72,11 @@ namespace ImageProcessorCore.Formats ColorTypes.Add((int)PngColorType.RgbWithAlpha, new byte[] { 8 }); } + /// + /// Gets or sets the png color type + /// + public PngColorType PngColorType { get; set; } + /// /// Decodes the stream to the image. /// @@ -237,7 +235,7 @@ namespace ImageProcessorCore.Formats this.bytesPerSample = 1; if (this.header.BitDepth >= 8) { - this.bytesPerSample = (this.header.BitDepth) / 8; + this.bytesPerSample = this.header.BitDepth / 8; } dataStream.Position = 0; @@ -249,7 +247,7 @@ namespace ImageProcessorCore.Formats decompressedStream.Flush(); byte[] decompressedBytes = decompressedStream.ToArray(); - DecodePixelData(decompressedBytes, pixels); + this.DecodePixelData(decompressedBytes, pixels); } } } @@ -284,7 +282,7 @@ namespace ImageProcessorCore.Formats case FilterType.Sub: - defilteredScanline = SubFilter.Decode(scanline, bytesPerPixel); + defilteredScanline = SubFilter.Decode(scanline, this.bytesPerPixel); break; @@ -296,13 +294,13 @@ namespace ImageProcessorCore.Formats case FilterType.Average: - defilteredScanline = AverageFilter.Decode(scanline, previousScanline, bytesPerPixel); + defilteredScanline = AverageFilter.Decode(scanline, previousScanline, this.bytesPerPixel); break; case FilterType.Paeth: - defilteredScanline = PaethFilter.Decode(scanline, previousScanline, bytesPerPixel); + defilteredScanline = PaethFilter.Decode(scanline, previousScanline, this.bytesPerPixel); break; @@ -311,16 +309,16 @@ namespace ImageProcessorCore.Formats } previousScanline = defilteredScanline; - ProcessDefilteredScanline(defilteredScanline, y, pixels); + this.ProcessDefilteredScanline(defilteredScanline, y, pixels); } } /// - /// Processes the defiltered scanline filling the image pixel data + /// Processes the de-filtered scanline filling the image pixel data /// /// The pixel format. /// The packed format. uint, long, float. - /// + /// The de-filtered scanline /// The current image row. /// The image pixels private void ProcessDefilteredScanline(byte[] defilteredScanline, int row, TColor[] pixels) @@ -333,7 +331,7 @@ namespace ImageProcessorCore.Formats for (int x = 0; x < this.header.Width; x++) { - int offset = 1 + (x * bytesPerPixel); + int offset = 1 + (x * this.bytesPerPixel); byte intensity = defilteredScanline[offset]; @@ -348,10 +346,10 @@ namespace ImageProcessorCore.Formats for (int x = 0; x < this.header.Width; x++) { - int offset = 1 + (x * bytesPerPixel); + int offset = 1 + (x * this.bytesPerPixel); byte intensity = defilteredScanline[offset]; - byte alpha = defilteredScanline[offset + bytesPerSample]; + byte alpha = defilteredScanline[offset + this.bytesPerSample]; TColor color = default(TColor); color.PackFromVector4(new Vector4(intensity, intensity, intensity, alpha) / 255F); @@ -362,16 +360,16 @@ namespace ImageProcessorCore.Formats case PngColorType.Palette: - byte[] newScanline = defilteredScanline.ToArrayByBitsLength(header.BitDepth); + byte[] newScanline = defilteredScanline.ToArrayByBitsLength(this.header.BitDepth); if (this.paletteAlpha != null && this.paletteAlpha.Length > 0) { // If the alpha palette is not null and has one or more entries, this means, that the image contains an alpha // channel and we should try to read it. - for (int i = 0; i < header.Width; i++) + for (int i = 0; i < this.header.Width; i++) { int index = newScanline[i]; - int offset = (row * header.Width) + i; + int offset = (row * this.header.Width) + i; int pixelOffset = index * 3; byte a = this.paletteAlpha.Length > index ? this.paletteAlpha[index] : (byte)255; @@ -389,10 +387,10 @@ namespace ImageProcessorCore.Formats } else { - for (int i = 0; i < header.Width; i++) + for (int i = 0; i < this.header.Width; i++) { int index = newScanline[i]; - int offset = (row * header.Width) + i; + int offset = (row * this.header.Width) + i; int pixelOffset = index * 3; byte r = this.palette[pixelOffset]; @@ -411,11 +409,11 @@ namespace ImageProcessorCore.Formats for (int x = 0; x < this.header.Width; x++) { - int offset = 1 + (x * bytesPerPixel); + int offset = 1 + (x * this.bytesPerPixel); byte r = defilteredScanline[offset]; - byte g = defilteredScanline[offset + bytesPerSample]; - byte b = defilteredScanline[offset + 2 * bytesPerSample]; + byte g = defilteredScanline[offset + this.bytesPerSample]; + byte b = defilteredScanline[offset + (2 * this.bytesPerSample)]; TColor color = default(TColor); color.PackFromVector4(new Vector4(r, g, b, 255) / 255F); @@ -428,12 +426,12 @@ namespace ImageProcessorCore.Formats for (int x = 0; x < this.header.Width; x++) { - int offset = 1 + (x * bytesPerPixel); + int offset = 1 + (x * this.bytesPerPixel); byte r = defilteredScanline[offset]; - byte g = defilteredScanline[offset + bytesPerSample]; - byte b = defilteredScanline[offset + 2 * bytesPerSample]; - byte a = defilteredScanline[offset + 3 * bytesPerSample]; + byte g = defilteredScanline[offset + this.bytesPerSample]; + byte b = defilteredScanline[offset + (2 * this.bytesPerSample)]; + byte a = defilteredScanline[offset + (3 * this.bytesPerSample)]; TColor color = default(TColor); color.PackFromVector4(new Vector4(r, g, b, a) / 255F); @@ -441,9 +439,6 @@ namespace ImageProcessorCore.Formats } break; - - default: - break; } } diff --git a/src/ImageProcessorCore/Formats/Png/PngEncoderCore.cs b/src/ImageProcessorCore/Formats/Png/PngEncoderCore.cs index fc6ad3f672..9f21ba47a9 100644 --- a/src/ImageProcessorCore/Formats/Png/PngEncoderCore.cs +++ b/src/ImageProcessorCore/Formats/Png/PngEncoderCore.cs @@ -2,7 +2,6 @@ // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // - namespace ImageProcessorCore.Formats { using System; @@ -27,7 +26,7 @@ namespace ImageProcessorCore.Formats /// /// Contains the raw pixel data from the image. /// - byte[] pixelData; + private byte[] pixelData; /// /// The image width. @@ -60,7 +59,7 @@ namespace ImageProcessorCore.Formats public PngColorType PngColorType { get; set; } /// - /// The compression level 1-9. + /// Gets or sets the compression level 1-9. /// Defaults to 6. /// public int CompressionLevel { get; set; } = 6; @@ -80,7 +79,7 @@ namespace ImageProcessorCore.Formats public float Gamma { get; set; } = 2.2F; /// - /// The quantizer for reducing the color count. + /// Gets or sets the quantizer for reducing the color count. /// public IQuantizer Quantizer { get; set; } @@ -134,7 +133,7 @@ namespace ImageProcessorCore.Formats // Set correct bit depth. this.bitDepth = this.Quality <= 256 - ? (byte)(ImageMaths.GetBitsNeededForColorDepth(this.Quality).Clamp(1, 8)) + ? (byte)ImageMaths.GetBitsNeededForColorDepth(this.Quality).Clamp(1, 8) : (byte)8; // Png only supports in four pixel depths: 1, 2, 4, and 8 bits when using the PLTE chunk @@ -147,7 +146,7 @@ namespace ImageProcessorCore.Formats this.bitDepth = 8; } - this.bytesPerPixel = CalculateBytesPerPixel(); + this.bytesPerPixel = this.CalculateBytesPerPixel(); PngHeader header = new PngHeader { @@ -183,6 +182,48 @@ namespace ImageProcessorCore.Formats stream.Flush(); } + /// + /// Writes an integer to the byte array. + /// + /// The containing image data. + /// The amount to offset by. + /// The value to write. + private static void WriteInteger(byte[] data, int offset, int value) + { + byte[] buffer = BitConverter.GetBytes(value); + + Array.Reverse(buffer); + Array.Copy(buffer, 0, data, offset, 4); + } + + /// + /// Writes an integer to the stream. + /// + /// The containing image data. + /// The value to write. + private static void WriteInteger(Stream stream, int value) + { + byte[] buffer = BitConverter.GetBytes(value); + + Array.Reverse(buffer); + + stream.Write(buffer, 0, 4); + } + + /// + /// Writes an unsigned integer to the stream. + /// + /// The containing image data. + /// The value to write. + private static void WriteInteger(Stream stream, uint value) + { + byte[] buffer = BitConverter.GetBytes(value); + + Array.Reverse(buffer); + + stream.Write(buffer, 0, 4); + } + /// /// Collects the indexed pixel data. /// @@ -197,7 +238,7 @@ namespace ImageProcessorCore.Formats { // Quatize the image and get the pixels QuantizedImage quantized = this.WritePaletteChunk(stream, header, image); - pixelData = quantized.Pixels; + this.pixelData = quantized.Pixels; } /// @@ -291,12 +332,12 @@ namespace ImageProcessorCore.Formats { List filteredScanlines = new List(); - byte[] previousScanline = new byte[width * this.bytesPerPixel]; + byte[] previousScanline = new byte[this.width * this.bytesPerPixel]; - for (int y = 0; y < height; y++) + for (int y = 0; y < this.height; y++) { - byte[] rawScanline = GetRawScanline(y); - byte[] filteredScanline = GetOptimalFilteredScanline(rawScanline, previousScanline, this.bytesPerPixel); + byte[] rawScanline = this.GetRawScanline(y); + byte[] filteredScanline = this.GetOptimalFilteredScanline(rawScanline, previousScanline, this.bytesPerPixel); filteredScanlines.Add(filteredScanline); @@ -320,22 +361,22 @@ namespace ImageProcessorCore.Formats /// The raw scanline /// The previous scanline /// The number of bytes per pixel - /// + /// The private byte[] GetOptimalFilteredScanline(byte[] rawScanline, byte[] previousScanline, int byteCount) { List> candidates = new List>(); byte[] sub = SubFilter.Encode(rawScanline, byteCount); - candidates.Add(new Tuple(sub, CalculateTotalVariation(sub))); + candidates.Add(new Tuple(sub, this.CalculateTotalVariation(sub))); byte[] up = UpFilter.Encode(rawScanline, previousScanline); - candidates.Add(new Tuple(up, CalculateTotalVariation(up))); + candidates.Add(new Tuple(up, this.CalculateTotalVariation(up))); byte[] average = AverageFilter.Encode(rawScanline, previousScanline, byteCount); - candidates.Add(new Tuple(average, CalculateTotalVariation(average))); + candidates.Add(new Tuple(average, this.CalculateTotalVariation(average))); byte[] paeth = PaethFilter.Encode(rawScanline, previousScanline, byteCount); - candidates.Add(new Tuple(paeth, CalculateTotalVariation(paeth))); + candidates.Add(new Tuple(paeth, this.CalculateTotalVariation(paeth))); int lowestTotalVariation = int.MaxValue; int lowestTotalVariationIndex = 0; @@ -354,7 +395,7 @@ namespace ImageProcessorCore.Formats /// /// Calculates the total variation of given byte array. Total variation is the sum of the absolute values of - /// neighbour differences. + /// neighbor differences. /// /// The scanline bytes /// The @@ -411,48 +452,6 @@ namespace ImageProcessorCore.Formats } } - /// - /// Writes an integer to the byte array. - /// - /// The containing image data. - /// The amount to offset by. - /// The value to write. - private static void WriteInteger(byte[] data, int offset, int value) - { - byte[] buffer = BitConverter.GetBytes(value); - - Array.Reverse(buffer); - Array.Copy(buffer, 0, data, offset, 4); - } - - /// - /// Writes an integer to the stream. - /// - /// The containing image data. - /// The value to write. - private static void WriteInteger(Stream stream, int value) - { - byte[] buffer = BitConverter.GetBytes(value); - - Array.Reverse(buffer); - - stream.Write(buffer, 0, 4); - } - - /// - /// Writes an unsigned integer to the stream. - /// - /// The containing image data. - /// The value to write. - private static void WriteInteger(Stream stream, uint value) - { - byte[] buffer = BitConverter.GetBytes(value); - - Array.Reverse(buffer); - - stream.Write(buffer, 0, 4); - } - /// /// Writes the header chunk to the stream. /// @@ -482,6 +481,7 @@ namespace ImageProcessorCore.Formats /// The containing image data. /// The . /// The image to encode. + /// The private QuantizedImage WritePaletteChunk(Stream stream, PngHeader header, ImageBase image) where TColor : IPackedVector where TPacked : struct @@ -600,6 +600,7 @@ namespace ImageProcessorCore.Formats /// /// Writes the pixel information to the stream. /// + /// The stream. private void WriteDataChunks(Stream stream) { byte[] data = this.EncodePixelData();