Browse Source

Merge remote-tracking branch 'refs/remotes/origin/Core' into Core-Flava

# Conflicts:
#	src/ImageProcessorCore/Image.cs
#	tests/ImageProcessorCore.Tests/FileTestBase.cs


Former-commit-id: df31902b9996a1027ac83bb3f4712cbf81ae6bb0
Former-commit-id: cdea3844dbe5a16b5272519be80d38b3d2d0fae2
Former-commit-id: ec4ffaa3de3f3ebe483e2f632c495406cf6627f3
af/merge-core
James Jackson-South 10 years ago
parent
commit
79c7dbe99a
  1. 39
      src/ImageProcessorCore - Copy/Formats/Jpg/Block.cs
  2. 106
      src/ImageProcessorCore - Copy/Formats/Jpg/FDCT.cs
  3. 34
      src/ImageProcessorCore - Copy/Formats/Jpg/JpegDecoder.cs
  4. 2
      src/ImageProcessorCore - Copy/Formats/Jpg/JpegDecoderCore.cs.REMOVED.git-id
  5. 985
      src/ImageProcessorCore - Copy/Formats/Jpg/JpegEncoderCore.cs
  6. 3
      src/ImageProcessorCore - Copy/ImageExtensions.cs
  7. 2
      src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs
  8. 209
      src/ImageProcessorCore/Formats/Jpg/JpegConstants.cs
  9. 16
      tests/ImageProcessorCore.Tests/FileTestBase.cs

39
src/ImageProcessorCore - Copy/Formats/Jpg/Block.cs

@ -1,19 +1,44 @@
namespace ImageProcessorCore.Formats // <copyright file="Block.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageProcessorCore.Formats
{ {
/// <summary>
/// Represents an 8x8 block of coefficients to transform and encode.
/// </summary>
internal class Block internal class Block
{ {
public const int blockSize = 64; /// <summary>
private int[] _data; /// Gets the size of the block.
/// </summary>
public const int BlockSize = 64;
/// <summary>
/// The array of block data.
/// </summary>
private readonly int[] data;
/// <summary>
/// Initializes a new instance of the <see cref="Block"/> class.
/// </summary>
public Block() public Block()
{ {
_data = new int[blockSize]; this.data = new int[BlockSize];
} }
public int this[int idx] /// <summary>
/// Gets the pixel data at the given block index.
/// </summary>
/// <param name="index">The index of the data to return.</param>
/// <returns>
/// The <see cref="int"/>.
/// </returns>
public int this[int index]
{ {
get { return _data[idx]; } get { return this.data[index]; }
set { _data[idx] = value; } set { this.data[index] = value; }
} }
} }
} }

106
src/ImageProcessorCore - Copy/Formats/Jpg/FDCT.cs

@ -5,9 +5,14 @@
namespace ImageProcessorCore.Formats namespace ImageProcessorCore.Formats
{ {
/// <summary>
/// Performs a fast, forward descrete cosine transform against the given block
/// decomposing it into 64 orthogonal basis signals.
/// </summary>
internal class FDCT internal class FDCT
{ {
// Trigonometric constants in 13-bit fixed point format. // Trigonometric constants in 13-bit fixed point format.
// TODO: Rename and describe these.
private const int fix_0_298631336 = 2446; private const int fix_0_298631336 = 2446;
private const int fix_0_390180644 = 3196; private const int fix_0_390180644 = 3196;
private const int fix_0_541196100 = 4433; private const int fix_0_541196100 = 4433;
@ -20,27 +25,42 @@ namespace ImageProcessorCore.Formats
private const int fix_2_053119869 = 16819; private const int fix_2_053119869 = 16819;
private const int fix_2_562915447 = 20995; private const int fix_2_562915447 = 20995;
private const int fix_3_072711026 = 25172; private const int fix_3_072711026 = 25172;
private const int constBits = 13;
private const int pass1Bits = 2;
private const int centerJSample = 128;
// fdct performs a forward DCT on an 8x8 block of coefficients, including a /// <summary>
// level shift. /// The number of bits
public static void Transform(Block b) /// </summary>
private const int Bits = 13;
/// <summary>
/// The number of bits to shift by on the first pass.
/// </summary>
private const int Pass1Bits = 2;
/// <summary>
/// The value to shift by
/// </summary>
private const int CenterJSample = 128;
/// <summary>
/// Performs a forward DCT on an 8x8 block of coefficients, including a
/// level shift.
/// </summary>
/// <param name="block">The block.</param>
public static void Transform(Block block)
{ {
// Pass 1: process rows. // Pass 1: process rows.
for (int y = 0; y < 8; y++) for (int y = 0; y < 8; y++)
{ {
int y8 = y * 8; int y8 = y * 8;
int x0 = b[y8 + 0]; int x0 = block[y8];
int x1 = b[y8 + 1]; int x1 = block[y8 + 1];
int x2 = b[y8 + 2]; int x2 = block[y8 + 2];
int x3 = b[y8 + 3]; int x3 = block[y8 + 3];
int x4 = b[y8 + 4]; int x4 = block[y8 + 4];
int x5 = b[y8 + 5]; int x5 = block[y8 + 5];
int x6 = b[y8 + 6]; int x6 = block[y8 + 6];
int x7 = b[y8 + 7]; int x7 = block[y8 + 7];
int tmp0 = x0 + x7; int tmp0 = x0 + x7;
int tmp1 = x1 + x6; int tmp1 = x1 + x6;
@ -57,19 +77,19 @@ namespace ImageProcessorCore.Formats
tmp2 = x2 - x5; tmp2 = x2 - x5;
tmp3 = x3 - x4; tmp3 = x3 - x4;
b[y8] = (tmp10 + tmp11 - 8 * centerJSample) << pass1Bits; block[y8] = (tmp10 + tmp11 - (8 * CenterJSample)) << Pass1Bits;
b[y8 + 4] = (tmp10 - tmp11) << pass1Bits; block[y8 + 4] = (tmp10 - tmp11) << Pass1Bits;
int z1 = (tmp12 + tmp13) * fix_0_541196100; int z1 = (tmp12 + tmp13) * fix_0_541196100;
z1 += 1 << (constBits - pass1Bits - 1); z1 += 1 << (Bits - Pass1Bits - 1);
b[y8 + 2] = (z1 + tmp12 * fix_0_765366865) >> (constBits - pass1Bits); block[y8 + 2] = (z1 + (tmp12 * fix_0_765366865)) >> (Bits - Pass1Bits);
b[y8 + 6] = (z1 - tmp13 * fix_1_847759065) >> (constBits - pass1Bits); block[y8 + 6] = (z1 - (tmp13 * fix_1_847759065)) >> (Bits - Pass1Bits);
tmp10 = tmp0 + tmp3; tmp10 = tmp0 + tmp3;
tmp11 = tmp1 + tmp2; tmp11 = tmp1 + tmp2;
tmp12 = tmp0 + tmp2; tmp12 = tmp0 + tmp2;
tmp13 = tmp1 + tmp3; tmp13 = tmp1 + tmp3;
z1 = (tmp12 + tmp13) * fix_1_175875602; z1 = (tmp12 + tmp13) * fix_1_175875602;
z1 += 1 << (constBits - pass1Bits - 1); z1 += 1 << (Bits - Pass1Bits - 1);
tmp0 = tmp0 * fix_1_501321110; tmp0 = tmp0 * fix_1_501321110;
tmp1 = tmp1 * fix_3_072711026; tmp1 = tmp1 * fix_3_072711026;
tmp2 = tmp2 * fix_2_053119869; tmp2 = tmp2 * fix_2_053119869;
@ -81,45 +101,45 @@ namespace ImageProcessorCore.Formats
tmp12 += z1; tmp12 += z1;
tmp13 += z1; tmp13 += z1;
b[y8 + 1] = (tmp0 + tmp10 + tmp12) >> (constBits - pass1Bits); block[y8 + 1] = (tmp0 + tmp10 + tmp12) >> (Bits - Pass1Bits);
b[y8 + 3] = (tmp1 + tmp11 + tmp13) >> (constBits - pass1Bits); block[y8 + 3] = (tmp1 + tmp11 + tmp13) >> (Bits - Pass1Bits);
b[y8 + 5] = (tmp2 + tmp11 + tmp12) >> (constBits - pass1Bits); block[y8 + 5] = (tmp2 + tmp11 + tmp12) >> (Bits - Pass1Bits);
b[y8 + 7] = (tmp3 + tmp10 + tmp13) >> (constBits - pass1Bits); block[y8 + 7] = (tmp3 + tmp10 + tmp13) >> (Bits - Pass1Bits);
} }
// Pass 2: process columns. // Pass 2: process columns.
// We remove pass1Bits scaling, but leave results scaled up by an overall factor of 8. // We remove pass1Bits scaling, but leave results scaled up by an overall factor of 8.
for (int x = 0; x < 8; x++) for (int x = 0; x < 8; x++)
{ {
int tmp0 = b[x] + b[56 + x]; int tmp0 = block[x] + block[56 + x];
int tmp1 = b[8 + x] + b[48 + x]; int tmp1 = block[8 + x] + block[48 + x];
int tmp2 = b[16 + x] + b[40 + x]; int tmp2 = block[16 + x] + block[40 + x];
int tmp3 = b[24 + x] + b[32 + x]; int tmp3 = block[24 + x] + block[32 + x];
int tmp10 = tmp0 + tmp3 + (1 << (pass1Bits - 1)); int tmp10 = tmp0 + tmp3 + (1 << (Pass1Bits - 1));
int tmp12 = tmp0 - tmp3; int tmp12 = tmp0 - tmp3;
int tmp11 = tmp1 + tmp2; int tmp11 = tmp1 + tmp2;
int tmp13 = tmp1 - tmp2; int tmp13 = tmp1 - tmp2;
tmp0 = b[x] - b[56 + x]; tmp0 = block[x] - block[56 + x];
tmp1 = b[8 + x] - b[48 + x]; tmp1 = block[8 + x] - block[48 + x];
tmp2 = b[16 + x] - b[40 + x]; tmp2 = block[16 + x] - block[40 + x];
tmp3 = b[24 + x] - b[32 + x]; tmp3 = block[24 + x] - block[32 + x];
b[x] = (tmp10 + tmp11) >> pass1Bits; block[x] = (tmp10 + tmp11) >> Pass1Bits;
b[32 + x] = (tmp10 - tmp11) >> pass1Bits; block[32 + x] = (tmp10 - tmp11) >> Pass1Bits;
int z1 = (tmp12 + tmp13) * fix_0_541196100; int z1 = (tmp12 + tmp13) * fix_0_541196100;
z1 += 1 << (constBits + pass1Bits - 1); z1 += 1 << (Bits + Pass1Bits - 1);
b[16 + x] = (z1 + tmp12 * fix_0_765366865) >> (constBits + pass1Bits); block[16 + x] = (z1 + (tmp12 * fix_0_765366865)) >> (Bits + Pass1Bits);
b[48 + x] = (z1 - tmp13 * fix_1_847759065) >> (constBits + pass1Bits); block[48 + x] = (z1 - (tmp13 * fix_1_847759065)) >> (Bits + Pass1Bits);
tmp10 = tmp0 + tmp3; tmp10 = tmp0 + tmp3;
tmp11 = tmp1 + tmp2; tmp11 = tmp1 + tmp2;
tmp12 = tmp0 + tmp2; tmp12 = tmp0 + tmp2;
tmp13 = tmp1 + tmp3; tmp13 = tmp1 + tmp3;
z1 = (tmp12 + tmp13) * fix_1_175875602; z1 = (tmp12 + tmp13) * fix_1_175875602;
z1 += 1 << (constBits + pass1Bits - 1); z1 += 1 << (Bits + Pass1Bits - 1);
tmp0 = tmp0 * fix_1_501321110; tmp0 = tmp0 * fix_1_501321110;
tmp1 = tmp1 * fix_3_072711026; tmp1 = tmp1 * fix_3_072711026;
tmp2 = tmp2 * fix_2_053119869; tmp2 = tmp2 * fix_2_053119869;
@ -131,10 +151,10 @@ namespace ImageProcessorCore.Formats
tmp12 += z1; tmp12 += z1;
tmp13 += z1; tmp13 += z1;
b[8 + x] = (tmp0 + tmp10 + tmp12) >> (constBits + pass1Bits); block[8 + x] = (tmp0 + tmp10 + tmp12) >> (Bits + Pass1Bits);
b[24 + x] = (tmp1 + tmp11 + tmp13) >> (constBits + pass1Bits); block[24 + x] = (tmp1 + tmp11 + tmp13) >> (Bits + Pass1Bits);
b[40 + x] = (tmp2 + tmp11 + tmp12) >> (constBits + pass1Bits); block[40 + x] = (tmp2 + tmp11 + tmp12) >> (Bits + Pass1Bits);
b[56 + x] = (tmp3 + tmp10 + tmp13) >> (constBits + pass1Bits); block[56 + x] = (tmp3 + tmp10 + tmp13) >> (Bits + Pass1Bits);
} }
} }
} }

34
src/ImageProcessorCore - Copy/Formats/Jpg/JpegDecoder.cs

@ -7,7 +7,6 @@ namespace ImageProcessorCore.Formats
{ {
using System; using System;
using System.IO; using System.IO;
using System.Threading.Tasks;
/// <summary> /// <summary>
/// Image decoder for generating an image out of a jpg stream. /// Image decoder for generating an image out of a jpg stream.
@ -96,39 +95,6 @@ namespace ImageProcessorCore.Formats
JpegDecoderCore decoder = new JpegDecoderCore(); JpegDecoderCore decoder = new JpegDecoderCore();
decoder.Decode(stream, image, false); decoder.Decode(stream, image, false);
// TODO: When nComp is 3 we set the ImageBase pixels internally, Eventually we should
// do the same here
if (decoder.nComp == 1)
{
int pixelWidth = decoder.width;
int pixelHeight = decoder.height;
float[] pixels = new float[pixelWidth * pixelHeight * 4];
Parallel.For(
0,
pixelHeight,
y =>
{
var yoff = decoder.img1.get_row_offset(y);
for (int x = 0; x < pixelWidth; x++)
{
int offset = ((y * pixelWidth) + x) * 4;
pixels[offset + 0] = decoder.img1.pixels[yoff + x] / 255f;
pixels[offset + 1] = decoder.img1.pixels[yoff + x] / 255f;
pixels[offset + 2] = decoder.img1.pixels[yoff + x] / 255f;
pixels[offset + 3] = 1;
}
});
image.SetPixels(pixelWidth, pixelHeight, pixels);
}
else if (decoder.nComp != 3)
{
throw new NotSupportedException("JpegDecoder only supports RGB and Grayscale color spaces.");
}
} }
/// <summary> /// <summary>

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

@ -1 +1 @@
07d53b1f9ee1e867cfd8bb664c2cf3f31c0e8289 7a5076971068e0f389da2fb1e8b25216f4049718

985
src/ImageProcessorCore - Copy/Formats/Jpg/JpegEncoderCore.cs

File diff suppressed because it is too large

3
src/ImageProcessorCore - Copy/ImageExtensions.cs

@ -116,7 +116,7 @@ namespace ImageProcessorCore
/// <returns>The <see cref="Image"/>.</returns> /// <returns>The <see cref="Image"/>.</returns>
public static Image Process(this Image source, int width, int height, Rectangle sourceRectangle, Rectangle targetRectangle, IImageSampler sampler) public static Image Process(this Image source, int width, int height, Rectangle sourceRectangle, Rectangle targetRectangle, IImageSampler sampler)
{ {
return PerformAction(source, false, (sourceImage, targetImage) => sampler.Apply(targetImage, sourceImage, width, height, targetRectangle, sourceRectangle)); return PerformAction(source, false, (sourceImage, targetImage) => sampler.Apply(targetImage, sourceImage, width, height, targetRectangle, sourceRectangle));
} }
/// <summary> /// <summary>
@ -135,6 +135,7 @@ namespace ImageProcessorCore
{ {
// Several properties require copying // Several properties require copying
// TODO: Check why we need to set these? // TODO: Check why we need to set these?
Quality = source.Quality,
HorizontalResolution = source.HorizontalResolution, HorizontalResolution = source.HorizontalResolution,
VerticalResolution = source.VerticalResolution, VerticalResolution = source.VerticalResolution,
CurrentImageFormat = source.CurrentImageFormat, CurrentImageFormat = source.CurrentImageFormat,

2
src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs

@ -53,7 +53,7 @@ namespace ImageProcessorCore.Formats
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
/// <param name="image">The image, where the data should be set to. /// <param name="image">The image, where the data should be set to.
/// Cannot be null (Nothing in Visual Basic).</param> /// Cannot be null (Nothing in Visual Basic).</param>
/// <param name="stream">The this._stream, where the image should be /// <param name="stream">The stream, where the image should be
/// decoded from. Cannot be null (Nothing in Visual Basic).</param> /// decoded from. Cannot be null (Nothing in Visual Basic).</param>
/// <exception cref="ArgumentNullException"> /// <exception cref="ArgumentNullException">
/// <para><paramref name="image"/> is null.</para> /// <para><paramref name="image"/> is null.</para>

209
src/ImageProcessorCore/Formats/Jpg/JpegConstants.cs

@ -0,0 +1,209 @@
// <copyright file="JpegConstants.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageProcessorCore.Formats
{
/// <summary>
/// Defines jpeg constants defined in the specification.
/// </summary>
internal static class JpegConstants
{
/// <summary>
/// The maximum allowable length in each dimension of a jpeg image.
/// </summary>
public const ushort MaxLength = 65535;
/// <summary>
/// Represents high detail chroma horizontal subsampling.
/// </summary>
public static readonly byte[] ChromaFourFourFourHorizontal = { 0x11, 0x11, 0x11 };
/// <summary>
/// Represents high detail chroma vertical subsampling.
/// </summary>
public static readonly byte[] ChromaFourFourFourVertical = { 0x11, 0x11, 0x11 };
/// <summary>
/// Represents medium detail chroma horizontal subsampling.
/// </summary>
public static readonly byte[] ChromaFourTwoTwoHorizontal = { 0x22, 0x11, 0x11 };
/// <summary>
/// Represents medium detail chroma vertical subsampling.
/// </summary>
public static readonly byte[] ChromaFourTwoTwoVertical = { 0x11, 0x11, 0x11 };
/// <summary>
/// Represents low detail chroma horizontal subsampling.
/// </summary>
public static readonly byte[] ChromaFourTwoZeroHorizontal = { 0x22, 0x11, 0x11 };
/// <summary>
/// Represents low detail chroma vertical subsampling.
/// </summary>
public static readonly byte[] ChromaFourTwoZeroVertical = { 0x22, 0x11, 0x11 };
/// <summary>
/// Describes component ids for start of frame components.
/// </summary>
internal static class Components
{
/// <summary>
/// The YCbCr luminance component id.
/// </summary>
public const byte Y = 1;
/// <summary>
/// The YCbCr chroma component id.
/// </summary>
public const byte Cb = 2;
/// <summary>
/// The YCbCr chroma component id.
/// </summary>
public const byte Cr = 3;
/// <summary>
/// The YIQ x coordinate component id.
/// </summary>
public const byte I = 4;
/// <summary>
/// The YIQ y coordinate component id.
/// </summary>
public const byte Q = 5;
}
/// <summary>
/// Describes common Jpeg markers
/// </summary>
internal static class Markers
{
/// <summary>
/// Marker prefix. Next byte is a marker.
/// </summary>
public const byte XFF = 0xff;
/// <summary>
/// Start of Image
/// </summary>
public const byte SOI = 0xd8;
/// <summary>
/// Start of Frame (baseline DCT)
/// <remarks>
/// Indicates that this is a baseline DCT-based JPEG, and specifies the width, height, number of components,
/// and component subsampling (e.g., 4:2:0).
/// </remarks>
/// </summary>
public const byte SOF0 = 0xc0;
/// <summary>
/// Start Of Frame (Extended Sequential DCT)
/// <remarks>
/// Indicates that this is a progressive DCT-based JPEG, and specifies the width, height, number of components,
/// and component subsampling (e.g., 4:2:0).
/// </remarks>
/// </summary>
public const byte SOF1 = 0xc1;
/// <summary>
/// Start Of Frame (progressive DCT)
/// <remarks>
/// Indicates that this is a progressive DCT-based JPEG, and specifies the width, height, number of components,
/// and component subsampling (e.g., 4:2:0).
/// </remarks>
/// </summary>
public const byte SOF2 = 0xc2;
/// <summary>
/// Define Huffman Table(s)
/// <remarks>
/// Specifies one or more Huffman tables.
/// </remarks>
/// </summary>
public const byte DHT = 0xc4;
/// <summary>
/// Define Quantization Table(s)
/// <remarks>
/// Specifies one or more quantization tables.
/// </remarks>
/// </summary>
public const byte DQT = 0xdb;
/// <summary>
/// Define Restart Interval
/// <remarks>
/// Specifies the interval between RSTn markers, in macroblocks. This marker is followed by two bytes
/// indicating the fixed size so it can be treated like any other variable size segment.
/// </remarks>
/// </summary>
public const byte DRI = 0xdd;
/// <summary>
/// Define First Restart
/// <remarks>
/// Inserted every r macroblocks, where r is the restart interval set by a DRI marker.
/// Not used if there was no DRI marker. The low three bits of the marker code cycle in value from 0 to 7.
/// </remarks>
/// </summary>
public const byte RST0 = 0xd0;
/// <summary>
/// Define Eigth Restart
/// <remarks>
/// Inserted every r macroblocks, where r is the restart interval set by a DRI marker.
/// Not used if there was no DRI marker. The low three bits of the marker code cycle in value from 0 to 7.
/// </remarks>
/// </summary>
public const byte RST7 = 0xd7;
/// <summary>
/// Start of Scan
/// <remarks>
/// Begins a top-to-bottom scan of the image. In baseline DCT JPEG images, there is generally a single scan.
/// Progressive DCT JPEG images usually contain multiple scans. This marker specifies which slice of data it
/// will contain, and is immediately followed by entropy-coded data.
/// </remarks>
/// </summary>
public const byte SOS = 0xda;
/// <summary>
/// Comment
/// <remarks>
/// Contains a text comment.
/// </remarks>
/// </summary>
public const byte COM = 0xfe;
/// <summary>
/// End of Image
/// </summary>
public const byte EOI = 0xd9;
/// <summary>
/// Application specific marker for marking the jpeg format.
/// <see href="http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/JPEG.html"/>
/// </summary>
public const byte APP0 = 0xe0;
/// <summary>
/// Application specific marker for marking where to store metadata.
/// </summary>
public const byte APP1 = 0xe1;
/// <summary>
/// Application specific marker used by Adobe for storing encoding information for DCT filters.
/// </summary>
public const byte APP14 = 0xee;
/// <summary>
/// Application specific marker used by GraphicConverter to store JPEG quality.
/// </summary>
public const byte APP15 = 0xef;
}
}
}

16
tests/ImageProcessorCore.Tests/FileTestBase.cs

@ -19,17 +19,17 @@ namespace ImageProcessorCore.Tests
/// </summary> /// </summary>
protected static readonly List<string> Files = new List<string> protected static readonly List<string> Files = new List<string>
{ {
//"TestImages/Formats/Jpg/Floorplan.jpeg", // Perf: Enable for local testing only "TestImages/Formats/Jpg/Floorplan.jpeg", // Perf: Enable for local testing only
//"TestImages/Formats/Jpg/Calliphora.jpg", "TestImages/Formats/Jpg/Calliphora.jpg",
//"TestImages/Formats/Jpg/fb.jpg", // Perf: Enable for local testing only "TestImages/Formats/Jpg/fb.jpg", // Perf: Enable for local testing only
//"TestImages/Formats/Jpg/progress.jpg", // Perf: Enable for local testing only "TestImages/Formats/Jpg/progress.jpg", // Perf: Enable for local testing only
//"TestImages/Formats/Jpg/gamma_dalai_lama_gray.jpg", // Perf: Enable for local testing only //"TestImages/Formats/Jpg/gamma_dalai_lama_gray.jpg", // Perf: Enable for local testing only
"TestImages/Formats/Bmp/Car.bmp", //"TestImages/Formats/Bmp/Car.bmp",
//"TestImages/Formats/Bmp/neg_height.bmp", // Perf: Enable for local testing only // "TestImages/Formats/Bmp/neg_height.bmp", // Perf: Enable for local testing only
//"TestImages/Formats/Png/blur.png", // Perf: Enable for local testing only //"TestImages/Formats/Png/blur.png", // Perf: Enable for local testing only
//"TestImages/Formats/Png/indexed.png", // Perf: Enable for local testing only //"TestImages/Formats/Png/indexed.png", // Perf: Enable for local testing only
"TestImages/Formats/Png/splash.png", //"TestImages/Formats/Png/splash.png",
"TestImages/Formats/Gif/rings.gif", //"TestImages/Formats/Gif/rings.gif",
//"TestImages/Formats/Gif/giphy.gif" // Perf: Enable for local testing only //"TestImages/Formats/Gif/giphy.gif" // Perf: Enable for local testing only
}; };

Loading…
Cancel
Save