Browse Source

Style Stalin

af/merge-core
antonfirsov 9 years ago
parent
commit
f3a3391cd6
  1. 6
      src/ImageSharp/Formats/Jpg/Components/Block8x8F.cs
  2. 2
      src/ImageSharp/Formats/Jpg/Components/Decoder/HuffmanTree.cs
  3. 6
      src/ImageSharp/Formats/Jpg/Components/Encoder/HuffIndex.cs
  4. 45
      src/ImageSharp/Formats/Jpg/Components/Encoder/HuffmanLut.cs
  5. 166
      src/ImageSharp/Formats/Jpg/Components/Encoder/HuffmanSpec.cs
  6. 12
      src/ImageSharp/Formats/Jpg/Components/Encoder/QuantIndex.cs
  7. 253
      src/ImageSharp/Formats/Jpg/JpegEncoderCore.cs
  8. 80
      src/ImageSharp/Formats/Jpg/Utils/JpegUtils.cs

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

@ -3,7 +3,6 @@
// Licensed under the Apache License, Version 2.0.
// </copyright>
// ReSharper disable InconsistentNaming
namespace ImageSharp.Formats
{
using System;
@ -19,6 +18,7 @@ namespace ImageSharp.Formats
internal partial struct Block8x8F
{
#pragma warning disable SA1204 // Static members must appear before non-static members
/// <summary>
/// Vector count
/// </summary>
@ -116,7 +116,7 @@ namespace ImageSharp.Formats
float* fPtr = (float*)blockPtr;
for (int i = 0; i < ScalarCount; i++)
{
dest[i] = (byte) *fPtr;
dest[i] = (byte)*fPtr;
fPtr++;
}
}
@ -146,7 +146,7 @@ namespace ImageSharp.Formats
Marshal.Copy((IntPtr)ptr, dest.Data, dest.Offset, ScalarCount);
}
}
/// <summary>
/// Copy raw 32bit floating point data to dest
/// </summary>

2
src/ImageSharp/Formats/Jpg/Components/Decoder/HuffmanTree.cs

@ -1,4 +1,4 @@
// <copyright file="Huffman.cs" company="James Jackson-South">
// <copyright file="HuffmanTree.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>

6
src/ImageSharp/Formats/Jpg/Components/Encoder/HuffIndex.cs

@ -1,4 +1,8 @@
namespace ImageSharp.Formats.Jpg.Components.Encoder
// <copyright file="HuffIndex.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Formats.Jpg.Components.Encoder
{
/// <summary>
/// Enumerates the Huffman tables

45
src/ImageSharp/Formats/Jpg/Components/Encoder/HuffmanLut.cs

@ -1,4 +1,9 @@
namespace ImageSharp.Formats.Jpg.Components.Encoder
// <copyright file="HuffmanLut.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Formats.Jpg.Components.Encoder
{
/// <summary>
/// A compiled look-up table representation of a huffmanSpec.
@ -9,9 +14,26 @@
internal struct HuffmanLut
{
/// <summary>
/// Initializes a new instance of the <see cref="HuffmanLut"/> class.
/// The compiled representations of theHuffmanSpec.
/// </summary>
public static readonly HuffmanLut[] TheHuffmanLut = new HuffmanLut[4];
/// <summary>
/// Initializes static members of the <see cref="HuffmanLut"/> struct.
/// </summary>
static HuffmanLut()
{
// Initialize the Huffman tables
for (int i = 0; i < HuffmanSpec.TheHuffmanSpecs.Length; i++)
{
TheHuffmanLut[i] = new HuffmanLut(HuffmanSpec.TheHuffmanSpecs[i]);
}
}
/// <summary>
/// Initializes a new instance of the <see cref="HuffmanLut"/> struct.
/// </summary>
/// <param name="spec">The encoding specifications.</param>
/// <param name="spec">dasd</param>
public HuffmanLut(HuffmanSpec spec)
{
int maxValue = 0;
@ -43,26 +65,9 @@
}
}
/// <summary>
/// Initialize static members
/// </summary>
static HuffmanLut()
{
// Initialize the Huffman tables
for (int i = 0; i < HuffmanSpec.TheHuffmanSpecs.Length; i++)
{
HuffmanLut.TheHuffmanLut[i] = new HuffmanLut(HuffmanSpec.TheHuffmanSpecs[i]);
}
}
/// <summary>
/// Gets the collection of huffman values.
/// </summary>
public uint[] Values { get; }
/// <summary>
/// The compiled representations of theHuffmanSpec.
/// </summary>
public static readonly HuffmanLut[] TheHuffmanLut = new HuffmanLut[4];
}
}

166
src/ImageSharp/Formats/Jpg/Components/Encoder/HuffmanSpec.cs

@ -1,35 +1,19 @@
namespace ImageSharp.Formats.Jpg.Components.Encoder
// <copyright file="HuffmanSpec.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Formats.Jpg.Components.Encoder
{
/// <summary>
/// The Huffman encoding specifications.
/// The Huffman encoding specifications.
/// </summary>
internal struct HuffmanSpec
{
/// <summary>
/// Gets count[i] - The number of codes of length i bits.
/// </summary>
public readonly byte[] Count;
/// <summary>
/// Gets value[i] - The decoded value of the codeword at the given index.
/// </summary>
public readonly byte[] Values;
/// <summary>
/// Initializes a new instance of the <see cref="HuffmanSpec"/> struct.
/// </summary>
/// <param name="count">The number of codes.</param>
/// <param name="values">The decoded values.</param>
public HuffmanSpec(byte[] count, byte[] values)
{
this.Count = count;
this.Values = values;
}
#pragma warning disable SA1118 // ParameterMustNotSpanMultipleLines
/// <summary>
/// The Huffman encoding specifications.
/// This encoder uses the same Huffman encoding for all images.
/// The Huffman encoding specifications.
/// This encoder uses the same Huffman encoding for all images.
/// </summary>
public static readonly HuffmanSpec[] TheHuffmanSpecs =
{
@ -37,76 +21,116 @@
new HuffmanSpec(
new byte[]
{
0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0
0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
0, 0, 0
},
new byte[]
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
}),
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
}),
new HuffmanSpec(
new byte[]
{
0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 125
0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0,
0, 1, 125
},
new byte[]
{
0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21,
0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71,
0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1,
0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72,
0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25,
0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a,
0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83,
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93,
0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3,
0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3,
0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3,
0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1,
0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa
0x01, 0x02, 0x03, 0x00, 0x04, 0x11,
0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13,
0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32,
0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1,
0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33,
0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38,
0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56,
0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65,
0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74,
0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83,
0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a,
0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6,
0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2,
0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9,
0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4,
0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1,
0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa
}),
new HuffmanSpec(
new byte[]
{
0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0
0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
0, 0, 0
},
new byte[]
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
}),
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11
}),
// Chrominance AC.
new HuffmanSpec(
new byte[]
{
0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 119
0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0,
1, 2, 119
},
new byte[]
{
0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31,
0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22,
0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1,
0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1,
0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18,
0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36,
0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47,
0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a,
0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a,
0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa,
0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba,
0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca,
0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa
0x00, 0x01, 0x02, 0x03, 0x11, 0x04,
0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51,
0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81,
0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1,
0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62,
0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1,
0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37,
0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46,
0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55,
0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64,
0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73,
0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a,
0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88,
0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4,
0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2,
0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9,
0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5,
0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3,
0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa
})
};
#pragma warning restore SA1118 // ParameterMustNotSpanMultipleLines
/// <summary>
/// Gets count[i] - The number of codes of length i bits.
/// </summary>
public readonly byte[] Count;
/// <summary>
/// Gets value[i] - The decoded value of the codeword at the given index.
/// </summary>
public readonly byte[] Values;
/// <summary>
/// Initializes a new instance of the <see cref="HuffmanSpec"/> struct.
/// </summary>
/// <param name="count">
/// The number of codes.
/// </param>
/// <param name="values">
/// The decoded values.
/// </param>
public HuffmanSpec(byte[] count, byte[] values)
{
this.Count = count;
this.Values = values;
}
}
}

12
src/ImageSharp/Formats/Jpg/Components/Encoder/QuantIndex.cs

@ -1,17 +1,21 @@
namespace ImageSharp.Formats.Jpg.Components.Encoder
// <copyright file="QuantIndex.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
namespace ImageSharp.Formats.Jpg.Components.Encoder
{
/// <summary>
/// Enumerates the quantization tables
/// Enumerates the quantization tables
/// </summary>
internal enum QuantIndex
{
/// <summary>
/// The luminance quantization table index
/// The luminance quantization table index
/// </summary>
Luminance = 0,
/// <summary>
/// The chrominance quantization table index
/// The chrominance quantization table index
/// </summary>
Chrominance = 1,
}

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

@ -10,22 +10,21 @@ namespace ImageSharp.Formats
using System.Numerics;
using System.Runtime.CompilerServices;
using ImageSharp.Formats.Jpg.Components;
using ImageSharp.Formats.Jpg.Components.Encoder;
using ImageSharp.Formats.Jpg.Utils;
/// <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.
/// </summary>
internal unsafe class JpegEncoderCore
{
/// <summary>
/// The number of quantization tables.
/// The number of quantization tables.
/// </summary>
private const int QuantizationTableCount = 2;
/// <summary>
/// Counts the number of bits needed to hold an integer.
/// Counts the number of bits needed to hold an integer.
/// </summary>
private static readonly uint[] BitCountLut =
{
@ -45,15 +44,15 @@ namespace ImageSharp.Formats
};
/// <summary>
/// The SOS (Start Of Scan) marker "\xff\xda" followed by 12 bytes:
/// - the marker length "\x00\x0c",
/// - the number of components "\x03",
/// - component 1 uses DC table 0 and AC table 0 "\x01\x00",
/// - component 2 uses DC table 1 and AC table 1 "\x02\x11",
/// - component 3 uses DC table 1 and AC table 1 "\x03\x11",
/// - the bytes "\x00\x3f\x00". Section B.2.3 of the spec says that for
/// sequential DCTs, those bytes (8-bit Ss, 8-bit Se, 4-bit Ah, 4-bit Al)
/// should be 0x00, 0x3f, 0x00&lt;&lt;4 | 0x00.
/// The SOS (Start Of Scan) marker "\xff\xda" followed by 12 bytes:
/// - the marker length "\x00\x0c",
/// - the number of components "\x03",
/// - component 1 uses DC table 0 and AC table 0 "\x01\x00",
/// - component 2 uses DC table 1 and AC table 1 "\x02\x11",
/// - component 3 uses DC table 1 and AC table 1 "\x03\x11",
/// - the bytes "\x00\x3f\x00". Section B.2.3 of the spec says that for
/// sequential DCTs, those bytes (8-bit Ss, 8-bit Se, 4-bit Ah, 4-bit Al)
/// should be 0x00, 0x3f, 0x00&lt;&lt;4 | 0x00.
/// </summary>
private static readonly byte[] SosHeaderYCbCr =
{
@ -78,10 +77,10 @@ namespace ImageSharp.Formats
};
/// <summary>
/// The unscaled quantization tables in zig-zag order. Each
/// encoder copies and scales the tables according to its quality parameter.
/// The values are derived from section K.1 after converting from natural to
/// zig-zag order.
/// The unscaled quantization tables in zig-zag order. Each
/// encoder copies and scales the tables according to its quality parameter.
/// The values are derived from section K.1 after converting from natural to
/// zig-zag order.
/// </summary>
private static readonly byte[,] UnscaledQuant =
{
@ -104,58 +103,69 @@ namespace ImageSharp.Formats
};
/// <summary>
/// A scratch buffer to reduce allocations.
/// A scratch buffer to reduce allocations.
/// </summary>
private readonly byte[] buffer = new byte[16];
/// <summary>
/// A buffer for reducing the number of stream writes when emitting Huffman tables. 64 seems to be enough.
/// A buffer for reducing the number of stream writes when emitting Huffman tables. 64 seems to be enough.
/// </summary>
private readonly byte[] emitBuffer = new byte[64];
/// <summary>
/// A buffer for reducing the number of stream writes when emitting Huffman tables. Max combined table lengths + identifier.
/// A buffer for reducing the number of stream writes when emitting Huffman tables. Max combined table lengths +
/// identifier.
/// </summary>
private readonly byte[] huffmanBuffer = new byte[179];
/// <summary>
/// The accumulated bits to write to the stream.
/// The accumulated bits to write to the stream.
/// </summary>
private uint accumulatedBits;
/// <summary>
/// The accumulated bit count.
/// The accumulated bit count.
/// </summary>
private uint bitCount;
/// <summary>
/// The scaled chrominance table, in zig-zag order.
/// The scaled chrominance table, in zig-zag order.
/// </summary>
private Block8x8F chrominanceQuantTable;
/// <summary>
/// The scaled luminance table, in zig-zag order.
/// The scaled luminance table, in zig-zag order.
/// </summary>
private Block8x8F luminanceQuantTable;
/// <summary>
/// The output stream. All attempted writes after the first error become no-ops.
/// The output stream. All attempted writes after the first error become no-ops.
/// </summary>
private Stream outputStream;
/// <summary>
/// The subsampling method to use.
/// The subsampling method to use.
/// </summary>
private JpegSubsample subsample;
/// <summary>
/// Encode writes the image to the jpeg baseline format with the given options.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <param name="image">The image to write from.</param>
/// <param name="stream">The stream to write to.</param>
/// <param name="quality">The quality.</param>
/// <param name="sample">The subsampling mode.</param>
/// <typeparam name="TColor">
/// The pixel format.
/// </typeparam>
/// <param name="image">
/// The image to write from.
/// </param>
/// <param name="stream">
/// The stream to write to.
/// </param>
/// <param name="quality">
/// The quality.
/// </param>
/// <param name="sample">
/// The subsampling mode.
/// </param>
public void Encode<TColor>(Image<TColor> image, Stream stream, int quality, JpegSubsample sample)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
@ -249,14 +259,30 @@ namespace ImageSharp.Formats
/// <summary>
/// Converts the 8x8 region of the image whose top-left corner is x,y to its YCbCr values.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <param name="pixels">The pixel accessor.</param>
/// <param name="x">The x-position within the image.</param>
/// <param name="y">The y-position within the image.</param>
/// <param name="yBlock">The luminance block.</param>
/// <param name="cbBlock">The red chroma block.</param>
/// <param name="crBlock">The blue chroma block.</param>
/// <param name="rgbBytes">Temporal <see cref="PixelArea{TColor}"/> provided by the caller</param>
/// <typeparam name="TColor">
/// The pixel format.
/// </typeparam>
/// <param name="pixels">
/// The pixel accessor.
/// </param>
/// <param name="x">
/// The x-position within the image.
/// </param>
/// <param name="y">
/// The y-position within the image.
/// </param>
/// <param name="yBlock">
/// The luminance block.
/// </param>
/// <param name="cbBlock">
/// The red chroma block.
/// </param>
/// <param name="crBlock">
/// The blue chroma block.
/// </param>
/// <param name="rgbBytes">
/// Temporal <see cref="PixelArea{TColor}"/> provided by the caller
/// </param>
private static void ToYCbCr<TColor>(
PixelAccessor<TColor> pixels,
int x,
@ -264,7 +290,8 @@ namespace ImageSharp.Formats
Block8x8F* yBlock,
Block8x8F* cbBlock,
Block8x8F* crBlock,
PixelArea<TColor> rgbBytes) where TColor : struct, IPackedPixel, IEquatable<TColor>
PixelArea<TColor> rgbBytes)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
float* yBlockRaw = (float*)yBlock;
float* cbBlockRaw = (float*)cbBlock;
@ -300,10 +327,18 @@ namespace ImageSharp.Formats
/// <summary>
/// Emits the least significant count of bits of bits to the bit-stream.
/// The precondition is bits <example>&lt; 1&lt;&lt;nBits &amp;&amp; nBits &lt;= 16</example>.
/// The precondition is bits
/// <example>
/// &lt; 1&lt;&lt;nBits &amp;&amp; nBits &lt;= 16
/// </example>
/// .
/// </summary>
/// <param name="bits">The packed bits.</param>
/// <param name="count">The number of bits</param>
/// <param name="bits">
/// The packed bits.
/// </param>
/// <param name="count">
/// The number of bits
/// </param>
private void Emit(uint bits, uint count)
{
count += this.bitCount;
@ -341,8 +376,12 @@ namespace ImageSharp.Formats
/// <summary>
/// Emits the given value with the given Huffman encoder.
/// </summary>
/// <param name="index">The index of the Huffman encoder</param>
/// <param name="value">The value to encode.</param>
/// <param name="index">
/// The index of the Huffman encoder
/// </param>
/// <param name="value">
/// The value to encode.
/// </param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void EmitHuff(HuffIndex index, int value)
{
@ -353,9 +392,15 @@ namespace ImageSharp.Formats
/// <summary>
/// Emits a run of runLength copies of value encoded with the given Huffman encoder.
/// </summary>
/// <param name="index">The index of the Huffman encoder</param>
/// <param name="runLength">The number of copies to encode.</param>
/// <param name="value">The value to encode.</param>
/// <param name="index">
/// The index of the Huffman encoder
/// </param>
/// <param name="runLength">
/// The number of copies to encode.
/// </param>
/// <param name="value">
/// The value to encode.
/// </param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void EmitHuffRLE(HuffIndex index, int runLength, int value)
{
@ -387,8 +432,12 @@ namespace ImageSharp.Formats
/// <summary>
/// Encodes the image with no subsampling.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <param name="pixels">The pixel accessor providing access to the image pixels.</param>
/// <typeparam name="TColor">
/// The pixel format.
/// </typeparam>
/// <param name="pixels">
/// The pixel accessor providing access to the image pixels.
/// </param>
private void Encode444<TColor>(PixelAccessor<TColor> pixels)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
@ -448,8 +497,12 @@ namespace ImageSharp.Formats
/// <summary>
/// Writes the application header containing the JFIF identifier plus extra data.
/// </summary>
/// <param name="horizontalResolution">The resolution of the image in the x- direction.</param>
/// <param name="verticalResolution">The resolution of the image in the y- direction.</param>
/// <param name="horizontalResolution">
/// The resolution of the image in the x- direction.
/// </param>
/// <param name="verticalResolution">
/// The resolution of the image in the y- direction.
/// </param>
private void WriteApplicationHeader(short horizontalResolution, short verticalResolution)
{
// Write the start of image marker. Markers are always prefixed with with 0xff.
@ -487,17 +540,33 @@ namespace ImageSharp.Formats
/// <summary>
/// Writes a block of pixel data using the given quantization table,
/// returning the post-quantized DC value of the DCT-transformed block.
/// The block is in natural (not zig-zag) order.
/// returning the post-quantized DC value of the DCT-transformed block.
/// The block is in natural (not zig-zag) order.
/// </summary>
/// <param name="index">The quantization table index.</param>
/// <param name="prevDC">The previous DC value.</param>
/// <param name="src">Source block</param>
/// <param name="tempDest">Temporal block to be used as FDCT Destination</param>
/// <param name="temp2">Temporal block 2</param>
/// <param name="quant">Quantization table</param>
/// <param name="unzigPtr">The 8x8 Unzig block ptr</param>
/// <returns>The <see cref="int"/></returns>
/// <param name="index">
/// The quantization table index.
/// </param>
/// <param name="prevDC">
/// The previous DC value.
/// </param>
/// <param name="src">
/// Source block
/// </param>
/// <param name="tempDest">
/// Temporal block to be used as FDCT Destination
/// </param>
/// <param name="temp2">
/// Temporal block 2
/// </param>
/// <param name="quant">
/// Quantization table
/// </param>
/// <param name="unzigPtr">
/// The 8x8 Unzig block ptr
/// </param>
/// <returns>
/// The <see cref="int"/>
/// </returns>
private float WriteBlock(
QuantIndex index,
float prevDC,
@ -554,7 +623,9 @@ namespace ImageSharp.Formats
/// <summary>
/// Writes the Define Huffman Table marker and tables.
/// </summary>
/// <param name="componentCount">The number of components to write.</param>
/// <param name="componentCount">
/// The number of components to write.
/// </param>
private void WriteDefineHuffmanTables(int componentCount)
{
// Table identifiers.
@ -601,7 +672,7 @@ namespace ImageSharp.Formats
}
/// <summary>
/// Writes the Define Quantization Marker and tables.
/// Writes the Define Quantization Marker and tables.
/// </summary>
private void WriteDefineQuantizationTables()
{
@ -625,7 +696,9 @@ namespace ImageSharp.Formats
/// <summary>
/// Writes the EXIF profile.
/// </summary>
/// <param name="exifProfile">The exif profile.</param>
/// <param name="exifProfile">
/// The exif profile.
/// </param>
/// <exception cref="ImageFormatException">
/// Thrown if the EXIF profile size exceeds the limit
/// </exception>
@ -657,9 +730,14 @@ namespace ImageSharp.Formats
/// <summary>
/// Writes the metadata profiles to the image.
/// </summary>
/// <param name="image">The image.</param>
/// <typeparam name="TColor">The pixel format.</typeparam>
private void WriteProfiles<TColor>(Image<TColor> image) where TColor : struct, IPackedPixel, IEquatable<TColor>
/// <param name="image">
/// The image.
/// </param>
/// <typeparam name="TColor">
/// The pixel format.
/// </typeparam>
private void WriteProfiles<TColor>(Image<TColor> image)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
this.WriteProfile(image.ExifProfile);
}
@ -667,9 +745,15 @@ namespace ImageSharp.Formats
/// <summary>
/// Writes the Start Of Frame (Baseline) marker
/// </summary>
/// <param name="width">The width of the image</param>
/// <param name="height">The height of the image</param>
/// <param name="componentCount">The number of components in a pixel</param>
/// <param name="width">
/// The width of the image
/// </param>
/// <param name="height">
/// The height of the image
/// </param>
/// <param name="componentCount">
/// The number of components in a pixel
/// </param>
private void WriteStartOfFrame(int width, int height, int componentCount)
{
// "default" to 4:2:0
@ -723,7 +807,9 @@ namespace ImageSharp.Formats
/// <summary>
/// Writes the StartOfScan marker.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TColor">
/// The pixel format.
/// </typeparam>
/// <param name="pixels">
/// The pixel accessor providing access to the image pixels.
/// </param>
@ -751,8 +837,9 @@ namespace ImageSharp.Formats
#pragma warning disable SA1201 // MethodShouldNotFollowAStruct
/// <summary>
/// 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
/// 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>
private struct BlockQuad
{
@ -761,10 +848,14 @@ namespace ImageSharp.Formats
/// <summary>
/// Encodes the image with subsampling. The Cb and Cr components are each subsampled
/// at a factor of 2 both horizontally and vertically.
/// at a factor of 2 both horizontally and vertically.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <param name="pixels">The pixel accessor providing access to the image pixels.</param>
/// <typeparam name="TColor">
/// The pixel format.
/// </typeparam>
/// <param name="pixels">
/// The pixel accessor providing access to the image pixels.
/// </param>
private void Encode420<TColor>(PixelAccessor<TColor> pixels)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
@ -838,8 +929,12 @@ namespace ImageSharp.Formats
/// <summary>
/// Writes the header for a marker with the given length.
/// </summary>
/// <param name="marker">The marker to write.</param>
/// <param name="length">The marker length.</param>
/// <param name="marker">
/// The marker to write.
/// </param>
/// <param name="length">
/// The marker length.
/// </param>
private void WriteMarkerHeader(byte marker, int length)
{
// Markers are always prefixed with with 0xff.

80
src/ImageSharp/Formats/Jpg/Utils/JpegUtils.cs

@ -10,18 +10,29 @@ namespace ImageSharp.Formats.Jpg.Utils
using ImageSharp.Formats.Jpg.Components.Encoder;
/// <summary>
/// Jpeg specific utilities and extension methods
/// Jpeg specific utilities and extension methods
/// </summary>
internal static unsafe class JpegUtils
{
/// <summary>
/// Copy a region of an image into dest. De "outlier" area will be stretched out with pixels on the right and bottom of the image.
/// Copy a region of an image into dest. De "outlier" area will be stretched out with pixels on the right and bottom of
/// the image.
/// </summary>
/// <typeparam name="TColor">The pixel type</typeparam>
/// <param name="pixels">The input pixel acessor</param>
/// <param name="dest">The destination <see cref="PixelArea{TColor}"/> </param>
/// <param name="sourceY">Starting Y coord</param>
/// <param name="sourceX">Starting X coord</param>
/// <typeparam name="TColor">
/// The pixel type
/// </typeparam>
/// <param name="pixels">
/// The input pixel acessor
/// </param>
/// <param name="dest">
/// The destination <see cref="PixelArea{TColor}"/>
/// </param>
/// <param name="sourceY">
/// Starting Y coord
/// </param>
/// <param name="sourceX">
/// Starting X coord
/// </param>
public static void CopyRGBBytesStretchedTo<TColor>(
this PixelAccessor<TColor> pixels,
PixelArea<TColor> dest,
@ -38,8 +49,12 @@ namespace ImageSharp.Formats.Jpg.Utils
/// <summary>
/// Copy an RGB value
/// </summary>
/// <param name="source">Source pointer</param>
/// <param name="dest">Destination pointer</param>
/// <param name="source">
/// Source pointer
/// </param>
/// <param name="dest">
/// Destination pointer
/// </param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static void CopyRgb(byte* source, byte* dest)
{
@ -48,6 +63,37 @@ namespace ImageSharp.Formats.Jpg.Utils
*dest = *source; // B
}
/// <summary>
/// Writes data to "Define Quantization Tables" block for QuantIndex
/// </summary>
/// <param name="dqt">
/// The "Define Quantization Tables" block
/// </param>
/// <param name="offset">
/// Offset in dqt
/// </param>
/// <param name="i">
/// The quantization index
/// </param>
/// <param name="q">
/// The quantazation table to copy data from
/// </param>
internal static void WriteDataToDqt(byte[] dqt, ref int offset, QuantIndex i, ref Block8x8F q)
{
dqt[offset++] = (byte)i;
for (int j = 0; j < Block8x8F.ScalarCount; j++)
{
dqt[offset++] = (byte)q[j];
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsInvalidStretchArea<TColor>(PixelArea<TColor> area, int fromX, int fromY)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
return fromX <= 0 || fromY <= 0 || fromX >= area.Width || fromY >= area.Height;
}
private static void StretchPixels<TColor>(PixelArea<TColor> area, int fromX, int fromY)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
@ -84,21 +130,5 @@ namespace ImageSharp.Formats.Jpg.Utils
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static bool IsInvalidStretchArea<TColor>(PixelArea<TColor> area, int fromX, int fromY)
where TColor : struct, IPackedPixel, IEquatable<TColor>
{
return fromX <= 0 || fromY <= 0 || fromX >= area.Width || fromY >= area.Height;
}
internal static void WriteDataToDqt(byte[] dqt, ref int offset, QuantIndex i, ref Block8x8F q)
{
dqt[offset++] = (byte)i;
for (int j = 0; j < Block8x8F.ScalarCount; j++)
{
dqt[offset++] = (byte)q[j];
}
}
}
}
Loading…
Cancel
Save