Browse Source

Cleanup [skip ci]

Former-commit-id: bff8258988879560d70275e17138ea80c4fcaa17
Former-commit-id: f88a9c5dc94265442f0f52c2595125e316e6efb0
Former-commit-id: 375b12dc3e97e8e6893f0f03869e8b525de4b07c
af/merge-core
James Jackson-South 10 years ago
parent
commit
b3c22c1f14
  1. 1
      ImageProcessorCore.sln
  2. 14
      Settings.StyleCop
  3. 2
      src/ImageProcessorCore/Formats/Gif/GifEncoder.cs
  4. 22
      src/ImageProcessorCore/Formats/Gif/GifEncoderCore.cs
  5. 118
      src/ImageProcessorCore/Formats/Gif/LzwEncoder.cs
  6. 13
      src/ImageProcessorCore/Formats/Gif/PackedField.cs
  7. 2
      src/ImageProcessorCore/Formats/Jpg/JpegDecoderCore.cs.REMOVED.git-id
  8. 2
      tests/ImageProcessorCore.Tests/FileTestBase.cs

1
ImageProcessorCore.sln

@ -15,6 +15,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SolutionItems", "SolutionIt
global.json = global.json global.json = global.json
build\package.json = build\package.json build\package.json = build\package.json
README.md = README.md README.md = README.md
Settings.StyleCop = Settings.StyleCop
EndProjectSection EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{815C0625-CD3D-440F-9F80-2D83856AB7AE}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Source", "Source", "{815C0625-CD3D-440F-9F80-2D83856AB7AE}"

14
Settings.StyleCop

@ -1,4 +1,18 @@
<StyleCopSettings Version="105"> <StyleCopSettings Version="105">
<GlobalSettings>
<CollectionProperty Name="RecognizedWords">
<Value>enum</Value>
<Value>exif</Value>
<Value>uint</Value>
<Value>lossy</Value>
<Value>octree</Value>
<Value>png</Value>
<Value>quantizer</Value>
<Value>unzig</Value>
<Value>cb</Value>
<Value>cr</Value>
</CollectionProperty>
</GlobalSettings>
<Analyzers> <Analyzers>
<Analyzer AnalyzerId="StyleCop.CSharp.DocumentationRules"> <Analyzer AnalyzerId="StyleCop.CSharp.DocumentationRules">
<AnalyzerSettings> <AnalyzerSettings>

2
src/ImageProcessorCore/Formats/Gif/GifEncoder.cs

@ -27,7 +27,7 @@ namespace ImageProcessorCore.Formats
public byte Threshold { get; set; } = 128; public byte Threshold { get; set; } = 128;
/// <summary> /// <summary>
/// The quantizer for reducing the color count. /// Gets or sets the quantizer for reducing the color count.
/// </summary> /// </summary>
public IQuantizer Quantizer { get; set; } public IQuantizer Quantizer { get; set; }

22
src/ImageProcessorCore/Formats/Gif/GifEncoderCore.cs

@ -35,7 +35,7 @@ namespace ImageProcessorCore.Formats
public byte Threshold { get; set; } = 128; public byte Threshold { get; set; } = 128;
/// <summary> /// <summary>
/// The quantizer for reducing the color count. /// Gets or sets the quantizer for reducing the color count.
/// </summary> /// </summary>
public IQuantizer Quantizer { get; set; } public IQuantizer Quantizer { get; set; }
@ -92,7 +92,7 @@ namespace ImageProcessorCore.Formats
foreach (ImageFrame<TColor, TPacked> frame in image.Frames) foreach (ImageFrame<TColor, TPacked> frame in image.Frames)
{ {
QuantizedImage<TColor, TPacked> quantizedFrame = ((IQuantizer<TColor, TPacked>)this.Quantizer).Quantize(frame, this.Quality); QuantizedImage<TColor, TPacked> quantizedFrame = ((IQuantizer<TColor, TPacked>)this.Quantizer).Quantize(frame, this.Quality);
this.WriteGraphicalControlExtension(frame, writer, GetTransparentIndex(quantizedFrame)); this.WriteGraphicalControlExtension(frame, writer, GetTransparentIndex(quantizedFrame));
this.WriteImageDescriptor(frame, writer); this.WriteImageDescriptor(frame, writer);
this.WriteColorTable(quantizedFrame, writer); this.WriteColorTable(quantizedFrame, writer);
@ -151,7 +151,7 @@ namespace ImageProcessorCore.Formats
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The image to encode.</param> /// <param name="image">The image to encode.</param>
/// <param name="writer">The writer to write to the stream with.</param> /// <param name="writer">The writer to write to the stream with.</param>
/// <param name="tranparencyIndex">The transparency index to set the default backgound index to.</param> /// <param name="tranparencyIndex">The transparency index to set the default background index to.</param>
private void WriteLogicalScreenDescriptor<TColor, TPacked>(Image<TColor, TPacked> image, EndianBinaryWriter writer, int tranparencyIndex) private void WriteLogicalScreenDescriptor<TColor, TPacked>(Image<TColor, TPacked> image, EndianBinaryWriter writer, int tranparencyIndex)
where TColor : IPackedVector<TPacked> where TColor : IPackedVector<TPacked>
where TPacked : struct where TPacked : struct
@ -175,7 +175,8 @@ namespace ImageProcessorCore.Formats
field.SetBits(5, 3, descriptor.GlobalColorTableSize); // 6-8 : GCT size. 2^(N+1) field.SetBits(5, 3, descriptor.GlobalColorTableSize); // 6-8 : GCT size. 2^(N+1)
// Reduce the number of writes // Reduce the number of writes
byte[] arr = { byte[] arr =
{
field.Byte, field.Byte,
descriptor.BackgroundColorIndex, // Background Color Index descriptor.BackgroundColorIndex, // Background Color Index
descriptor.PixelAspectRatio // Pixel aspect ratio. Assume 1:1 descriptor.PixelAspectRatio // Pixel aspect ratio. Assume 1:1
@ -185,11 +186,11 @@ namespace ImageProcessorCore.Formats
} }
/// <summary> /// <summary>
/// Writes the application exstension to the stream. /// Writes the application extension to the stream.
/// </summary> /// </summary>
/// <param name="writer">The writer to write to the stream with.</param> /// <param name="writer">The writer to write to the stream with.</param>
/// <param name="repeatCount">The animated image repeat count.</param> /// <param name="repeatCount">The animated image repeat count.</param>
/// <param name="frames">Th number of image frames.</param> /// <param name="frames">The number of image frames.</param>
private void WriteApplicationExtension(EndianBinaryWriter writer, ushort repeatCount, int frames) private void WriteApplicationExtension(EndianBinaryWriter writer, ushort repeatCount, int frames)
{ {
// Application Extension Header // Application Extension Header
@ -244,7 +245,8 @@ namespace ImageProcessorCore.Formats
}; };
// Reduce the number of writes. // Reduce the number of writes.
byte[] intro = { byte[] intro =
{
GifConstants.ExtensionIntroducer, GifConstants.ExtensionIntroducer,
GifConstants.GraphicControlLabel, GifConstants.GraphicControlLabel,
4 // Size 4 // Size
@ -311,9 +313,11 @@ namespace ImageProcessorCore.Formats
int colorTableLength = (int)Math.Pow(2, this.bitDepth) * 3; int colorTableLength = (int)Math.Pow(2, this.bitDepth) * 3;
byte[] colorTable = new byte[colorTableLength]; byte[] colorTable = new byte[colorTableLength];
Parallel.For(0, pixelCount, Parallel.For(
0,
pixelCount,
i => i =>
{ {
int offset = i * 3; int offset = i * 3;
Color color = new Color(palette[i].ToVector4()); Color color = new Color(palette[i].ToVector4());

118
src/ImageProcessorCore/Formats/Gif/LzwEncoder.cs

@ -15,15 +15,14 @@ namespace ImageProcessorCore.Formats
/// Adapted from Jef Poskanzer's Java port by way of J. M. G. Elliott. K Weiner 12/00 /// Adapted from Jef Poskanzer's Java port by way of J. M. G. Elliott. K Weiner 12/00
/// <para> /// <para>
/// GIFCOMPR.C - GIF Image compression routines /// GIFCOMPR.C - GIF Image compression routines
/// /// </para>
/// <para>
/// Lempel-Ziv compression based on 'compress'. GIF modifications by /// Lempel-Ziv compression based on 'compress'. GIF modifications by
/// David Rowley (mgardi@watdcsu.waterloo.edu) /// David Rowley (mgardi@watdcsu.waterloo.edu)
/// </para> /// </para>
/// <para>
/// GIF Image compression - modified 'compress' /// GIF Image compression - modified 'compress'
/// /// <para>
/// Based on: compress.c - File compression ala IEEE Computer, June 1984. /// Based on: compress.c - File compression ala IEEE Computer, June 1984.
///
/// By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas) /// By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
/// Jim McKie (decvax!mcvax!jim) /// Jim McKie (decvax!mcvax!jim)
/// Steve Davies (decvax!vax135!petsd!peora!srd) /// Steve Davies (decvax!vax135!petsd!peora!srd)
@ -44,7 +43,25 @@ namespace ImageProcessorCore.Formats
private readonly int initialCodeSize; private readonly int initialCodeSize;
private int curPixel; private readonly int[] hashTable = new int[HashSize];
private readonly int[] codeTable = new int[HashSize];
private readonly int[] masks =
{
0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF,
0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
};
/// <summary>
/// Define the storage for the packet accumulator.
/// </summary>
private readonly byte[] accumulators = new byte[256];
/// <summary>
/// The current pixel
/// </summary>
private int currentPixel;
/// <summary> /// <summary>
/// Number of bits/code /// Number of bits/code
@ -56,13 +73,15 @@ namespace ImageProcessorCore.Formats
/// </summary> /// </summary>
private int maxbits = Bits; private int maxbits = Bits;
private int maxcode; // maximum code, given bitCount /// <summary>
/// maximum code, given bitCount
private int maxmaxcode = 1 << Bits; // should NEVER generate this code /// </summary>
private int maxcode;
private readonly int[] hashTable = new int[HashSize];
private readonly int[] codeTable = new int[HashSize]; /// <summary>
/// should NEVER generate this code
/// </summary>
private int maxmaxcode = 1 << Bits;
/// <summary> /// <summary>
/// For dynamic table sizing /// For dynamic table sizing
@ -91,7 +110,6 @@ namespace ImageProcessorCore.Formats
// for the decompressor. Late addition: construct the table according to // for the decompressor. Late addition: construct the table according to
// file size for noticeable speed improvement on small files. Please direct // file size for noticeable speed improvement on small files. Please direct
// questions about this implementation to ames!jaw. // questions about this implementation to ames!jaw.
private int globalInitialBits; private int globalInitialBits;
private int clearCode; private int clearCode;
@ -112,27 +130,15 @@ namespace ImageProcessorCore.Formats
// Maintain a BITS character long buffer (so that 8 codes will // Maintain a BITS character long buffer (so that 8 codes will
// fit in it exactly). Use the VAX insv instruction to insert each // fit in it exactly). Use the VAX insv instruction to insert each
// code in turn. When the buffer fills up empty it and start over. // code in turn. When the buffer fills up empty it and start over.
private int currentAccumulator; private int currentAccumulator;
private int currentBits; private int currentBits;
private readonly int[] masks =
{
0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF,
0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
};
/// <summary> /// <summary>
/// Number of characters so far in this 'packet' /// Number of characters so far in this 'packet'
/// </summary> /// </summary>
private int accumulatorCount; private int accumulatorCount;
/// <summary>
/// Define the storage for the packet accumulator.
/// </summary>
private readonly byte[] accumulators = new byte[256];
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="LzwEncoder"/> class. /// Initializes a new instance of the <see cref="LzwEncoder"/> class.
/// </summary> /// </summary>
@ -153,7 +159,7 @@ namespace ImageProcessorCore.Formats
// Write "initial code size" byte // Write "initial code size" byte
stream.WriteByte((byte)this.initialCodeSize); stream.WriteByte((byte)this.initialCodeSize);
this.curPixel = 0; this.currentPixel = 0;
// Compress and write the pixel data // Compress and write the pixel data
this.Compress(this.initialCodeSize + 1, stream); this.Compress(this.initialCodeSize + 1, stream);
@ -215,7 +221,7 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Compress the packets to the stream. /// Compress the packets to the stream.
/// </summary> /// </summary>
/// <param name="intialBits">The inital bits.</param> /// <param name="intialBits">The initial bits.</param>
/// <param name="stream">The stream to write to.</param> /// <param name="stream">The stream to write to.</param>
private void Compress(int intialBits, Stream stream) private void Compress(int intialBits, Stream stream)
{ {
@ -242,7 +248,11 @@ namespace ImageProcessorCore.Formats
ent = this.NextPixel(); ent = this.NextPixel();
hshift = 0; hshift = 0;
for (fcode = this.hsize; fcode < 65536; fcode *= 2) { ++hshift; } for (fcode = this.hsize; fcode < 65536; fcode *= 2)
{
++hshift;
}
hshift = 8 - hshift; // set hash code range bound hshift = 8 - hshift; // set hash code range bound
hsizeReg = this.hsize; hsizeReg = this.hsize;
@ -263,13 +273,20 @@ namespace ImageProcessorCore.Formats
} }
// Non-empty slot // Non-empty slot
if (this.hashTable[i] >= 0) if (this.hashTable[i] >= 0)
{ {
int disp = hsizeReg - i; int disp = hsizeReg - i;
if (i == 0) disp = 1; if (i == 0)
{
disp = 1;
}
do do
{ {
if ((i -= disp) < 0) { i += hsizeReg; } if ((i -= disp) < 0)
{
i += hsizeReg;
}
if (this.hashTable[i] == fcode) if (this.hashTable[i] == fcode)
{ {
@ -279,7 +296,10 @@ namespace ImageProcessorCore.Formats
} }
while (this.hashTable[i] >= 0); while (this.hashTable[i] >= 0);
if (this.hashTable[i] == fcode) { continue; } if (this.hashTable[i] == fcode)
{
continue;
}
} }
this.Output(ent, stream); this.Output(ent, stream);
@ -289,7 +309,10 @@ namespace ImageProcessorCore.Formats
this.codeTable[i] = this.freeEntry++; // code -> hashtable this.codeTable[i] = this.freeEntry++; // code -> hashtable
this.hashTable[i] = fcode; this.hashTable[i] = fcode;
} }
else this.ClearBlock(stream); else
{
this.ClearBlock(stream);
}
} }
// Put out the final code. // Put out the final code.
@ -298,13 +321,16 @@ namespace ImageProcessorCore.Formats
this.Output(this.eofCode, stream); this.Output(this.eofCode, stream);
} }
// Flush the packet to disk, and reset the accumulator /// <summary>
private void FlushPacket(Stream outs) /// Flush the packet to disk, and reset the accumulator.
/// </summary>
/// <param name="outStream">The output stream.</param>
private void FlushPacket(Stream outStream)
{ {
if (this.accumulatorCount > 0) if (this.accumulatorCount > 0)
{ {
outs.WriteByte((byte)this.accumulatorCount); outStream.WriteByte((byte)this.accumulatorCount);
outs.Write(this.accumulators, 0, this.accumulatorCount); outStream.Write(this.accumulators, 0, this.accumulatorCount);
this.accumulatorCount = 0; this.accumulatorCount = 0;
} }
} }
@ -317,16 +343,18 @@ namespace ImageProcessorCore.Formats
/// </returns> /// </returns>
private int NextPixel() private int NextPixel()
{ {
if (this.curPixel == this.pixelArray.Length) if (this.currentPixel == this.pixelArray.Length)
{ {
return Eof; return Eof;
} }
if (this.curPixel == this.pixelArray.Length) if (this.currentPixel == this.pixelArray.Length)
{
return Eof; return Eof;
}
this.curPixel++; this.currentPixel++;
return this.pixelArray[this.curPixel - 1] & 0xff; return this.pixelArray[this.currentPixel - 1] & 0xff;
} }
/// <summary> /// <summary>
@ -338,8 +366,14 @@ namespace ImageProcessorCore.Formats
{ {
this.currentAccumulator &= this.masks[this.currentBits]; this.currentAccumulator &= this.masks[this.currentBits];
if (this.currentBits > 0) this.currentAccumulator |= (code << this.currentBits); if (this.currentBits > 0)
else this.currentAccumulator = code; {
this.currentAccumulator |= code << this.currentBits;
}
else
{
this.currentAccumulator = code;
}
this.currentBits += this.bitCount; this.currentBits += this.bitCount;

13
src/ImageProcessorCore/Formats/Gif/PackedField.cs

@ -38,9 +38,11 @@ namespace ImageProcessorCore.Formats
{ {
bitValue = 0; bitValue = 0;
} }
returnValue |= bitValue; returnValue |= bitValue;
bitShift--; bitShift--;
} }
return Convert.ToByte(returnValue & 0xFF); return Convert.ToByte(returnValue & 0xFF);
} }
} }
@ -77,6 +79,7 @@ namespace ImageProcessorCore.Formats
+ index; + index;
throw new ArgumentOutOfRangeException(nameof(index), message); throw new ArgumentOutOfRangeException(nameof(index), message);
} }
Bits[index] = valueToSet; Bits[index] = valueToSet;
} }
@ -105,10 +108,10 @@ namespace ImageProcessorCore.Formats
int bitShift = length - 1; int bitShift = length - 1;
for (int i = startIndex; i < startIndex + length; i++) for (int i = startIndex; i < startIndex + length; i++)
{ {
int bitValueIfSet = (1 << bitShift); int bitValueIfSet = 1 << bitShift;
int bitValue = (valueToSet & bitValueIfSet); int bitValue = valueToSet & bitValueIfSet;
int bitIsSet = (bitValue >> bitShift); int bitIsSet = bitValue >> bitShift;
Bits[i] = (bitIsSet == 1); Bits[i] = bitIsSet == 1;
bitShift--; bitShift--;
} }
} }
@ -127,6 +130,7 @@ namespace ImageProcessorCore.Formats
string message = $"Index must be between 0 and 7. Supplied index: {index}"; string message = $"Index must be between 0 and 7. Supplied index: {index}";
throw new ArgumentOutOfRangeException(nameof(index), message); throw new ArgumentOutOfRangeException(nameof(index), message);
} }
return Bits[index]; return Bits[index];
} }
@ -162,6 +166,7 @@ namespace ImageProcessorCore.Formats
returnValue += bitValue; returnValue += bitValue;
bitShift--; bitShift--;
} }
return returnValue; return returnValue;
} }

2
src/ImageProcessorCore/Formats/Jpg/JpegDecoderCore.cs.REMOVED.git-id

@ -1 +1 @@
d6958d9584977251f1a5b84a877bb4c3a1336135 4b157cb3b1a798514be3c1b13c1ed4294bf9d6f1

2
tests/ImageProcessorCore.Tests/FileTestBase.cs

@ -21,7 +21,7 @@ namespace ImageProcessorCore.Tests
{ {
//TestImages.Png.P1, //TestImages.Png.P1,
//TestImages.Png.Pd, //TestImages.Png.Pd,
//TestImages.Jpg.Floorplan, // Perf: Enable for local testing only TestImages.Jpg.Floorplan, // Perf: Enable for local testing only
TestImages.Jpg.Calliphora, TestImages.Jpg.Calliphora,
//TestImages.Jpg.Cmyk, // Perf: Enable for local testing only //TestImages.Jpg.Cmyk, // Perf: Enable for local testing only
//TestImages.Jpg.Turtle, //TestImages.Jpg.Turtle,

Loading…
Cancel
Save