Skip to content

Commit 1b32629

Browse files
Improve performance of Tiff decoders
1 parent e101736 commit 1b32629

12 files changed

+47
-16
lines changed

src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero1TiffColor.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,18 @@ public static void Decode<TPixel>(byte[] data, Buffer2D<TPixel> pixels, int left
3333

3434
for (int y = top; y < top + height; y++)
3535
{
36+
Span<TPixel> buffer = pixels.GetRowSpan(y);
3637
for (int x = left; x < left + width; x += 8)
3738
{
3839
byte b = data[offset++];
3940
int maxShift = Math.Min(left + width - x, 8);
4041

41-
for (int shift = 0; shift < maxShift; shift++)
42+
for (int shift = 0, index = x; shift < maxShift; shift++, index++)
4243
{
4344
int bit = (b >> (7 - shift)) & 1;
4445
byte intensity = (bit == 1) ? (byte)255 : (byte)0;
4546
color.FromRgba32(new Rgba32(intensity, intensity, intensity, 255));
46-
pixels[x + shift, y] = color;
47+
buffer[index] = color;
4748
}
4849
}
4950
}

src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero4TiffColor.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Six Labors and contributors.
22
// Licensed under the Apache License, Version 2.0.
33

4+
using System;
45
using System.Runtime.CompilerServices;
56
using SixLabors.ImageSharp.Memory;
67
using SixLabors.ImageSharp.PixelFormats;
@@ -33,17 +34,19 @@ public static void Decode<TPixel>(byte[] data, Buffer2D<TPixel> pixels, int left
3334

3435
for (int y = top; y < top + height; y++)
3536
{
37+
Span<TPixel> buffer = pixels.GetRowSpan(y);
38+
3639
for (int x = left; x < left + width - 1; x += 2)
3740
{
3841
byte byteData = data[offset++];
3942

4043
byte intensity1 = (byte)(((byteData & 0xF0) >> 4) * 17);
4144
color.FromRgba32(new Rgba32(intensity1, intensity1, intensity1, 255));
42-
pixels[x, y] = color;
45+
buffer[x] = color;
4346

4447
byte intensity2 = (byte)((byteData & 0x0F) * 17);
4548
color.FromRgba32(new Rgba32(intensity2, intensity2, intensity2, 255));
46-
pixels[x + 1, y] = color;
49+
buffer[x + 1] = color;
4750
}
4851

4952
if (isOddWidth)

src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZero8TiffColor.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Six Labors and contributors.
22
// Licensed under the Apache License, Version 2.0.
33

4+
using System;
45
using System.Runtime.CompilerServices;
56
using SixLabors.ImageSharp.Memory;
67
using SixLabors.ImageSharp.PixelFormats;
@@ -32,11 +33,13 @@ public static void Decode<TPixel>(byte[] data, Buffer2D<TPixel> pixels, int left
3233

3334
for (int y = top; y < top + height; y++)
3435
{
36+
Span<TPixel> buffer = pixels.GetRowSpan(y);
37+
3538
for (int x = left; x < left + width; x++)
3639
{
3740
byte intensity = data[offset++];
3841
color.FromRgba32(new Rgba32(intensity, intensity, intensity, 255));
39-
pixels[x, y] = color;
42+
buffer[x] = color;
4043
}
4144
}
4245
}

src/ImageSharp/Formats/Tiff/PhotometricInterpretation/BlackIsZeroTiffColor.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,14 @@ public static void Decode<TPixel>(byte[] data, uint[] bitsPerSample, Buffer2D<TP
3636

3737
for (int y = top; y < top + height; y++)
3838
{
39+
Span<TPixel> buffer = pixels.GetRowSpan(y);
40+
3941
for (int x = left; x < left + width; x++)
4042
{
4143
int value = bitReader.ReadBits(bitsPerSample[0]);
4244
float intensity = ((float)value) / factor;
4345
color.FromVector4(new Vector4(intensity, intensity, intensity, 1.0f));
44-
pixels[x, y] = color;
46+
buffer[x] = color;
4547
}
4648

4749
bitReader.NextRow();

src/ImageSharp/Formats/Tiff/PhotometricInterpretation/PaletteTiffColor.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,12 @@ public static void Decode<TPixel>(byte[] data, uint[] bitsPerSample, uint[] colo
3737

3838
for (int y = top; y < top + height; y++)
3939
{
40+
Span<TPixel> buffer = pixels.GetRowSpan(y);
41+
4042
for (int x = left; x < left + width; x++)
4143
{
4244
int index = bitReader.ReadBits(bitsPerSample[0]);
43-
pixels[x, y] = palette[index];
45+
buffer[x] = palette[index];
4446
}
4547

4648
bitReader.NextRow();

src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb888TiffColor.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Six Labors and contributors.
22
// Licensed under the Apache License, Version 2.0.
33

4+
using System;
45
using System.Runtime.CompilerServices;
56
using SixLabors.ImageSharp.Memory;
67
using SixLabors.ImageSharp.PixelFormats;
@@ -32,13 +33,15 @@ public static void Decode<TPixel>(byte[] data, Buffer2D<TPixel> pixels, int left
3233

3334
for (int y = top; y < top + height; y++)
3435
{
36+
Span<TPixel> buffer = pixels.GetRowSpan(y);
37+
3538
for (int x = left; x < left + width; x++)
3639
{
3740
byte r = data[offset++];
3841
byte g = data[offset++];
3942
byte b = data[offset++];
4043
color.FromRgba32(new Rgba32(r, g, b, 255));
41-
pixels[x, y] = color;
44+
buffer[x] = color;
4245
}
4346
}
4447
}

src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbPlanarTiffColor.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,16 @@ public static void Decode<TPixel>(byte[][] data, uint[] bitsPerSample, Buffer2D<
4040

4141
for (int y = top; y < top + height; y++)
4242
{
43+
Span<TPixel> buffer = pixels.GetRowSpan(y);
44+
4345
for (int x = left; x < left + width; x++)
4446
{
4547
float r = ((float)rBitReader.ReadBits(bitsPerSample[0])) / rFactor;
4648
float g = ((float)gBitReader.ReadBits(bitsPerSample[1])) / gFactor;
4749
float b = ((float)bBitReader.ReadBits(bitsPerSample[2])) / bFactor;
4850
color.FromVector4(new Vector4(r, g, b, 1.0f));
49-
pixels[x, y] = color;
51+
52+
buffer[x] = color;
5053
}
5154

5255
rBitReader.NextRow();

src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbTiffColor.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,16 @@ public static void Decode<TPixel>(byte[] data, uint[] bitsPerSample, Buffer2D<TP
3838

3939
for (int y = top; y < top + height; y++)
4040
{
41+
Span<TPixel> buffer = pixels.GetRowSpan(y);
42+
4143
for (int x = left; x < left + width; x++)
4244
{
4345
float r = ((float)bitReader.ReadBits(bitsPerSample[0])) / rFactor;
4446
float g = ((float)bitReader.ReadBits(bitsPerSample[1])) / gFactor;
4547
float b = ((float)bitReader.ReadBits(bitsPerSample[2])) / bFactor;
4648
color.FromVector4(new Vector4(r, g, b, 1.0f));
47-
pixels[x, y] = color;
49+
50+
buffer[x] = color;
4851
}
4952

5053
bitReader.NextRow();

src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero1TiffColor.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,20 @@ public static void Decode<TPixel>(byte[] data, Buffer2D<TPixel> pixels, int left
3333

3434
for (int y = top; y < top + height; y++)
3535
{
36+
Span<TPixel> buffer = pixels.GetRowSpan(y);
37+
3638
for (int x = left; x < left + width; x += 8)
3739
{
3840
byte b = data[offset++];
3941
int maxShift = Math.Min(left + width - x, 8);
4042

41-
for (int shift = 0; shift < maxShift; shift++)
43+
for (int shift = 0, index = x; shift < maxShift; shift++, index++)
4244
{
4345
int bit = (b >> (7 - shift)) & 1;
4446
byte intensity = (bit == 1) ? (byte)0 : (byte)255;
4547
color.FromRgba32(new Rgba32(intensity, intensity, intensity, 255));
46-
pixels[x + shift, y] = color;
48+
49+
buffer[index] = color;
4750
}
4851
}
4952
}

src/ImageSharp/Formats/Tiff/PhotometricInterpretation/WhiteIsZero4TiffColor.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Six Labors and contributors.
22
// Licensed under the Apache License, Version 2.0.
33

4+
using System;
45
using System.Runtime.CompilerServices;
56
using SixLabors.ImageSharp.Memory;
67
using SixLabors.ImageSharp.PixelFormats;
@@ -33,17 +34,19 @@ public static void Decode<TPixel>(byte[] data, Buffer2D<TPixel> pixels, int left
3334

3435
for (int y = top; y < top + height; y++)
3536
{
37+
Span<TPixel> buffer = pixels.GetRowSpan(y);
38+
3639
for (int x = left; x < left + width - 1; x += 2)
3740
{
3841
byte byteData = data[offset++];
3942

4043
byte intensity1 = (byte)((15 - ((byteData & 0xF0) >> 4)) * 17);
4144
color.FromRgba32(new Rgba32(intensity1, intensity1, intensity1, 255));
42-
pixels[x, y] = color;
45+
buffer[x] = color;
4346

4447
byte intensity2 = (byte)((15 - (byteData & 0x0F)) * 17);
4548
color.FromRgba32(new Rgba32(intensity2, intensity2, intensity2, 255));
46-
pixels[x + 1, y] = color;
49+
buffer[x + 1] = color;
4750
}
4851

4952
if (isOddWidth)

0 commit comments

Comments
 (0)