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>
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;
/// <summary>
@ -104,7 +117,9 @@ namespace SixLabors.ImageSharp.Formats.Tiff
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
{
@ -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;
}
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/>
public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken)
{
@ -168,7 +203,7 @@ namespace SixLabors.ImageSharp.Formats.Tiff
private static TiffByteOrder ReadByteOrder(Stream stream)
{
byte[] headerBytes = new byte[2];
var headerBytes = new byte[2];
stream.Read(headerBytes, 0, 2);
if (headerBytes[0] == TiffConstants.ByteOrderLittleEndian && headerBytes[1] == TiffConstants.ByteOrderLittleEndian)
{
@ -187,26 +222,26 @@ namespace SixLabors.ImageSharp.Formats.Tiff
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="tags">The IFD tags.</param>
/// <param name="metadata">The frame metadata.</param>
/// <param name="frameMetaData">The frame metadata.</param>
/// <returns>
/// The tiff frame.
/// </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>
{
var coreMetadata = new ImageFrameMetadata();
metadata = coreMetadata.GetTiffMetadata();
metadata.Tags = tags;
frameMetaData = coreMetadata.GetTiffMetadata();
frameMetaData.Tags = tags;
this.VerifyAndParseOptions(metadata);
this.VerifyAndParseOptions(frameMetaData);
int width = (int)metadata.Width;
int height = (int)metadata.Height;
int width = (int)frameMetaData.Width;
int height = (int)frameMetaData.Height;
var frame = new ImageFrame<TPixel>(this.configuration, width, height, coreMetadata);
int rowsPerStrip = (int)metadata.RowsPerStrip;
uint[] stripOffsets = metadata.StripOffsets;
uint[] stripByteCounts = metadata.StripByteCounts;
int rowsPerStrip = (int)frameMetaData.RowsPerStrip;
uint[] stripOffsets = frameMetaData.StripOffsets;
uint[] stripByteCounts = frameMetaData.StripByteCounts;
if (this.PlanarConfiguration == TiffPlanarConfiguration.Planar)
{

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

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

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

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

Loading…
Cancel
Save