Browse Source

moved Jpeg classes to separate folders

pull/58/head
antonfirsov 9 years ago
parent
commit
61ba0e70b9
  1. 2
      src/ImageSharp/Formats/Jpg/Components/Block8x8F.cs
  2. 2
      src/ImageSharp/Formats/Jpg/Components/Decoder/Bits.cs
  3. 2
      src/ImageSharp/Formats/Jpg/Components/Decoder/Bytes.cs
  4. 2
      src/ImageSharp/Formats/Jpg/Components/Decoder/Component.cs
  5. 2
      src/ImageSharp/Formats/Jpg/Components/Decoder/GrayImage.cs
  6. 4
      src/ImageSharp/Formats/Jpg/Components/Decoder/HuffmanTree.cs
  7. 2
      src/ImageSharp/Formats/Jpg/Components/Decoder/YCbCrImage.cs
  8. 2
      src/ImageSharp/Formats/Jpg/Components/Encoder/HuffIndex.cs
  9. 2
      src/ImageSharp/Formats/Jpg/Components/Encoder/HuffmanLut.cs
  10. 2
      src/ImageSharp/Formats/Jpg/Components/Encoder/HuffmanSpec.cs
  11. 2
      src/ImageSharp/Formats/Jpg/Components/Encoder/QuantIndex.cs
  12. 55
      src/ImageSharp/Formats/Jpg/JpegDecoderCore.cs
  13. 11
      src/ImageSharp/Formats/Jpg/JpegEncoderCore.cs
  14. 2
      src/ImageSharp/Formats/Jpg/Utils/JpegUtils.cs
  15. 2
      src/ImageSharp/Formats/Jpg/Utils/MutableSpan.cs
  16. 2
      src/ImageSharp/Formats/Jpg/Utils/MutableSpanExtensions.cs
  17. 1
      tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs
  18. 11
      tests/ImageSharp.Tests/Formats/Jpg/JpegTests.cs
  19. 1
      tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementations.cs
  20. 2
      tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs
  21. 4
      tests/ImageSharp.Tests/Formats/Jpg/UtilityTestClassBase.cs

2
src/ImageSharp/Formats/Jpg/Components/Block8x8F.cs

@ -11,6 +11,8 @@ namespace ImageSharp.Formats
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using ImageSharp.Formats.Jpg.Utils;
/// <summary> /// <summary>
/// DCT code Ported from https://github.com/norishigefukushima/dct_simd /// DCT code Ported from https://github.com/norishigefukushima/dct_simd
/// </summary> /// </summary>

2
src/ImageSharp/Formats/Jpg/Components/Bits.cs → src/ImageSharp/Formats/Jpg/Components/Decoder/Bits.cs

@ -3,7 +3,7 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
// </copyright> // </copyright>
namespace ImageSharp.Formats namespace ImageSharp.Formats.Jpg.Components.Decoder
{ {
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;

2
src/ImageSharp/Formats/Jpg/Components/Bytes.cs → src/ImageSharp/Formats/Jpg/Components/Decoder/Bytes.cs

@ -2,7 +2,7 @@
// Copyright (c) James Jackson-South and contributors. // Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
// </copyright> // </copyright>
namespace ImageSharp.Formats namespace ImageSharp.Formats.Jpg.Components.Decoder
{ {
using System; using System;
using System.Buffers; using System.Buffers;

2
src/ImageSharp/Formats/Jpg/Components/Component.cs → src/ImageSharp/Formats/Jpg/Components/Decoder/Component.cs

@ -3,7 +3,7 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
// </copyright> // </copyright>
namespace ImageSharp.Formats namespace ImageSharp.Formats.Jpg.Components.Decoder
{ {
/// <summary> /// <summary>
/// Represents a single color component /// Represents a single color component

2
src/ImageSharp/Formats/Jpg/Components/GrayImage.cs → src/ImageSharp/Formats/Jpg/Components/Decoder/GrayImage.cs

@ -3,7 +3,7 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
// </copyright> // </copyright>
namespace ImageSharp.Formats namespace ImageSharp.Formats.Jpg.Components.Decoder
{ {
/// <summary> /// <summary>
/// Represents a grayscale image /// Represents a grayscale image

4
src/ImageSharp/Formats/Jpg/Components/Huffman.cs → src/ImageSharp/Formats/Jpg/Components/Decoder/HuffmanTree.cs

@ -2,7 +2,7 @@
// Copyright (c) James Jackson-South and contributors. // Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
// </copyright> // </copyright>
namespace ImageSharp.Formats namespace ImageSharp.Formats.Jpg.Components.Decoder
{ {
using System; using System;
using System.Buffers; using System.Buffers;
@ -10,7 +10,7 @@ namespace ImageSharp.Formats
/// <summary> /// <summary>
/// Represents a Huffman tree /// Represents a Huffman tree
/// </summary> /// </summary>
internal struct Huffman : IDisposable internal struct HuffmanTree : IDisposable
{ {
/// <summary> /// <summary>
/// Gets or sets the number of codes in the tree. /// Gets or sets the number of codes in the tree.

2
src/ImageSharp/Formats/Jpg/Components/YCbCrImage.cs → src/ImageSharp/Formats/Jpg/Components/Decoder/YCbCrImage.cs

@ -3,7 +3,7 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
// </copyright> // </copyright>
namespace ImageSharp.Formats namespace ImageSharp.Formats.Jpg.Components.Decoder
{ {
/// <summary> /// <summary>
/// Represents an image made up of three color components (luminance, blue chroma, red chroma) /// Represents an image made up of three color components (luminance, blue chroma, red chroma)

2
src/ImageSharp/Formats/Jpg/Components/HuffIndex.cs → src/ImageSharp/Formats/Jpg/Components/Encoder/HuffIndex.cs

@ -1,4 +1,4 @@
namespace ImageSharp.Formats.Jpg.Components namespace ImageSharp.Formats.Jpg.Components.Encoder
{ {
/// <summary> /// <summary>
/// Enumerates the Huffman tables /// Enumerates the Huffman tables

2
src/ImageSharp/Formats/Jpg/Components/HuffmanLut.cs → src/ImageSharp/Formats/Jpg/Components/Encoder/HuffmanLut.cs

@ -1,4 +1,4 @@
namespace ImageSharp.Formats.Jpg.Components namespace ImageSharp.Formats.Jpg.Components.Encoder
{ {
/// <summary> /// <summary>
/// A compiled look-up table representation of a huffmanSpec. /// A compiled look-up table representation of a huffmanSpec.

2
src/ImageSharp/Formats/Jpg/Components/HuffmanSpec.cs → src/ImageSharp/Formats/Jpg/Components/Encoder/HuffmanSpec.cs

@ -1,4 +1,4 @@
namespace ImageSharp.Formats.Jpg.Components namespace ImageSharp.Formats.Jpg.Components.Encoder
{ {
/// <summary> /// <summary>
/// The Huffman encoding specifications. /// The Huffman encoding specifications.

2
src/ImageSharp/Formats/Jpg/Components/QuantIndex.cs → src/ImageSharp/Formats/Jpg/Components/Encoder/QuantIndex.cs

@ -1,4 +1,4 @@
namespace ImageSharp.Formats.Jpg.Components namespace ImageSharp.Formats.Jpg.Components.Encoder
{ {
/// <summary> /// <summary>
/// Enumerates the quantization tables /// Enumerates the quantization tables

55
src/ImageSharp/Formats/Jpg/JpegDecoderCore.cs

@ -11,6 +11,9 @@ namespace ImageSharp.Formats
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using ImageSharp.Formats.Jpg.Components.Decoder;
using ImageSharp.Formats.Jpg.Utils;
/// <summary> /// <summary>
/// Performs the jpeg decoding operation. /// Performs the jpeg decoding operation.
/// </summary> /// </summary>
@ -76,7 +79,7 @@ namespace ImageSharp.Formats
/// <summary> /// <summary>
/// The huffman trees /// The huffman trees
/// </summary> /// </summary>
private readonly Huffman[] huffmanTrees; private readonly HuffmanTree[] huffmanTrees;
/// <summary> /// <summary>
/// Quantization tables, in zigzag order. /// Quantization tables, in zigzag order.
@ -186,7 +189,7 @@ namespace ImageSharp.Formats
public JpegDecoderCore() 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.huffmanTrees = new HuffmanTree[(MaxTc + 1) * (MaxTh + 1)];
this.quantizationTables = new Block8x8F[MaxTq + 1]; this.quantizationTables = new Block8x8F[MaxTq + 1];
this.temp = new byte[2 * Block8x8F.ScalarCount]; this.temp = new byte[2 * Block8x8F.ScalarCount];
@ -546,42 +549,42 @@ namespace ImageSharp.Formats
} }
} }
private void ProcessDefineHuffmanTablesMarkerLoop(ref Huffman huffman, ref int remaining) private void ProcessDefineHuffmanTablesMarkerLoop(ref HuffmanTree huffmanTree, ref int remaining)
{ {
// Read nCodes and huffman.Valuess (and derive h.Length). // Read nCodes and huffman.Valuess (and derive h.Length).
// nCodes[i] is the number of codes with code length i. // nCodes[i] is the number of codes with code length i.
// h.Length is the total number of codes. // h.Length is the total number of codes.
huffman.Length = 0; huffmanTree.Length = 0;
int[] ncodes = new int[MaxCodeLength]; int[] ncodes = new int[MaxCodeLength];
for (int i = 0; i < ncodes.Length; i++) for (int i = 0; i < ncodes.Length; i++)
{ {
ncodes[i] = this.temp[i + 1]; ncodes[i] = this.temp[i + 1];
huffman.Length += ncodes[i]; huffmanTree.Length += ncodes[i];
} }
if (huffman.Length == 0) if (huffmanTree.Length == 0)
{ {
throw new ImageFormatException("Huffman table has zero length"); throw new ImageFormatException("Huffman table has zero length");
} }
if (huffman.Length > MaxNCodes) if (huffmanTree.Length > MaxNCodes)
{ {
throw new ImageFormatException("Huffman table has excessive length"); throw new ImageFormatException("Huffman table has excessive length");
} }
remaining -= huffman.Length + 17; remaining -= huffmanTree.Length + 17;
if (remaining < 0) if (remaining < 0)
{ {
throw new ImageFormatException("DHT has wrong length"); throw new ImageFormatException("DHT has wrong length");
} }
this.ReadFull(huffman.Values, 0, huffman.Length); this.ReadFull(huffmanTree.Values, 0, huffmanTree.Length);
// Derive the look-up table. // Derive the look-up table.
for (int i = 0; i < huffman.Lut.Length; i++) for (int i = 0; i < huffmanTree.Lut.Length; i++)
{ {
huffman.Lut[i] = 0; huffmanTree.Lut[i] = 0;
} }
uint x = 0, code = 0; uint x = 0, code = 0;
@ -598,11 +601,11 @@ namespace ImageSharp.Formats
// The high 8 bits of lutValue are the encoded value. // The high 8 bits of lutValue are the encoded value.
// The low 8 bits are 1 plus the codeLength. // The low 8 bits are 1 plus the codeLength.
byte base2 = (byte)(code << (7 - i)); byte base2 = (byte)(code << (7 - i));
ushort lutValue = (ushort)((huffman.Values[x] << 8) | (2 + i)); ushort lutValue = (ushort)((huffmanTree.Values[x] << 8) | (2 + i));
for (int k = 0; k < 1 << (7 - i); k++) for (int k = 0; k < 1 << (7 - i); k++)
{ {
huffman.Lut[base2 | k] = lutValue; huffmanTree.Lut[base2 | k] = lutValue;
} }
code++; code++;
@ -617,15 +620,15 @@ namespace ImageSharp.Formats
int nc = ncodes[i]; int nc = ncodes[i];
if (nc == 0) if (nc == 0)
{ {
huffman.MinCodes[i] = -1; huffmanTree.MinCodes[i] = -1;
huffman.MaxCodes[i] = -1; huffmanTree.MaxCodes[i] = -1;
huffman.Indices[i] = -1; huffmanTree.Indices[i] = -1;
} }
else else
{ {
huffman.MinCodes[i] = c; huffmanTree.MinCodes[i] = c;
huffman.MaxCodes[i] = c + nc - 1; huffmanTree.MaxCodes[i] = c + nc - 1;
huffman.Indices[i] = index; huffmanTree.Indices[i] = index;
c += nc; c += nc;
index += nc; index += nc;
} }
@ -637,12 +640,12 @@ namespace ImageSharp.Formats
/// <summary> /// <summary>
/// Returns the next Huffman-coded value from the bit-stream, decoded according to the given value. /// Returns the next Huffman-coded value from the bit-stream, decoded according to the given value.
/// </summary> /// </summary>
/// <param name="huffman">The huffman value</param> /// <param name="huffmanTree">The huffman value</param>
/// <returns>The <see cref="byte"/></returns> /// <returns>The <see cref="byte"/></returns>
private byte DecodeHuffman(ref Huffman huffman) private byte DecodeHuffman(ref HuffmanTree huffmanTree)
{ {
// Copy stuff to the stack: // Copy stuff to the stack:
if (huffman.Length == 0) if (huffmanTree.Length == 0)
{ {
throw new ImageFormatException("Uninitialized Huffman table"); throw new ImageFormatException("Uninitialized Huffman table");
} }
@ -653,7 +656,7 @@ namespace ImageSharp.Formats
if (errorCode == ErrorCodes.NoError) if (errorCode == ErrorCodes.NoError)
{ {
ushort v = huffman.Lut[(this.bits.Accumulator >> (this.bits.UnreadBits - LutSize)) & 0xff]; ushort v = huffmanTree.Lut[(this.bits.Accumulator >> (this.bits.UnreadBits - LutSize)) & 0xff];
if (v != 0) if (v != 0)
{ {
@ -689,9 +692,9 @@ namespace ImageSharp.Formats
this.bits.UnreadBits--; this.bits.UnreadBits--;
this.bits.Mask >>= 1; this.bits.Mask >>= 1;
if (code <= huffman.MaxCodes[i]) if (code <= huffmanTree.MaxCodes[i])
{ {
return huffman.Values[huffman.Indices[i] + code - huffman.MinCodes[i]]; return huffmanTree.Values[huffmanTree.Indices[i] + code - huffmanTree.MinCodes[i]];
} }
code <<= 1; code <<= 1;
@ -1927,7 +1930,7 @@ namespace ImageSharp.Formats
/// <param name="zigStart">The zig-zag start index</param> /// <param name="zigStart">The zig-zag start index</param>
/// <param name="zigEnd">The zig-zag end index</param> /// <param name="zigEnd">The zig-zag end index</param>
/// <param name="delta">The low transform offset</param> /// <param name="delta">The low transform offset</param>
private void Refine(Block8x8F* b, ref Huffman h, int* unzigPtr, int zigStart, int zigEnd, int delta) private void Refine(Block8x8F* b, ref HuffmanTree h, int* unzigPtr, int zigStart, int zigEnd, int delta)
{ {
// Refining a DC component is trivial. // Refining a DC component is trivial.
if (zigStart == 0) if (zigStart == 0)

11
src/ImageSharp/Formats/Jpg/JpegEncoderCore.cs

@ -11,6 +11,8 @@ namespace ImageSharp.Formats
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using ImageSharp.Formats.Jpg.Components; using ImageSharp.Formats.Jpg.Components;
using ImageSharp.Formats.Jpg.Components.Encoder;
using ImageSharp.Formats.Jpg.Utils;
/// <summary> /// <summary>
/// Image encoder for writing an image to a stream as a jpeg. /// Image encoder for writing an image to a stream as a jpeg.
@ -402,7 +404,7 @@ namespace ImageSharp.Formats
private void Encode444<TColor>(PixelAccessor<TColor> pixels) private void Encode444<TColor>(PixelAccessor<TColor> pixels)
where TColor : struct, IPackedPixel, IEquatable<TColor> where TColor : struct, IPackedPixel, IEquatable<TColor>
{ {
// TODO: Need a JpegEncoderScanImpl<TColor> struct to encapsulate all this mess: // TODO: Need a JpegEncoderScanProcessor<TColor> struct to encapsulate all this mess:
Block8x8F b = default(Block8x8F); Block8x8F b = default(Block8x8F);
Block8x8F cb = default(Block8x8F); Block8x8F cb = default(Block8x8F);
Block8x8F cr = default(Block8x8F); Block8x8F cr = default(Block8x8F);
@ -740,7 +742,7 @@ namespace ImageSharp.Formats
private void WriteStartOfScan<TColor>(PixelAccessor<TColor> pixels) private void WriteStartOfScan<TColor>(PixelAccessor<TColor> pixels)
where TColor : struct, IPackedPixel, IEquatable<TColor> where TColor : struct, IPackedPixel, IEquatable<TColor>
{ {
// TODO: This method should be the entry point for a JpegEncoderScanImpl<TColor> struct // TODO: This method should be the entry point for a JpegEncoderScanProcessor<TColor> struct
// TODO: We should allow grayscale writing. // TODO: We should allow grayscale writing.
this.outputStream.Write(SosHeaderYCbCr, 0, SosHeaderYCbCr.Length); this.outputStream.Write(SosHeaderYCbCr, 0, SosHeaderYCbCr.Length);
@ -761,7 +763,8 @@ namespace ImageSharp.Formats
#pragma warning disable SA1201 // MethodShouldNotFollowAStruct #pragma warning disable SA1201 // MethodShouldNotFollowAStruct
/// <summary> /// <summary>
/// This struct belongs to Encode420. Much easeier to understand code if they are together. Why should I move it Up? :P /// Poor man's stackalloc for Encode420.
/// This struct belongs to Encode420. Much easeier to understand code if they are close to each other. Why should I move it Up? :P
/// </summary> /// </summary>
private struct BlockQuad private struct BlockQuad
{ {
@ -777,7 +780,7 @@ namespace ImageSharp.Formats
private void Encode420<TColor>(PixelAccessor<TColor> pixels) private void Encode420<TColor>(PixelAccessor<TColor> pixels)
where TColor : struct, IPackedPixel, IEquatable<TColor> where TColor : struct, IPackedPixel, IEquatable<TColor>
{ {
// TODO: Need a JpegEncoderScanImpl<TColor> struct to encapsulate all this mess: // TODO: Need a JpegEncoderScanProcessor<TColor> struct to encapsulate all this mess:
Block8x8F b = default(Block8x8F); Block8x8F b = default(Block8x8F);
BlockQuad cb = default(BlockQuad); BlockQuad cb = default(BlockQuad);

2
src/ImageSharp/Formats/Jpg/JpegUtils.cs → src/ImageSharp/Formats/Jpg/Utils/JpegUtils.cs

@ -2,7 +2,7 @@
// Copyright (c) James Jackson-South and contributors. // Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
// </copyright> // </copyright>
namespace ImageSharp.Formats namespace ImageSharp.Formats.Jpg.Utils
{ {
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;

2
src/ImageSharp/Formats/Jpg/Components/MutableSpan.cs → src/ImageSharp/Formats/Jpg/Utils/MutableSpan.cs

@ -3,7 +3,7 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
// </copyright> // </copyright>
namespace ImageSharp.Formats namespace ImageSharp.Formats.Jpg.Utils
{ {
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;

2
src/ImageSharp/Formats/Jpg/Components/MutableSpanExtensions.cs → src/ImageSharp/Formats/Jpg/Utils/MutableSpanExtensions.cs

@ -3,7 +3,7 @@
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
// </copyright> // </copyright>
namespace ImageSharp.Formats namespace ImageSharp.Formats.Jpg.Utils
{ {
using System.Numerics; using System.Numerics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;

1
tests/ImageSharp.Tests/Formats/Jpg/Block8x8FTests.cs

@ -9,6 +9,7 @@ namespace ImageSharp.Tests
using System.Numerics; using System.Numerics;
using ImageSharp.Formats; using ImageSharp.Formats;
using ImageSharp.Formats.Jpg.Utils;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;

11
tests/ImageSharp.Tests/Formats/Jpg/JpegTests.cs

@ -11,6 +11,8 @@ namespace ImageSharp.Tests
{ {
using System.Numerics; using System.Numerics;
using ImageSharp.Formats.Jpg.Utils;
public class JpegTests public class JpegTests
{ {
private ITestOutputHelper Output { get; } private ITestOutputHelper Output { get; }
@ -68,12 +70,11 @@ namespace ImageSharp.Tests
TestImages.Jpeg.Cmyk TestImages.Jpeg.Cmyk
}; };
private const PixelTypes BenchmarkPixels = PixelTypes.StandardImageClass; private const PixelTypes BenchmarkPixels = PixelTypes.StandardImageClass; //PixelTypes.Color | PixelTypes.Argb;
//PixelTypes.Color | PixelTypes.StandardImageClass | PixelTypes.Argb;
[Theory( //[Theory] // Benchmark, enable manually
Skip = "Benchmark, enable manually!"
)]
[WithFileCollection(nameof(BenchmarkFiles), BenchmarkPixels, JpegSubsample.Ratio420, 75)] [WithFileCollection(nameof(BenchmarkFiles), BenchmarkPixels, JpegSubsample.Ratio420, 75)]
[WithFileCollection(nameof(BenchmarkFiles), BenchmarkPixels, JpegSubsample.Ratio444, 75)] [WithFileCollection(nameof(BenchmarkFiles), BenchmarkPixels, JpegSubsample.Ratio444, 75)]
public void Benchmark_JpegEncoder<TColor>(TestImageProvider<TColor> provider, JpegSubsample subSample, int quality) public void Benchmark_JpegEncoder<TColor>(TestImageProvider<TColor> provider, JpegSubsample subSample, int quality)

1
tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementations.cs

@ -7,6 +7,7 @@ namespace ImageSharp.Tests
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using ImageSharp.Formats; using ImageSharp.Formats;
using ImageSharp.Formats.Jpg.Utils;
/// <summary> /// <summary>
/// This class contains simplified (unefficient) reference implementations to produce verification data for unit tests /// This class contains simplified (unefficient) reference implementations to produce verification data for unit tests

2
tests/ImageSharp.Tests/Formats/Jpg/ReferenceImplementationsTests.cs

@ -3,6 +3,8 @@ namespace ImageSharp.Tests.Formats.Jpg
{ {
using System.Numerics; using System.Numerics;
using ImageSharp.Formats; using ImageSharp.Formats;
using ImageSharp.Formats.Jpg.Utils;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;

4
tests/ImageSharp.Tests/Formats/Jpg/UtilityTestClassBase.cs

@ -9,7 +9,9 @@ namespace ImageSharp.Tests
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using ImageSharp.Formats.Jpg.Utils;
/// <summary> /// <summary>
/// Utility class to measure the execution of an operation. /// Utility class to measure the execution of an operation.
/// </summary> /// </summary>

Loading…
Cancel
Save