Skip to content

Commit 8cf4991

Browse files
Merge pull request #2339 from ptasev/pt/tiff-encoder-l16
Added L16 support to tiff encoder
2 parents 52efdbf + 9ed23d9 commit 8cf4991

16 files changed

+163
-21
lines changed

src/ImageSharp/Formats/Tiff/Compression/HorizontalPredictor.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,11 @@ public static void ApplyHorizontalPrediction(Span<byte> rows, int width, int bit
6767
{
6868
ApplyHorizontalPrediction8Bit(rows, width);
6969
}
70+
else if (bitsPerPixel == 16)
71+
{
72+
// Assume rows are L16 grayscale since that's currently the only way 16 bits is supported by encoder
73+
ApplyHorizontalPrediction16Bit(rows, width);
74+
}
7075
else if (bitsPerPixel == 24)
7176
{
7277
ApplyHorizontalPrediction24Bit(rows, width);
@@ -102,6 +107,32 @@ private static void ApplyHorizontalPrediction24Bit(Span<byte> rows, int width)
102107
}
103108
}
104109

110+
/// <summary>
111+
/// Applies a horizontal predictor to the L16 row.
112+
/// Make use of the fact that many continuous-tone images rarely vary much in pixel value from one pixel to the next.
113+
/// In such images, if we replace the pixel values by differences between consecutive pixels, many of the differences should be 0, plus
114+
/// or minus 1, and so on.This reduces the apparent information content and allows LZW to encode the data more compactly.
115+
/// </summary>
116+
/// <param name="rows">The L16 pixel rows.</param>
117+
/// <param name="width">The width.</param>
118+
[MethodImpl(InliningOptions.ShortMethod)]
119+
private static void ApplyHorizontalPrediction16Bit(Span<byte> rows, int width)
120+
{
121+
DebugGuard.IsTrue(rows.Length % width == 0, "Values must be equals");
122+
int height = rows.Length / width;
123+
for (int y = 0; y < height; y++)
124+
{
125+
Span<byte> rowSpan = rows.Slice(y * width, width);
126+
Span<L16> rowL16 = MemoryMarshal.Cast<byte, L16>(rowSpan);
127+
128+
for (int x = rowL16.Length - 1; x >= 1; x--)
129+
{
130+
ushort val = (ushort)(rowL16[x].PackedValue - rowL16[x - 1].PackedValue);
131+
rowL16[x].PackedValue = val;
132+
}
133+
}
134+
}
135+
105136
/// <summary>
106137
/// Applies a horizontal predictor to a gray pixel row.
107138
/// </summary>

src/ImageSharp/Formats/Tiff/Constants/TiffConstants.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,11 @@ internal static class TiffConstants
7373
/// </summary>
7474
public static readonly TiffBitsPerSample BitsPerSample8Bit = new TiffBitsPerSample(8, 0, 0);
7575

76+
/// <summary>
77+
/// The bits per sample for 16-bit grayscale images.
78+
/// </summary>
79+
public static readonly TiffBitsPerSample BitsPerSample16Bit = new TiffBitsPerSample(16, 0, 0);
80+
7681
/// <summary>
7782
/// The bits per sample for color images with 8 bits for each color channel.
7883
/// </summary>

src/ImageSharp/Formats/Tiff/TiffBitsPerPixel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public enum TiffBitsPerPixel
5454
/// <summary>
5555
/// 16 bits per pixel, for gray images.
5656
///
57-
/// Note: The TiffEncoder does not yet support 16 bits per color channel and will default to 24 bits per pixel instead.
57+
/// Note: The TiffEncoder does not yet support 16 bits per color channel and will default to 16 bits grayscale instead.
5858
/// </summary>
5959
Bit16 = 16,
6060

src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,11 +376,14 @@ private void SanitizeAndSetEncoderOptions(
376376
case TiffBitsPerPixel.Bit8:
377377
this.SetEncoderOptions(bitsPerPixel, photometricInterpretation ?? TiffPhotometricInterpretation.BlackIsZero, compression, predictor);
378378
break;
379+
case TiffBitsPerPixel.Bit16:
380+
// Assume desire to encode as L16 grayscale
381+
this.SetEncoderOptions(bitsPerPixel, TiffPhotometricInterpretation.BlackIsZero, compression, predictor);
382+
break;
379383
case TiffBitsPerPixel.Bit6:
380384
case TiffBitsPerPixel.Bit10:
381385
case TiffBitsPerPixel.Bit12:
382386
case TiffBitsPerPixel.Bit14:
383-
case TiffBitsPerPixel.Bit16:
384387
case TiffBitsPerPixel.Bit30:
385388
case TiffBitsPerPixel.Bit36:
386389
case TiffBitsPerPixel.Bit42:
@@ -413,13 +416,20 @@ private void SanitizeAndSetEncoderOptions(
413416
return;
414417
}
415418

416-
// At the moment only 8 and 32 bits per pixel can be preserved by the tiff encoder.
419+
// At the moment only 8, 16 and 32 bits per pixel can be preserved by the tiff encoder.
417420
if (inputBitsPerPixel == 8)
418421
{
419422
this.SetEncoderOptions(TiffBitsPerPixel.Bit8, TiffPhotometricInterpretation.BlackIsZero, compression, predictor);
420423
return;
421424
}
422425

426+
if (inputBitsPerPixel == 16)
427+
{
428+
// Assume desire to encode as L16 grayscale
429+
this.SetEncoderOptions(TiffBitsPerPixel.Bit16, TiffPhotometricInterpretation.BlackIsZero, compression, predictor);
430+
return;
431+
}
432+
423433
this.SetEncoderOptions(TiffBitsPerPixel.Bit24, TiffPhotometricInterpretation.Rgb, compression, predictor);
424434
return;
425435
}
@@ -434,6 +444,12 @@ private void SanitizeAndSetEncoderOptions(
434444
return;
435445
}
436446

447+
if (inputBitsPerPixel == 16)
448+
{
449+
this.SetEncoderOptions(TiffBitsPerPixel.Bit16, photometricInterpretation, compression, predictor);
450+
return;
451+
}
452+
437453
this.SetEncoderOptions(TiffBitsPerPixel.Bit8, photometricInterpretation, compression, predictor);
438454
return;
439455

src/ImageSharp/Formats/Tiff/TiffEncoderEntriesCollector.cs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -343,20 +343,20 @@ private static ushort[] GetBitsPerSampleValue(TiffEncoderCore encoder)
343343
return TiffConstants.BitsPerSampleRgb8Bit.ToArray();
344344

345345
case TiffPhotometricInterpretation.WhiteIsZero:
346-
if (encoder.BitsPerPixel == TiffBitsPerPixel.Bit1)
346+
return encoder.BitsPerPixel switch
347347
{
348-
return TiffConstants.BitsPerSample1Bit.ToArray();
349-
}
350-
351-
return TiffConstants.BitsPerSample8Bit.ToArray();
348+
TiffBitsPerPixel.Bit1 => TiffConstants.BitsPerSample1Bit.ToArray(),
349+
TiffBitsPerPixel.Bit16 => TiffConstants.BitsPerSample16Bit.ToArray(),
350+
_ => TiffConstants.BitsPerSample8Bit.ToArray()
351+
};
352352

353353
case TiffPhotometricInterpretation.BlackIsZero:
354-
if (encoder.BitsPerPixel == TiffBitsPerPixel.Bit1)
354+
return encoder.BitsPerPixel switch
355355
{
356-
return TiffConstants.BitsPerSample1Bit.ToArray();
357-
}
358-
359-
return TiffConstants.BitsPerSample8Bit.ToArray();
356+
TiffBitsPerPixel.Bit1 => TiffConstants.BitsPerSample1Bit.ToArray(),
357+
TiffBitsPerPixel.Bit16 => TiffConstants.BitsPerSample16Bit.ToArray(),
358+
_ => TiffConstants.BitsPerSample8Bit.ToArray()
359+
};
360360

361361
default:
362362
return TiffConstants.BitsPerSampleRgb8Bit.ToArray();

src/ImageSharp/Formats/Tiff/Writers/TiffColorWriterFactory.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,13 @@ public static TiffBaseColorWriter<TPixel> Create<TPixel>(
2727
return new TiffPaletteWriter<TPixel>(image, quantizer, pixelSamplingStrategy, memoryAllocator, configuration, entriesCollector, bitsPerPixel);
2828
case TiffPhotometricInterpretation.BlackIsZero:
2929
case TiffPhotometricInterpretation.WhiteIsZero:
30-
if (bitsPerPixel == 1)
30+
return bitsPerPixel switch
3131
{
32-
return new TiffBiColorWriter<TPixel>(image, memoryAllocator, configuration, entriesCollector);
33-
}
32+
1 => new TiffBiColorWriter<TPixel>(image, memoryAllocator, configuration, entriesCollector),
33+
16 => new TiffGrayL16Writer<TPixel>(image, memoryAllocator, configuration, entriesCollector),
34+
_ => new TiffGrayWriter<TPixel>(image, memoryAllocator, configuration, entriesCollector)
35+
};
3436

35-
return new TiffGrayWriter<TPixel>(image, memoryAllocator, configuration, entriesCollector);
3637
default:
3738
return new TiffRgbWriter<TPixel>(image, memoryAllocator, configuration, entriesCollector);
3839
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
using SixLabors.ImageSharp.Memory;
5+
using SixLabors.ImageSharp.PixelFormats;
6+
7+
namespace SixLabors.ImageSharp.Formats.Tiff.Writers;
8+
9+
internal sealed class TiffGrayL16Writer<TPixel> : TiffCompositeColorWriter<TPixel>
10+
where TPixel : unmanaged, IPixel<TPixel>
11+
{
12+
public TiffGrayL16Writer(ImageFrame<TPixel> image, MemoryAllocator memoryAllocator, Configuration configuration, TiffEncoderEntriesCollector entriesCollector)
13+
: base(image, memoryAllocator, configuration, entriesCollector)
14+
{
15+
}
16+
17+
/// <inheritdoc />
18+
public override int BitsPerPixel => 16;
19+
20+
/// <inheritdoc />
21+
protected override void EncodePixels(Span<TPixel> pixels, Span<byte> buffer) => PixelOperations<TPixel>.Instance.ToL16Bytes(this.Configuration, pixels, buffer, pixels.Length);
22+
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,15 @@ public void ThrowsNotSupported<TPixel>(TestImageProvider<TPixel> provider)
2727
[InlineData(RgbUncompressed, 24, 256, 256, 300, 300, PixelResolutionUnit.PixelsPerInch)]
2828
[InlineData(SmallRgbDeflate, 24, 32, 32, 96, 96, PixelResolutionUnit.PixelsPerInch)]
2929
[InlineData(Calliphora_GrayscaleUncompressed, 8, 200, 298, 96, 96, PixelResolutionUnit.PixelsPerInch)]
30+
[InlineData(Calliphora_GrayscaleUncompressed16Bit, 16, 200, 298, 96, 96, PixelResolutionUnit.PixelsPerInch)]
3031
[InlineData(Flower4BitPalette, 4, 73, 43, 72, 72, PixelResolutionUnit.PixelsPerInch)]
3132
public void Identify(string imagePath, int expectedPixelSize, int expectedWidth, int expectedHeight, double expectedHResolution, double expectedVResolution, PixelResolutionUnit expectedResolutionUnit)
3233
{
3334
TestFile testFile = TestFile.Create(imagePath);
3435
using MemoryStream stream = new(testFile.Bytes, false);
3536
ImageInfo info = Image.Identify(stream);
3637

37-
Assert.Equal(expectedPixelSize, info.PixelType?.BitsPerPixel);
38+
Assert.Equal(expectedPixelSize, info.PixelType.BitsPerPixel);
3839
Assert.Equal(expectedWidth, info.Width);
3940
Assert.Equal(expectedHeight, info.Height);
4041
Assert.NotNull(info.Metadata);
@@ -64,6 +65,7 @@ public void ByteOrder(string imagePath, ByteOrder expectedByteOrder)
6465
[Theory]
6566
[WithFile(RgbUncompressed, PixelTypes.Rgba32)]
6667
[WithFile(Calliphora_GrayscaleUncompressed, PixelTypes.Rgba32)]
68+
[WithFile(Calliphora_GrayscaleUncompressed16Bit, PixelTypes.Rgba32)]
6769
[WithFile(Calliphora_RgbUncompressed, PixelTypes.Rgba32)]
6870
[WithFile(Calliphora_BiColorUncompressed, PixelTypes.Rgba32)]
6971
public void TiffDecoder_CanDecode_Uncompressed<TPixel>(TestImageProvider<TPixel> provider)
@@ -599,6 +601,8 @@ public void TiffDecoder_CanDecode_128Bit_WithUnassociatedAlpha<TPixel>(TestImage
599601
[WithFile(RgbDeflateMultistrip, PixelTypes.Rgba32)]
600602
[WithFile(Calliphora_GrayscaleDeflate, PixelTypes.Rgba32)]
601603
[WithFile(Calliphora_GrayscaleDeflate_Predictor, PixelTypes.Rgba32)]
604+
[WithFile(Calliphora_GrayscaleDeflate16Bit, PixelTypes.Rgba32)]
605+
[WithFile(Calliphora_GrayscaleDeflate_Predictor16Bit, PixelTypes.Rgba32)]
602606
[WithFile(Calliphora_RgbDeflate_Predictor, PixelTypes.Rgba32)]
603607
[WithFile(RgbDeflate, PixelTypes.Rgba32)]
604608
[WithFile(RgbDeflatePredictor, PixelTypes.Rgba32)]
@@ -615,6 +619,7 @@ public void TiffDecoder_CanDecode_DeflateCompressed<TPixel>(TestImageProvider<TP
615619
[WithFile(Calliphora_RgbPaletteLzw_Predictor, PixelTypes.Rgba32)]
616620
[WithFile(Calliphora_RgbLzwPredictor, PixelTypes.Rgba32)]
617621
[WithFile(Calliphora_GrayscaleLzw_Predictor, PixelTypes.Rgba32)]
622+
[WithFile(Calliphora_GrayscaleLzw_Predictor16Bit, PixelTypes.Rgba32)]
618623
[WithFile(SmallRgbLzw, PixelTypes.Rgba32)]
619624
public void TiffDecoder_CanDecode_LzwCompressed<TPixel>(TestImageProvider<TPixel> provider)
620625
where TPixel : unmanaged, IPixel<TPixel> => TestTiffDecoder(provider);

tests/ImageSharp.Tests/Formats/Tiff/TiffEncoderTests.cs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ public class TiffEncoderTests : TiffEncoderBaseTester
1717
[InlineData(TiffPhotometricInterpretation.PaletteColor, TiffBitsPerPixel.Bit8)]
1818
[InlineData(TiffPhotometricInterpretation.BlackIsZero, TiffBitsPerPixel.Bit8)]
1919
[InlineData(TiffPhotometricInterpretation.WhiteIsZero, TiffBitsPerPixel.Bit8)]
20+
[InlineData(TiffPhotometricInterpretation.BlackIsZero, TiffBitsPerPixel.Bit16)]
2021
//// Unsupported TiffPhotometricInterpretation should default to 24 bits
2122
[InlineData(TiffPhotometricInterpretation.CieLab, TiffBitsPerPixel.Bit24)]
2223
[InlineData(TiffPhotometricInterpretation.ColorFilterArray, TiffBitsPerPixel.Bit24)]
@@ -28,7 +29,9 @@ public void EncoderOptions_SetPhotometricInterpretation_Works(TiffPhotometricInt
2829
{
2930
// arrange
3031
var tiffEncoder = new TiffEncoder { PhotometricInterpretation = photometricInterpretation };
31-
using Image input = new Image<Rgb24>(10, 10);
32+
using Image input = expectedBitsPerPixel is TiffBitsPerPixel.Bit16
33+
? new Image<L16>(10, 10)
34+
: new Image<Rgb24>(10, 10);
3235
using var memStream = new MemoryStream();
3336

3437
// act
@@ -44,6 +47,7 @@ public void EncoderOptions_SetPhotometricInterpretation_Works(TiffPhotometricInt
4447

4548
[Theory]
4649
[InlineData(TiffBitsPerPixel.Bit24)]
50+
[InlineData(TiffBitsPerPixel.Bit16)]
4751
[InlineData(TiffBitsPerPixel.Bit8)]
4852
[InlineData(TiffBitsPerPixel.Bit4)]
4953
[InlineData(TiffBitsPerPixel.Bit1)]
@@ -117,14 +121,17 @@ public void EncoderOptions_WithInvalidCompressionAndPixelTypeCombination_Default
117121
[Theory]
118122
[InlineData(null, TiffCompression.Deflate, TiffBitsPerPixel.Bit24, TiffCompression.Deflate)]
119123
[InlineData(TiffPhotometricInterpretation.Rgb, TiffCompression.Deflate, TiffBitsPerPixel.Bit24, TiffCompression.Deflate)]
124+
[InlineData(TiffPhotometricInterpretation.BlackIsZero, TiffCompression.Deflate, TiffBitsPerPixel.Bit16, TiffCompression.Deflate)]
120125
[InlineData(TiffPhotometricInterpretation.BlackIsZero, TiffCompression.Deflate, TiffBitsPerPixel.Bit8, TiffCompression.Deflate)]
121126
[InlineData(TiffPhotometricInterpretation.PaletteColor, TiffCompression.Deflate, TiffBitsPerPixel.Bit8, TiffCompression.Deflate)]
122127
[InlineData(null, TiffCompression.PackBits, TiffBitsPerPixel.Bit24, TiffCompression.PackBits)]
123128
[InlineData(TiffPhotometricInterpretation.Rgb, TiffCompression.PackBits, TiffBitsPerPixel.Bit24, TiffCompression.PackBits)]
124-
[InlineData(TiffPhotometricInterpretation.PaletteColor, TiffCompression.PackBits, TiffBitsPerPixel.Bit8, TiffCompression.PackBits)]
129+
[InlineData(TiffPhotometricInterpretation.BlackIsZero, TiffCompression.PackBits, TiffBitsPerPixel.Bit16, TiffCompression.PackBits)]
125130
[InlineData(TiffPhotometricInterpretation.BlackIsZero, TiffCompression.PackBits, TiffBitsPerPixel.Bit8, TiffCompression.PackBits)]
131+
[InlineData(TiffPhotometricInterpretation.PaletteColor, TiffCompression.PackBits, TiffBitsPerPixel.Bit8, TiffCompression.PackBits)]
126132
[InlineData(null, TiffCompression.Lzw, TiffBitsPerPixel.Bit24, TiffCompression.Lzw)]
127133
[InlineData(TiffPhotometricInterpretation.Rgb, TiffCompression.Lzw, TiffBitsPerPixel.Bit24, TiffCompression.Lzw)]
134+
[InlineData(TiffPhotometricInterpretation.BlackIsZero, TiffCompression.Lzw, TiffBitsPerPixel.Bit16, TiffCompression.Lzw)]
128135
[InlineData(TiffPhotometricInterpretation.BlackIsZero, TiffCompression.Lzw, TiffBitsPerPixel.Bit8, TiffCompression.Lzw)]
129136
[InlineData(TiffPhotometricInterpretation.PaletteColor, TiffCompression.Lzw, TiffBitsPerPixel.Bit8, TiffCompression.Lzw)]
130137
[InlineData(TiffPhotometricInterpretation.BlackIsZero, TiffCompression.CcittGroup3Fax, TiffBitsPerPixel.Bit1, TiffCompression.CcittGroup3Fax)]
@@ -143,7 +150,9 @@ public void EncoderOptions_SetPhotometricInterpretationAndCompression_Works(
143150
{
144151
// arrange
145152
var tiffEncoder = new TiffEncoder { PhotometricInterpretation = photometricInterpretation, Compression = compression };
146-
using Image input = new Image<Rgb24>(10, 10);
153+
using Image input = expectedBitsPerPixel is TiffBitsPerPixel.Bit16
154+
? new Image<L16>(10, 10)
155+
: new Image<Rgb24>(10, 10);
147156
using var memStream = new MemoryStream();
148157

149158
// act
@@ -160,6 +169,7 @@ public void EncoderOptions_SetPhotometricInterpretationAndCompression_Works(
160169
[Theory]
161170
[WithFile(Calliphora_BiColorUncompressed, PixelTypes.Rgba32, TiffBitsPerPixel.Bit1)]
162171
[WithFile(GrayscaleUncompressed, PixelTypes.Rgba32, TiffBitsPerPixel.Bit8)]
172+
[WithFile(GrayscaleUncompressed16Bit, PixelTypes.L16, TiffBitsPerPixel.Bit16)]
163173
[WithFile(RgbUncompressed, PixelTypes.Rgba32, TiffBitsPerPixel.Bit24)]
164174
[WithFile(Rgb4BitPalette, PixelTypes.Rgba32, TiffBitsPerPixel.Bit4)]
165175
[WithFile(RgbPalette, PixelTypes.Rgba32, TiffBitsPerPixel.Bit8)]
@@ -406,6 +416,36 @@ public void TiffEncoder_EncodeColorPalette_WithLzwCompressionAndPredictor_Works<
406416
where TPixel : unmanaged, IPixel<TPixel> =>
407417
TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit8, TiffPhotometricInterpretation.PaletteColor, TiffCompression.Lzw, TiffPredictor.Horizontal, useExactComparer: false, compareTolerance: 0.001f);
408418

419+
[Theory]
420+
[WithFile(Calliphora_GrayscaleUncompressed16Bit, PixelTypes.Rgba32)]
421+
public void TiffEncoder_EncodeGray16_Works<TPixel>(TestImageProvider<TPixel> provider)
422+
where TPixel : unmanaged, IPixel<TPixel> => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit16, TiffPhotometricInterpretation.BlackIsZero);
423+
424+
[Theory]
425+
[WithFile(Calliphora_GrayscaleUncompressed16Bit, PixelTypes.Rgba32)]
426+
public void TiffEncoder_EncodeGray16_WithDeflateCompression_Works<TPixel>(TestImageProvider<TPixel> provider)
427+
where TPixel : unmanaged, IPixel<TPixel> => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit16, TiffPhotometricInterpretation.BlackIsZero, TiffCompression.Deflate);
428+
429+
[Theory]
430+
[WithFile(Calliphora_GrayscaleUncompressed16Bit, PixelTypes.Rgba32)]
431+
public void TiffEncoder_EncodeGray16_WithDeflateCompressionAndPredictor_Works<TPixel>(TestImageProvider<TPixel> provider)
432+
where TPixel : unmanaged, IPixel<TPixel> => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit16, TiffPhotometricInterpretation.BlackIsZero, TiffCompression.Deflate, TiffPredictor.Horizontal);
433+
434+
[Theory]
435+
[WithFile(Calliphora_GrayscaleUncompressed16Bit, PixelTypes.Rgba32)]
436+
public void TiffEncoder_EncodeGray16_WithLzwCompression_Works<TPixel>(TestImageProvider<TPixel> provider)
437+
where TPixel : unmanaged, IPixel<TPixel> => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit16, TiffPhotometricInterpretation.BlackIsZero, TiffCompression.Lzw);
438+
439+
[Theory]
440+
[WithFile(Calliphora_GrayscaleUncompressed16Bit, PixelTypes.Rgba32)]
441+
public void TiffEncoder_EncodeGray16_WithLzwCompressionAndPredictor_Works<TPixel>(TestImageProvider<TPixel> provider)
442+
where TPixel : unmanaged, IPixel<TPixel> => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit16, TiffPhotometricInterpretation.BlackIsZero, TiffCompression.Lzw, TiffPredictor.Horizontal);
443+
444+
[Theory]
445+
[WithFile(Calliphora_GrayscaleUncompressed16Bit, PixelTypes.Rgba32)]
446+
public void TiffEncoder_EncodeGray16_WithPackBitsCompression_Works<TPixel>(TestImageProvider<TPixel> provider)
447+
where TPixel : unmanaged, IPixel<TPixel> => TestTiffEncoderCore(provider, TiffBitsPerPixel.Bit16, TiffPhotometricInterpretation.BlackIsZero, TiffCompression.PackBits);
448+
409449
[Theory]
410450
[WithFile(Calliphora_BiColorUncompressed, PixelTypes.Rgba32)]
411451
public void TiffEncoder_EncodeBiColor_BlackIsZero_Works<TPixel>(TestImageProvider<TPixel> provider)
@@ -473,6 +513,7 @@ public void TiffEncoder_EncodeBiColor_WithModifiedHuffmanCompression_BlackIsZero
473513

474514
[Theory]
475515
[WithFile(GrayscaleUncompressed, PixelTypes.L8, TiffPhotometricInterpretation.BlackIsZero, TiffCompression.PackBits)]
516+
[WithFile(GrayscaleUncompressed16Bit, PixelTypes.L16, TiffPhotometricInterpretation.BlackIsZero, TiffCompression.PackBits)]
476517
[WithFile(RgbUncompressed, PixelTypes.Rgba32, TiffPhotometricInterpretation.Rgb, TiffCompression.Deflate)]
477518
[WithFile(RgbUncompressed, PixelTypes.Rgb24, TiffPhotometricInterpretation.Rgb, TiffCompression.None)]
478519
[WithFile(RgbUncompressed, PixelTypes.Rgba32, TiffPhotometricInterpretation.Rgb, TiffCompression.None)]

0 commit comments

Comments
 (0)