diff --git a/Settings.StyleCop b/Settings.StyleCop index 27579cbaa4..ee82216a47 100644 --- a/Settings.StyleCop +++ b/Settings.StyleCop @@ -21,6 +21,9 @@ scanline scanlines png's + codeword + unscaled + zig-zag diff --git a/src/ImageSharp/Formats/Jpg/JpegEncoderCore.cs b/src/ImageSharp/Formats/Jpg/JpegEncoderCore.cs index bd745eda86..9e502cfcb9 100644 --- a/src/ImageSharp/Formats/Jpg/JpegEncoderCore.cs +++ b/src/ImageSharp/Formats/Jpg/JpegEncoderCore.cs @@ -2,14 +2,18 @@ // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // - namespace ImageSharp.Formats { using System; using System.IO; + /// + /// Image encoder for writing an image to a stream as a jpeg. + /// internal class JpegEncoderCore { + private const int NQuantIndex = 2; + /// /// Maps from the zig-zag ordering to the natural ordering. For example, /// unzig[3] is the column and row of the fourth element in zig-zag order. The @@ -23,12 +27,10 @@ namespace ImageSharp.Formats 39, 46, 53, 60, 61, 54, 47, 55, 62, 63, }; - private const int NQuantIndex = 2; - /// /// Counts the number of bits needed to hold an integer. /// - private readonly byte[] bitCount = + private readonly byte[] bitCountLut = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, @@ -143,48 +145,6 @@ namespace ImageSharp.Formats }) }; - /// - /// A compiled look-up table representation of a huffmanSpec. - /// Each value maps to a uint32 of which the 8 most significant bits hold the - /// codeword size in bits and the 24 least significant bits hold the codeword. - /// The maximum codeword size is 16 bits. - /// - private class HuffmanLut - { - public readonly uint[] Values; - - public HuffmanLut(HuffmanSpec s) - { - int maxValue = 0; - - foreach (var v in s.Values) - { - if (v > maxValue) - { - maxValue = v; - } - } - - this.Values = new uint[maxValue + 1]; - - int code = 0; - int k = 0; - - for (int i = 0; i < s.Count.Length; i++) - { - int nBits = (i + 1) << 24; - for (int j = 0; j < s.Count[i]; j++) - { - this.Values[s.Values[k]] = (uint)(nBits | code); - code++; - k++; - } - - code <<= 1; - } - } - } - // w is the writer to write to. err is the first error encountered during // writing. All attempted writes after the first error become no-ops. private Stream outputStream; @@ -220,10 +180,10 @@ namespace ImageSharp.Formats /// /// Writes the given byte to the stream. /// - /// + /// The byte to write. private void WriteByte(byte b) { - var data = new byte[1]; + byte[] data = new byte[1]; data[0] = b; this.outputStream.Write(data, 0, 1); } @@ -286,11 +246,11 @@ namespace ImageSharp.Formats uint bt; if (a < 0x100) { - bt = this.bitCount[a]; + bt = this.bitCountLut[a]; } else { - bt = 8 + (uint)this.bitCount[a >> 8]; + bt = 8 + (uint)this.bitCountLut[a >> 8]; } this.EmitHuff(index, (int)((uint)(runLength << 4) | bt)); @@ -318,7 +278,7 @@ namespace ImageSharp.Formats this.EmitHuffRLE((HuffIndex)((2 * (int)index) + 0), 0, dc - prevDC); // Emit the AC components. - var h = (HuffIndex)((2 * (int)index) + 1); + HuffIndex h = (HuffIndex)((2 * (int)index) + 1); int runLength = 0; for (int zig = 1; zig < Block.BlockSize; zig++) @@ -715,7 +675,7 @@ namespace ImageSharp.Formats specs = new[] { this.theHuffmanSpec[0], this.theHuffmanSpec[1] }; } - foreach (var s in specs) + foreach (HuffmanSpec s in specs) { markerlen += 1 + 16 + s.Values.Length; } @@ -734,7 +694,7 @@ namespace ImageSharp.Formats /// /// Writes the StartOfScan marker. /// - /// The pixel accessor providing acces to the image pixels. + /// The pixel accessor providing access to the image pixels. private void WriteSOS(PixelAccessor pixels) where TColor : struct, IPackedPixel where TPacked : struct @@ -871,6 +831,55 @@ namespace ImageSharp.Formats Chrominance = 1, } + /// + /// A compiled look-up table representation of a huffmanSpec. + /// Each value maps to a uint32 of which the 8 most significant bits hold the + /// codeword size in bits and the 24 least significant bits hold the codeword. + /// The maximum codeword size is 16 bits. + /// + private class HuffmanLut + { + /// + /// The collection of huffman values. + /// + public readonly uint[] Values; + + /// + /// Initializes a new instance of the class. + /// + /// The encoding specifications. + public HuffmanLut(HuffmanSpec spec) + { + int maxValue = 0; + + foreach (byte v in spec.Values) + { + if (v > maxValue) + { + maxValue = v; + } + } + + this.Values = new uint[maxValue + 1]; + + int code = 0; + int k = 0; + + for (int i = 0; i < spec.Count.Length; i++) + { + int bits = (i + 1) << 24; + for (int j = 0; j < spec.Count[i]; j++) + { + this.Values[spec.Values[k]] = (uint)(bits | code); + code++; + k++; + } + + code <<= 1; + } + } + } + /// /// The Huffman encoding specifications. ///