mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
37 changed files with 458 additions and 369 deletions
@ -1,56 +1,138 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Tiff |
|||
{ |
|||
/// <summary>
|
|||
/// The number of bits per component.
|
|||
/// </summary>
|
|||
public enum TiffBitsPerSample |
|||
public readonly struct TiffBitsPerSample : IEquatable<TiffBitsPerSample> |
|||
{ |
|||
/// <summary>
|
|||
/// The Bits per samples is not known.
|
|||
/// The bits for the channel 0.
|
|||
/// </summary>
|
|||
Unknown = 0, |
|||
public readonly ushort Channel0; |
|||
|
|||
/// <summary>
|
|||
/// One bit per sample for bicolor images.
|
|||
/// The bits for the channel 1.
|
|||
/// </summary>
|
|||
Bit1 = 1, |
|||
public readonly ushort Channel1; |
|||
|
|||
/// <summary>
|
|||
/// Four bits per sample for grayscale images with 16 different levels of gray or paletted images with a palette of 16 colors.
|
|||
/// The bits for the channel 2.
|
|||
/// </summary>
|
|||
Bit4 = 4, |
|||
public readonly ushort Channel2; |
|||
|
|||
/// <summary>
|
|||
/// Eight bits per sample for grayscale images with 256 different levels of gray or paletted images with a palette of 256 colors.
|
|||
/// The number of channels.
|
|||
/// </summary>
|
|||
Bit8 = 8, |
|||
public readonly byte Channels; |
|||
|
|||
/// <summary>
|
|||
/// Six bits per sample, each channel has 2 bits.
|
|||
/// Initializes a new instance of the <see cref="TiffBitsPerSample"/> struct.
|
|||
/// </summary>
|
|||
Bit6 = 6, |
|||
/// <param name="channel0">The bits for the channel 0.</param>
|
|||
/// <param name="channel1">The bits for the channel 1.</param>
|
|||
/// <param name="channel2">The bits for the channel 2.</param>
|
|||
public TiffBitsPerSample(ushort channel0, ushort channel1, ushort channel2) |
|||
{ |
|||
this.Channel0 = (ushort)Numerics.Clamp(channel0, 0, 32); |
|||
this.Channel1 = (ushort)Numerics.Clamp(channel1, 0, 32); |
|||
this.Channel2 = (ushort)Numerics.Clamp(channel2, 0, 32); |
|||
|
|||
/// <summary>
|
|||
/// Twelve bits per sample, each channel has 4 bits.
|
|||
/// </summary>
|
|||
Bit12 = 12, |
|||
this.Channels = 0; |
|||
this.Channels += (byte)(this.Channel0 != 0 ? 1 : 0); |
|||
this.Channels += (byte)(this.Channel1 != 0 ? 1 : 0); |
|||
this.Channels += (byte)(this.Channel2 != 0 ? 1 : 0); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// 24 bits per sample, each color channel has 8 Bits.
|
|||
/// Tries to parse a ushort array and convert it into a TiffBitsPerSample struct.
|
|||
/// </summary>
|
|||
Bit24 = 24, |
|||
/// <param name="value">The value to parse.</param>
|
|||
/// <param name="sample">The tiff bits per sample.</param>
|
|||
/// <returns>True, if the value could be parsed.</returns>
|
|||
public static bool TryParse(ushort[] value, out TiffBitsPerSample sample) |
|||
{ |
|||
if (value is null || value.Length == 0) |
|||
{ |
|||
sample = default; |
|||
return false; |
|||
} |
|||
|
|||
ushort c2; |
|||
ushort c1; |
|||
ushort c0; |
|||
switch (value.Length) |
|||
{ |
|||
case 3: |
|||
c2 = value[2]; |
|||
c1 = value[1]; |
|||
c0 = value[0]; |
|||
break; |
|||
case 2: |
|||
c2 = 0; |
|||
c1 = value[1]; |
|||
c0 = value[0]; |
|||
break; |
|||
default: |
|||
c2 = 0; |
|||
c1 = 0; |
|||
c0 = value[0]; |
|||
break; |
|||
} |
|||
|
|||
sample = new TiffBitsPerSample(c0, c1, c2); |
|||
return true; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override bool Equals(object obj) |
|||
=> obj is TiffBitsPerSample sample && this.Equals(sample); |
|||
|
|||
/// <inheritdoc/>
|
|||
public bool Equals(TiffBitsPerSample other) |
|||
=> this.Channel0 == other.Channel0 |
|||
&& this.Channel1 == other.Channel1 |
|||
&& this.Channel2 == other.Channel2; |
|||
|
|||
/// <inheritdoc/>
|
|||
public override int GetHashCode() |
|||
=> HashCode.Combine(this.Channel0, this.Channel1, this.Channel2); |
|||
|
|||
/// <summary>
|
|||
/// Thirty bits per sample, each channel has 10 bits.
|
|||
/// Converts the bits per sample struct to an ushort array.
|
|||
/// </summary>
|
|||
Bit30 = 30, |
|||
/// <returns>Bits per sample as ushort array.</returns>
|
|||
public ushort[] ToArray() |
|||
{ |
|||
if (this.Channel1 == 0) |
|||
{ |
|||
return new[] { this.Channel0 }; |
|||
} |
|||
|
|||
if (this.Channel2 == 0) |
|||
{ |
|||
return new[] { this.Channel0, this.Channel1 }; |
|||
} |
|||
|
|||
return new[] { this.Channel0, this.Channel1, this.Channel2 }; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Forty two bits per sample, each channel has 14 bits.
|
|||
/// Gets the bits per pixel for the given bits per sample.
|
|||
/// </summary>
|
|||
Bit42 = 42, |
|||
/// <returns>Bits per pixel.</returns>
|
|||
public TiffBitsPerPixel BitsPerPixel() |
|||
{ |
|||
int bitsPerPixel = this.Channel0 + this.Channel1 + this.Channel2; |
|||
return (TiffBitsPerPixel)bitsPerPixel; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public override string ToString() |
|||
=> $"TiffBitsPerSample({this.Channel0}, {this.Channel1}, {this.Channel2})"; |
|||
} |
|||
} |
|||
|
|||
@ -1,111 +0,0 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using SixLabors.ImageSharp.Formats.Tiff.Constants; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.Tiff |
|||
{ |
|||
internal static class TiffBitsPerSampleExtensions |
|||
{ |
|||
/// <summary>
|
|||
/// Gets the bits per channel array for a given BitsPerSample value, e,g, for RGB888: [8, 8, 8]
|
|||
/// </summary>
|
|||
/// <param name="tiffBitsPerSample">The tiff bits per sample.</param>
|
|||
/// <returns>Bits per sample array.</returns>
|
|||
public static ushort[] Bits(this TiffBitsPerSample tiffBitsPerSample) |
|||
{ |
|||
switch (tiffBitsPerSample) |
|||
{ |
|||
case TiffBitsPerSample.Bit1: |
|||
return TiffConstants.BitsPerSample1Bit; |
|||
case TiffBitsPerSample.Bit4: |
|||
return TiffConstants.BitsPerSample4Bit; |
|||
case TiffBitsPerSample.Bit6: |
|||
return TiffConstants.BitsPerSampleRgb2Bit; |
|||
case TiffBitsPerSample.Bit8: |
|||
return TiffConstants.BitsPerSample8Bit; |
|||
case TiffBitsPerSample.Bit12: |
|||
return TiffConstants.BitsPerSampleRgb4Bit; |
|||
case TiffBitsPerSample.Bit24: |
|||
return TiffConstants.BitsPerSampleRgb8Bit; |
|||
case TiffBitsPerSample.Bit30: |
|||
return TiffConstants.BitsPerSampleRgb10Bit; |
|||
case TiffBitsPerSample.Bit42: |
|||
return TiffConstants.BitsPerSampleRgb14Bit; |
|||
|
|||
default: |
|||
return Array.Empty<ushort>(); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Maps an array of bits per sample to a concrete enum value.
|
|||
/// </summary>
|
|||
/// <param name="bitsPerSample">The bits per sample array.</param>
|
|||
/// <returns>TiffBitsPerSample enum value.</returns>
|
|||
public static TiffBitsPerSample GetBitsPerSample(this ushort[] bitsPerSample) |
|||
{ |
|||
switch (bitsPerSample.Length) |
|||
{ |
|||
case 3: |
|||
if (bitsPerSample[2] == TiffConstants.BitsPerSampleRgb14Bit[2] && |
|||
bitsPerSample[1] == TiffConstants.BitsPerSampleRgb14Bit[1] && |
|||
bitsPerSample[0] == TiffConstants.BitsPerSampleRgb14Bit[0]) |
|||
{ |
|||
return TiffBitsPerSample.Bit42; |
|||
} |
|||
|
|||
if (bitsPerSample[2] == TiffConstants.BitsPerSampleRgb10Bit[2] && |
|||
bitsPerSample[1] == TiffConstants.BitsPerSampleRgb10Bit[1] && |
|||
bitsPerSample[0] == TiffConstants.BitsPerSampleRgb10Bit[0]) |
|||
{ |
|||
return TiffBitsPerSample.Bit30; |
|||
} |
|||
|
|||
if (bitsPerSample[2] == TiffConstants.BitsPerSampleRgb8Bit[2] && |
|||
bitsPerSample[1] == TiffConstants.BitsPerSampleRgb8Bit[1] && |
|||
bitsPerSample[0] == TiffConstants.BitsPerSampleRgb8Bit[0]) |
|||
{ |
|||
return TiffBitsPerSample.Bit24; |
|||
} |
|||
|
|||
if (bitsPerSample[2] == TiffConstants.BitsPerSampleRgb4Bit[2] && |
|||
bitsPerSample[1] == TiffConstants.BitsPerSampleRgb4Bit[1] && |
|||
bitsPerSample[0] == TiffConstants.BitsPerSampleRgb4Bit[0]) |
|||
{ |
|||
return TiffBitsPerSample.Bit12; |
|||
} |
|||
|
|||
if (bitsPerSample[2] == TiffConstants.BitsPerSampleRgb2Bit[2] && |
|||
bitsPerSample[1] == TiffConstants.BitsPerSampleRgb2Bit[1] && |
|||
bitsPerSample[0] == TiffConstants.BitsPerSampleRgb2Bit[0]) |
|||
{ |
|||
return TiffBitsPerSample.Bit6; |
|||
} |
|||
|
|||
break; |
|||
|
|||
case 1: |
|||
if (bitsPerSample[0] == TiffConstants.BitsPerSample1Bit[0]) |
|||
{ |
|||
return TiffBitsPerSample.Bit1; |
|||
} |
|||
|
|||
if (bitsPerSample[0] == TiffConstants.BitsPerSample4Bit[0]) |
|||
{ |
|||
return TiffBitsPerSample.Bit4; |
|||
} |
|||
|
|||
if (bitsPerSample[0] == TiffConstants.BitsPerSample8Bit[0]) |
|||
{ |
|||
return TiffBitsPerSample.Bit8; |
|||
} |
|||
|
|||
break; |
|||
} |
|||
|
|||
return TiffBitsPerSample.Unknown; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:3122afede012fa00b8cb379b2f9125a34a38188c3346ec5e18d3b4bddcbb451b |
|||
size 1131 |
|||
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:b0c13012d8d35215b01192eb38058db4543486c60b4918beec8719a94d1e208e |
|||
size 2679 |
|||
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:1268d843a2338409ec3a9f5a5a62e23d38c3a898035619994a02f21eff7590bf |
|||
size 3453 |
|||
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:a91d6946730604dd65c63f1653fb33031682f26218de33ebf3d0b362cb6883af |
|||
size 4269 |
|||
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:86fc9309872f4e4668350b95fae315d878ec9658046d738050a2743f5fa44446 |
|||
size 5043 |
|||
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:dcd07668c73f24c2a13133ac4910b59a568502a6d3762675eef61a7e3b090165 |
|||
size 5817 |
|||
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:79531a10710dee89b86e2467818b7c03a24ff28ebd98c7bdcc292559671e1887 |
|||
size 6591 |
|||
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:75e74d8816942ff6e9dfda411f9171f0f1dd1a5a88cb1410238b55a2b2aeeb71 |
|||
size 1164 |
|||
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:5f7a63eb8636e2b1ee39dfda4d0bddfc98bdc9eb94bea2dd657619331fa38b5b |
|||
size 14483 |
|||
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:ab3d6b619a198ff2e5fdd8f9752bf43c5b03a782625b1f0e3f2cfe0f20c4b24a |
|||
size 19177 |
|||
@ -0,0 +1,3 @@ |
|||
version https://git-lfs.github.com/spec/v1 |
|||
oid sha256:0a143fb6c5792fa7755e06feb757c745ad68944336985dc5be8a0c37247fe36d |
|||
size 19177 |
|||
Loading…
Reference in new issue