diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegBlockPostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegBlockPostProcessor.cs
index 5e8e8fa2cc..2f59bcb822 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegBlockPostProcessor.cs
+++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegBlockPostProcessor.cs
@@ -47,9 +47,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
this.DequantiazationTable = ZigZag.CreateDequantizationTable(ref decoder.QuantizationTables[qtIndex]);
this.subSamplingDivisors = component.SubSamplingDivisors;
- this.SourceBlock = default(Block8x8F);
- this.WorkspaceBlock1 = default(Block8x8F);
- this.WorkspaceBlock2 = default(Block8x8F);
+ this.SourceBlock = default;
+ this.WorkspaceBlock1 = default;
+ this.WorkspaceBlock2 = default;
}
///
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/FourByte.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/FourByte.cs
deleted file mode 100644
index e276dc156f..0000000000
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/FourByte.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using System.Runtime.InteropServices;
-
-namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
-{
- [StructLayout(LayoutKind.Sequential)]
- internal readonly struct FourByte
- {
- public readonly byte X;
-
- public readonly byte Y;
-
- public readonly byte Z;
-
- public readonly byte W;
- }
-}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsJpegPixelArea.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsJpegPixelArea.cs
deleted file mode 100644
index f37c5d9032..0000000000
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsJpegPixelArea.cs
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using System;
-using System.Diagnostics;
-using System.Numerics;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-using SixLabors.ImageSharp.Memory;
-
-namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
-{
- ///
- /// Represents a section of the jpeg component data laid out in pixel order.
- ///
- internal struct PdfJsJpegPixelArea : IDisposable
- {
- private readonly MemoryManager memoryManager;
-
- private IBuffer componentData;
-
- private int rowStride;
-
- ///
- /// Gets the number of components
- ///
- public int NumberOfComponents;
-
- ///
- /// Gets the width
- ///
- public int Width;
-
- ///
- /// Gets the height
- ///
- public int Height;
-
- ///
- /// Initializes a new instance of the struct.
- ///
- /// The to use for buffer allocations.
- /// The image width
- /// The image height
- /// The number of components
- public PdfJsJpegPixelArea(MemoryManager memoryManager, int imageWidth, int imageHeight, int numberOfComponents)
- {
- this.memoryManager = memoryManager;
- this.Width = imageWidth;
- this.Height = imageHeight;
- this.NumberOfComponents = numberOfComponents;
- this.componentData = null;
- this.rowStride = this.Width * this.NumberOfComponents;
- this.componentData = this.memoryManager.Allocate(this.Width * this.Height * this.NumberOfComponents);
- }
-
- ////
- //// Organsizes the decoded jpeg components into a linear array ordered by component.
- //// This must be called before attempting to retrieve the data.
- ////
- //// The jpeg component blocks
- // public void LinearizeBlockData(PdfJsComponentBlocks components)
- // {
- // ref byte componentDataRef = ref MemoryMarshal.GetReference(this.componentData.Span);
- // const uint Mask3Lsb = 0xFFFFFFF8; // Used to clear the 3 LSBs
-
- // using (IBuffer xScaleBlockOffset = this.memoryManager.Allocate(this.Width))
- // {
- // ref int xScaleBlockOffsetRef = ref MemoryMarshal.GetReference(xScaleBlockOffset.Span);
- // int numberOfComponents = this.NumberOfComponents;
- // int width = this.Width;
- // int height = this.Height;
- //
- // for (int i = 0; i < numberOfComponents; i++)
- // {
- // ref PdfJsComponent component = ref components.Components[i];
- // ref short outputRef = ref MemoryMarshal.GetReference(component.Output.Span);
- // Vector2 componentScale = component.Scale;
- // float cX = componentScale.X;
- // float cY = componentScale.Y;
- // int blocksPerScanline = (component.BlocksPerLine + 1) << 3;
- //
- // // Precalculate the xScaleBlockOffset
- // int j;
- // for (int x = 0; x < width; x++)
- // {
- // j = (int)(x * cX);
- // Unsafe.Add(ref xScaleBlockOffsetRef, x) = (int)((j & Mask3Lsb) << 3) | (j & 7);
- // }
- //
- // // Linearize the blocks of the component
- // int offset = i;
- // for (int y = 0; y < height; y++)
- // {
- // j = (int)(y * cY);
- // int index = blocksPerScanline * (int)(j & Mask3Lsb) | ((j & 7) << 3);
- // for (int x = 0; x < width; x++)
- // {
- // Unsafe.Add(ref componentDataRef, offset) = (byte)Unsafe.Add(ref outputRef, index + Unsafe.Add(ref xScaleBlockOffsetRef, x));
- // offset += numberOfComponents;
- // }
- // }
- // }
- // }
- // }
-
- ///
- /// Gets a representing the row 'y' beginning from the the first byte on that row.
- ///
- /// The y-coordinate of the pixel row. Must be greater than or equal to zero and less than the height of the pixel area.
- /// The
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public Span GetRowSpan(int y)
- {
- this.CheckCoordinates(y);
- return this.componentData.Slice(y * this.rowStride, this.rowStride);
- }
-
- ///
- public void Dispose()
- {
- this.componentData?.Dispose();
- this.componentData = null;
- }
-
- ///
- /// Checks the coordinates to ensure they are within bounds.
- ///
- /// The y-coordinate of the row. Must be greater than zero and less than the height of the area.
- ///
- /// Thrown if the coordinates are not within the bounds of the image.
- ///
- [Conditional("DEBUG")]
- private void CheckCoordinates(int y)
- {
- if (y < 0 || y >= this.Height)
- {
- throw new ArgumentOutOfRangeException(nameof(y), y, $"{y} is outwith the area bounds.");
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsYCbCrToRgbTables.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsYCbCrToRgbTables.cs
deleted file mode 100644
index 203a7b1eb2..0000000000
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/PdfJsYCbCrToRgbTables.cs
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using System.Runtime.CompilerServices;
-using SixLabors.ImageSharp.PixelFormats;
-
-namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
-{
- ///
- /// Provides 8-bit lookup tables for converting from YCbCr to Rgb colorspace.
- /// Methods to build the tables are based on libjpeg implementation.
- ///
- internal readonly struct PdfJsYCbCrToRgbTables
- {
- ///
- /// The red red-chrominance table
- ///
- public static int[] CrRTable = new int[256];
-
- ///
- /// The blue blue-chrominance table
- ///
- public static int[] CbBTable = new int[256];
-
- ///
- /// The green red-chrominance table
- ///
- public static int[] CrGTable = new int[256];
-
- ///
- /// The green blue-chrominance table
- ///
- public static int[] CbGTable = new int[256];
-
- // Speediest right-shift on some machines and gives us enough accuracy at 4 decimal places.
- private const int ScaleBits = 16;
-
- private const int Half = 1 << (ScaleBits - 1);
-
- private const int MinSample = 0;
-
- private const int HalfSample = 128;
-
- private const int MaxSample = 255;
-
- ///
- /// Initializes the YCbCr tables
- ///
- public static void Create()
- {
- for (int i = 0, x = -128; i <= 255; i++, x++)
- {
- // i is the actual input pixel value, in the range 0..255
- // The Cb or Cr value we are thinking of is x = i - 128
- // Cr=>R value is nearest int to 1.402 * x
- CrRTable[i] = RightShift((Fix(1.402F) * x) + Half);
-
- // Cb=>B value is nearest int to 1.772 * x
- CbBTable[i] = RightShift((Fix(1.772F) * x) + Half);
-
- // Cr=>G value is scaled-up -0.714136286
- CrGTable[i] = (-Fix(0.714136286F)) * x;
-
- // Cb => G value is scaled - up - 0.344136286 * x
- // We also add in Half so that need not do it in inner loop
- CbGTable[i] = ((-Fix(0.344136286F)) * x) + Half;
- }
- }
-
- ///
- /// Optimized method to pack bytes to the image from the YCbCr color space.
- ///
- /// The pixel format.
- /// The packed pixel.
- /// The y luminance component.
- /// The cb chroma component.
- /// The cr chroma component.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void PackYCbCr(ref TPixel packed, byte y, byte cb, byte cr)
- where TPixel : struct, IPixel
- {
- byte r = (byte)(y + CrRTable[cr]).Clamp(0, 255);
-
- // The values for the G calculation are left scaled up, since we must add them together before rounding.
- byte g = (byte)(y + RightShift(CbGTable[cb] + CrGTable[cr])).Clamp(0, 255);
-
- byte b = (byte)(y + CbBTable[cb]).Clamp(0, 255);
-
- packed.PackFromRgba32(new Rgba32(r, g, b, 255));
- }
-
- ///
- /// Optimized method to pack bytes to the image from the YccK color space.
- ///
- /// The pixel format.
- /// The packed pixel.
- /// The y luminance component.
- /// The cb chroma component.
- /// The cr chroma component.
- /// The keyline component.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static void PackYccK(ref TPixel packed, byte y, byte cb, byte cr, byte k)
- where TPixel : struct, IPixel
- {
- int c = (MaxSample - (y + CrRTable[cr])).Clamp(0, 255);
-
- // The values for the G calculation are left scaled up, since we must add them together before rounding.
- int m = (MaxSample - (y + RightShift(CbGTable[cb] + CrGTable[cr]))).Clamp(0, 255);
-
- int cy = (MaxSample - (y + CbBTable[cb])).Clamp(0, 255);
-
- byte r = (byte)((c * k) / MaxSample);
- byte g = (byte)((m * k) / MaxSample);
- byte b = (byte)((cy * k) / MaxSample);
-
- packed.PackFromRgba32(new Rgba32(r, g, b, MaxSample));
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static int Fix(float x)
- {
- return (int)((x * (1L << ScaleBits)) + 0.5F);
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private static int RightShift(int x)
- {
- return x >> ScaleBits;
- }
- }
-}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/ThreeByte.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/ThreeByte.cs
deleted file mode 100644
index 6b0e0ae4af..0000000000
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/Components/ThreeByte.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using System.Runtime.InteropServices;
-
-namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort.Components
-{
- [StructLayout(LayoutKind.Sequential)]
- internal readonly struct ThreeByte
- {
- public readonly byte X;
-
- public readonly byte Y;
-
- public readonly byte Z;
- }
-}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegConstants.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegConstants.cs
index 08b42891d5..2c369d3908 100644
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegConstants.cs
+++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegConstants.cs
@@ -194,62 +194,11 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
///
public const ushort RST7 = 0xFFD7;
- ///
- /// Contains JFIF specific markers
- ///
- public static class JFif
- {
- ///
- /// Represents J in ASCII
- ///
- public const byte J = 0x4A;
-
- ///
- /// Represents F in ASCII
- ///
- public const byte F = 0x46;
-
- ///
- /// Represents I in ASCII
- ///
- public const byte I = 0x49;
-
- ///
- /// Represents the null "0" marker
- ///
- public const byte Null = 0x0;
- }
-
///
/// Contains Adobe specific markers
///
public static class Adobe
{
- ///
- /// Represents A in ASCII
- ///
- public const byte A = 0x41;
-
- ///
- /// Represents d in ASCII
- ///
- public const byte D = 0x64;
-
- ///
- /// Represents b in ASCII
- ///
- public const byte O = 0x6F;
-
- ///
- /// Represents b in ASCII
- ///
- public const byte B = 0x62;
-
- ///
- /// Represents e in ASCII
- ///
- public const byte E = 0x65;
-
///
/// The color transform is unknown.(RGB or CMYK)
///
@@ -265,93 +214,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
///
public const byte ColorTransformYcck = 2;
}
-
- ///
- /// Contains EXIF specific markers
- ///
- public static class Exif
- {
- ///
- /// Represents E in ASCII
- ///
- public const byte E = 0x45;
-
- ///
- /// Represents x in ASCII
- ///
- public const byte X = 0x78;
-
- ///
- /// Represents i in ASCII
- ///
- public const byte I = 0x69;
-
- ///
- /// Represents f in ASCII
- ///
- public const byte F = 0x66;
-
- ///
- /// Represents the null "0" marker
- ///
- public const byte Null = 0x0;
- }
-
- ///
- /// Contains ICC specific markers
- ///
- public static class ICC
- {
- ///
- /// Represents I in ASCII
- ///
- public const byte I = 0x49;
-
- ///
- /// Represents C in ASCII
- ///
- public const byte C = 0x43;
-
- ///
- /// Represents _ in ASCII
- ///
- public const byte UnderScore = 0x5F;
-
- ///
- /// Represents P in ASCII
- ///
- public const byte P = 0x50;
-
- ///
- /// Represents R in ASCII
- ///
- public const byte R = 0x52;
-
- ///
- /// Represents O in ASCII
- ///
- public const byte O = 0x4F;
-
- ///
- /// Represents F in ASCII
- ///
- public const byte F = 0x46;
-
- ///
- /// Represents L in ASCII
- ///
- public const byte L = 0x4C;
-
- ///
- /// Represents E in ASCII
- ///
- public const byte E = 0x45;
-
- ///
- /// Represents the null "0" marker
- ///
- public const byte Null = 0x0;
- }
}
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs
index 07c909e334..336c61699d 100644
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs
@@ -58,8 +58,9 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
///
private PdfJsHuffmanTables acHuffmanTables;
- private PdfJsJpegPixelArea pixelArea;
-
+ ///
+ /// The reset interval determined by RST markers
+ ///
private ushort resetInterval;
///
@@ -77,14 +78,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
///
private AdobeMarker adobe;
- ///
- /// Initializes static members of the class.
- ///
- static PdfJsJpegDecoderCore()
- {
- PdfJsYCbCrToRgbTables.Create();
- }
-
///
/// Initializes a new instance of the class.
///
@@ -143,6 +136,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
///
public IEnumerable Components => this.Frame.Components;
+ ///
public Block8x8F[] QuantizationTables { get; private set; }
///
@@ -341,7 +335,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
public void Dispose()
{
this.Frame?.Dispose();
- this.pixelArea.Dispose();
// Set large fields to null.
this.Frame = null;
@@ -349,53 +342,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
this.acHuffmanTables = null;
}
- ///
- /// Fills the given image with the color data. TODO: Delete ME!!
- ///
- /// The pixel format.
- /// The image
- private void FillPixelData(ImageFrame image)
- where TPixel : struct, IPixel
- {
- if (this.ComponentCount > 4)
- {
- throw new ImageFormatException($"Unsupported color mode. Max components 4; found {this.ComponentCount}");
- }
-
- this.pixelArea = new PdfJsJpegPixelArea(this.configuration.MemoryManager, image.Width, image.Height, this.ComponentCount);
-
- // this.pixelArea.LinearizeBlockData(this.components);
- if (this.ComponentCount == 1)
- {
- this.FillGrayScaleImage(image);
- return;
- }
-
- if (this.ComponentCount == 3)
- {
- if (this.adobe.Equals(default) || this.adobe.ColorTransform == PdfJsJpegConstants.Markers.Adobe.ColorTransformYCbCr)
- {
- this.FillYCbCrImage(image);
- }
- else if (this.adobe.ColorTransform == PdfJsJpegConstants.Markers.Adobe.ColorTransformUnknown)
- {
- this.FillRgbImage(image);
- }
- }
-
- if (this.ComponentCount == 4)
- {
- if (this.adobe.ColorTransform == PdfJsJpegConstants.Markers.Adobe.ColorTransformYcck)
- {
- this.FillYcckImage(image);
- }
- else
- {
- this.FillCmykImage(image);
- }
- }
- }
-
///
/// Returns the correct colorspace based on the image component count
///
@@ -844,100 +790,6 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
tables[index] = new PdfJsHuffmanTable(this.configuration.MemoryManager, codeLengths, values);
}
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private void FillGrayScaleImage(ImageFrame image)
- where TPixel : struct, IPixel
- {
- for (int y = 0; y < image.Height; y++)
- {
- ref TPixel imageRowRef = ref MemoryMarshal.GetReference(image.GetPixelRowSpan(y));
- ref byte areaRowRef = ref MemoryMarshal.GetReference(this.pixelArea.GetRowSpan(y));
-
- for (int x = 0; x < image.Width; x++)
- {
- ref byte luminance = ref Unsafe.Add(ref areaRowRef, x);
- ref TPixel pixel = ref Unsafe.Add(ref imageRowRef, x);
- var rgba = new Rgba32(luminance, luminance, luminance);
- pixel.PackFromRgba32(rgba);
- }
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private void FillYCbCrImage(ImageFrame image)
- where TPixel : struct, IPixel
- {
- for (int y = 0; y < image.Height; y++)
- {
- ref TPixel imageRowRef = ref MemoryMarshal.GetReference(image.GetPixelRowSpan(y));
- ref ThreeByte areaRowRef = ref MemoryMarshal.GetReference(MemoryMarshal.Cast(this.pixelArea.GetRowSpan(y)));
-
- for (int x = 0; x < image.Width; x++)
- {
- ref ThreeByte ycbcr = ref Unsafe.Add(ref areaRowRef, x);
- ref TPixel pixel = ref Unsafe.Add(ref imageRowRef, x);
- PdfJsYCbCrToRgbTables.PackYCbCr(ref pixel, ycbcr.X, ycbcr.Y, ycbcr.Z);
- }
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private void FillYcckImage(ImageFrame image)
- where TPixel : struct, IPixel
- {
- for (int y = 0; y < image.Height; y++)
- {
- ref TPixel imageRowRef = ref MemoryMarshal.GetReference(image.GetPixelRowSpan(y));
- ref FourByte areaRowRef = ref MemoryMarshal.GetReference(MemoryMarshal.Cast(this.pixelArea.GetRowSpan(y)));
-
- for (int x = 0; x < image.Width; x++)
- {
- ref FourByte ycbcrk = ref Unsafe.Add(ref areaRowRef, x);
- ref TPixel pixel = ref Unsafe.Add(ref imageRowRef, x);
- PdfJsYCbCrToRgbTables.PackYccK(ref pixel, ycbcrk.X, ycbcrk.Y, ycbcrk.Z, ycbcrk.W);
- }
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private void FillCmykImage(ImageFrame image)
- where TPixel : struct, IPixel
- {
- for (int y = 0; y < image.Height; y++)
- {
- ref TPixel imageRowRef = ref MemoryMarshal.GetReference(image.GetPixelRowSpan(y));
- ref FourByte areaRowRef = ref MemoryMarshal.GetReference(MemoryMarshal.Cast(this.pixelArea.GetRowSpan(y)));
-
- for (int x = 0; x < image.Width; x++)
- {
- ref FourByte cmyk = ref Unsafe.Add(ref areaRowRef, x);
- byte k = cmyk.W;
-
- // TODO: We should see if Vector3 breaks this.
- byte r = (byte)((cmyk.X * k) / 255);
- byte g = (byte)((cmyk.Y * k) / 255);
- byte b = (byte)((cmyk.Z * k) / 255);
-
- ref TPixel pixel = ref Unsafe.Add(ref imageRowRef, x);
- var rgba = new Rgba32(r, g, b);
- pixel.PackFromRgba32(rgba);
- }
- }
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- private void FillRgbImage(ImageFrame image)
- where TPixel : struct, IPixel
- {
- for (int y = 0; y < image.Height; y++)
- {
- Span imageRowSpan = image.GetPixelRowSpan(y);
- Span areaRowSpan = this.pixelArea.GetRowSpan(y);
-
- PixelOperations.Instance.PackFromRgb24Bytes(areaRowSpan, imageRowSpan, image.Width);
- }
- }
-
///
/// Reads a from the stream advancing it by two bytes
///