Browse Source

Set bits per pixel in tiff metadata

pull/1570/head
Brian Popow 6 years ago
parent
commit
d5980eafae
  1. 21
      src/ImageSharp/Formats/Tiff/TiffBitsPerPixel.cs
  2. 61
      src/ImageSharp/Formats/Tiff/TiffDecoderCore.cs
  3. 13
      src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs
  4. 9
      src/ImageSharp/Formats/Tiff/TiffMetadata.cs

21
src/ImageSharp/Formats/Tiff/TiffBitsPerPixel.cs

@ -0,0 +1,21 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp.Formats.Tiff
{
/// <summary>
/// Enumerates the available bits per pixel the tiff encoder supports.
/// </summary>
public enum TiffBitsPerPixel
{
/// <summary>
/// 8 bits per pixel. Each pixel consists of 1 byte.
/// </summary>
Pixel8 = 8,
/// <summary>
/// 24 bits per pixel. Each pixel consists of 3 bytes.
/// </summary>
Pixel24 = 24,
}
}

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

@ -33,6 +33,19 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// </summary> /// </summary>
private readonly bool ignoreMetadata; private readonly bool ignoreMetadata;
/// <summary>
/// The image metadata.
/// </summary>
private ImageMetadata metadata;
/// <summary>
/// The tiff specific metadata.
/// </summary>
private TiffMetadata tiffMetaData;
/// <summary>
/// The stream to decode from.
/// </summary>
private BufferedReadStream inputStream; private BufferedReadStream inputStream;
/// <summary> /// <summary>
@ -104,7 +117,9 @@ namespace SixLabors.ImageSharp.Formats.Tiff
framesMetadata.Add(frameMetadata); framesMetadata.Add(frameMetadata);
} }
ImageMetadata metadata = framesMetadata.CreateMetadata(this.ignoreMetadata, tiffStream.ByteOrder); this.metadata = framesMetadata.CreateMetadata(this.ignoreMetadata, tiffStream.ByteOrder);
this.tiffMetaData = this.metadata.GetTiffMetadata();
this.SetBitsPerPixel(framesMetadata);
// todo: tiff frames can have different sizes // todo: tiff frames can have different sizes
{ {
@ -119,11 +134,31 @@ namespace SixLabors.ImageSharp.Formats.Tiff
} }
} }
var image = new Image<TPixel>(this.configuration, metadata, frames); var image = new Image<TPixel>(this.configuration, this.metadata, frames);
return image; return image;
} }
private void SetBitsPerPixel(List<TiffFrameMetadata> framesMetadata)
{
TiffFrameMetadata firstMetaData = framesMetadata.First();
ushort[] bitsPerSample = firstMetaData.BitsPerSample;
var bitsPerPixel = 0;
foreach (var bps in bitsPerSample)
{
bitsPerPixel += bps;
}
if (bitsPerPixel == 24)
{
this.tiffMetaData.BitsPerPixel = TiffBitsPerPixel.Pixel24;
}
else if (bitsPerPixel == 8)
{
this.tiffMetaData.BitsPerPixel = TiffBitsPerPixel.Pixel8;
}
}
/// <inheritdoc/> /// <inheritdoc/>
public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken)
{ {
@ -168,7 +203,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
private static TiffByteOrder ReadByteOrder(Stream stream) private static TiffByteOrder ReadByteOrder(Stream stream)
{ {
byte[] headerBytes = new byte[2]; var headerBytes = new byte[2];
stream.Read(headerBytes, 0, 2); stream.Read(headerBytes, 0, 2);
if (headerBytes[0] == TiffConstants.ByteOrderLittleEndian && headerBytes[1] == TiffConstants.ByteOrderLittleEndian) if (headerBytes[0] == TiffConstants.ByteOrderLittleEndian && headerBytes[1] == TiffConstants.ByteOrderLittleEndian)
{ {
@ -187,26 +222,26 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// </summary> /// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam> /// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="tags">The IFD tags.</param> /// <param name="tags">The IFD tags.</param>
/// <param name="metadata">The frame metadata.</param> /// <param name="frameMetaData">The frame metadata.</param>
/// <returns> /// <returns>
/// The tiff frame. /// The tiff frame.
/// </returns> /// </returns>
private ImageFrame<TPixel> DecodeFrame<TPixel>(IExifValue[] tags, out TiffFrameMetadata metadata) private ImageFrame<TPixel> DecodeFrame<TPixel>(IExifValue[] tags, out TiffFrameMetadata frameMetaData)
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
var coreMetadata = new ImageFrameMetadata(); var coreMetadata = new ImageFrameMetadata();
metadata = coreMetadata.GetTiffMetadata(); frameMetaData = coreMetadata.GetTiffMetadata();
metadata.Tags = tags; frameMetaData.Tags = tags;
this.VerifyAndParseOptions(metadata); this.VerifyAndParseOptions(frameMetaData);
int width = (int)metadata.Width; int width = (int)frameMetaData.Width;
int height = (int)metadata.Height; int height = (int)frameMetaData.Height;
var frame = new ImageFrame<TPixel>(this.configuration, width, height, coreMetadata); var frame = new ImageFrame<TPixel>(this.configuration, width, height, coreMetadata);
int rowsPerStrip = (int)metadata.RowsPerStrip; int rowsPerStrip = (int)frameMetaData.RowsPerStrip;
uint[] stripOffsets = metadata.StripOffsets; uint[] stripOffsets = frameMetaData.StripOffsets;
uint[] stripByteCounts = metadata.StripByteCounts; uint[] stripByteCounts = frameMetaData.StripByteCounts;
if (this.PlanarConfiguration == TiffPlanarConfiguration.Planar) if (this.PlanarConfiguration == TiffPlanarConfiguration.Planar)
{ {

13
src/ImageSharp/Formats/Tiff/TiffEncoderCore.cs

@ -5,8 +5,10 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using SixLabors.ImageSharp.Advanced; using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Memory; using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.Metadata;
using SixLabors.ImageSharp.Metadata.Profiles.Exif; using SixLabors.ImageSharp.Metadata.Profiles.Exif;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -32,6 +34,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// </summary> /// </summary>
private Configuration configuration; private Configuration configuration;
/// <summary>
/// The color depth, in number of bits per pixel.
/// </summary>
private TiffBitsPerPixel? bitsPerPixel;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="TiffEncoderCore"/> class. /// Initializes a new instance of the <see cref="TiffEncoderCore"/> class.
/// </summary> /// </summary>
@ -66,9 +73,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff
Guard.NotNull(stream, nameof(stream)); Guard.NotNull(stream, nameof(stream));
this.configuration = image.GetConfiguration(); this.configuration = image.GetConfiguration();
ImageMetadata metadata = image.Metadata;
TiffMetadata tiffMetadata = metadata.GetTiffMetadata();
this.bitsPerPixel ??= tiffMetadata.BitsPerPixel;
// TODO: bits per pixel hardcoded to 24 for the start. short bpp = (short)this.bitsPerPixel;
short bpp = 24;
int bytesPerLine = 4 * (((image.Width * bpp) + 31) / 32); int bytesPerLine = 4 * (((image.Width * bpp) + 31) / 32);
this.padding = bytesPerLine - (int)(image.Width * (bpp / 8F)); this.padding = bytesPerLine - (int)(image.Width * (bpp / 8F));

9
src/ImageSharp/Formats/Tiff/TiffMetadata.cs

@ -1,9 +1,6 @@
// Copyright (c) Six Labors. // Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
using System.Collections;
using System.Collections.Generic;
namespace SixLabors.ImageSharp.Formats.Tiff namespace SixLabors.ImageSharp.Formats.Tiff
{ {
/// <summary> /// <summary>
@ -26,6 +23,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
{ {
this.ByteOrder = other.ByteOrder; this.ByteOrder = other.ByteOrder;
this.XmpProfile = other.XmpProfile; this.XmpProfile = other.XmpProfile;
this.BitsPerPixel = other.BitsPerPixel;
} }
/// <summary> /// <summary>
@ -33,6 +31,11 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// </summary> /// </summary>
public TiffByteOrder ByteOrder { get; set; } public TiffByteOrder ByteOrder { get; set; }
/// <summary>
/// Gets or sets the number of bits per pixel.
/// </summary>
public TiffBitsPerPixel BitsPerPixel { get; set; } = TiffBitsPerPixel.Pixel24;
/// <summary> /// <summary>
/// Gets or sets the XMP profile. /// Gets or sets the XMP profile.
/// </summary> /// </summary>

Loading…
Cancel
Save