diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero16TiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero16TiffColor{TPixel}.cs index 13a570dbcb..79017d8ce8 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero16TiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero16TiffColor{TPixel}.cs @@ -32,15 +32,25 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation var l16 = default(L16); for (int y = top; y < top + height; y++) { - for (int x = left; x < left + width; x++) + if (this.isBigEndian) { - ushort intensity = TiffUtils.ConvertToShort(data.Slice(offset, 2), this.isBigEndian); - offset += 2; + for (int x = left; x < left + width; x++) + { + ushort intensity = TiffUtils.ConvertToShortBigEndian(data.Slice(offset, 2)); + offset += 2; - l16.PackedValue = intensity; - color.FromL16(l16); + pixels[x, y] = TiffUtils.ColorFromL16(l16, intensity, color); + } + } + else + { + for (int x = left; x < left + width; x++) + { + ushort intensity = TiffUtils.ConvertToShortLittleEndian(data.Slice(offset, 2)); + offset += 2; - pixels[x, y] = color; + pixels[x, y] = TiffUtils.ColorFromL16(l16, intensity, color); + } } } } diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb161616TiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb161616TiffColor{TPixel}.cs index 89cf1cb48e..d2cb65cd5e 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb161616TiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb161616TiffColor{TPixel}.cs @@ -34,19 +34,33 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation { Span pixelRow = pixels.GetRowSpan(y); - for (int x = left; x < left + width; x++) + if (this.isBigEndian) { - ulong r = TiffUtils.ConvertToShort(data.Slice(offset, 2), this.isBigEndian); - offset += 2; - ulong g = TiffUtils.ConvertToShort(data.Slice(offset, 2), this.isBigEndian); - offset += 2; - ulong b = TiffUtils.ConvertToShort(data.Slice(offset, 2), this.isBigEndian); - offset += 2; + for (int x = left; x < left + width; x++) + { + ulong r = TiffUtils.ConvertToShortBigEndian(data.Slice(offset, 2)); + offset += 2; + ulong g = TiffUtils.ConvertToShortBigEndian(data.Slice(offset, 2)); + offset += 2; + ulong b = TiffUtils.ConvertToShortBigEndian(data.Slice(offset, 2)); + offset += 2; - rgba.PackedValue = r | (g << 16) | (b << 32) | (0xfffful << 48); - color.FromRgba64(rgba); + pixelRow[x] = TiffUtils.ColorFromRgba64(rgba, r, g, b, color); + } + } + else + { + for (int x = left; x < left + width; x++) + { + ulong r = TiffUtils.ConvertToShortLittleEndian(data.Slice(offset, 2)); + offset += 2; + ulong g = TiffUtils.ConvertToShortLittleEndian(data.Slice(offset, 2)); + offset += 2; + ulong b = TiffUtils.ConvertToShortLittleEndian(data.Slice(offset, 2)); + offset += 2; - pixelRow[x] = color; + pixelRow[x] = TiffUtils.ColorFromRgba64(rgba, r, g, b, color); + } } } } diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb16PlanarTiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb16PlanarTiffColor{TPixel}.cs index 75b0b3a8b6..43b985c907 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb16PlanarTiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb16PlanarTiffColor{TPixel}.cs @@ -35,17 +35,31 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation var rgba = default(Rgba64); for (int y = top; y < top + height; y++) { - for (int x = left; x < left + width; x++) + if (this.isBigEndian) { - ulong r = TiffUtils.ConvertToShort(redData.Slice(offset, 2), this.isBigEndian); - ulong g = TiffUtils.ConvertToShort(greenData.Slice(offset, 2), this.isBigEndian); - ulong b = TiffUtils.ConvertToShort(blueData.Slice(offset, 2), this.isBigEndian); + for (int x = left; x < left + width; x++) + { + ulong r = TiffUtils.ConvertToShortBigEndian(redData.Slice(offset, 2)); + ulong g = TiffUtils.ConvertToShortBigEndian(greenData.Slice(offset, 2)); + ulong b = TiffUtils.ConvertToShortBigEndian(blueData.Slice(offset, 2)); - offset += 2; + offset += 2; - rgba.PackedValue = r | (g << 16) | (b << 32) | (0xfffful << 48); - color.FromRgba64(rgba); - pixels[x, y] = color; + pixels[x, y] = TiffUtils.ColorFromRgba64(rgba, r, g, b, color); + } + } + else + { + for (int x = left; x < left + width; x++) + { + ulong r = TiffUtils.ConvertToShortLittleEndian(redData.Slice(offset, 2)); + ulong g = TiffUtils.ConvertToShortLittleEndian(greenData.Slice(offset, 2)); + ulong b = TiffUtils.ConvertToShortLittleEndian(blueData.Slice(offset, 2)); + + offset += 2; + + pixels[x, y] = TiffUtils.ColorFromRgba64(rgba, r, g, b, color); + } } } } diff --git a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero16TiffColor{TPixel}.cs b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero16TiffColor{TPixel}.cs index d84efef66a..7a0aae2678 100644 --- a/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero16TiffColor{TPixel}.cs +++ b/src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero16TiffColor{TPixel}.cs @@ -32,15 +32,25 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation var l16 = default(L16); for (int y = top; y < top + height; y++) { - for (int x = left; x < left + width; x++) + if (this.isBigEndian) { - ushort intensity = (ushort)(ushort.MaxValue - TiffUtils.ConvertToShort(data.Slice(offset, 2), this.isBigEndian)); - offset += 2; + for (int x = left; x < left + width; x++) + { + ushort intensity = (ushort)(ushort.MaxValue - TiffUtils.ConvertToShortBigEndian(data.Slice(offset, 2))); + offset += 2; - l16.PackedValue = intensity; - color.FromL16(l16); + pixels[x, y] = TiffUtils.ColorFromL16(l16, intensity, color); + } + } + else + { + for (int x = left; x < left + width; x++) + { + ushort intensity = (ushort)(ushort.MaxValue - TiffUtils.ConvertToShortLittleEndian(data.Slice(offset, 2))); + offset += 2; - pixels[x, y] = color; + pixels[x, y] = TiffUtils.ColorFromL16(l16, intensity, color); + } } } } diff --git a/src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs b/src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs index 5a31b231ec..4f769c0475 100644 --- a/src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs +++ b/src/ImageSharp/Formats/Tiff/Utils/TiffUtils.cs @@ -3,6 +3,8 @@ using System; using System.Buffers.Binary; +using System.Runtime.CompilerServices; +using SixLabors.ImageSharp.PixelFormats; namespace SixLabors.ImageSharp.Formats.Tiff.Utils { @@ -11,8 +13,30 @@ namespace SixLabors.ImageSharp.Formats.Tiff.Utils /// internal static class TiffUtils { - public static ushort ConvertToShort(ReadOnlySpan buffer, bool isBigEndian) => isBigEndian - ? BinaryPrimitives.ReadUInt16BigEndian(buffer) - : BinaryPrimitives.ReadUInt16LittleEndian(buffer); + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort ConvertToShortBigEndian(ReadOnlySpan buffer) => + BinaryPrimitives.ReadUInt16BigEndian(buffer); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ushort ConvertToShortLittleEndian(ReadOnlySpan buffer) => + BinaryPrimitives.ReadUInt16LittleEndian(buffer); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TPixel ColorFromL16(L16 l16, ushort intensity, TPixel color) + where TPixel : unmanaged, IPixel + { + l16.PackedValue = intensity; + color.FromL16(l16); + return color; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static TPixel ColorFromRgba64(Rgba64 rgba, ulong r, ulong g, ulong b, TPixel color) + where TPixel : unmanaged, IPixel + { + rgba.PackedValue = r | (g << 16) | (b << 32) | (0xfffful << 48); + color.FromRgba64(rgba); + return color; + } } }