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)
{
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/>
@ -303,20 +303,22 @@
/// </summary>
public byte HiVal { get; }
private readonly byte[] colorTable;
/// <summary>
/// Provides the mapping between index values and the corresponding colors in the base color space.
/// </summary>
public IReadOnlyList<byte> ColorTable { get; }
public ReadOnlySpan<byte> ColorTable => colorTable;
/// <summary>
/// Create a new <see cref="IndexedColorSpaceDetails"/>.
/// </summary>
public IndexedColorSpaceDetails(ColorSpaceDetails baseColorSpaceDetails, byte hiVal, IReadOnlyList<byte> colorTable)
public IndexedColorSpaceDetails(ColorSpaceDetails baseColorSpaceDetails, byte hiVal, byte[] colorTable)
: base(ColorSpace.Indexed)
{
BaseColorSpace = baseColorSpaceDetails ?? throw new ArgumentNullException(nameof(baseColorSpaceDetails));
HiVal = hiVal;
ColorTable = colorTable;
this.colorTable = colorTable;
BaseType = baseColorSpaceDetails.Type;
}
@ -361,7 +363,7 @@
internal ReadOnlySpan<byte> UnwrapIndexedColorSpaceBytes(ReadOnlySpan<byte> input)
{
var multiplier = 1;
Func<byte, IEnumerable<byte>>? transformer = null;
Func<byte, ReadOnlyMemory<byte>>? transformer = null;
switch (BaseType)
{
case ColorSpace.DeviceRGB:
@ -425,7 +427,7 @@
var i = 0;
foreach (var b in input)
{
foreach (var newByte in transformer(b))
foreach (var newByte in transformer(b).Span)
{
result[i++] = newByte;
}
@ -726,7 +728,7 @@
/// <inheritdoc/>
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);
for (var i = 0; i < values.Length; i += 3)
{
@ -795,19 +797,19 @@
/// <summary>
/// Create a new <see cref="CalGrayColorSpaceDetails"/>.
/// </summary>
public CalGrayColorSpaceDetails(IReadOnlyList<double> whitePoint, IReadOnlyList<double>? blackPoint, double? gamma)
public CalGrayColorSpaceDetails(double[] whitePoint, double[]? blackPoint, double? gamma)
: base(ColorSpace.CalGray)
{
WhitePoint = whitePoint ?? throw new ArgumentNullException(nameof(whitePoint));
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)
{
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;
@ -927,31 +929,31 @@
/// <summary>
/// Create a new <see cref="CalRGBColorSpaceDetails"/>.
/// </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)
{
WhitePoint = whitePoint ?? throw new ArgumentNullException(nameof(whitePoint));
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)
{
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)
{
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)
{
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 =
@ -1065,25 +1067,25 @@
/// <summary>
/// Create a new <see cref="LabColorSpaceDetails"/>.
/// </summary>
public LabColorSpaceDetails(IReadOnlyList<double> whitePoint, IReadOnlyList<double>? blackPoint, IReadOnlyList<double>? matrix)
public LabColorSpaceDetails(double[] whitePoint, double[]? blackPoint, double[]? matrix)
: base(ColorSpace.Lab)
{
WhitePoint = whitePoint?.Select(v => v).ToArray() ?? throw new ArgumentNullException(nameof(whitePoint));
if (WhitePoint.Count != 3)
WhitePoint = whitePoint ?? throw new ArgumentNullException(nameof(whitePoint));
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)
{
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)
{
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);

View File

@ -2,15 +2,14 @@
{
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Content;
using Filters;
using Graphics.Colors;
using Parser.Parts;
using System.Linq;
using Tokenization.Scanner;
using Tokens;
using UglyToad.PdfPig.Functions;
using System;
internal static class ColorSpaceMapper
{
@ -56,7 +55,7 @@
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 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);
}
@ -195,14 +194,14 @@
var whitePoint = whitePointToken.Data.OfType<NumericToken>().Select(x => x.Double).ToArray();
// BlackPoint is optional
IReadOnlyList<double>? blackPoint = null;
double[]? blackPoint = null;
if (dictionaryToken.TryGet(NameToken.BlackPoint, scanner, out ArrayToken? blackPointToken))
{
blackPoint = blackPointToken.Data.OfType<NumericToken>().Select(x => x.Double).ToArray();
}
// Matrix is optional
IReadOnlyList<double>? matrix = null;
double[]? matrix = null;
if (dictionaryToken.TryGet(NameToken.Matrix, scanner, out ArrayToken? matrixToken))
{
matrix = matrixToken.Data.OfType<NumericToken>().Select(x => x.Double).ToArray();
@ -245,7 +244,7 @@
}
// Range is optional
IReadOnlyList<double>? range = null;
double[]? range = null;
if (streamToken.StreamDictionary.TryGet(NameToken.Range, scanner, out ArrayToken? arrayToken))
{
range = arrayToken.Data.OfType<NumericToken>().Select(x => x.Double).ToArray();