diff --git a/ImageSharp.46.sln b/ImageSharp.46.sln
index fe112b9ea..270d391cc 100644
--- a/ImageSharp.46.sln
+++ b/ImageSharp.46.sln
@@ -7,6 +7,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageSharp46", "src\ImageSh
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageSharp.Tests46", "tests\ImageSharp.Tests46\ImageSharp.Tests46.csproj", "{635E0A15-3893-4763-A7F6-FCCFF85BCCA4}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleBenchmark", "tests\ConsoleBenchmark\ConsoleBenchmark.csproj", "{8783E3A1-79F1-4E37-AA79-F06C48BED5E7}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -21,6 +23,10 @@ Global
{635E0A15-3893-4763-A7F6-FCCFF85BCCA4}.Debug|Any CPU.Build.0 = Debug|Any CPU
{635E0A15-3893-4763-A7F6-FCCFF85BCCA4}.Release|Any CPU.ActiveCfg = Release|Any CPU
{635E0A15-3893-4763-A7F6-FCCFF85BCCA4}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8783E3A1-79F1-4E37-AA79-F06C48BED5E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8783E3A1-79F1-4E37-AA79-F06C48BED5E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8783E3A1-79F1-4E37-AA79-F06C48BED5E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8783E3A1-79F1-4E37-AA79-F06C48BED5E7}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/ImageSharp46/Formats/Jpg/Components/Block.cs b/src/ImageSharp46/Formats/Jpg/Components/Block.cs
index 8bc5a861c..168413292 100644
--- a/src/ImageSharp46/Formats/Jpg/Components/Block.cs
+++ b/src/ImageSharp46/Formats/Jpg/Components/Block.cs
@@ -3,12 +3,14 @@
// Licensed under the Apache License, Version 2.0.
//
+using System.Buffers;
+
namespace ImageSharp.Formats
{
///
/// Represents an 8x8 block of coefficients to transform and encode.
///
- internal class Block
+ internal struct Block
{
///
/// Gets the size of the block.
@@ -18,16 +20,23 @@ namespace ImageSharp.Formats
///
/// The array of block data.
///
- private readonly int[] data;
+ public int[] Data;
///
/// Initializes a new instance of the class.
///
- public Block()
+ //public Block()
+ //{
+ // this.data = new int[BlockSize];
+ //}
+
+ public void Init()
{
- this.data = new int[BlockSize];
+ this.Data = new int[BlockSize];
}
+ public bool IsInitialized => this.Data != null;
+
///
/// Gets the pixel data at the given block index.
///
@@ -37,8 +46,8 @@ namespace ImageSharp.Formats
///
public int this[int index]
{
- get { return this.data[index]; }
- set { this.data[index] = value; }
+ get { return this.Data[index]; }
+ set { this.Data[index] = value; }
}
}
}
diff --git a/src/ImageSharp46/Formats/Jpg/Components/Component.cs b/src/ImageSharp46/Formats/Jpg/Components/Component.cs
index f56b6d513..f70dbff3f 100644
--- a/src/ImageSharp46/Formats/Jpg/Components/Component.cs
+++ b/src/ImageSharp46/Formats/Jpg/Components/Component.cs
@@ -8,26 +8,26 @@ namespace ImageSharp.Formats
///
/// Represents a single color component
///
- internal class Component
+ internal struct Component
{
///
/// Gets or sets the horizontal sampling factor.
///
- public int HorizontalFactor { get; set; }
+ public int HorizontalFactor;
///
/// Gets or sets the vertical sampling factor.
///
- public int VerticalFactor { get; set; }
+ public int VerticalFactor;
///
/// Gets or sets the identifier
///
- public byte Identifier { get; set; }
+ public byte Identifier;
///
/// Gets or sets the quantization table destination selector.
///
- public byte Selector { get; set; }
+ public byte Selector;
}
}
diff --git a/src/ImageSharp46/Formats/Jpg/Components/FDCT.cs b/src/ImageSharp46/Formats/Jpg/Components/FDCT.cs
index cd27b9e73..13ce80f55 100644
--- a/src/ImageSharp46/Formats/Jpg/Components/FDCT.cs
+++ b/src/ImageSharp46/Formats/Jpg/Components/FDCT.cs
@@ -45,7 +45,7 @@ namespace ImageSharp.Formats
/// Performs a forward DCT on an 8x8 block of coefficients, including a level shift.
///
/// The block of coefficients.
- public static void Transform(Block block)
+ public static void Transform(ref Block block)
{
// Pass 1: process rows.
for (int y = 0; y < 8; y++)
diff --git a/src/ImageSharp46/Formats/Jpg/Components/Huffman.cs b/src/ImageSharp46/Formats/Jpg/Components/Huffman.cs
index 2c38cfd38..cef99ea1a 100644
--- a/src/ImageSharp46/Formats/Jpg/Components/Huffman.cs
+++ b/src/ImageSharp46/Formats/Jpg/Components/Huffman.cs
@@ -8,7 +8,7 @@ namespace ImageSharp.Formats
///
/// Represents a Huffman tree
///
- internal class Huffman
+ internal struct Huffman
{
///
/// Initializes a new instance of the class.
@@ -16,20 +16,29 @@ namespace ImageSharp.Formats
/// The log-2 size of the Huffman decoder's look-up table.
/// The maximum (inclusive) number of codes in a Huffman tree.
/// The maximum (inclusive) number of bits in a Huffman code.
- public Huffman(int lutSize, int maxNCodes, int maxCodeLength)
+ //public Huffman(int lutSize, int maxNCodes, int maxCodeLength)
+ //{
+ // this.Lut = new ushort[1 << lutSize];
+ // this.Values = new byte[maxNCodes];
+ // this.MinCodes = new int[maxCodeLength];
+ // this.MaxCodes = new int[maxCodeLength];
+ // this.Indices = new int[maxCodeLength];
+ // this.Length = 0;
+ //}
+
+ public void Init(int lutSize, int maxNCodes, int maxCodeLength)
{
this.Lut = new ushort[1 << lutSize];
this.Values = new byte[maxNCodes];
this.MinCodes = new int[maxCodeLength];
this.MaxCodes = new int[maxCodeLength];
this.Indices = new int[maxCodeLength];
- this.Length = 0;
}
///
/// Gets or sets the number of codes in the tree.
///
- public int Length { get; set; }
+ public int Length;
///
/// Gets the look-up table for the next LutSize bits in the bit-stream.
@@ -37,28 +46,30 @@ namespace ImageSharp.Formats
/// are 1 plus the code length, or 0 if the value is too large to fit in
/// lutSize bits.
///
- public ushort[] Lut { get; }
+ public ushort[] Lut;
///
/// Gets the the decoded values, sorted by their encoding.
///
- public byte[] Values { get; }
+ public byte[] Values;
///
/// Gets the array of minimum codes.
/// MinCodes[i] is the minimum code of length i, or -1 if there are no codes of that length.
///
- public int[] MinCodes { get; }
+ public int[] MinCodes;
///
/// Gets the array of maximum codes.
/// MaxCodes[i] is the maximum code of length i, or -1 if there are no codes of that length.
///
- public int[] MaxCodes { get; }
+ public int[] MaxCodes;
///
/// Gets the array of indices. Indices[i] is the index into Values of MinCodes[i].
///
- public int[] Indices { get; }
+ public int[] Indices;
}
+
+
}
\ No newline at end of file
diff --git a/src/ImageSharp46/Formats/Jpg/Components/IDCT.cs b/src/ImageSharp46/Formats/Jpg/Components/IDCT.cs
index bc145779a..8bbbae357 100644
--- a/src/ImageSharp46/Formats/Jpg/Components/IDCT.cs
+++ b/src/ImageSharp46/Formats/Jpg/Components/IDCT.cs
@@ -3,6 +3,8 @@
// Licensed under the Apache License, Version 2.0.
//
+using System.Numerics;
+
namespace ImageSharp.Formats
{
///
@@ -39,8 +41,10 @@ namespace ImageSharp.Formats
/// ASSP, Vol. ASSP- 32, pp. 803-816, Aug. 1984.
///
/// The source block of coefficients
- public static void Transform(Block src)
+ public static void Transform(ref Block block)
{
+
+ var src = block.Data;
// Horizontal 1-D IDCT.
for (int y = 0; y < 8; y++)
{
diff --git a/src/ImageSharp46/Formats/Jpg/JpegDecoderCore.cs b/src/ImageSharp46/Formats/Jpg/JpegDecoderCore.cs
index a1e596649..d64803eb4 100644
--- a/src/ImageSharp46/Formats/Jpg/JpegDecoderCore.cs
+++ b/src/ImageSharp46/Formats/Jpg/JpegDecoderCore.cs
@@ -44,6 +44,8 @@ namespace ImageSharp.Formats
///
private const int MaxTh = 3;
+ private const int ThRowSize = MaxTh + 1;
+
///
/// The maximum number of quantization tables
///
@@ -85,7 +87,9 @@ namespace ImageSharp.Formats
///
/// The huffman trees
///
- private readonly Huffman[,] huffmanTrees;
+ //private readonly Huffman[,] huffmanTrees;
+
+ private readonly Huffman[] huffmanTrees;
///
/// Quantization tables, in zigzag order.
@@ -187,12 +191,16 @@ namespace ImageSharp.Formats
///
private short verticalResolution;
+ private int blockIndex;
+
///
/// Initializes a new instance of the class.
///
public JpegDecoderCore()
{
- this.huffmanTrees = new Huffman[MaxTc + 1, MaxTh + 1];
+ //this.huffmanTrees = new Huffman[MaxTc + 1, MaxTh + 1];
+ this.huffmanTrees = new Huffman[(MaxTc + 1)*(MaxTh + 1)];
+
this.quantizationTables = new Block[MaxTq + 1];
this.temp = new byte[2 * Block.BlockSize];
this.componentArray = new Component[MaxComponents];
@@ -201,23 +209,26 @@ namespace ImageSharp.Formats
this.bytes = new Bytes();
// TODO: This looks like it could be static.
+
for (int i = 0; i < MaxTc + 1; i++)
{
for (int j = 0; j < MaxTh + 1; j++)
{
- this.huffmanTrees[i, j] = new Huffman(LutSize, MaxNCodes, MaxCodeLength);
+ //this.huffmanTrees[i, j].Init(LutSize, MaxNCodes, MaxCodeLength);
+ this.huffmanTrees[i* ThRowSize + j].Init(LutSize, MaxNCodes, MaxCodeLength);
}
}
for (int i = 0; i < this.quantizationTables.Length; i++)
{
- this.quantizationTables[i] = new Block();
+ //this.quantizationTables[i] = new Block();
+ this.quantizationTables[i].Init();
}
- for (int i = 0; i < this.componentArray.Length; i++)
- {
- this.componentArray[i] = new Component();
- }
+ //for (int i = 0; i < this.componentArray.Length; i++)
+ //{
+ // this.componentArray[i] = new Component();
+ //}
}
@@ -502,92 +513,96 @@ namespace ImageSharp.Formats
throw new ImageFormatException("Bad Th value");
}
- Huffman huffman = this.huffmanTrees[tc, th];
+ ProcessDefineHuffmanTablesMarkerLoop(ref this.huffmanTrees[tc* ThRowSize + th], ref remaining);
+ }
+ }
- // Read nCodes and huffman.Valuess (and derive h.Length).
- // nCodes[i] is the number of codes with code length i.
- // h.Length is the total number of codes.
- huffman.Length = 0;
+ private void ProcessDefineHuffmanTablesMarkerLoop(ref Huffman huffman, ref int remaining)
+ {
- int[] ncodes = new int[MaxCodeLength];
- for (int i = 0; i < ncodes.Length; i++)
- {
- ncodes[i] = this.temp[i + 1];
- huffman.Length += ncodes[i];
- }
+ // Read nCodes and huffman.Valuess (and derive h.Length).
+ // nCodes[i] is the number of codes with code length i.
+ // h.Length is the total number of codes.
+ huffman.Length = 0;
- if (huffman.Length == 0)
- {
- throw new ImageFormatException("Huffman table has zero length");
- }
+ int[] ncodes = new int[MaxCodeLength];
+ for (int i = 0; i < ncodes.Length; i++)
+ {
+ ncodes[i] = this.temp[i + 1];
+ huffman.Length += ncodes[i];
+ }
- if (huffman.Length > MaxNCodes)
- {
- throw new ImageFormatException("Huffman table has excessive length");
- }
+ if (huffman.Length == 0)
+ {
+ throw new ImageFormatException("Huffman table has zero length");
+ }
- remaining -= huffman.Length + 17;
- if (remaining < 0)
- {
- throw new ImageFormatException("DHT has wrong length");
- }
+ if (huffman.Length > MaxNCodes)
+ {
+ throw new ImageFormatException("Huffman table has excessive length");
+ }
- this.ReadFull(huffman.Values, 0, huffman.Length);
+ remaining -= huffman.Length + 17;
+ if (remaining < 0)
+ {
+ throw new ImageFormatException("DHT has wrong length");
+ }
- // Derive the look-up table.
- for (int i = 0; i < huffman.Lut.Length; i++)
- {
- huffman.Lut[i] = 0;
- }
+ this.ReadFull(huffman.Values, 0, huffman.Length);
+
+ // Derive the look-up table.
+ for (int i = 0; i < huffman.Lut.Length; i++)
+ {
+ huffman.Lut[i] = 0;
+ }
- uint x = 0, code = 0;
+ uint x = 0, code = 0;
- for (int i = 0; i < LutSize; i++)
+ for (int i = 0; i < LutSize; i++)
+ {
+ code <<= 1;
+
+ for (int j = 0; j < ncodes[i]; j++)
{
- code <<= 1;
+ // The codeLength is 1+i, so shift code by 8-(1+i) to
+ // calculate the high bits for every 8-bit sequence
+ // whose codeLength's high bits matches code.
+ // The high 8 bits of lutValue are the encoded value.
+ // The low 8 bits are 1 plus the codeLength.
+ byte base2 = (byte) (code << (7 - i));
+ ushort lutValue = (ushort) ((huffman.Values[x] << 8) | (2 + i));
- for (int j = 0; j < ncodes[i]; j++)
+ for (int k = 0; k < 1 << (7 - i); k++)
{
- // The codeLength is 1+i, so shift code by 8-(1+i) to
- // calculate the high bits for every 8-bit sequence
- // whose codeLength's high bits matches code.
- // The high 8 bits of lutValue are the encoded value.
- // The low 8 bits are 1 plus the codeLength.
- byte base2 = (byte)(code << (7 - i));
- ushort lutValue = (ushort)((huffman.Values[x] << 8) | (2 + i));
-
- for (int k = 0; k < 1 << (7 - i); k++)
- {
- huffman.Lut[base2 | k] = lutValue;
- }
-
- code++;
- x++;
+ huffman.Lut[base2 | k] = lutValue;
}
+
+ code++;
+ x++;
}
+ }
- // Derive minCodes, maxCodes, and indices.
- int c = 0, index = 0;
- for (int i = 0; i < ncodes.Length; i++)
+ // Derive minCodes, maxCodes, and indices.
+ int c = 0, index = 0;
+ for (int i = 0; i < ncodes.Length; i++)
+ {
+ int nc = ncodes[i];
+ if (nc == 0)
{
- int nc = ncodes[i];
- if (nc == 0)
- {
- huffman.MinCodes[i] = -1;
- huffman.MaxCodes[i] = -1;
- huffman.Indices[i] = -1;
- }
- else
- {
- huffman.MinCodes[i] = c;
- huffman.MaxCodes[i] = c + nc - 1;
- huffman.Indices[i] = index;
- c += nc;
- index += nc;
- }
-
- c <<= 1;
+ huffman.MinCodes[i] = -1;
+ huffman.MaxCodes[i] = -1;
+ huffman.Indices[i] = -1;
+ }
+ else
+ {
+ huffman.MinCodes[i] = c;
+ huffman.MaxCodes[i] = c + nc - 1;
+ huffman.Indices[i] = index;
+ c += nc;
+ index += nc;
}
+
+ c <<= 1;
}
}
@@ -596,7 +611,7 @@ namespace ImageSharp.Formats
///
/// The huffman value
/// The
- private byte DecodeHuffman(Huffman huffman)
+ private byte DecodeHuffman(ref Huffman huffman)
{
if (huffman.Length == 0)
{
@@ -1480,7 +1495,8 @@ namespace ImageSharp.Formats
this.ReadFull(this.temp, 0, remaining);
byte scanComponentCount = this.temp[0];
- if (remaining != 4 + (2 * scanComponentCount))
+ int scanComponentCountBy2 = 2 * scanComponentCount;
+ if (remaining != 4 + scanComponentCountBy2)
{
throw new ImageFormatException("SOS length inconsistent with number of components");
}
@@ -1490,51 +1506,7 @@ namespace ImageSharp.Formats
for (int i = 0; i < scanComponentCount; i++)
{
- // Component selector.
- int cs = this.temp[1 + (2 * i)];
- int compIndex = -1;
- for (int j = 0; j < this.componentCount; j++)
- {
- Component compv = this.componentArray[j];
- if (cs == compv.Identifier)
- {
- compIndex = j;
- }
- }
-
- if (compIndex < 0)
- {
- throw new ImageFormatException("Unknown component selector");
- }
-
- scan[i].Index = (byte)compIndex;
-
- // Section B.2.3 states that "the value of Cs_j shall be different from
- // the values of Cs_1 through Cs_(j-1)". Since we have previously
- // verified that a frame's component identifiers (C_i values in section
- // B.2.2) are unique, it suffices to check that the implicit indexes
- // into comp are unique.
- for (int j = 0; j < i; j++)
- {
- if (scan[i].Index == scan[j].Index)
- {
- throw new ImageFormatException("Repeated component selector");
- }
- }
-
- totalHv += this.componentArray[compIndex].HorizontalFactor * this.componentArray[compIndex].VerticalFactor;
-
- scan[i].DcTableSelector = (byte)(this.temp[2 + (2 * i)] >> 4);
- if (scan[i].DcTableSelector > MaxTh)
- {
- throw new ImageFormatException("Bad DC table selector value");
- }
-
- scan[i].AcTableSelector = (byte)(this.temp[2 + (2 * i)] & 0x0f);
- if (scan[i].AcTableSelector > MaxTh)
- {
- throw new ImageFormatException("Bad AC table selector value");
- }
+ ProcessScanImpl(i, ref scan[i], scan, ref totalHv);
}
// Section B.2.3 states that if there is more than one component then the
@@ -1565,10 +1537,10 @@ namespace ImageSharp.Formats
if (this.isProgressive)
{
- zigStart = this.temp[1 + (2 * scanComponentCount)];
- zigEnd = this.temp[2 + (2 * scanComponentCount)];
- ah = this.temp[3 + (2 * scanComponentCount)] >> 4;
- al = this.temp[3 + (2 * scanComponentCount)] & 0x0f;
+ zigStart = this.temp[1 + scanComponentCountBy2];
+ zigEnd = this.temp[2 + scanComponentCountBy2];
+ ah = this.temp[3 + scanComponentCountBy2] >> 4;
+ al = this.temp[3 + scanComponentCountBy2] & 0x0f;
if ((zigStart == 0 && zigEnd != 0) || zigStart > zigEnd || Block.BlockSize <= zigEnd)
{
@@ -1608,7 +1580,7 @@ namespace ImageSharp.Formats
for (int j = 0; j < this.progCoeffs[compIndex].Length; j++)
{
- this.progCoeffs[compIndex][j] = new Block();
+ this.progCoeffs[compIndex][j].Init();
}
}
}
@@ -1620,7 +1592,7 @@ namespace ImageSharp.Formats
byte expectedRst = JpegConstants.Markers.RST0;
// b is the decoded coefficients block, in natural (not zig-zag) order.
- Block b;
+ //Block b;
int[] dc = new int[MaxComponents];
// bx and by are the location of the current block, in units of 8x8
@@ -1636,7 +1608,7 @@ namespace ImageSharp.Formats
int compIndex = scan[i].Index;
int hi = this.componentArray[compIndex].HorizontalFactor;
int vi = this.componentArray[compIndex].VerticalFactor;
- Block qt = this.quantizationTables[this.componentArray[compIndex].Selector];
+
for (int j = 0; j < hi * vi; j++)
{
@@ -1679,168 +1651,28 @@ namespace ImageSharp.Formats
}
}
+ var qtIndex = this.componentArray[compIndex].Selector;
+
// Load the previous partially decoded coefficients, if applicable.
- b = this.isProgressive ? this.progCoeffs[compIndex][((@by * mxx) * hi) + bx] : new Block();
-
- if (ah != 0)
- {
- this.Refine(b, this.huffmanTrees[AcTable, scan[i].AcTableSelector], zigStart, zigEnd, 1 << al);
- }
- else
- {
- int zig = zigStart;
- if (zig == 0)
- {
- zig++;
-
- // Decode the DC coefficient, as specified in section F.2.2.1.
- byte value = this.DecodeHuffman(this.huffmanTrees[DcTable, scan[i].DcTableSelector]);
- if (value > 16)
- {
- throw new ImageFormatException("Excessive DC component");
- }
-
- int deltaDC = this.ReceiveExtend(value);
- dc[compIndex] += deltaDC;
- b[0] = dc[compIndex] << al;
- }
-
- if (zig <= zigEnd && this.eobRun > 0)
- {
- this.eobRun--;
- }
- else
- {
- // Decode the AC coefficients, as specified in section F.2.2.2.
- Huffman huffv = this.huffmanTrees[AcTable, scan[i].AcTableSelector];
- for (; zig <= zigEnd; zig++)
- {
- byte value = this.DecodeHuffman(huffv);
- byte val0 = (byte)(value >> 4);
- byte val1 = (byte)(value & 0x0f);
- if (val1 != 0)
- {
- zig += val0;
- if (zig > zigEnd)
- {
- break;
- }
-
- int ac = this.ReceiveExtend(val1);
- b[Unzig[zig]] = ac << al;
- }
- else
- {
- if (val0 != 0x0f)
- {
- this.eobRun = (ushort)(1 << val0);
- if (val0 != 0)
- {
- this.eobRun |= (ushort)this.DecodeBits(val0);
- }
-
- this.eobRun--;
- break;
- }
-
- zig += 0x0f;
- }
- }
- }
- }
+
+ //b = this.isProgressive ? this.progCoeffs[compIndex][blockIndex] : new Block();
if (this.isProgressive)
{
- if (zigEnd != Block.BlockSize - 1 || al != 0)
- {
- // We haven't completely decoded this 8x8 block. Save the coefficients.
- this.progCoeffs[compIndex][((by * mxx) * hi) + bx] = b;
-
- // At this point, we could execute the rest of the loop body to dequantize and
- // perform the inverse DCT, to save early stages of a progressive image to the
- // *image.YCbCr buffers (the whole point of progressive encoding), but in Go,
- // the jpeg.Decode function does not return until the entire image is decoded,
- // so we "continue" here to avoid wasted computation.
- continue;
- }
- }
-
- // Dequantize, perform the inverse DCT and store the block to the image.
- for (int zig = 0; zig < Block.BlockSize; zig++)
- {
- b[Unzig[zig]] *= qt[zig];
- }
-
- IDCT.Transform(b);
-
- byte[] dst;
- int offset;
- int stride;
-
- if (this.componentCount == 1)
- {
- dst = this.grayImage.Pixels;
- stride = this.grayImage.Stride;
- offset = this.grayImage.Offset + (8 * ((by * this.grayImage.Stride) + bx));
+ blockIndex = ((@by * mxx) * hi) + bx;
+ ProcessBlockImpl(ah,
+ ref this.progCoeffs[compIndex][blockIndex],
+ scan, i, zigStart, zigEnd, al, dc, compIndex, @by, mxx, hi, bx,
+ ref this.quantizationTables[qtIndex]
+ );
}
else
{
- switch (compIndex)
- {
- case 0:
- dst = this.ycbcrImage.YChannel;
- stride = this.ycbcrImage.YStride;
- offset = this.ycbcrImage.YOffset + (8 * ((by * this.ycbcrImage.YStride) + bx));
- break;
-
- case 1:
- dst = this.ycbcrImage.CbChannel;
- stride = this.ycbcrImage.CStride;
- offset = this.ycbcrImage.COffset + (8 * ((by * this.ycbcrImage.CStride) + bx));
- break;
-
- case 2:
- dst = this.ycbcrImage.CrChannel;
- stride = this.ycbcrImage.CStride;
- offset = this.ycbcrImage.COffset + (8 * ((by * this.ycbcrImage.CStride) + bx));
- break;
-
- case 3:
-
- dst = this.blackPixels;
- stride = this.blackStride;
- offset = 8 * ((by * this.blackStride) + bx);
- break;
-
- default:
- throw new ImageFormatException("Too many components");
- }
- }
-
- // Level shift by +128, clip to [0, 255], and write to dst.
- for (int y = 0; y < 8; y++)
- {
- int y8 = y * 8;
- int yStride = y * stride;
-
- for (int x = 0; x < 8; x++)
- {
- int c = b[y8 + x];
- if (c < -128)
- {
- c = 0;
- }
- else if (c > 127)
- {
- c = 255;
- }
- else
- {
- c += 128;
- }
-
- dst[yStride + x + offset] = (byte)c;
- }
+ var b = new Block();
+ b.Init();
+ ProcessBlockImpl(ah, ref b, scan, i, zigStart, zigEnd, al, dc, compIndex, @by, mxx, hi,
+ bx, ref this.quantizationTables[qtIndex]
+ );
}
}
@@ -1883,6 +1715,226 @@ namespace ImageSharp.Formats
// for my
}
+ private void ProcessBlockImpl(int ah, ref Block b, Scan[] scan, int i, int zigStart, int zigEnd, int al,
+ int[] dc, int compIndex, int @by, int mxx, int hi, int bx, ref Block qt)
+ {
+ if (ah != 0)
+ {
+ this.Refine(ref b, ref this.huffmanTrees[AcTable * ThRowSize + scan[i].AcTableSelector], zigStart, zigEnd, 1 << al);
+ }
+ else
+ {
+ int zig = zigStart;
+ if (zig == 0)
+ {
+ zig++;
+
+ // Decode the DC coefficient, as specified in section F.2.2.1.
+ byte value = this.DecodeHuffman(ref this.huffmanTrees[DcTable * ThRowSize + scan[i].DcTableSelector]);
+ if (value > 16)
+ {
+ throw new ImageFormatException("Excessive DC component");
+ }
+
+ int deltaDC = this.ReceiveExtend(value);
+ dc[compIndex] += deltaDC;
+ b[0] = dc[compIndex] << al;
+ }
+
+ if (zig <= zigEnd && this.eobRun > 0)
+ {
+ this.eobRun--;
+ }
+ else
+ {
+ // Decode the AC coefficients, as specified in section F.2.2.2.
+ //Huffman huffv = ;
+ for (; zig <= zigEnd; zig++)
+ {
+ byte value = this.DecodeHuffman(ref this.huffmanTrees[AcTable * ThRowSize + scan[i].AcTableSelector]);
+ byte val0 = (byte) (value >> 4);
+ byte val1 = (byte) (value & 0x0f);
+ if (val1 != 0)
+ {
+ zig += val0;
+ if (zig > zigEnd)
+ {
+ break;
+ }
+
+ int ac = this.ReceiveExtend(val1);
+ b[Unzig[zig]] = ac << al;
+ }
+ else
+ {
+ if (val0 != 0x0f)
+ {
+ this.eobRun = (ushort) (1 << val0);
+ if (val0 != 0)
+ {
+ this.eobRun |= (ushort) this.DecodeBits(val0);
+ }
+
+ this.eobRun--;
+ break;
+ }
+
+ zig += 0x0f;
+ }
+ }
+ }
+ }
+
+ if (this.isProgressive)
+ {
+ if (zigEnd != Block.BlockSize - 1 || al != 0)
+ {
+ // We haven't completely decoded this 8x8 block. Save the coefficients.
+ this.progCoeffs[compIndex][((@by*mxx)*hi) + bx] = b;
+
+ // At this point, we could execute the rest of the loop body to dequantize and
+ // perform the inverse DCT, to save early stages of a progressive image to the
+ // *image.YCbCr buffers (the whole point of progressive encoding), but in Go,
+ // the jpeg.Decode function does not return until the entire image is decoded,
+ // so we "continue" here to avoid wasted computation.
+ return;
+ }
+ }
+
+ // Dequantize, perform the inverse DCT and store the block to the image.
+ for (int zig = 0; zig < Block.BlockSize; zig++)
+ {
+ b[Unzig[zig]] *= qt[zig];
+ }
+
+ IDCT.Transform(ref b);
+
+ byte[] dst;
+ int offset;
+ int stride;
+
+ if (this.componentCount == 1)
+ {
+ dst = this.grayImage.Pixels;
+ stride = this.grayImage.Stride;
+ offset = this.grayImage.Offset + (8*((@by*this.grayImage.Stride) + bx));
+ }
+ else
+ {
+ switch (compIndex)
+ {
+ case 0:
+ dst = this.ycbcrImage.YChannel;
+ stride = this.ycbcrImage.YStride;
+ offset = this.ycbcrImage.YOffset + (8*((@by*this.ycbcrImage.YStride) + bx));
+ break;
+
+ case 1:
+ dst = this.ycbcrImage.CbChannel;
+ stride = this.ycbcrImage.CStride;
+ offset = this.ycbcrImage.COffset + (8*((@by*this.ycbcrImage.CStride) + bx));
+ break;
+
+ case 2:
+ dst = this.ycbcrImage.CrChannel;
+ stride = this.ycbcrImage.CStride;
+ offset = this.ycbcrImage.COffset + (8*((@by*this.ycbcrImage.CStride) + bx));
+ break;
+
+ case 3:
+
+ dst = this.blackPixels;
+ stride = this.blackStride;
+ offset = 8*((@by*this.blackStride) + bx);
+ break;
+
+ default:
+ throw new ImageFormatException("Too many components");
+ }
+ }
+
+ // Level shift by +128, clip to [0, 255], and write to dst.
+ for (int y = 0; y < 8; y++)
+ {
+ int y8 = y*8;
+ int yStride = y*stride;
+
+ for (int x = 0; x < 8; x++)
+ {
+ int c = b[y8 + x];
+ if (c < -128)
+ {
+ c = 0;
+ }
+ else if (c > 127)
+ {
+ c = 255;
+ }
+ else
+ {
+ c += 128;
+ }
+
+ dst[yStride + x + offset] = (byte) c;
+ }
+ }
+ }
+
+ private void ProcessScanImpl(int i, ref Scan currentScan, Scan[] scan, ref int totalHv)
+ {
+ // Component selector.
+ int cs = this.temp[1 + (2 * i)];
+ int compIndex = -1;
+ for (int j = 0; j < this.componentCount; j++)
+ {
+ //Component compv = ;
+ if (cs == this.componentArray[j].Identifier)
+ {
+ compIndex = j;
+ }
+ }
+
+ if (compIndex < 0)
+ {
+ throw new ImageFormatException("Unknown component selector");
+ }
+
+ currentScan.Index = (byte)compIndex;
+
+ ProcessComponentImpl(i, ref currentScan, scan, ref totalHv, ref this.componentArray[compIndex]);
+ }
+
+ private void ProcessComponentImpl(int i, ref Scan currentScan, Scan[] scan, ref int totalHv, ref Component currentComponent)
+ {
+ // Section B.2.3 states that "the value of Cs_j shall be different from
+ // the values of Cs_1 through Cs_(j-1)". Since we have previously
+ // verified that a frame's component identifiers (C_i values in section
+ // B.2.2) are unique, it suffices to check that the implicit indexes
+ // into comp are unique.
+ for (int j = 0; j < i; j++)
+ {
+ if (currentScan.Index == scan[j].Index)
+ {
+ throw new ImageFormatException("Repeated component selector");
+ }
+ }
+
+
+ totalHv += currentComponent.HorizontalFactor*currentComponent.VerticalFactor;
+
+ currentScan.DcTableSelector = (byte) (this.temp[2 + (2*i)] >> 4);
+ if (currentScan.DcTableSelector > MaxTh)
+ {
+ throw new ImageFormatException("Bad DC table selector value");
+ }
+
+ currentScan.AcTableSelector = (byte) (this.temp[2 + (2*i)] & 0x0f);
+ if (currentScan.AcTableSelector > MaxTh)
+ {
+ throw new ImageFormatException("Bad AC table selector value");
+ }
+ }
+
///
/// Decodes a successive approximation refinement block, as specified in section G.1.2.
///
@@ -1891,7 +1943,7 @@ namespace ImageSharp.Formats
/// The zig-zag start index
/// The zig-zag end index
/// The low transform offset
- private void Refine(Block b, Huffman h, int zigStart, int zigEnd, int delta)
+ private void Refine(ref Block b, ref Huffman h, int zigStart, int zigEnd, int delta)
{
// Refining a DC component is trivial.
if (zigStart == 0)
@@ -1918,7 +1970,7 @@ namespace ImageSharp.Formats
{
bool done = false;
int z = 0;
- byte val = this.DecodeHuffman(h);
+ byte val = this.DecodeHuffman(ref h);
int val0 = val >> 4;
int val1 = val & 0x0f;
diff --git a/src/ImageSharp46/Formats/Jpg/JpegEncoderCore.cs b/src/ImageSharp46/Formats/Jpg/JpegEncoderCore.cs
index 9cb4fce26..9a282a72b 100644
--- a/src/ImageSharp46/Formats/Jpg/JpegEncoderCore.cs
+++ b/src/ImageSharp46/Formats/Jpg/JpegEncoderCore.cs
@@ -488,9 +488,9 @@ namespace ImageSharp.Formats
/// The quantization table index.
/// The previous DC value.
/// The
- private int WriteBlock(Block block, QuantIndex index, int prevDC)
+ private int WriteBlock(ref Block block, QuantIndex index, int prevDC)
{
- FDCT.Transform(block);
+ FDCT.Transform(ref block);
// Emit the DC delta.
int dc = Round(block[0], 8 * this.quant[(int)index][0]);
@@ -541,7 +541,8 @@ namespace ImageSharp.Formats
/// The red chroma block.
/// The blue chroma block.
// ReSharper disable StyleCop.SA1305
- private void ToYCbCr(PixelAccessor pixels, int x, int y, Block yBlock, Block cbBlock, Block crBlock)
+ private void ToYCbCr(PixelAccessor pixels, int x, int y,
+ ref Block yBlock, ref Block cbBlock, ref Block crBlock)
// ReSharper restore StyleCop.SA1305
where TColor : struct, IPackedPixel
where TPacked : struct
@@ -858,10 +859,10 @@ namespace ImageSharp.Formats
{
for (int x = 0; x < pixels.Width; x += 8)
{
- this.ToYCbCr(pixels, x, y, b, cb, cr);
- prevDCY = this.WriteBlock(b, QuantIndex.Luminance, prevDCY);
- prevDCCb = this.WriteBlock(cb, QuantIndex.Chrominance, prevDCCb);
- prevDCCr = this.WriteBlock(cr, QuantIndex.Chrominance, prevDCCr);
+ this.ToYCbCr(pixels, x, y, ref b, ref cb, ref cr);
+ prevDCY = this.WriteBlock(ref b, QuantIndex.Luminance, prevDCY);
+ prevDCCb = this.WriteBlock(ref cb, QuantIndex.Chrominance, prevDCCb);
+ prevDCCr = this.WriteBlock(ref cr, QuantIndex.Chrominance, prevDCCr);
}
}
}
@@ -902,14 +903,14 @@ namespace ImageSharp.Formats
int xOff = (i & 1) * 8;
int yOff = (i & 2) * 4;
- this.ToYCbCr(pixels, x + xOff, y + yOff, b, cb[i], cr[i]);
- prevDCY = this.WriteBlock(b, QuantIndex.Luminance, prevDCY);
+ this.ToYCbCr(pixels, x + xOff, y + yOff, ref b, ref cb[i], ref cr[i]);
+ prevDCY = this.WriteBlock(ref b, QuantIndex.Luminance, prevDCY);
}
this.Scale16X16To8X8(b, cb);
- prevDCCb = this.WriteBlock(b, QuantIndex.Chrominance, prevDCCb);
+ prevDCCb = this.WriteBlock(ref b, QuantIndex.Chrominance, prevDCCb);
this.Scale16X16To8X8(b, cr);
- prevDCCr = this.WriteBlock(b, QuantIndex.Chrominance, prevDCCr);
+ prevDCCr = this.WriteBlock(ref b, QuantIndex.Chrominance, prevDCCr);
}
}
}
diff --git a/src/ImageSharp46/ImageSharp46.csproj b/src/ImageSharp46/ImageSharp46.csproj
index bf7829e22..e88dbb0e2 100644
--- a/src/ImageSharp46/ImageSharp46.csproj
+++ b/src/ImageSharp46/ImageSharp46.csproj
@@ -86,7 +86,10 @@
True
-
+
+ ..\..\packages\System.Numerics.Vectors.4.1.1\lib\net46\System.Numerics.Vectors.dll
+ True
+
..\..\packages\System.Runtime.CompilerServices.Unsafe.4.0.0\lib\netstandard1.0\System.Runtime.CompilerServices.Unsafe.dll
True
diff --git a/src/ImageSharp46/packages.config b/src/ImageSharp46/packages.config
index b67050550..6ace6583b 100644
--- a/src/ImageSharp46/packages.config
+++ b/src/ImageSharp46/packages.config
@@ -23,6 +23,7 @@
+
diff --git a/tests/ConsoleBenchmark/App.config b/tests/ConsoleBenchmark/App.config
new file mode 100644
index 000000000..5bf749f82
--- /dev/null
+++ b/tests/ConsoleBenchmark/App.config
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/ConsoleBenchmark/ConsoleBenchmark.csproj b/tests/ConsoleBenchmark/ConsoleBenchmark.csproj
new file mode 100644
index 000000000..da38098fc
--- /dev/null
+++ b/tests/ConsoleBenchmark/ConsoleBenchmark.csproj
@@ -0,0 +1,89 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {8783E3A1-79F1-4E37-AA79-F06C48BED5E7}
+ Exe
+ Properties
+ ConsoleBenchmark
+ ConsoleBenchmark
+ v4.6.1
+ 512
+ true
+
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+
+
+
+
+ ..\..\packages\System.Numerics.Vectors.4.1.1\lib\net46\System.Numerics.Vectors.dll
+ True
+
+
+
+
+
+
+
+
+ ..\..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll
+ True
+
+
+ ..\..\packages\xunit.extensibility.core.2.1.0\lib\dotnet\xunit.core.dll
+ True
+
+
+ ..\..\packages\xunit.extensibility.execution.2.1.0\lib\net45\xunit.execution.desktop.dll
+ True
+
+
+
+
+
+
+
+
+
+
+
+
+ {fba0b5f6-09c2-4317-8ef6-6adb9b20e6b1}
+ ImageSharp46
+
+
+ {635e0a15-3893-4763-a7f6-fccff85bcca4}
+ ImageSharp.Tests46
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/ConsoleBenchmark/Program.cs b/tests/ConsoleBenchmark/Program.cs
new file mode 100644
index 000000000..52a53e316
--- /dev/null
+++ b/tests/ConsoleBenchmark/Program.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ImageSharp.Tests;
+using ImageSharp.Tests46.Benchmark;
+using Xunit.Abstractions;
+
+namespace ConsoleBenchmark
+{
+ class Program
+ {
+ private class Output : ITestOutputHelper
+ {
+ public void WriteLine(string message)
+ {
+ Console.WriteLine(message);
+ }
+
+ public void WriteLine(string format, params object[] args)
+ {
+ Console.WriteLine(format, args);
+ }
+ }
+
+ static void Main(string[] args)
+ {
+ DecodeJpegBenchmark benchmark = new DecodeJpegBenchmark(new Output());
+ benchmark.JpegCore(100);
+ //JpegSandbox test = new JpegSandbox(null);
+
+ //test.OpenJpeg_SaveBmp(TestImages.Jpeg.Calliphora);
+ }
+ }
+}
diff --git a/tests/ConsoleBenchmark/Properties/AssemblyInfo.cs b/tests/ConsoleBenchmark/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..5d8efdb2e
--- /dev/null
+++ b/tests/ConsoleBenchmark/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ConsoleBenchmark")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Sapa")]
+[assembly: AssemblyProduct("ConsoleBenchmark")]
+[assembly: AssemblyCopyright("Copyright © Sapa 2016")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("8783e3a1-79f1-4e37-aa79-f06c48bed5e7")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Bmp/Car.bmp b/tests/ConsoleBenchmark/TestImages/Formats/Bmp/Car.bmp
new file mode 100644
index 000000000..edaf3a8e4
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Bmp/Car.bmp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9d3a4a30cd67db6ded1e57126c7ba275404703e64b3dfb1c9c711128c15b0124
+size 810054
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Bmp/F.bmp b/tests/ConsoleBenchmark/TestImages/Formats/Bmp/F.bmp
new file mode 100644
index 000000000..d95598bef
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Bmp/F.bmp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6da008d2b285b2db946e6d4ebf8569b0ddd4a05ef273b38304cb65afccac87b3
+size 65502
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Bmp/neg_height.bmp b/tests/ConsoleBenchmark/TestImages/Formats/Bmp/neg_height.bmp
new file mode 100644
index 000000000..d0b99a902
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Bmp/neg_height.bmp
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:81437b88a5d92fcb545fae4991643a0c73d95d0277dac0b79074971780008c8c
+size 6220854
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Gif/giphy.gif b/tests/ConsoleBenchmark/TestImages/Formats/Gif/giphy.gif
new file mode 100644
index 000000000..029afdec6
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Gif/giphy.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3f42abd9f3e493a0acd5303ab0d37a6179835c5a14364a1f001abd9d9e906f96
+size 53655
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Gif/rings.gif b/tests/ConsoleBenchmark/TestImages/Formats/Gif/rings.gif
new file mode 100644
index 000000000..acd5d6339
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Gif/rings.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:716448da88152225767c024aac498f5b7562b6e8391907cefc9d03dba40050fd
+size 53435
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Jpg/Calliphora.jpg b/tests/ConsoleBenchmark/TestImages/Formats/Jpg/Calliphora.jpg
new file mode 100644
index 000000000..aa3fdef01
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Jpg/Calliphora.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:67172fcab405f914587b88cd1106328e6b24ab59d622ba509dcc99509951ff5c
+size 254766
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Jpg/Floorplan.jpeg b/tests/ConsoleBenchmark/TestImages/Formats/Jpg/Floorplan.jpeg
new file mode 100644
index 000000000..6f439d220
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Jpg/Floorplan.jpeg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:de00b34b78dfa0886c93d8dd5cede27b4940d5c620e44631e77e6dc8838befc3
+size 161577
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Jpg/cmyk.jpg b/tests/ConsoleBenchmark/TestImages/Formats/Jpg/cmyk.jpg
new file mode 100644
index 000000000..2fe8f0a61
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Jpg/cmyk.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:33e3546a64df7fa1d528441926421b193e399a83490a6307762fb7eee9640bf0
+size 611572
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Jpg/exif.jpg b/tests/ConsoleBenchmark/TestImages/Formats/Jpg/exif.jpg
new file mode 100644
index 000000000..cba862660
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Jpg/exif.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8a9d04b92d0de5836c59ede8ae421235488e4031e893e07b1fe7e4b78f6a9901
+size 32764
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Jpg/fb.jpg b/tests/ConsoleBenchmark/TestImages/Formats/Jpg/fb.jpg
new file mode 100644
index 000000000..7241890e2
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Jpg/fb.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:93bb4d6281dc1e845db57e836e0dca30b7a4062e81044efb27ad4d8b1a33130c
+size 15787
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Jpg/gamma_dalai_lama_gray.jpg b/tests/ConsoleBenchmark/TestImages/Formats/Jpg/gamma_dalai_lama_gray.jpg
new file mode 100644
index 000000000..c305caef4
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Jpg/gamma_dalai_lama_gray.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3d92a88b04518e266b98d9d2f5b4eb88f3f91c332d3397ea859bab8cabc41185
+size 84887
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Jpg/progress.jpg b/tests/ConsoleBenchmark/TestImages/Formats/Jpg/progress.jpg
new file mode 100644
index 000000000..30b214c22
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Jpg/progress.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a9a1f0da3c5b3a3e7e7f35abe9f5b458163b48ca56226227b3d3cffe06af1971
+size 44884
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Jpg/turtle.jpg b/tests/ConsoleBenchmark/TestImages/Formats/Jpg/turtle.jpg
new file mode 100644
index 000000000..07d96543b
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Jpg/turtle.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9e5c576b0c5e743cfd498b110305268ecbae63c62061ba6c7eb8e060728191f1
+size 55126
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Png/blur.png b/tests/ConsoleBenchmark/TestImages/Formats/Png/blur.png
new file mode 100644
index 000000000..2ac488b7c
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Png/blur.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:10df946d3d6a9832bacd9ac2587b890c348d17731412c8fd17c34f66f35d9c94
+size 183768
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Png/indexed.png b/tests/ConsoleBenchmark/TestImages/Formats/Png/indexed.png
new file mode 100644
index 000000000..f06e1cbd6
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Png/indexed.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:65566cde707c02757a26fb5fb7702be9c53f55c17a1748d81c384559de2d1173
+size 33529
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Png/pd.png b/tests/ConsoleBenchmark/TestImages/Formats/Png/pd.png
new file mode 100644
index 000000000..12fde3229
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Png/pd.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:91dd938fb916d368738826741551aea694b340ba3362f56200c5d3c5e5510267
+size 1406
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Png/pl.png b/tests/ConsoleBenchmark/TestImages/Formats/Png/pl.png
new file mode 100644
index 000000000..15e991284
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Png/pl.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:aa550e61fe276d2ebee8666d0cbb811449433edb76e01bcd38cb00c1aafc417e
+size 91
diff --git a/tests/ConsoleBenchmark/TestImages/Formats/Png/splash.png b/tests/ConsoleBenchmark/TestImages/Formats/Png/splash.png
new file mode 100644
index 000000000..ca4f86bce
--- /dev/null
+++ b/tests/ConsoleBenchmark/TestImages/Formats/Png/splash.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f4c13422913f1c1910f8dd607236e79b4a5c7053deb8ce1c8be8372eca7465fb
+size 245033
diff --git a/tests/ConsoleBenchmark/packages.config b/tests/ConsoleBenchmark/packages.config
new file mode 100644
index 000000000..50e8c3f1f
--- /dev/null
+++ b/tests/ConsoleBenchmark/packages.config
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/tests/ImageSharp.Benchmarks/Image/DecodeJpeg.cs b/tests/ImageSharp.Benchmarks/Image/DecodeJpeg.cs
index 6f2bd5e60..49af14763 100644
--- a/tests/ImageSharp.Benchmarks/Image/DecodeJpeg.cs
+++ b/tests/ImageSharp.Benchmarks/Image/DecodeJpeg.cs
@@ -26,17 +26,17 @@ namespace ImageSharp.Benchmarks.Image
}
}
- [Benchmark(Baseline = true, Description = "System.Drawing Jpeg")]
- public Size JpegSystemDrawing()
- {
- using (MemoryStream memoryStream = new MemoryStream(this.jpegBytes))
- {
- using (Image image = Image.FromStream(memoryStream))
- {
- return image.Size;
- }
- }
- }
+ //[Benchmark(Baseline = true, Description = "System.Drawing Jpeg")]
+ //public Size JpegSystemDrawing()
+ //{
+ // using (MemoryStream memoryStream = new MemoryStream(this.jpegBytes))
+ // {
+ // using (Image image = Image.FromStream(memoryStream))
+ // {
+ // return image.Size;
+ // }
+ // }
+ //}
[Benchmark(Description = "ImageSharp Jpeg")]
public CoreSize JpegCore()
diff --git a/tests/ImageSharp.Tests46/Benchmark/DecodeJpeg.cs b/tests/ImageSharp.Tests46/Benchmark/DecodeJpegBenchmark.cs
similarity index 91%
rename from tests/ImageSharp.Tests46/Benchmark/DecodeJpeg.cs
rename to tests/ImageSharp.Tests46/Benchmark/DecodeJpegBenchmark.cs
index 968ca070f..6de820f8b 100644
--- a/tests/ImageSharp.Tests46/Benchmark/DecodeJpeg.cs
+++ b/tests/ImageSharp.Tests46/Benchmark/DecodeJpegBenchmark.cs
@@ -14,20 +14,20 @@ namespace ImageSharp.Tests46.Benchmark
using CoreImage = ImageSharp.Image;
using CoreSize = ImageSharp.Size;
- public class DecodeJpeg
+ public class DecodeJpegBenchmark
{
private static byte[] jpegBytes = File.ReadAllBytes(TestImages.Jpeg.Calliphora);
private ITestOutputHelper _output;
- public DecodeJpeg(ITestOutputHelper output)
+ public DecodeJpegBenchmark(ITestOutputHelper output)
{
_output = output;
}
private void DoBenchmark(int times, Action action, [CallerMemberName]string method = null)
{
- _output.WriteLine($"Starting {method}.. ");
+ _output.WriteLine($"{method} x {times} ... ");
Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < times; i++)
{
diff --git a/tests/ImageSharp.Tests46/ImageSharp.Tests46.csproj b/tests/ImageSharp.Tests46/ImageSharp.Tests46.csproj
index 194d84be8..a1b4e990f 100644
--- a/tests/ImageSharp.Tests46/ImageSharp.Tests46.csproj
+++ b/tests/ImageSharp.Tests46/ImageSharp.Tests46.csproj
@@ -1,5 +1,6 @@
+
Debug
@@ -12,6 +13,8 @@
v4.6.1
512
+
+
true
@@ -37,7 +40,10 @@
-
+
+ ..\..\packages\System.Numerics.Vectors.4.1.1\lib\net46\System.Numerics.Vectors.dll
+ True
+
@@ -62,7 +68,7 @@
-
+
@@ -148,8 +154,16 @@
-
+
+
+
+
+
+ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.
+
+
+