Browse Source

Extract jpeg component classes [skip ci]

Former-commit-id: 89550ed1243331a85c00f315dc8cd4c06b14ae9c
Former-commit-id: 8d15dd77d84254cb59154322736904f05a434875
Former-commit-id: 219c0fd3b6925bde6cac1323b17bad9a857ec56d
af/merge-core
James Jackson-South 10 years ago
parent
commit
63d9bd40dd
  1. 2
      src/ImageProcessorCore/Colors/Colorspaces/YCbCr.cs
  2. 31
      src/ImageProcessorCore/Formats/Jpg/Components/Bits.cs
  3. 0
      src/ImageProcessorCore/Formats/Jpg/Components/Block.cs
  4. 43
      src/ImageProcessorCore/Formats/Jpg/Components/Bytes.cs
  5. 33
      src/ImageProcessorCore/Formats/Jpg/Components/Component.cs
  6. 0
      src/ImageProcessorCore/Formats/Jpg/Components/FDCT.cs
  7. 101
      src/ImageProcessorCore/Formats/Jpg/Components/GrayImage.cs
  8. 64
      src/ImageProcessorCore/Formats/Jpg/Components/Huffman.cs
  9. 0
      src/ImageProcessorCore/Formats/Jpg/Components/IDCT.cs
  10. 228
      src/ImageProcessorCore/Formats/Jpg/Components/YCbCrImage.cs
  11. 2
      src/ImageProcessorCore/Formats/Jpg/JpegDecoderCore.cs.REMOVED.git-id

2
src/ImageProcessorCore/Colors/Colorspaces/YCbCr.cs

@ -10,7 +10,7 @@ namespace ImageProcessorCore
using System.Numerics;
/// <summary>
/// Represents an YCbCr (luminance, chroma, chroma) color conforming to the
/// Represents an YCbCr (luminance, blue chroma, red chroma) color conforming to the
/// Full range standard used in digital imaging systems.
/// <see href="http://en.wikipedia.org/wiki/YCbCr"/>
/// </summary>

31
src/ImageProcessorCore/Formats/Jpg/Components/Bits.cs

@ -0,0 +1,31 @@
// <copyright file="Bits.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>
/// Holds the unprocessed bits that have been taken from the byte-stream.
/// The n least significant bits of a form the unread bits, to be read in MSB to
/// LSB order.
/// </summary>
internal class Bits
{
/// <summary>
/// Gets or sets the accumulator.
/// </summary>
public uint Accumulator { get; set; }
/// <summary>
/// Gets or sets the mask.
/// <![CDATA[mask==1<<(unreadbits-1) when unreadbits>0, with mask==0 when unreadbits==0.]]>
/// </summary>
public uint Mask { get; set; }
/// <summary>
/// Gets or sets the number of unread bits in the accumulator.
/// </summary>
public int UnreadBits { get; set; }
}
}

0
src/ImageProcessorCore/Formats/Jpg/Block.cs → src/ImageProcessorCore/Formats/Jpg/Components/Block.cs

43
src/ImageProcessorCore/Formats/Jpg/Components/Bytes.cs

@ -0,0 +1,43 @@
// <copyright file="Bytes.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>
/// Bytes is a byte buffer, similar to a stream, except that it
/// has to be able to unread more than 1 byte, due to byte stuffing.
/// Byte stuffing is specified in section F.1.2.3.
/// </summary>
internal class Bytes
{
/// <summary>
/// Initializes a new instance of the <see cref="Bytes"/> class.
/// </summary>
public Bytes()
{
this.Buffer = new byte[4096];
this.I = 0;
this.J = 0;
this.UnreadableBytes = 0;
}
/// <summary>
/// Gets or sets the buffer.
/// buffer[i:j] are the buffered bytes read from the underlying
/// stream that haven't yet been passed further on.
/// </summary>
public byte[] Buffer { get; set; }
public int I { get; set; }
public int J { get; set; }
/// <summary>
/// Gets or sets the unreadable bytes. The number of bytes to back up i after
/// overshooting. It can be 0, 1 or 2.
/// </summary>
public int UnreadableBytes { get; set; }
}
}

33
src/ImageProcessorCore/Formats/Jpg/Components/Component.cs

@ -0,0 +1,33 @@
// <copyright file="Component.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 a single color component
/// </summary>
internal class Component
{
/// <summary>
/// Gets or sets the horizontal sampling factor.
/// </summary>
public int HorizontalFactor { get; set; }
/// <summary>
/// Gets or sets the vertical sampling factor.
/// </summary>
public int VerticalFactor { get; set; }
/// <summary>
/// Gets or sets the identifier
/// </summary>
public byte Identifier { get; set; }
/// <summary>
/// Gets or sets the quantization table destination selector.
/// </summary>
public byte Selector { get; set; }
}
}

0
src/ImageProcessorCore/Formats/Jpg/FDCT.cs → src/ImageProcessorCore/Formats/Jpg/Components/FDCT.cs

101
src/ImageProcessorCore/Formats/Jpg/Components/GrayImage.cs

@ -0,0 +1,101 @@
// <copyright file="GrayImage.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 a grayscale image
/// </summary>
internal class GrayImage
{
/// <summary>
/// Initializes a new instance of the <see cref="GrayImage"/> class.
/// </summary>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
public GrayImage(int width, int height)
{
this.Width = width;
this.Height = height;
this.Pixels = new byte[width * height];
this.Stride = width;
this.Offset = 0;
}
/// <summary>
/// Prevents a default instance of the <see cref="GrayImage"/> class from being created.
/// </summary>
private GrayImage()
{
}
/// <summary>
/// Gets or sets the pixels.
/// </summary>
public byte[] Pixels { get; set; }
/// <summary>
/// Gets or sets the stride.
/// </summary>
public int Stride { get; set; }
/// <summary>
/// Gets or sets the horizontal position.
/// </summary>
public int X { get; set; }
/// <summary>
/// Gets or sets the vertical position.
/// </summary>
public int Y { get; set; }
/// <summary>
/// Gets or sets the width.
/// </summary>
public int Width { get; set; }
/// <summary>
/// Gets or sets the height.
/// </summary>
public int Height { get; set; }
/// <summary>
/// Gets or sets the offset
/// </summary>
public int Offset { get; set; }
/// <summary>
/// Gets an image made up of a subset of the originals pixels.
/// </summary>
/// <param name="x">The x-coordinate of the image.</param>
/// <param name="y">The y-coordinate of the image.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <returns>
/// The <see cref="GrayImage"/>.
/// </returns>
public GrayImage Subimage(int x, int y, int width, int height)
{
return new GrayImage
{
Width = width,
Height = height,
Pixels = this.Pixels,
Stride = this.Stride,
Offset = (y * this.Stride) + x
};
}
/// <summary>
/// Gets the row offset at the given position
/// </summary>
/// <param name="y">The y-coordinate of the image.</param>
/// <returns>The <see cref="int"/></returns>
public int GetRowOffset(int y)
{
return this.Offset + (y * this.Stride);
}
}
}

64
src/ImageProcessorCore/Formats/Jpg/Components/Huffman.cs

@ -0,0 +1,64 @@
// <copyright file="Huffman.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 a Huffman tree
/// </summary>
internal class Huffman
{
/// <summary>
/// Initializes a new instance of the <see cref="Huffman"/> class.
/// </summary>
/// <param name="lutSize">The log-2 size of the Huffman decoder's look-up table.</param>
/// <param name="maxNCodes">The maximum (inclusive) number of codes in a Huffman tree.</param>
/// <param name="maxCodeLength">The maximum (inclusive) number of bits in a Huffman code.</param>
public Huffman(int lutSize, int maxNCodes, int maxCodeLength)
{
this.Lut = new ushort[1 << lutSize];
this.Values = new byte[maxNCodes];
this.MinCodes = new int[maxCodeLength];
this.MaxCodes = new int[maxCodeLength];
this.Indices = new int[maxCodeLength];
this.Length = 0;
}
/// <summary>
/// Gets or sets the number of codes in the tree.
/// </summary>
public int Length { get; set; }
/// <summary>
/// Gets the look-up table for the next LutSize bits in the bit-stream.
/// The high 8 bits of the uint16 are the encoded value. The low 8 bits
/// are 1 plus the code length, or 0 if the value is too large to fit in
/// lutSize bits.
/// </summary>
public ushort[] Lut { get; }
/// <summary>
/// Gets the the decoded values, sorted by their encoding.
/// </summary>
public byte[] Values { get; }
/// <summary>
/// Gets the array of minimum codes.
/// MinCodes[i] is the minimum code of length i, or -1 if there are no codes of that length.
/// </summary>
public int[] MinCodes { get; }
/// <summary>
/// Gets the array of maximum codes.
/// MaxCodes[i] is the maximum code of length i, or -1 if there are no codes of that length.
/// </summary>
public int[] MaxCodes { get; }
/// <summary>
/// Gets the array of indices. Indices[i] is the index into Values of MinCodes[i].
/// </summary>
public int[] Indices { get; }
}
}

0
src/ImageProcessorCore/Formats/Jpg/IDCT.cs → src/ImageProcessorCore/Formats/Jpg/Components/IDCT.cs

228
src/ImageProcessorCore/Formats/Jpg/Components/YCbCrImage.cs

@ -0,0 +1,228 @@
// <copyright file="YCbCrImage.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 image made up of three color components (luminance, blue chroma, red chroma)
/// </summary>
internal class YCbCrImage
{
/// <summary>
/// Initializes a new instance of the <see cref="YCbCrImage"/> class.
/// </summary>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="ratio">The ratio.</param>
public YCbCrImage(int width, int height, YCbCrSubsampleRatio ratio)
{
int cw, ch;
YCbCrSize(width, height, ratio, out cw, out ch);
this.YChannel = new byte[width * height];
this.CbChannel = new byte[cw * ch];
this.CrChannel = new byte[cw * ch];
this.Ratio = ratio;
this.YStride = width;
this.CStride = cw;
this.X = 0;
this.Y = 0;
this.Width = width;
this.Height = height;
}
/// <summary>
/// Prevents a default instance of the <see cref="YCbCrImage"/> class from being created.
/// </summary>
private YCbCrImage()
{
}
/// <summary>
/// Provides enumeration of the various available subsample ratios.
/// </summary>
public enum YCbCrSubsampleRatio
{
YCbCrSubsampleRatio444,
YCbCrSubsampleRatio422,
YCbCrSubsampleRatio420,
YCbCrSubsampleRatio440,
YCbCrSubsampleRatio411,
YCbCrSubsampleRatio410,
}
/// <summary>
/// Gets or sets the luminance components channel.
/// </summary>
public byte[] YChannel { get; set; }
/// <summary>
/// Gets or sets the blue chroma components channel.
/// </summary>
public byte[] CbChannel { get; set; }
/// <summary>
/// Gets or sets the red chroma components channel.
/// </summary>
public byte[] CrChannel { get; set; }
/// <summary>
/// Gets or sets the Y slice index delta between vertically adjacent pixels.
/// </summary>
public int YStride { get; set; }
/// <summary>
/// Gets or sets the red and blue chroma slice index delta between vertically adjacent pixels
/// that map to separate chroma samples.
/// </summary>
public int CStride { get; set; }
/// <summary>
/// Gets or sets the index of the first luminance element.
/// </summary>
public int YOffset { get; set; }
/// <summary>
/// Gets or sets the index of the first element of red or blue chroma.
/// </summary>
public int COffset { get; set; }
/// <summary>
/// Gets or sets the horizontal position.
/// </summary>
public int X { get; set; }
/// <summary>
/// Gets or sets the vertical position.
/// </summary>
public int Y { get; set; }
/// <summary>
/// Gets or sets the width.
/// </summary>
public int Width { get; set; }
/// <summary>
/// Gets or sets the height.
/// </summary>
public int Height { get; set; }
/// <summary>
/// Gets or sets the subsampling ratio.
/// </summary>
public YCbCrSubsampleRatio Ratio { get; set; }
/// <summary>
/// Gets an image made up of a subset of the originals pixels.
/// </summary>
/// <param name="x">The x-coordinate of the image.</param>
/// <param name="y">The y-coordinate of the image.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <returns>
/// The <see cref="YCbCrImage"/>.
/// </returns>
public YCbCrImage Subimage(int x, int y, int width, int height)
{
YCbCrImage ret = new YCbCrImage
{
Width = width,
Height = height,
YChannel = this.YChannel,
CbChannel = this.CbChannel,
CrChannel = this.CrChannel,
Ratio = this.Ratio,
YStride = this.YStride,
CStride = this.CStride,
YOffset = (y * this.YStride) + x,
COffset = (y * this.CStride) + x
};
return ret;
}
/// <summary>
/// Returns the offset of the first luminance component at the given row
/// </summary>
/// <param name="y">The row number.</param>
/// <returns>
/// The <see cref="int"/>.
/// </returns>
public int GetRowYOffset(int y)
{
return y * this.YStride;
}
/// <summary>
/// Returns the offset of the first chroma component at the given row
/// </summary>
/// <param name="y">The row number.</param>
/// <returns>
/// The <see cref="int"/>.
/// </returns>
public int GetRowCOffset(int y)
{
switch (this.Ratio)
{
case YCbCrSubsampleRatio.YCbCrSubsampleRatio422:
return y * this.CStride;
case YCbCrSubsampleRatio.YCbCrSubsampleRatio420:
return (y / 2) * this.CStride;
case YCbCrSubsampleRatio.YCbCrSubsampleRatio440:
return (y / 2) * this.CStride;
case YCbCrSubsampleRatio.YCbCrSubsampleRatio411:
return y * this.CStride;
case YCbCrSubsampleRatio.YCbCrSubsampleRatio410:
return (y / 2) * this.CStride;
default:
return y * this.CStride;
}
}
/// <summary>
/// Returns the height and width of the chroma components
/// </summary>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="ratio">The subsampling ratio.</param>
/// <param name="chromaWidth">The chroma width.</param>
/// <param name="chromaHeight">The chroma height.</param>
private static void YCbCrSize(int width, int height, YCbCrSubsampleRatio ratio, out int chromaWidth, out int chromaHeight)
{
switch (ratio)
{
case YCbCrSubsampleRatio.YCbCrSubsampleRatio422:
chromaWidth = (width + 1) / 2;
chromaHeight = height;
break;
case YCbCrSubsampleRatio.YCbCrSubsampleRatio420:
chromaWidth = (width + 1) / 2;
chromaHeight = (height + 1) / 2;
break;
case YCbCrSubsampleRatio.YCbCrSubsampleRatio440:
chromaWidth = width;
chromaHeight = (height + 1) / 2;
break;
case YCbCrSubsampleRatio.YCbCrSubsampleRatio411:
chromaWidth = (width + 3) / 4;
chromaHeight = height;
break;
case YCbCrSubsampleRatio.YCbCrSubsampleRatio410:
chromaWidth = (width + 3) / 4;
chromaHeight = (height + 1) / 2;
break;
default:
// Default to 4:4:4 subsampling.
chromaWidth = width;
chromaHeight = height;
break;
}
}
}
}

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

@ -1 +1 @@
efdc36c9d84d1fd42bf3b1e722946bccef95db1c
8ce31914f581080b90c50b6a6529db20a29e7551
Loading…
Cancel
Save