Reduce ColorSpaceDetails virtual calls

This commit is contained in:
Jason Nelson 2024-04-01 19:11:17 -07:00 committed by BobLd
parent 4fcc5c6c57
commit 8babdfdda5
2 changed files with 34 additions and 33 deletions

View File

@ -279,7 +279,7 @@
internal static ColorSpaceDetails Stencil(ColorSpaceDetails colorSpaceDetails, double[] decode) internal static ColorSpaceDetails Stencil(ColorSpaceDetails colorSpaceDetails, double[] decode)
{ {
var blackIsOne = decode.Length >= 2 && decode[0] == 1 && decode[1] == 0; var blackIsOne = decode.Length >= 2 && decode[0] == 1 && decode[1] == 0;
return new IndexedColorSpaceDetails(colorSpaceDetails, 1, blackIsOne ? new byte[] { 255, 0 } : new byte[] { 0, 255 }); return new IndexedColorSpaceDetails(colorSpaceDetails, 1, blackIsOne ? [255, 0] : [0, 255]);
} }
/// <inheritdoc/> /// <inheritdoc/>
@ -303,20 +303,22 @@
/// </summary> /// </summary>
public byte HiVal { get; } public byte HiVal { get; }
private readonly byte[] colorTable;
/// <summary> /// <summary>
/// Provides the mapping between index values and the corresponding colors in the base color space. /// Provides the mapping between index values and the corresponding colors in the base color space.
/// </summary> /// </summary>
public IReadOnlyList<byte> ColorTable { get; } public ReadOnlySpan<byte> ColorTable => colorTable;
/// <summary> /// <summary>
/// Create a new <see cref="IndexedColorSpaceDetails"/>. /// Create a new <see cref="IndexedColorSpaceDetails"/>.
/// </summary> /// </summary>
public IndexedColorSpaceDetails(ColorSpaceDetails baseColorSpaceDetails, byte hiVal, IReadOnlyList<byte> colorTable) public IndexedColorSpaceDetails(ColorSpaceDetails baseColorSpaceDetails, byte hiVal, byte[] colorTable)
: base(ColorSpace.Indexed) : base(ColorSpace.Indexed)
{ {
BaseColorSpace = baseColorSpaceDetails ?? throw new ArgumentNullException(nameof(baseColorSpaceDetails)); BaseColorSpace = baseColorSpaceDetails ?? throw new ArgumentNullException(nameof(baseColorSpaceDetails));
HiVal = hiVal; HiVal = hiVal;
ColorTable = colorTable; this.colorTable = colorTable;
BaseType = baseColorSpaceDetails.Type; BaseType = baseColorSpaceDetails.Type;
} }
@ -361,7 +363,7 @@
internal ReadOnlySpan<byte> UnwrapIndexedColorSpaceBytes(ReadOnlySpan<byte> input) internal ReadOnlySpan<byte> UnwrapIndexedColorSpaceBytes(ReadOnlySpan<byte> input)
{ {
var multiplier = 1; var multiplier = 1;
Func<byte, IEnumerable<byte>>? transformer = null; Func<byte, ReadOnlyMemory<byte>>? transformer = null;
switch (BaseType) switch (BaseType)
{ {
case ColorSpace.DeviceRGB: case ColorSpace.DeviceRGB:
@ -425,7 +427,7 @@
var i = 0; var i = 0;
foreach (var b in input) foreach (var b in input)
{ {
foreach (var newByte in transformer(b)) foreach (var newByte in transformer(b).Span)
{ {
result[i++] = newByte; result[i++] = newByte;
} }
@ -726,7 +728,7 @@
/// <inheritdoc/> /// <inheritdoc/>
internal override ReadOnlySpan<byte> Transform(ReadOnlySpan<byte> values) internal override ReadOnlySpan<byte> Transform(ReadOnlySpan<byte> values)
{ {
var cache = new Dictionary<int, double[]>(); var cache = new Dictionary<int, double[]>(values.Length * 3);
var transformed = new List<byte>(values.Length * 3); var transformed = new List<byte>(values.Length * 3);
for (var i = 0; i < values.Length; i += 3) for (var i = 0; i < values.Length; i += 3)
{ {
@ -795,19 +797,19 @@
/// <summary> /// <summary>
/// Create a new <see cref="CalGrayColorSpaceDetails"/>. /// Create a new <see cref="CalGrayColorSpaceDetails"/>.
/// </summary> /// </summary>
public CalGrayColorSpaceDetails(IReadOnlyList<double> whitePoint, IReadOnlyList<double>? blackPoint, double? gamma) public CalGrayColorSpaceDetails(double[] whitePoint, double[]? blackPoint, double? gamma)
: base(ColorSpace.CalGray) : base(ColorSpace.CalGray)
{ {
WhitePoint = whitePoint ?? throw new ArgumentNullException(nameof(whitePoint)); WhitePoint = whitePoint ?? throw new ArgumentNullException(nameof(whitePoint));
if (WhitePoint.Count != 3) if (WhitePoint.Count != 3)
{ {
throw new ArgumentOutOfRangeException(nameof(whitePoint), whitePoint, $"Must consist of exactly three numbers, but was passed {whitePoint.Count}."); throw new ArgumentOutOfRangeException(nameof(whitePoint), whitePoint, $"Must consist of exactly three numbers, but was passed {whitePoint.Length}.");
} }
BlackPoint = blackPoint ?? new[] { 0.0, 0, 0 }.ToArray(); BlackPoint = blackPoint ?? [0.0, 0, 0];
if (BlackPoint.Count != 3) if (BlackPoint.Count != 3)
{ {
throw new ArgumentOutOfRangeException(nameof(blackPoint), blackPoint, $"Must consist of exactly three numbers, but was passed {blackPoint?.Count ?? 0}."); throw new ArgumentOutOfRangeException(nameof(blackPoint), blackPoint, $"Must consist of exactly three numbers, but was passed {blackPoint?.Length ?? 0}.");
} }
Gamma = gamma ?? 1.0; Gamma = gamma ?? 1.0;
@ -927,31 +929,31 @@
/// <summary> /// <summary>
/// Create a new <see cref="CalRGBColorSpaceDetails"/>. /// Create a new <see cref="CalRGBColorSpaceDetails"/>.
/// </summary> /// </summary>
public CalRGBColorSpaceDetails(IReadOnlyList<double> whitePoint, IReadOnlyList<double>? blackPoint, IReadOnlyList<double>? gamma, IReadOnlyList<double>? matrix) public CalRGBColorSpaceDetails(double[] whitePoint, double[]? blackPoint, double[]? gamma, double[]? matrix)
: base(ColorSpace.CalRGB) : base(ColorSpace.CalRGB)
{ {
WhitePoint = whitePoint ?? throw new ArgumentNullException(nameof(whitePoint)); WhitePoint = whitePoint ?? throw new ArgumentNullException(nameof(whitePoint));
if (WhitePoint.Count != 3) if (WhitePoint.Count != 3)
{ {
throw new ArgumentOutOfRangeException(nameof(whitePoint), whitePoint, $"Must consist of exactly three numbers, but was passed {whitePoint.Count}."); throw new ArgumentOutOfRangeException(nameof(whitePoint), whitePoint, $"Must consist of exactly three numbers, but was passed {whitePoint.Length}.");
} }
BlackPoint = blackPoint ?? new[] { 0.0, 0, 0 }; BlackPoint = blackPoint ?? [0.0, 0, 0];
if (BlackPoint.Count != 3) if (BlackPoint.Count != 3)
{ {
throw new ArgumentOutOfRangeException(nameof(blackPoint), blackPoint, $"Must consist of exactly three numbers, but was passed {blackPoint!.Count}."); throw new ArgumentOutOfRangeException(nameof(blackPoint), blackPoint, $"Must consist of exactly three numbers, but was passed {blackPoint!.Length}.");
} }
Gamma = gamma ?? new[] { 1.0, 1, 1 }; Gamma = gamma ?? [1.0, 1, 1];
if (Gamma.Count != 3) if (Gamma.Count != 3)
{ {
throw new ArgumentOutOfRangeException(nameof(gamma), gamma, $"Must consist of exactly three numbers, but was passed {gamma!.Count}."); throw new ArgumentOutOfRangeException(nameof(gamma), gamma, $"Must consist of exactly three numbers, but was passed {gamma!.Length}.");
} }
Matrix = matrix ?? new[] { 1.0, 0, 0, 0, 1, 0, 0, 0, 1 }; Matrix = matrix ?? [1.0, 0, 0, 0, 1, 0, 0, 0, 1];
if (Matrix.Count != 9) if (Matrix.Count != 9)
{ {
throw new ArgumentOutOfRangeException(nameof(matrix), matrix, $"Must consist of exactly nine numbers, but was passed {matrix!.Count}."); throw new ArgumentOutOfRangeException(nameof(matrix), matrix, $"Must consist of exactly nine numbers, but was passed {matrix!.Length}.");
} }
colorSpaceTransformer = colorSpaceTransformer =
@ -1065,25 +1067,25 @@
/// <summary> /// <summary>
/// Create a new <see cref="LabColorSpaceDetails"/>. /// Create a new <see cref="LabColorSpaceDetails"/>.
/// </summary> /// </summary>
public LabColorSpaceDetails(IReadOnlyList<double> whitePoint, IReadOnlyList<double>? blackPoint, IReadOnlyList<double>? matrix) public LabColorSpaceDetails(double[] whitePoint, double[]? blackPoint, double[]? matrix)
: base(ColorSpace.Lab) : base(ColorSpace.Lab)
{ {
WhitePoint = whitePoint?.Select(v => v).ToArray() ?? throw new ArgumentNullException(nameof(whitePoint)); WhitePoint = whitePoint ?? throw new ArgumentNullException(nameof(whitePoint));
if (WhitePoint.Count != 3) if (whitePoint.Length != 3)
{ {
throw new ArgumentOutOfRangeException(nameof(whitePoint), whitePoint, $"Must consist of exactly three numbers, but was passed {whitePoint.Count}."); throw new ArgumentOutOfRangeException(nameof(whitePoint), whitePoint, $"Must consist of exactly three numbers, but was passed {whitePoint.Length}.");
} }
BlackPoint = blackPoint?.Select(v => v).ToArray() ?? new[] { 0.0, 0.0, 0.0 }; BlackPoint = blackPoint ?? [0.0, 0.0, 0.0];
if (BlackPoint.Count != 3) if (BlackPoint.Count != 3)
{ {
throw new ArgumentOutOfRangeException(nameof(blackPoint), blackPoint, $"Must consist of exactly three numbers, but was passed {blackPoint!.Count}."); throw new ArgumentOutOfRangeException(nameof(blackPoint), blackPoint, $"Must consist of exactly three numbers, but was passed {blackPoint!.Length}.");
} }
Matrix = matrix?.Select(v => v).ToArray() ?? new[] { -100.0, 100.0, -100.0, 100.0 }; Matrix = matrix ?? [-100.0, 100.0, -100.0, 100.0];
if (Matrix.Count != 4) if (Matrix.Count != 4)
{ {
throw new ArgumentOutOfRangeException(nameof(matrix), matrix, $"Must consist of exactly four numbers, but was passed {matrix!.Count}."); throw new ArgumentOutOfRangeException(nameof(matrix), matrix, $"Must consist of exactly four numbers, but was passed {matrix!.Length}.");
} }
colorSpaceTransformer = new CIEBasedColorSpaceTransformer((WhitePoint[0], WhitePoint[1], WhitePoint[2]), RGBWorkingSpace.sRGB); colorSpaceTransformer = new CIEBasedColorSpaceTransformer((WhitePoint[0], WhitePoint[1], WhitePoint[2]), RGBWorkingSpace.sRGB);

View File

@ -2,15 +2,14 @@
{ {
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content; using Content;
using Filters; using Filters;
using Graphics.Colors; using Graphics.Colors;
using Parser.Parts; using Parser.Parts;
using System.Linq;
using Tokenization.Scanner; using Tokenization.Scanner;
using Tokens; using Tokens;
using UglyToad.PdfPig.Functions; using UglyToad.PdfPig.Functions;
using System;
internal static class ColorSpaceMapper internal static class ColorSpaceMapper
{ {
@ -56,7 +55,7 @@
var colorSpaceDetails = GetColorSpaceDetails(colorSpace, imageDictionary.Without(NameToken.Filter).Without(NameToken.F), scanner, resourceStore, filterProvider, true); var colorSpaceDetails = GetColorSpaceDetails(colorSpace, imageDictionary.Without(NameToken.Filter).Without(NameToken.F), scanner, resourceStore, filterProvider, true);
var decodeRaw = imageDictionary.GetObjectOrDefault(NameToken.Decode, NameToken.D) as ArrayToken ?? new ArrayToken([]); var decodeRaw = imageDictionary.GetObjectOrDefault(NameToken.Decode, NameToken.D) as ArrayToken ?? new ArrayToken([]);
var decode = decodeRaw.Data.OfType<NumericToken>().Select(x => x.Double).ToArray(); var decode = decodeRaw.Data.OfType<NumericToken>().Select(static x => x.Double).ToArray();
return IndexedColorSpaceDetails.Stencil(colorSpaceDetails, decode); return IndexedColorSpaceDetails.Stencil(colorSpaceDetails, decode);
} }
@ -195,14 +194,14 @@
var whitePoint = whitePointToken.Data.OfType<NumericToken>().Select(x => x.Double).ToArray(); var whitePoint = whitePointToken.Data.OfType<NumericToken>().Select(x => x.Double).ToArray();
// BlackPoint is optional // BlackPoint is optional
IReadOnlyList<double>? blackPoint = null; double[]? blackPoint = null;
if (dictionaryToken.TryGet(NameToken.BlackPoint, scanner, out ArrayToken? blackPointToken)) if (dictionaryToken.TryGet(NameToken.BlackPoint, scanner, out ArrayToken? blackPointToken))
{ {
blackPoint = blackPointToken.Data.OfType<NumericToken>().Select(x => x.Double).ToArray(); blackPoint = blackPointToken.Data.OfType<NumericToken>().Select(x => x.Double).ToArray();
} }
// Matrix is optional // Matrix is optional
IReadOnlyList<double>? matrix = null; double[]? matrix = null;
if (dictionaryToken.TryGet(NameToken.Matrix, scanner, out ArrayToken? matrixToken)) if (dictionaryToken.TryGet(NameToken.Matrix, scanner, out ArrayToken? matrixToken))
{ {
matrix = matrixToken.Data.OfType<NumericToken>().Select(x => x.Double).ToArray(); matrix = matrixToken.Data.OfType<NumericToken>().Select(x => x.Double).ToArray();
@ -245,7 +244,7 @@
} }
// Range is optional // Range is optional
IReadOnlyList<double>? range = null; double[]? range = null;
if (streamToken.StreamDictionary.TryGet(NameToken.Range, scanner, out ArrayToken? arrayToken)) if (streamToken.StreamDictionary.TryGet(NameToken.Range, scanner, out ArrayToken? arrayToken))
{ {
range = arrayToken.Data.OfType<NumericToken>().Select(x => x.Double).ToArray(); range = arrayToken.Data.OfType<NumericToken>().Select(x => x.Double).ToArray();