mirror of https://github.com/SixLabors/ImageSharp
4 changed files with 157 additions and 1 deletions
@ -0,0 +1,79 @@ |
|||||
|
// <copyright file="TiffEncoderCore.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp.Formats |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Buffers; |
||||
|
using System.IO; |
||||
|
using System.Linq; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using System.Text; |
||||
|
using ImageSharp.Formats.Tiff; |
||||
|
using ImageSharp.Memory; |
||||
|
using ImageSharp.PixelFormats; |
||||
|
|
||||
|
using Quantizers; |
||||
|
|
||||
|
using static ComparableExtensions; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Performs the TIFF encoding operation.
|
||||
|
/// </summary>
|
||||
|
internal sealed class TiffEncoderCore |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The options for the encoder.
|
||||
|
/// </summary>
|
||||
|
private readonly ITiffEncoderOptions options; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="TiffEncoderCore"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="options">The options for the encoder.</param>
|
||||
|
public TiffEncoderCore(ITiffEncoderOptions options) |
||||
|
{ |
||||
|
this.options = options ?? new TiffEncoderOptions(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Encodes the image to the specified stream from the <see cref="Image{TPixel}"/>.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TPixel">The pixel format.</typeparam>
|
||||
|
/// <param name="image">The <see cref="ImageBase{TPixel}"/> to encode from.</param>
|
||||
|
/// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param>
|
||||
|
public void Encode<TPixel>(Image<TPixel> image, Stream stream) |
||||
|
where TPixel : struct, IPixel<TPixel> |
||||
|
{ |
||||
|
Guard.NotNull(image, nameof(image)); |
||||
|
Guard.NotNull(stream, nameof(stream)); |
||||
|
|
||||
|
using (BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8, true)) |
||||
|
{ |
||||
|
this.WriteHeader(writer, 0); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Writes the TIFF file header.
|
||||
|
/// </summary>
|
||||
|
/// <param name="writer">The <see cref="BinaryWriter"/> to write data to.</param>
|
||||
|
/// <param name="firstIfdOffset">The byte offset to the first IFD in the file.</param>
|
||||
|
public void WriteHeader(BinaryWriter writer, uint firstIfdOffset) |
||||
|
{ |
||||
|
if (firstIfdOffset == 0 || firstIfdOffset % TiffConstants.SizeOfWordBoundary != 0) |
||||
|
{ |
||||
|
throw new ArgumentException("IFD offsets must be non-zero and on a word boundary.", nameof(firstIfdOffset)); |
||||
|
} |
||||
|
|
||||
|
ushort byteOrderMarker = BitConverter.IsLittleEndian ? TiffConstants.ByteOrderLittleEndianShort |
||||
|
: TiffConstants.ByteOrderBigEndianShort; |
||||
|
|
||||
|
writer.Write(byteOrderMarker); |
||||
|
writer.Write((ushort)42); |
||||
|
writer.Write(firstIfdOffset); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,61 @@ |
|||||
|
// <copyright file="TiffEncoderHeaderTests.cs" company="James Jackson-South">
|
||||
|
// Copyright (c) James Jackson-South and contributors.
|
||||
|
// Licensed under the Apache License, Version 2.0.
|
||||
|
// </copyright>
|
||||
|
|
||||
|
namespace ImageSharp.Tests |
||||
|
{ |
||||
|
using System; |
||||
|
using System.IO; |
||||
|
using Xunit; |
||||
|
|
||||
|
using ImageSharp.Formats; |
||||
|
using System.Text; |
||||
|
|
||||
|
public class TiffEncoderHeaderTests |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void WriteHeader_WritesValidHeader() |
||||
|
{ |
||||
|
MemoryStream stream = new MemoryStream(); |
||||
|
TiffEncoderCore encoder = new TiffEncoderCore(null); |
||||
|
|
||||
|
using (BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8, true)) |
||||
|
{ |
||||
|
encoder.WriteHeader(writer, 1232); |
||||
|
} |
||||
|
|
||||
|
stream.Position = 0; |
||||
|
Assert.Equal(8, stream.Length); |
||||
|
Assert.Equal(new byte[] { 0x49, 0x49, 42, 0, 0xD0, 0x04, 0x00, 0x00 }, stream.ToArray()); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void WriteHeader_ThrowsExceptionIfFirstIfdOffsetIsZero() |
||||
|
{ |
||||
|
MemoryStream stream = new MemoryStream(); |
||||
|
TiffEncoderCore encoder = new TiffEncoderCore(null); |
||||
|
|
||||
|
using (BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8, true)) |
||||
|
{ |
||||
|
ArgumentException e = Assert.Throws<ArgumentException>(() => { encoder.WriteHeader(writer, 0); }); |
||||
|
Assert.Equal("IFD offsets must be non-zero and on a word boundary.\r\nParameter name: firstIfdOffset", e.Message); |
||||
|
Assert.Equal("firstIfdOffset", e.ParamName); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void WriteHeader_ThrowsExceptionIfIfdOffsetIsNotOnAWordBoundary() |
||||
|
{ |
||||
|
MemoryStream stream = new MemoryStream(); |
||||
|
TiffEncoderCore encoder = new TiffEncoderCore(null); |
||||
|
|
||||
|
using (BinaryWriter writer = new BinaryWriter(stream, Encoding.UTF8, true)) |
||||
|
{ |
||||
|
ArgumentException e = Assert.Throws<ArgumentException>(() => { encoder.WriteHeader(writer, 1234); }); |
||||
|
Assert.Equal("IFD offsets must be non-zero and on a word boundary.\r\nParameter name: firstIfdOffset", e.Message); |
||||
|
Assert.Equal("firstIfdOffset", e.ParamName); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue