Browse Source

Add support for decoding 24bit per channel color tiff with planar pixel data

pull/1724/head
Brian Popow 5 years ago
parent
commit
28c1356a76
  1. 2
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb16PlanarTiffColor{TPixel}.cs
  2. 87
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb24PlanarTiffColor{TPixel}.cs
  3. 5
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorDecoderFactory{TPixel}.cs
  4. 2
      tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
  5. 2
      tests/ImageSharp.Tests/TestImages.cs
  6. 3
      tests/Images/Input/Tiff/flower-rgb-planar-24.tiff
  7. 3
      tests/Images/Input/Tiff/flower-rgb-planar-24_lsb.tiff

2
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb16PlanarTiffColor{TPixel}.cs

@ -10,7 +10,7 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
{
/// <summary>
/// Implements the 'RGB' photometric interpretation with 'Planar' layout for all 16 bit.
/// Implements the 'RGB' photometric interpretation with 'Planar' layout for each color channel with 16 bit.
/// </summary>
internal class Rgb16PlanarTiffColor<TPixel> : TiffBasePlanarColorDecoder<TPixel>
where TPixel : unmanaged, IPixel<TPixel>

87
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb24PlanarTiffColor{TPixel}.cs

@ -0,0 +1,87 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Buffers;
using System.Numerics;
using SixLabors.ImageSharp.Formats.Tiff.Utils;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
{
/// <summary>
/// Implements the 'RGB' photometric interpretation with 'Planar' layout for each color channel with 24 bit.
/// </summary>
internal class Rgb24PlanarTiffColor<TPixel> : TiffBasePlanarColorDecoder<TPixel>
where TPixel : unmanaged, IPixel<TPixel>
{
private readonly bool isBigEndian;
/// <summary>
/// Initializes a new instance of the <see cref="Rgb24PlanarTiffColor{TPixel}" /> class.
/// </summary>
/// <param name="isBigEndian">if set to <c>true</c> decodes the pixel data as big endian, otherwise as little endian.</param>
public Rgb24PlanarTiffColor(bool isBigEndian) => this.isBigEndian = isBigEndian;
/// <inheritdoc/>
public override void Decode(IMemoryOwner<byte>[] data, Buffer2D<TPixel> pixels, int left, int top, int width, int height)
{
// Note: due to an issue with netcore 2.1 and default values and unpredictable behavior with those,
// we define our own defaults as a workaround. See: https://github.com/dotnet/runtime/issues/55623
var color = default(TPixel);
color.FromVector4(TiffUtils.Vector4Default);
float scale = 1.0f / 0xFFFFFF;
byte[] buffer = new byte[4];
int bufferStartIdx = this.isBigEndian ? 1 : 0;
Span<byte> redData = data[0].GetSpan();
Span<byte> greenData = data[1].GetSpan();
Span<byte> blueData = data[2].GetSpan();
int offset = 0;
for (int y = top; y < top + height; y++)
{
Span<TPixel> pixelRow = pixels.GetRowSpan(y).Slice(left, width);
if (this.isBigEndian)
{
for (int x = 0; x < pixelRow.Length; x++)
{
redData.Slice(offset, 3).CopyTo(buffer.AsSpan(bufferStartIdx));
ulong r = TiffUtils.ConvertToUIntBigEndian(buffer);
greenData.Slice(offset, 3).CopyTo(buffer.AsSpan(bufferStartIdx));
ulong g = TiffUtils.ConvertToUIntBigEndian(buffer);
blueData.Slice(offset, 3).CopyTo(buffer.AsSpan(bufferStartIdx));
ulong b = TiffUtils.ConvertToUIntBigEndian(buffer);
offset += 3;
var colorVector = new Vector4(r * scale, g * scale, b * scale, 1.0f);
color.FromVector4(colorVector);
pixelRow[x] = color;
}
}
else
{
for (int x = 0; x < pixelRow.Length; x++)
{
redData.Slice(offset, 3).CopyTo(buffer.AsSpan(bufferStartIdx));
ulong r = TiffUtils.ConvertToUIntLittleEndian(buffer);
greenData.Slice(offset, 3).CopyTo(buffer.AsSpan(bufferStartIdx));
ulong g = TiffUtils.ConvertToUIntLittleEndian(buffer);
blueData.Slice(offset, 3).CopyTo(buffer.AsSpan(bufferStartIdx));
ulong b = TiffUtils.ConvertToUIntLittleEndian(buffer);
offset += 3;
var colorVector = new Vector4(r * scale, g * scale, b * scale, 1.0f);
color.FromVector4(colorVector);
pixelRow[x] = color;
}
}
}
}
}
}

5
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorDecoderFactory{TPixel}.cs

@ -166,6 +166,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
return new Rgb16PlanarTiffColor<TPixel>(byteOrder == ByteOrder.BigEndian);
}
if (bitsPerSample.Channel0 == 24 && bitsPerSample.Channel1 == 24 && bitsPerSample.Channel2 == 24)
{
return new Rgb24PlanarTiffColor<TPixel>(byteOrder == ByteOrder.BigEndian);
}
return new RgbPlanarTiffColor<TPixel>(bitsPerSample);
default:

2
tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs

@ -176,6 +176,8 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
[Theory]
[WithFile(FlowerRgb242424Contiguous, PixelTypes.Rgba32)]
[WithFile(FlowerRgb242424ContiguousLittleEndian, PixelTypes.Rgba32)]
[WithFile(FlowerRgb242424Planar, PixelTypes.Rgba32)]
[WithFile(FlowerRgb242424PlanarLittleEndian, PixelTypes.Rgba32)]
public void TiffDecoder_CanDecode_72Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel> => TestTiffDecoder(provider);

2
tests/ImageSharp.Tests/TestImages.cs

@ -561,6 +561,8 @@ namespace SixLabors.ImageSharp.Tests
public const string RgbPalette = "Tiff/rgb_palette.tiff";
public const string Rgb4BitPalette = "Tiff/bike_colorpalette_4bit.tiff";
public const string RgbPaletteDeflate = "Tiff/rgb_palette_deflate.tiff";
public const string FlowerRgb242424Planar = "Tiff/flower-rgb-planar-24.tiff";
public const string FlowerRgb242424PlanarLittleEndian = "Tiff/flower-rgb-planar-24_lsb.tiff";
public const string FlowerRgb242424Contiguous = "Tiff/flower-rgb-contig-24.tiff";
public const string FlowerRgb242424ContiguousLittleEndian = "Tiff/flower-rgb-contig-24_lsb.tiff";
public const string FlowerRgb161616Contiguous = "Tiff/flower-rgb-contig-16.tiff";

3
tests/Images/Input/Tiff/flower-rgb-planar-24.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:752452ac51ad1e836fb81267ab708ff81cf81a4c7e00daeed703f67782b563ec
size 28586

3
tests/Images/Input/Tiff/flower-rgb-planar-24_lsb.tiff

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:72f27af4fe177ebe47bef2af64723497d5a5f44808424bedfc2012fe4e3fc34e
size 28586
Loading…
Cancel
Save