diff --git a/src/ImageSharp/Formats/Jpeg/Common/IJpegComponent.cs b/src/ImageSharp/Formats/Jpeg/Common/IJpegComponent.cs
new file mode 100644
index 0000000000..3dbd010223
--- /dev/null
+++ b/src/ImageSharp/Formats/Jpeg/Common/IJpegComponent.cs
@@ -0,0 +1,8 @@
+namespace SixLabors.ImageSharp.Formats.Jpeg.Common
+{
+ internal interface IJpegComponent
+ {
+ int WidthInBlocks { get; }
+ int HeightInBlocks { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/JpegBlockProcessor.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/JpegBlockProcessor.cs
index e58e7997d8..4182e18a97 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/JpegBlockProcessor.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/JpegBlockProcessor.cs
@@ -49,9 +49,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
{
OldComponent component = decoder.Components[this.componentIndex];
- for (int by = 0; by < component.BlockCountY; by++)
+ for (int by = 0; by < component.HeightInBlocks; by++)
{
- for (int bx = 0; bx < component.BlockCountX; bx++)
+ for (int bx = 0; bx < component.WidthInBlocks; bx++)
{
this.ProcessBlockColors(decoder, component, bx, by);
}
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OldComponent.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OldComponent.cs
index 90f4c60ee8..bd3667e235 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OldComponent.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/Components/Decoder/OldComponent.cs
@@ -11,7 +11,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
/// Represents a single color component
///
- internal class OldComponent : IDisposable
+ internal class OldComponent : IDisposable, IJpegComponent
{
public OldComponent(byte identifier, int index)
{
@@ -55,12 +55,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
///
/// Gets the number of blocks for this component along the X axis
///
- public int BlockCountX { get; private set; }
+ public int WidthInBlocks { get; private set; }
///
/// Gets the number of blocks for this component along the Y axis
///
- public int BlockCountY { get; private set; }
+ public int HeightInBlocks { get; private set; }
public ref Block8x8 GetBlockReference(int bx, int by)
{
@@ -73,9 +73,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder
/// The instance
public void InitializeBlocks(OldJpegDecoderCore decoder)
{
- this.BlockCountX = decoder.MCUCountX * this.HorizontalFactor;
- this.BlockCountY = decoder.MCUCountY * this.VerticalFactor;
- this.SpectralBlocks = Buffer2D.CreateClean(this.BlockCountX, this.BlockCountY);
+ this.WidthInBlocks = decoder.MCUCountX * this.HorizontalFactor;
+ this.HeightInBlocks = decoder.MCUCountY * this.VerticalFactor;
+ this.SpectralBlocks = Buffer2D.CreateClean(this.WidthInBlocks, this.HeightInBlocks);
}
///
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/FrameComponent.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/FrameComponent.cs
index 8383f54549..8f050b6c63 100644
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/FrameComponent.cs
+++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/FrameComponent.cs
@@ -7,10 +7,12 @@ using SixLabors.ImageSharp.Memory;
namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
{
+ using SixLabors.ImageSharp.Formats.Jpeg.Common;
+
///
/// Represents a single frame component
///
- internal class FrameComponent : IDisposable
+ internal class FrameComponent : IDisposable, IJpegComponent
{
#pragma warning disable SA1401 // Fields should be private
@@ -56,12 +58,12 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
///
/// Gets the number of blocks per line
///
- public int BlocksPerLine { get; private set; }
+ public int WidthInBlocks { get; private set; }
///
/// Gets the number of blocks per column
///
- public int BlocksPerColumn { get; private set; }
+ public int HeightInBlocks { get; private set; }
///
/// Gets or sets the index for the DC Huffman table
@@ -88,10 +90,10 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
public void Init()
{
- this.BlocksPerLine = (int)MathF.Ceiling(
+ this.WidthInBlocks = (int)MathF.Ceiling(
MathF.Ceiling(this.Frame.SamplesPerLine / 8F) * this.HorizontalFactor / this.Frame.MaxHorizontalFactor);
- this.BlocksPerColumn = (int)MathF.Ceiling(
+ this.HeightInBlocks = (int)MathF.Ceiling(
MathF.Ceiling(this.Frame.Scanlines / 8F) * this.VerticalFactor / this.Frame.MaxVerticalFactor);
this.BlocksPerLineForMcu = this.Frame.McusPerLine * this.HorizontalFactor;
@@ -106,7 +108,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetBlockBufferOffset(int row, int col)
{
- return 64 * (((this.BlocksPerLine + 1) * row) + col);
+ return 64 * (((this.WidthInBlocks + 1) * row) + col);
}
public Span GetBlockBuffer(int row, int col)
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/ScanDecoder.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/ScanDecoder.cs
index d8152c7b9b..42da5964fa 100644
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/ScanDecoder.cs
+++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/ScanDecoder.cs
@@ -87,7 +87,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
int mcuExpected;
if (componentsLength == 1)
{
- mcuExpected = components[this.compIndex].BlocksPerLine * components[this.compIndex].BlocksPerColumn;
+ mcuExpected = components[this.compIndex].WidthInBlocks * components[this.compIndex].HeightInBlocks;
}
else
{
@@ -468,8 +468,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DecodeBlockBaseline(ref HuffmanTable dcHuffmanTable, ref HuffmanTable acHuffmanTable, FrameComponent component, int mcu, Stream stream)
{
- int blockRow = mcu / component.BlocksPerLine;
- int blockCol = mcu % component.BlocksPerLine;
+ int blockRow = mcu / component.WidthInBlocks;
+ int blockCol = mcu % component.WidthInBlocks;
int offset = component.GetBlockBufferOffset(blockRow, blockCol);
this.DecodeBaseline(component, offset, ref dcHuffmanTable, ref acHuffmanTable, stream);
}
@@ -488,8 +488,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DecodeBlockDCFirst(ref HuffmanTable dcHuffmanTable, FrameComponent component, int mcu, Stream stream)
{
- int blockRow = mcu / component.BlocksPerLine;
- int blockCol = mcu % component.BlocksPerLine;
+ int blockRow = mcu / component.WidthInBlocks;
+ int blockCol = mcu % component.WidthInBlocks;
int offset = component.GetBlockBufferOffset(blockRow, blockCol);
this.DecodeDCFirst(component, offset, ref dcHuffmanTable, stream);
}
@@ -508,8 +508,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DecodeBlockDCSuccessive(FrameComponent component, int mcu, Stream stream)
{
- int blockRow = mcu / component.BlocksPerLine;
- int blockCol = mcu % component.BlocksPerLine;
+ int blockRow = mcu / component.WidthInBlocks;
+ int blockCol = mcu % component.WidthInBlocks;
int offset = component.GetBlockBufferOffset(blockRow, blockCol);
this.DecodeDCSuccessive(component, offset, stream);
}
@@ -528,8 +528,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DecodeBlockACFirst(ref HuffmanTable acHuffmanTable, FrameComponent component, int mcu, Stream stream)
{
- int blockRow = mcu / component.BlocksPerLine;
- int blockCol = mcu % component.BlocksPerLine;
+ int blockRow = mcu / component.WidthInBlocks;
+ int blockCol = mcu % component.WidthInBlocks;
int offset = component.GetBlockBufferOffset(blockRow, blockCol);
this.DecodeACFirst(component, offset, ref acHuffmanTable, stream);
}
@@ -548,8 +548,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DecodeBlockACSuccessive(ref HuffmanTable acHuffmanTable, FrameComponent component, int mcu, Stream stream)
{
- int blockRow = mcu / component.BlocksPerLine;
- int blockCol = mcu % component.BlocksPerLine;
+ int blockRow = mcu / component.WidthInBlocks;
+ int blockCol = mcu % component.WidthInBlocks;
int offset = component.GetBlockBufferOffset(blockRow, blockCol);
this.DecodeACSuccessive(component, offset, ref acHuffmanTable, stream);
}
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/JpegDecoderCore.cs
index 3357d03874..a9962a7b8e 100644
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/JpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/JpegDecoderCore.cs
@@ -298,8 +298,8 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
Scale = new System.Numerics.Vector2(
frameComponent.HorizontalFactor / (float)this.Frame.MaxHorizontalFactor,
frameComponent.VerticalFactor / (float)this.Frame.MaxVerticalFactor),
- BlocksPerLine = frameComponent.BlocksPerLine,
- BlocksPerColumn = frameComponent.BlocksPerColumn
+ BlocksPerLine = frameComponent.WidthInBlocks,
+ BlocksPerColumn = frameComponent.HeightInBlocks
};
// this.QuantizeAndInverseComponentData(ref component, frameComponent);
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
index a8128ca80b..eedc96fb30 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/JpegDecoderTests.cs
@@ -11,12 +11,15 @@ using Xunit;
namespace SixLabors.ImageSharp.Tests
{
using System;
+ using System.Collections.Generic;
using System.IO;
using System.Linq;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Jpeg;
+ using SixLabors.ImageSharp.Formats.Jpeg.Common;
using SixLabors.ImageSharp.Formats.Jpeg.GolangPort;
+ using SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison;
using SixLabors.ImageSharp.Tests.TestUtilities.ReferenceCodecs;
@@ -62,7 +65,53 @@ namespace SixLabors.ImageSharp.Tests
private static IImageDecoder OldJpegDecoder => new OldJpegDecoder();
private static IImageDecoder PdfJsJpegDecoder => new JpegDecoder();
-
+
+ private static void VerifyJpegComponent(IJpegComponent component, int expectedBlocksX, int expectedBlocksY)
+ {
+ Assert.Equal(component.WidthInBlocks, expectedBlocksX);
+ Assert.Equal(component.HeightInBlocks, expectedBlocksY);
+ }
+
+ private static void Verify3ComponentJpeg(
+ IEnumerable components,
+ int xBc0, int yBc0,
+ int xBc1, int yBc1,
+ int xBc2, int yBc2)
+ {
+ IJpegComponent[] c = components.ToArray();
+ Assert.Equal(3, components.Count());
+
+ VerifyJpegComponent(c[0], xBc0, yBc0);
+ VerifyJpegComponent(c[1], xBc1, yBc1);
+ VerifyJpegComponent(c[2], xBc2, yBc2);
+ }
+
+ [Fact]
+ public void ParseStream_BasicPropertiesAreCorrect1_Old()
+ {
+ byte[] bytes = TestFile.Create(TestImages.Jpeg.Progressive.Progress).Bytes;
+ using (var ms = new MemoryStream(bytes))
+ {
+ var decoder = new OldJpegDecoderCore(Configuration.Default, new JpegDecoder());
+ decoder.ParseStream(ms);
+
+ Verify3ComponentJpeg(decoder.Components, 43, 61, 22, 31, 22, 31);
+ }
+ }
+
+ [Fact]
+ public void ParseStream_BasicPropertiesAreCorrect1_PdfJs()
+ {
+ byte[] bytes = TestFile.Create(TestImages.Jpeg.Progressive.Progress).Bytes;
+ using (var ms = new MemoryStream(bytes))
+ {
+ var decoder = new JpegDecoderCore(Configuration.Default, new JpegDecoder());
+ decoder.ParseStream(ms);
+
+ Verify3ComponentJpeg(decoder.Frame.Components, 43, 61, 22, 31, 22, 31);
+ }
+ }
+
[Theory]
[WithFileCollection(nameof(BaselineTestJpegs), PixelTypes.Rgba32)]
public void DecodeBaselineJpeg(TestImageProvider provider)
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/LibJpegTools.cs b/tests/ImageSharp.Tests/Formats/Jpg/LibJpegTools.cs
index 851e600633..628e5966cb 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/LibJpegTools.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/LibJpegTools.cs
@@ -1,6 +1,8 @@
namespace SixLabors.ImageSharp.Tests
{
using System;
+ using System.Collections.Generic;
+ using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Numerics;
@@ -8,6 +10,7 @@ namespace SixLabors.ImageSharp.Tests
using BitMiracle.LibJpeg.Classic;
+ using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Formats.Jpeg.Common;
using SixLabors.ImageSharp.Formats.Jpeg.GolangPort;
using SixLabors.ImageSharp.Formats.Jpeg.GolangPort.Components.Decoder;
@@ -47,7 +50,7 @@ namespace SixLabors.ImageSharp.Tests
}
}
- private SpectralData(ComponentData[] components)
+ internal SpectralData(ComponentData[] components)
{
this.ComponentCount = components.Length;
this.Components = components;
@@ -272,7 +275,7 @@ namespace SixLabors.ImageSharp.Tests
}
}
- private void MakeBlock(short[] data, int y, int x)
+ internal void MakeBlock(short[] data, int y, int x)
{
this.MinVal = Math.Min(this.MinVal, data.Min());
this.MaxVal = Math.Max(this.MaxVal, data.Max());
@@ -302,8 +305,8 @@ namespace SixLabors.ImageSharp.Tests
public static ComponentData Load(OldComponent c)
{
var result = new ComponentData(
- c.BlockCountY,
- c.BlockCountX,
+ c.HeightInBlocks,
+ c.WidthInBlocks,
c.Index
);
@@ -454,9 +457,69 @@ namespace SixLabors.ImageSharp.Tests
return result / (count * Block8x8.Size);
}
+ private static string DumpToolFullPath => Path.Combine(
+ TestEnvironment.ToolsDirectoryFullPath,
+ @"jpeg\dump-jpeg-coeffs.exe");
+
public static void RunDumpJpegCoeffsTool(string sourceFile, string destFile)
{
- throw new NotImplementedException();
+ string args = $@"""{sourceFile}"" ""{destFile}""";
+ var process = Process.Start(DumpToolFullPath, args);
+ process.WaitForExit();
+ }
+
+ public static SpectralData ExtractSpectralData(string inputFile)
+ {
+ TestFile testFile = TestFile.Create(inputFile);
+
+ string outDir = TestEnvironment.CreateOutputDirectory(".Temp", $"JpegCoeffs");
+ string fn = $"{Path.GetFileName(inputFile)}-{new Random().Next(1000)}.dctcoeffs";
+ string coeffFileFullPath = Path.Combine(outDir, fn);
+
+ try
+ {
+ RunDumpJpegCoeffsTool(testFile.FullPath, coeffFileFullPath);
+ byte[] spectralBytes = File.ReadAllBytes(coeffFileFullPath);
+ File.Delete(coeffFileFullPath);
+
+ using (var ms = new MemoryStream(testFile.Bytes))
+ {
+ OldJpegDecoderCore decoder = new OldJpegDecoderCore(Configuration.Default, new JpegDecoder());
+ decoder.ParseStream(ms);
+
+ Span dump = new Span(spectralBytes).NonPortableCast();
+ int counter = 0;
+
+ OldComponent[] components = decoder.Components;
+ ComponentData[] result = new ComponentData[components.Length];
+
+ for (int i = 0; i < components.Length; i++)
+ {
+ OldComponent c = components[i];
+ ComponentData resultComponent = new ComponentData(c.HeightInBlocks, c.WidthInBlocks, i);
+ result[i] = resultComponent;
+
+ for (int y = 0; y < c.HeightInBlocks; y++)
+ {
+ for (int x = 0; x < c.WidthInBlocks; x++)
+ {
+ short[] block = dump.Slice(counter, 64).ToArray();
+ resultComponent.MakeBlock(block, y, x);
+ counter += 64;
+ }
+ }
+ }
+
+ return new SpectralData(result);
+ }
+ }
+ finally
+ {
+ if (File.Exists(coeffFileFullPath))
+ {
+ File.Delete(coeffFileFullPath);
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs
index dfa1d91046..49495d4e1a 100644
--- a/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs
+++ b/tests/ImageSharp.Tests/Formats/Jpg/SpectralJpegTests.cs
@@ -47,10 +47,28 @@ namespace SixLabors.ImageSharp.Tests
[Fact]
public void RunDumpJpegCoeffsTool()
{
+ if (!TestEnvironment.IsWindows) return;
+
string inputFile = TestFile.GetInputFileFullPath(TestImages.Jpeg.Progressive.Progress);
-
+ string outputDir = TestEnvironment.CreateOutputDirectory(nameof(SpectralJpegTests));
+ string outputFile = Path.Combine(outputDir, "progress.dctdump");
+
+ LibJpegTools.RunDumpJpegCoeffsTool(inputFile, outputFile);
+
+ Assert.True(File.Exists(outputFile));
}
+ [Theory]
+ [InlineData(TestImages.Jpeg.Baseline.Calliphora)]
+ [InlineData(TestImages.Jpeg.Progressive.Progress)]
+ public void ExtractSpectralData(string testImage)
+ {
+ LibJpegTools.SpectralData data = LibJpegTools.ExtractSpectralData(testImage);
+
+ Assert.True(data.ComponentCount == 3);
+ Assert.True(data.Components.Length == 3);
+ }
+
[Theory]
[WithFileCollection(nameof(BaselineTestJpegs), PixelTypes.Rgba32)]
public void BuildLibJpegSpectralResult(TestImageProvider provider)
diff --git a/tests/ImageSharp.Tests/Image/ImageRotationTests.cs b/tests/ImageSharp.Tests/Image/ImageRotationTests.cs
index bc9c28898f..0e7dc5917e 100644
--- a/tests/ImageSharp.Tests/Image/ImageRotationTests.cs
+++ b/tests/ImageSharp.Tests/Image/ImageRotationTests.cs
@@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.Tests
private static (Size original, Size rotated) Rotate(int angle)
{
var file = TestFile.Create(TestImages.Bmp.Car);
- using (var image = Image.Load(file.FilePath))
+ using (var image = Image.Load(file.FullPath))
{
Size original = image.Bounds().Size;
image.Mutate(x => x.Rotate(angle));
diff --git a/tests/ImageSharp.Tests/Image/ImageTests.cs b/tests/ImageSharp.Tests/Image/ImageTests.cs
index fa19557dff..a9952f5c48 100644
--- a/tests/ImageSharp.Tests/Image/ImageTests.cs
+++ b/tests/ImageSharp.Tests/Image/ImageTests.cs
@@ -34,7 +34,7 @@ namespace SixLabors.ImageSharp.Tests
public void ConstructorFileSystem()
{
TestFile file = TestFile.Create(TestImages.Bmp.Car);
- using (Image image = Image.Load(file.FilePath))
+ using (Image image = Image.Load(file.FullPath))
{
Assert.Equal(600, image.Width);
Assert.Equal(450, image.Height);
diff --git a/tests/ImageSharp.Tests/TestFile.cs b/tests/ImageSharp.Tests/TestFile.cs
index d3c40f86aa..f56802e548 100644
--- a/tests/ImageSharp.Tests/TestFile.cs
+++ b/tests/ImageSharp.Tests/TestFile.cs
@@ -38,39 +38,34 @@ namespace SixLabors.ImageSharp.Tests
///
private byte[] bytes;
- ///
- /// The file.
- ///
- private readonly string file;
-
///
/// Initializes a new instance of the class.
///
/// The file.
private TestFile(string file)
{
- this.file = file;
+ this.FullPath = file;
}
///
/// Gets the image bytes.
///
- public byte[] Bytes => this.bytes ?? (this.bytes = File.ReadAllBytes(this.file));
+ public byte[] Bytes => this.bytes ?? (this.bytes = File.ReadAllBytes(this.FullPath));
///
- /// The file name.
+ /// The full path to file.
///
- public string FilePath => this.file;
+ public string FullPath { get; }
///
/// The file name.
///
- public string FileName => Path.GetFileName(this.file);
+ public string FileName => Path.GetFileName(this.FullPath);
///
/// The file name without extension.
///
- public string FileNameWithoutExtension => Path.GetFileNameWithoutExtension(this.file);
+ public string FileNameWithoutExtension => Path.GetFileNameWithoutExtension(this.FullPath);
///
/// Gets the image with lazy initialization.
@@ -116,7 +111,7 @@ namespace SixLabors.ImageSharp.Tests
///
public string GetFileName(object value)
{
- return $"{this.FileNameWithoutExtension}-{value}{Path.GetExtension(this.file)}";
+ return $"{this.FileNameWithoutExtension}-{value}{Path.GetExtension(this.FullPath)}";
}
///
diff --git a/tests/Images/External b/tests/Images/External
index 086c854f00..fd428515bb 160000
--- a/tests/Images/External
+++ b/tests/Images/External
@@ -1 +1 @@
-Subproject commit 086c854f001e3bb1fa9085e76ba902171140dcc6
+Subproject commit fd428515bb3b125621c3b9518dfd07c6d919d3bf