Browse Source

Decoding 16bit rgb planar now also respects byte order

pull/1720/head
Brian Popow 5 years ago
parent
commit
a1ee0d638d
  1. 1
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb161616TiffColor{TPixel}.cs
  2. 53
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb16PlanarTiffColor{TPixel}.cs
  3. 4
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbPlanarTiffColor{TPixel}.cs
  4. 28
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffBasePlanarColorDecoder{TPixel}.cs
  5. 7
      src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffColorDecoderFactory{TPixel}.cs
  6. 2
      src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
  7. 1
      tests/ImageSharp.Tests/Formats/Tiff/TiffDecoderTests.cs
  8. 1
      tests/ImageSharp.Tests/TestImages.cs
  9. 3
      tests/Images/Input/Tiff/flower-rgb-planar-16_lsb.tiff

1
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/Rgb161616TiffColor{TPixel}.cs

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0.
using System;
using System.Buffers.Binary;
using SixLabors.ImageSharp.Formats.Tiff.Utils;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;

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

@ -0,0 +1,53 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Buffers;
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 all 16 bit.
/// </summary>
internal class Rgb16PlanarTiffColor<TPixel> : TiffBasePlanarColorDecoder<TPixel>
where TPixel : unmanaged, IPixel<TPixel>
{
private readonly bool isBigEndian;
/// <summary>
/// Initializes a new instance of the <see cref="Rgb16PlanarTiffColor{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 Rgb16PlanarTiffColor(bool isBigEndian) => this.isBigEndian = isBigEndian;
/// <inheritdoc/>
public override void Decode(IMemoryOwner<byte>[] data, Buffer2D<TPixel> pixels, int left, int top, int width, int height)
{
var color = default(TPixel);
System.Span<byte> redData = data[0].GetSpan();
System.Span<byte> greenData = data[1].GetSpan();
System.Span<byte> blueData = data[2].GetSpan();
int offset = 0;
var rgba = default(Rgba64);
for (int y = top; y < top + height; y++)
{
for (int x = left; x < left + width; x++)
{
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);
offset += 2;
rgba.PackedValue = r | (g << 16) | (b << 32) | (0xfffful << 48);
color.FromRgba64(rgba);
pixels[x, y] = color;
}
}
}
}
}

4
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/RgbPlanarTiffColor{TPixel}.cs

@ -12,7 +12,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
/// <summary>
/// Implements the 'RGB' photometric interpretation with 'Planar' layout (for all bit depths).
/// </summary>
internal class RgbPlanarTiffColor<TPixel>
internal class RgbPlanarTiffColor<TPixel> : TiffBasePlanarColorDecoder<TPixel>
where TPixel : unmanaged, IPixel<TPixel>
{
private readonly float rFactor;
@ -47,7 +47,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
/// <param name="top">The y-coordinate of the top of the image block.</param>
/// <param name="width">The width of the image block.</param>
/// <param name="height">The height of the image block.</param>
public void Decode(IMemoryOwner<byte>[] data, Buffer2D<TPixel> pixels, int left, int top, int width, int height)
public override void Decode(IMemoryOwner<byte>[] data, Buffer2D<TPixel> pixels, int left, int top, int width, int height)
{
var color = default(TPixel);

28
src/ImageSharp/Formats/Tiff/PhotometricInterpretation/TiffBasePlanarColorDecoder{TPixel}.cs

@ -0,0 +1,28 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
using System.Buffers;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
{
/// <summary>
/// The base class for planar color decoders.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
internal abstract class TiffBasePlanarColorDecoder<TPixel>
where TPixel : unmanaged, IPixel<TPixel>
{
/// <summary>
/// Decodes source raw pixel data using the current photometric interpretation.
/// </summary>
/// <param name="data">The buffers to read image data from.</param>
/// <param name="pixels">The image buffer to write pixels to.</param>
/// <param name="left">The x-coordinate of the left-hand side of the image block.</param>
/// <param name="top">The y-coordinate of the top of the image block.</param>
/// <param name="width">The width of the image block.</param>
/// <param name="height">The height of the image block.</param>
public abstract void Decode(IMemoryOwner<byte>[] data, Buffer2D<TPixel> pixels, int left, int top, int width, int height);
}
}

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

@ -145,12 +145,17 @@ namespace SixLabors.ImageSharp.Formats.Tiff.PhotometricInterpretation
}
}
public static RgbPlanarTiffColor<TPixel> CreatePlanar(TiffColorType colorType, TiffBitsPerSample bitsPerSample, ushort[] colorMap)
public static TiffBasePlanarColorDecoder<TPixel> CreatePlanar(TiffColorType colorType, TiffBitsPerSample bitsPerSample, ushort[] colorMap, ByteOrder byteOrder)
{
switch (colorType)
{
case TiffColorType.RgbPlanar:
DebugGuard.IsTrue(colorMap == null, "colorMap");
if (bitsPerSample.Channel0 == 16 && bitsPerSample.Channel1 == 16 && bitsPerSample.Channel2 == 16)
{
return new Rgb16PlanarTiffColor<TPixel>(byteOrder == ByteOrder.BigEndian);
}
return new RgbPlanarTiffColor<TPixel>(bitsPerSample);
default:

2
src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs

@ -266,7 +266,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
using TiffBaseDecompressor decompressor = TiffDecompressorsFactory.Create(this.CompressionType, this.memoryAllocator, this.PhotometricInterpretation, frame.Width, bitsPerPixel, this.Predictor, this.FaxCompressionOptions);
RgbPlanarTiffColor<TPixel> colorDecoder = TiffColorDecoderFactory<TPixel>.CreatePlanar(this.ColorType, this.BitsPerSample, this.ColorMap);
TiffBasePlanarColorDecoder<TPixel> colorDecoder = TiffColorDecoderFactory<TPixel>.CreatePlanar(this.ColorType, this.BitsPerSample, this.ColorMap, this.byteOrder);
for (int i = 0; i < stripsPerPlane; i++)
{

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

@ -166,6 +166,7 @@ namespace SixLabors.ImageSharp.Tests.Formats.Tiff
[Theory]
[WithFile(FlowerRgb161616Contiguous, PixelTypes.Rgba32)]
[WithFile(FlowerRgb161616Planar, PixelTypes.Rgba32)]
[WithFile(FlowerRgb161616PlanarLittleEndian, PixelTypes.Rgba32)]
[WithFile(Issues1716Rgb161616BitLittleEndian, PixelTypes.Rgba32)]
public void TiffDecoder_CanDecode_48Bit<TPixel>(TestImageProvider<TPixel> provider)
where TPixel : unmanaged, IPixel<TPixel> => TestTiffDecoder(provider);

1
tests/ImageSharp.Tests/TestImages.cs

@ -563,6 +563,7 @@ namespace SixLabors.ImageSharp.Tests
public const string RgbPaletteDeflate = "Tiff/rgb_palette_deflate.tiff";
public const string FlowerRgb161616Contiguous = "Tiff/flower-rgb-contig-16.tiff";
public const string FlowerRgb161616Planar = "Tiff/flower-rgb-planar-16.tiff";
public const string FlowerRgb161616PlanarLittleEndian = "Tiff/flower-rgb-planar-16_lsb.tiff";
public const string FlowerRgb141414Contiguous = "Tiff/flower-rgb-contig-14.tiff";
public const string FlowerRgb141414Planar = "Tiff/flower-rgb-planar-14.tiff";
public const string FlowerRgb101010Contiguous = "Tiff/flower-rgb-contig-10.tiff";

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

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