diff --git a/src/UglyToad.PdfPig/Graphics/Colors/ColorSpaceDetails.cs b/src/UglyToad.PdfPig/Graphics/Colors/ColorSpaceDetails.cs index 55df8e0a..6e5dd1aa 100644 --- a/src/UglyToad.PdfPig/Graphics/Colors/ColorSpaceDetails.cs +++ b/src/UglyToad.PdfPig/Graphics/Colors/ColorSpaceDetails.cs @@ -63,7 +63,7 @@ /// /// Transform image bytes. /// - internal abstract ReadOnlySpan Transform(ReadOnlySpan decoded); + internal abstract Span Transform(Span decoded); /// /// Convert to byte. @@ -131,7 +131,7 @@ } /// - internal override ReadOnlySpan Transform(ReadOnlySpan decoded) + internal override Span Transform(Span decoded) { return decoded; } @@ -193,7 +193,7 @@ } /// - internal override ReadOnlySpan Transform(ReadOnlySpan decoded) + internal override Span Transform(Span decoded) { return decoded; } @@ -256,7 +256,7 @@ } /// - internal override ReadOnlySpan Transform(ReadOnlySpan decoded) + internal override Span Transform(Span decoded) { return decoded; } @@ -360,80 +360,82 @@ }); } - internal ReadOnlySpan UnwrapIndexedColorSpaceBytes(ReadOnlySpan input) + internal Span UnwrapIndexedColorSpaceBytes(Span input) { - var multiplier = 1; - Func>? transformer = null; switch (BaseType) { case ColorSpace.DeviceRGB: case ColorSpace.CalRGB: case ColorSpace.Lab: - transformer = x => + { + Span result = new byte[input.Length * 3]; + var i = 0; + foreach (var x in input) { - var r = new byte[3]; - for (var i = 0; i < 3; i++) + for (var j = 0; j < 3; ++j) { - r[i] = ColorTable[x * 3 + i]; + result[i++] = ColorTable[x * 3 + j]; } + } - return r; - }; - multiplier = 3; - break; + return result; + } case ColorSpace.DeviceCMYK: - transformer = x => + { + Span result = new byte[input.Length * 4]; + var i = 0; + foreach (var x in input) { - var r = new byte[4]; - for (var i = 0; i < 4; i++) + for (var j = 0; j < 4; ++j) { - r[i] = ColorTable[x * 4 + i]; + result[i++] = ColorTable[x * 4 + j]; } + } - return r; - }; - - multiplier = 4; - break; + return result; + } case ColorSpace.DeviceGray: case ColorSpace.CalGray: case ColorSpace.Separation: - transformer = x => new[] { ColorTable[x] }; - multiplier = 1; - break; + { + for (var i = 0; i < input.Length; ++i) + { + ref byte b = ref input[i]; + b = ColorTable[b]; + } + + return input; + } case ColorSpace.DeviceN: case ColorSpace.ICCBased: - transformer = x => + { + int i = 0; + if (BaseColorSpace.NumberOfColorComponents == 1) { - var r = new byte[BaseColorSpace.NumberOfColorComponents]; - for (var i = 0; i < BaseColorSpace.NumberOfColorComponents; i++) + // In place + for (i = 0; i < input.Length; ++i) { - r[i] = ColorTable[x * BaseColorSpace.NumberOfColorComponents + i]; + ref byte b = ref input[i]; + b = ColorTable[b]; } - return r; - }; - - multiplier = BaseColorSpace.NumberOfColorComponents; - break; - } - - if (transformer != null) - { - var result = new byte[input.Length * multiplier]; - var i = 0; - foreach (var b in input) - { - foreach (var newByte in transformer(b).Span) - { - result[i++] = newByte; + return input; } - } - return result; + Span result = new byte[input.Length * BaseColorSpace.NumberOfColorComponents]; + foreach (var x in input) + { + for (var j = 0; j < BaseColorSpace.NumberOfColorComponents; ++j) + { + result[i++] = ColorTable[x * BaseColorSpace.NumberOfColorComponents + j]; + } + } + + return result; + } } return input; @@ -453,7 +455,7 @@ /// Unwrap then transform using base color space details. /// /// - internal override ReadOnlySpan Transform(ReadOnlySpan decoded) + internal override Span Transform(Span decoded) { var unwraped = UnwrapIndexedColorSpaceBytes(decoded); return BaseColorSpace.Transform(unwraped); @@ -549,7 +551,7 @@ } /// - internal override ReadOnlySpan Transform(ReadOnlySpan decoded) + internal override Span Transform(Span decoded) { var cache = new Dictionary(); var transformed = new List(); @@ -726,7 +728,7 @@ } /// - internal override ReadOnlySpan Transform(ReadOnlySpan values) + internal override Span Transform(Span values) { var colorCache = new Dictionary(values.Length); var transformed = new List(values.Length); @@ -842,7 +844,7 @@ } /// - internal override ReadOnlySpan Transform(ReadOnlySpan decoded) + internal override Span Transform(Span decoded) { var transformed = new byte[decoded.Length]; @@ -984,7 +986,7 @@ } /// - internal override ReadOnlySpan Transform(ReadOnlySpan decoded) + internal override Span Transform(Span decoded) { var transformed = new byte[decoded.Length]; int index = 0; @@ -1106,7 +1108,7 @@ } /// - internal override ReadOnlySpan Transform(ReadOnlySpan decoded) + internal override Span Transform(Span decoded) { var transformed = new byte[decoded.Length]; int index = 0; @@ -1293,7 +1295,7 @@ } /// - internal override ReadOnlySpan Transform(ReadOnlySpan decoded) + internal override Span Transform(Span decoded) { // TODO - use ICC profile @@ -1391,7 +1393,7 @@ /// Cannot be called for , will throw a . /// /// - internal override ReadOnlySpan Transform(ReadOnlySpan decoded) + internal override Span Transform(Span decoded) { throw new InvalidOperationException("PatternColorSpaceDetails"); } @@ -1446,7 +1448,7 @@ } /// - internal override ReadOnlySpan Transform(ReadOnlySpan decoded) + internal override Span Transform(Span decoded) { throw new InvalidOperationException("UnsupportedColorSpaceDetails"); }