mirror of https://github.com/SixLabors/ImageSharp
committed by
GitHub
32 changed files with 488 additions and 1161 deletions
@ -1,88 +0,0 @@ |
|||||
// Copyright (c) Six Labors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.IO; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Streams |
|
||||
{ |
|
||||
internal class TiffBigEndianStream : TiffStream |
|
||||
{ |
|
||||
public TiffBigEndianStream(Stream stream) |
|
||||
: base(stream) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public override ByteOrder ByteOrder => ByteOrder.BigEndian; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts buffer data into an <see cref="short"/> using the correct endianness.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The converted value.</returns>
|
|
||||
public override short ReadInt16() |
|
||||
{ |
|
||||
byte[] bytes = this.ReadBytes(2); |
|
||||
return (short)((bytes[0] << 8) | bytes[1]); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts buffer data into an <see cref="int"/> using the correct endianness.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The converted value.</returns>
|
|
||||
public override int ReadInt32() |
|
||||
{ |
|
||||
byte[] bytes = this.ReadBytes(4); |
|
||||
return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts buffer data into a <see cref="uint"/> using the correct endianness.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The converted value.</returns>
|
|
||||
public override uint ReadUInt32() |
|
||||
{ |
|
||||
return (uint)this.ReadInt32(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts buffer data into a <see cref="ushort"/> using the correct endianness.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The converted value.</returns>
|
|
||||
public override ushort ReadUInt16() |
|
||||
{ |
|
||||
return (ushort)this.ReadInt16(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts buffer data into a <see cref="float"/> using the correct endianness.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The converted value.</returns>
|
|
||||
public override float ReadSingle() |
|
||||
{ |
|
||||
byte[] bytes = this.ReadBytes(4); |
|
||||
|
|
||||
if (BitConverter.IsLittleEndian) |
|
||||
{ |
|
||||
Array.Reverse(bytes); |
|
||||
} |
|
||||
|
|
||||
return BitConverter.ToSingle(bytes, 0); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts buffer data into a <see cref="double"/> using the correct endianness.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The converted value.</returns>
|
|
||||
public override double ReadDouble() |
|
||||
{ |
|
||||
byte[] bytes = this.ReadBytes(8); |
|
||||
|
|
||||
if (BitConverter.IsLittleEndian) |
|
||||
{ |
|
||||
Array.Reverse(bytes); |
|
||||
} |
|
||||
|
|
||||
return BitConverter.ToDouble(bytes, 0); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,88 +0,0 @@ |
|||||
// Copyright (c) Six Labors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System; |
|
||||
using System.IO; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Streams |
|
||||
{ |
|
||||
internal class TiffLittleEndianStream : TiffStream |
|
||||
{ |
|
||||
public TiffLittleEndianStream(Stream stream) |
|
||||
: base(stream) |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public override ByteOrder ByteOrder => ByteOrder.LittleEndian; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts buffer data into an <see cref="short"/> using the correct endianness.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The converted value.</returns>
|
|
||||
public override short ReadInt16() |
|
||||
{ |
|
||||
byte[] bytes = this.ReadBytes(2); |
|
||||
return (short)(bytes[0] | (bytes[1] << 8)); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts buffer data into an <see cref="int"/> using the correct endianness.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The converted value.</returns>
|
|
||||
public override int ReadInt32() |
|
||||
{ |
|
||||
byte[] bytes = this.ReadBytes(4); |
|
||||
return bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts buffer data into a <see cref="uint"/> using the correct endianness.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The converted value.</returns>
|
|
||||
public override uint ReadUInt32() |
|
||||
{ |
|
||||
return (uint)this.ReadInt32(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts buffer data into a <see cref="ushort"/> using the correct endianness.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The converted value.</returns>
|
|
||||
public override ushort ReadUInt16() |
|
||||
{ |
|
||||
return (ushort)this.ReadInt16(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts buffer data into a <see cref="float"/> using the correct endianness.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The converted value.</returns>
|
|
||||
public override float ReadSingle() |
|
||||
{ |
|
||||
byte[] bytes = this.ReadBytes(4); |
|
||||
|
|
||||
if (!BitConverter.IsLittleEndian) |
|
||||
{ |
|
||||
Array.Reverse(bytes); |
|
||||
} |
|
||||
|
|
||||
return BitConverter.ToSingle(bytes, 0); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts buffer data into a <see cref="double"/> using the correct endianness.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The converted value.</returns>
|
|
||||
public override double ReadDouble() |
|
||||
{ |
|
||||
byte[] bytes = this.ReadBytes(8); |
|
||||
|
|
||||
if (!BitConverter.IsLittleEndian) |
|
||||
{ |
|
||||
Array.Reverse(bytes); |
|
||||
} |
|
||||
|
|
||||
return BitConverter.ToDouble(bytes, 0); |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -1,94 +0,0 @@ |
|||||
// Copyright (c) Six Labors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System.IO; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Streams |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The tiff data stream base class.
|
|
||||
/// </summary>
|
|
||||
internal abstract class TiffStream |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The input stream.
|
|
||||
/// </summary>
|
|
||||
private readonly Stream stream; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Initializes a new instance of the <see cref="TiffStream"/> class.
|
|
||||
/// </summary>
|
|
||||
/// <param name="stream">The stream.</param>
|
|
||||
protected TiffStream(Stream stream) |
|
||||
{ |
|
||||
this.stream = stream; |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets a value indicating whether the file is encoded in little-endian or big-endian format.
|
|
||||
/// </summary>
|
|
||||
public abstract ByteOrder ByteOrder { get; } |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the input stream.
|
|
||||
/// </summary>
|
|
||||
public Stream InputStream => this.stream; |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Gets the stream position.
|
|
||||
/// </summary>
|
|
||||
public long Position => this.stream.Position; |
|
||||
|
|
||||
public void Seek(uint offset) |
|
||||
{ |
|
||||
this.stream.Seek(offset, SeekOrigin.Begin); |
|
||||
} |
|
||||
|
|
||||
public void Skip(uint offset) |
|
||||
{ |
|
||||
this.stream.Seek(offset, SeekOrigin.Current); |
|
||||
} |
|
||||
|
|
||||
public void Skip(int offset) |
|
||||
{ |
|
||||
this.stream.Seek(offset, SeekOrigin.Current); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts buffer data into a <see cref="byte"/> using the correct endianness.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The converted value.</returns>
|
|
||||
public byte ReadByte() |
|
||||
{ |
|
||||
return (byte)this.stream.ReadByte(); |
|
||||
} |
|
||||
|
|
||||
/// <summary>
|
|
||||
/// Converts buffer data into an <see cref="sbyte"/> using the correct endianness.
|
|
||||
/// </summary>
|
|
||||
/// <returns>The converted value.</returns>
|
|
||||
public sbyte ReadSByte() |
|
||||
{ |
|
||||
return (sbyte)this.stream.ReadByte(); |
|
||||
} |
|
||||
|
|
||||
public byte[] ReadBytes(uint count) |
|
||||
{ |
|
||||
byte[] buf = new byte[count]; |
|
||||
this.stream.Read(buf, 0, buf.Length); |
|
||||
return buf; |
|
||||
} |
|
||||
|
|
||||
public abstract short ReadInt16(); |
|
||||
|
|
||||
public abstract int ReadInt32(); |
|
||||
|
|
||||
public abstract uint ReadUInt32(); |
|
||||
|
|
||||
public abstract ushort ReadUInt16(); |
|
||||
|
|
||||
public abstract float ReadSingle(); |
|
||||
|
|
||||
public abstract double ReadDouble(); |
|
||||
} |
|
||||
} |
|
||||
@ -1,200 +0,0 @@ |
|||||
// Copyright (c) Six Labors.
|
|
||||
// Licensed under the Apache License, Version 2.0.
|
|
||||
|
|
||||
using System.Linq; |
|
||||
|
|
||||
using SixLabors.ImageSharp.Metadata.Profiles.Exif; |
|
||||
|
|
||||
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff |
|
||||
{ |
|
||||
/// <summary>
|
|
||||
/// The tiff metadata extensions
|
|
||||
/// </summary>
|
|
||||
internal static class TiffFrameMetadataExtensions |
|
||||
{ |
|
||||
public static T[] GetArray<T>(this TiffFrameMetadata meta, ExifTag tag, bool optional = false) |
|
||||
where T : struct |
|
||||
{ |
|
||||
if (meta.TryGetArray(tag, out T[] result)) |
|
||||
{ |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
if (!optional) |
|
||||
{ |
|
||||
TiffThrowHelper.ThrowTagNotFound(nameof(tag)); |
|
||||
} |
|
||||
|
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
public static bool TryGetArray<T>(this TiffFrameMetadata meta, ExifTag tag, out T[] result) |
|
||||
where T : struct |
|
||||
{ |
|
||||
foreach (IExifValue entry in meta.FrameTags) |
|
||||
{ |
|
||||
if (entry.Tag == tag) |
|
||||
{ |
|
||||
DebugGuard.IsTrue(entry.IsArray, "Expected array entry"); |
|
||||
|
|
||||
result = (T[])entry.GetValue(); |
|
||||
return true; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
result = null; |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
public static TEnum[] GetEnumArray<TEnum, TTagValue>(this TiffFrameMetadata meta, ExifTag tag, bool optional = false) |
|
||||
where TEnum : struct |
|
||||
where TTagValue : struct |
|
||||
{ |
|
||||
if (meta.TryGetArray(tag, out TTagValue[] result)) |
|
||||
{ |
|
||||
return result.Select(a => (TEnum)(object)a).ToArray(); |
|
||||
} |
|
||||
|
|
||||
if (!optional) |
|
||||
{ |
|
||||
TiffThrowHelper.ThrowTagNotFound(nameof(tag)); |
|
||||
} |
|
||||
|
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
public static string GetString(this TiffFrameMetadata meta, ExifTag tag) |
|
||||
{ |
|
||||
foreach (IExifValue entry in meta.FrameTags) |
|
||||
{ |
|
||||
if (entry.Tag == tag) |
|
||||
{ |
|
||||
DebugGuard.IsTrue(entry.DataType == ExifDataType.Ascii, "Expected string entry"); |
|
||||
object value = entry.GetValue(); |
|
||||
DebugGuard.IsTrue(value is string, "Expected string entry"); |
|
||||
|
|
||||
return (string)value; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
public static bool SetString(this TiffFrameMetadata meta, ExifTag tag, string value) |
|
||||
{ |
|
||||
IExifValue obj = FindOrCreate(meta, tag); |
|
||||
DebugGuard.IsTrue(obj.DataType == ExifDataType.Ascii, "Expected string entry"); |
|
||||
|
|
||||
return obj.TrySetValue(value); |
|
||||
} |
|
||||
|
|
||||
public static TEnum? GetSingleEnumNullable<TEnum, TTagValue>(this TiffFrameMetadata meta, ExifTag tag) |
|
||||
where TEnum : struct |
|
||||
where TTagValue : struct |
|
||||
{ |
|
||||
if (!meta.TryGetSingle(tag, out TTagValue value)) |
|
||||
{ |
|
||||
return null; |
|
||||
} |
|
||||
|
|
||||
return (TEnum)(object)value; |
|
||||
} |
|
||||
|
|
||||
public static TEnum GetSingleEnum<TEnum, TTagValue>(this TiffFrameMetadata meta, ExifTag tag, TEnum? defaultValue = null) |
|
||||
where TEnum : struct |
|
||||
where TTagValue : struct |
|
||||
=> meta.GetSingleEnumNullable<TEnum, TTagValue>(tag) ?? (defaultValue != null ? defaultValue.Value : throw TiffThrowHelper.TagNotFound(nameof(tag))); |
|
||||
|
|
||||
public static bool SetSingleEnum<TEnum, TTagValue>(this TiffFrameMetadata meta, ExifTag tag, TEnum value) |
|
||||
where TEnum : struct |
|
||||
where TTagValue : struct |
|
||||
{ |
|
||||
IExifValue obj = FindOrCreate(meta, tag); |
|
||||
|
|
||||
object val = (TTagValue)(object)value; |
|
||||
return obj.TrySetValue(val); |
|
||||
} |
|
||||
|
|
||||
public static T GetSingle<T>(this TiffFrameMetadata meta, ExifTag tag) |
|
||||
where T : struct |
|
||||
{ |
|
||||
if (meta.TryGetSingle(tag, out T result)) |
|
||||
{ |
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
throw TiffThrowHelper.TagNotFound(nameof(tag)); |
|
||||
} |
|
||||
|
|
||||
public static bool TryGetSingle<T>(this TiffFrameMetadata meta, ExifTag tag, out T result) |
|
||||
where T : struct |
|
||||
{ |
|
||||
foreach (IExifValue entry in meta.FrameTags) |
|
||||
{ |
|
||||
if (entry.Tag == tag) |
|
||||
{ |
|
||||
DebugGuard.IsTrue(!entry.IsArray, "Expected non array entry"); |
|
||||
|
|
||||
object value = entry.GetValue(); |
|
||||
|
|
||||
result = (T)value; |
|
||||
return true; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
result = default; |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
public static bool SetSingle<T>(this TiffFrameMetadata meta, ExifTag tag, T value) |
|
||||
where T : struct |
|
||||
{ |
|
||||
IExifValue obj = FindOrCreate(meta, tag); |
|
||||
DebugGuard.IsTrue(!obj.IsArray, "Expected non array entry"); |
|
||||
|
|
||||
object val = value; |
|
||||
return obj.TrySetValue(val); |
|
||||
} |
|
||||
|
|
||||
public static bool Remove(this TiffFrameMetadata meta, ExifTag tag) |
|
||||
{ |
|
||||
IExifValue obj = null; |
|
||||
foreach (IExifValue entry in meta.FrameTags) |
|
||||
{ |
|
||||
if (entry.Tag == tag) |
|
||||
{ |
|
||||
obj = entry; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if (obj != null) |
|
||||
{ |
|
||||
return meta.FrameTags.Remove(obj); |
|
||||
} |
|
||||
|
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
private static IExifValue FindOrCreate(TiffFrameMetadata meta, ExifTag tag) |
|
||||
{ |
|
||||
IExifValue obj = null; |
|
||||
foreach (IExifValue entry in meta.FrameTags) |
|
||||
{ |
|
||||
if (entry.Tag == tag) |
|
||||
{ |
|
||||
obj = entry; |
|
||||
break; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
if (obj == null) |
|
||||
{ |
|
||||
obj = ExifValues.Create(tag); |
|
||||
meta.FrameTags.Add(obj); |
|
||||
} |
|
||||
|
|
||||
return obj; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,3 @@ |
|||||
|
version https://git-lfs.github.com/spec/v1 |
||||
|
oid sha256:026bb9372882d8fc15540b4f94e23138e75aacb0ebf2f5940b056fc66819ec46 |
||||
|
size 1968862 |
||||
Loading…
Reference in new issue