mirror of https://github.com/SixLabors/ImageSharp
26 changed files with 746 additions and 36 deletions
@ -0,0 +1,26 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Diagnostics; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.OpenExr |
|||
{ |
|||
[DebuggerDisplay("Name: {Name}, Type: {Type}, Length: {Length}")] |
|||
internal class ExrAttribute |
|||
{ |
|||
public static readonly ExrAttribute EmptyAttribute = new(string.Empty, string.Empty, 0); |
|||
|
|||
public ExrAttribute(string name, string type, int length) |
|||
{ |
|||
this.Name = name; |
|||
this.Type = type; |
|||
this.Length = length; |
|||
} |
|||
|
|||
public string Name { get; } |
|||
|
|||
public string Type { get; } |
|||
|
|||
public int Length { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,24 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.OpenExr |
|||
{ |
|||
internal struct ExrBox2i |
|||
{ |
|||
public ExrBox2i(int xMin, int yMin, int xMax, int yMax) |
|||
{ |
|||
this.xMin = xMin; |
|||
this.yMin = yMin; |
|||
this.xMax = xMax; |
|||
this.yMax = yMax; |
|||
} |
|||
|
|||
public int xMin { get; } |
|||
|
|||
public int yMin { get; } |
|||
|
|||
public int xMax { get; } |
|||
|
|||
public int yMax { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,30 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Runtime.InteropServices; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.OpenExr |
|||
{ |
|||
[StructLayout(LayoutKind.Sequential, Pack = 1)] |
|||
internal readonly struct ExrChannelInfo |
|||
{ |
|||
public ExrChannelInfo(string channelName, ExrPixelType pixelType, byte pLinear, int xSampling, int ySampling) |
|||
{ |
|||
this.ChannelName = channelName; |
|||
this.PixelType = pixelType; |
|||
this.PLinear = pLinear; |
|||
this.XSampling = xSampling; |
|||
this.YSampling = ySampling; |
|||
} |
|||
|
|||
public string ChannelName { get; } |
|||
|
|||
public ExrPixelType PixelType { get; } |
|||
|
|||
public byte PLinear { get; } |
|||
|
|||
public int XSampling { get; } |
|||
|
|||
public int YSampling { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,10 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.OpenExr |
|||
{ |
|||
internal enum ExrCompression : int |
|||
{ |
|||
None = 0 |
|||
} |
|||
} |
|||
@ -0,0 +1,18 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.OpenExr |
|||
{ |
|||
/// <summary>
|
|||
/// Registers the image encoders, decoders and mime type detectors for the OpenExr format.
|
|||
/// </summary>
|
|||
public sealed class ExrConfigurationModule : IConfigurationModule |
|||
{ |
|||
/// <inheritdoc/>
|
|||
public void Configure(Configuration configuration) |
|||
{ |
|||
configuration.ImageFormatsManager.SetDecoder(ExrFormat.Instance, new ExrDecoder()); |
|||
configuration.ImageFormatsManager.AddImageFormatDetector(new ExrImageFormatDetector()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Collections.Generic; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.OpenExr |
|||
{ |
|||
/// <summary>
|
|||
/// Defines constants relating to OpenExr images.
|
|||
/// </summary>
|
|||
internal static class ExrConstants |
|||
{ |
|||
/// <summary>
|
|||
/// The list of mimetypes that equate to a OpenExr image.
|
|||
/// </summary>
|
|||
public static readonly IEnumerable<string> MimeTypes = new[] { "image/x-exr" }; |
|||
|
|||
/// <summary>
|
|||
/// The list of file extensions that equate to a OpenExr image.
|
|||
/// </summary>
|
|||
public static readonly IEnumerable<string> FileExtensions = new[] { "exr" }; |
|||
|
|||
/// <summary>
|
|||
/// The magick bytes identifying an OpenExr image.
|
|||
/// </summary>
|
|||
public static readonly int MagickBytes = 20000630; |
|||
} |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.IO; |
|||
using System.Threading; |
|||
using System.Threading.Tasks; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.OpenExr |
|||
{ |
|||
/// <summary>
|
|||
/// Image decoder for generating an image out of a OpenExr stream.
|
|||
/// </summary>
|
|||
public sealed class ExrDecoder : IImageDecoder, IExrDecoderOptions, IImageInfoDetector |
|||
{ |
|||
/// <inheritdoc/>
|
|||
public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream) |
|||
where TPixel : unmanaged, IPixel<TPixel> |
|||
{ |
|||
Guard.NotNull(stream, nameof(stream)); |
|||
|
|||
var decoder = new ExrDecoderCore(configuration, this); |
|||
return decoder.Decode<TPixel>(configuration, stream); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public Image Decode(Configuration configuration, Stream stream) |
|||
=> this.Decode<Rgba32>(configuration, stream); |
|||
|
|||
/// <inheritdoc/>
|
|||
public Task<Image<TPixel>> DecodeAsync<TPixel>(Configuration configuration, Stream stream, CancellationToken cancellationToken) |
|||
where TPixel : unmanaged, IPixel<TPixel> |
|||
{ |
|||
Guard.NotNull(stream, nameof(stream)); |
|||
|
|||
var decoder = new ExrDecoderCore(configuration, this); |
|||
return decoder.DecodeAsync<TPixel>(configuration, stream, cancellationToken); |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public async Task<Image> DecodeAsync(Configuration configuration, Stream stream, CancellationToken cancellationToken) |
|||
=> await this.DecodeAsync<Rgba32>(configuration, stream, cancellationToken) |
|||
.ConfigureAwait(false); |
|||
|
|||
/// <inheritdoc/>
|
|||
public IImageInfo Identify(Configuration configuration, Stream stream) |
|||
{ |
|||
Guard.NotNull(stream, nameof(stream)); |
|||
|
|||
return new ExrDecoderCore(configuration, this).Identify(configuration, stream); |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public Task<IImageInfo> IdentifyAsync(Configuration configuration, Stream stream, CancellationToken cancellationToken) |
|||
{ |
|||
Guard.NotNull(stream, nameof(stream)); |
|||
|
|||
return new ExrDecoderCore(configuration, this).IdentifyAsync(configuration, stream, cancellationToken); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,256 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Buffers.Binary; |
|||
using System.Collections.Generic; |
|||
using System.Text; |
|||
using System.Threading; |
|||
using SixLabors.ImageSharp.Formats.Pbm; |
|||
using SixLabors.ImageSharp.IO; |
|||
using SixLabors.ImageSharp.Memory; |
|||
using SixLabors.ImageSharp.Metadata; |
|||
using SixLabors.ImageSharp.PixelFormats; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.OpenExr |
|||
{ |
|||
/// <summary>
|
|||
/// Performs the OpenExr decoding operation.
|
|||
/// </summary>
|
|||
internal sealed class ExrDecoderCore : IImageDecoderInternals |
|||
{ |
|||
/// <summary>
|
|||
/// Reusable buffer.
|
|||
/// </summary>
|
|||
private readonly byte[] buffer = new byte[4]; |
|||
|
|||
/// <summary>
|
|||
/// Used for allocating memory during processing operations.
|
|||
/// </summary>
|
|||
private readonly MemoryAllocator memoryAllocator; |
|||
|
|||
/// <summary>
|
|||
/// The bitmap decoder options.
|
|||
/// </summary>
|
|||
private readonly IExrDecoderOptions options; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ExrDecoderCore"/> class.
|
|||
/// </summary>
|
|||
/// <param name="configuration">The configuration.</param>
|
|||
/// <param name="options">The options.</param>
|
|||
public ExrDecoderCore(Configuration configuration, IExrDecoderOptions options) |
|||
{ |
|||
this.Configuration = configuration; |
|||
this.memoryAllocator = configuration.MemoryAllocator; |
|||
this.options = options; |
|||
} |
|||
|
|||
/// <inheritdoc />
|
|||
public Configuration Configuration { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the dimensions of the image.
|
|||
/// </summary>
|
|||
public Size Dimensions => new(this.Width, this.Height); |
|||
|
|||
private int Width { get; set; } |
|||
|
|||
private int Height { get; set; } |
|||
|
|||
/// <inheritdoc />
|
|||
public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken cancellationToken) |
|||
where TPixel : unmanaged, IPixel<TPixel> => throw new NotImplementedException(); |
|||
|
|||
/// <inheritdoc />
|
|||
public IImageInfo Identify(BufferedReadStream stream, CancellationToken cancellationToken) |
|||
{ |
|||
// Skip over the magick bytes.
|
|||
stream.Read(this.buffer, 0, 4); |
|||
|
|||
// Read version number.
|
|||
byte version = (byte)stream.ReadByte(); |
|||
if (version != 2) |
|||
{ |
|||
ExrThrowHelper.ThrowNotSupportedVersion(); |
|||
} |
|||
|
|||
// Next three bytes contain info's about the image.
|
|||
// We ignore those for now.
|
|||
stream.Read(this.buffer, 0, 3); |
|||
|
|||
ExrHeader header = this.ParseHeader(stream); |
|||
|
|||
if (!header.IsValid()) |
|||
{ |
|||
ExrThrowHelper.ThrowInvalidImageHeader(); |
|||
} |
|||
|
|||
if (header.Channels.Count != 3) |
|||
{ |
|||
ExrThrowHelper.ThrowNotSupported("Only 3 channels are supported!"); |
|||
} |
|||
|
|||
this.Width = header.DataWindow.Value.xMax - header.DataWindow.Value.xMin + 1; |
|||
this.Height = header.DataWindow.Value.yMax - header.DataWindow.Value.yMin + 1; |
|||
|
|||
// TODO: calculate bits per pixel.
|
|||
int bitsPerPixel = 48; |
|||
|
|||
return new ImageInfo(new PixelTypeInfo(bitsPerPixel), this.Width, this.Height, new ImageMetadata()); |
|||
} |
|||
|
|||
private ExrHeader ParseHeader(BufferedReadStream stream) |
|||
{ |
|||
ExrAttribute attribute = this.ReadAttribute(stream); |
|||
var header = new ExrHeader(); |
|||
|
|||
while (!attribute.Equals(ExrAttribute.EmptyAttribute)) |
|||
{ |
|||
switch (attribute.Name) |
|||
{ |
|||
case "channels": |
|||
IList<ExrChannelInfo> channels = this.ParseChannelList(stream, attribute.Length); |
|||
header.Channels = channels; |
|||
break; |
|||
case "compression": |
|||
var compression = (ExrCompression)stream.ReadByte(); |
|||
header.Compression = compression; |
|||
break; |
|||
case "dataWindow": |
|||
ExrBox2i dataWindow = this.ReadBox2i(stream); |
|||
header.DataWindow = dataWindow; |
|||
break; |
|||
case "displayWindow": |
|||
ExrBox2i displayWindow = this.ReadBox2i(stream); |
|||
header.DisplayWindow = displayWindow; |
|||
break; |
|||
case "lineOrder": |
|||
var lineOrder = (ExrLineOrder)stream.ReadByte(); |
|||
header.LineOrder = lineOrder; |
|||
break; |
|||
case "pixelAspectRatio": |
|||
float aspectRatio = stream.ReadSingle(this.buffer); |
|||
header.AspectRatio = aspectRatio; |
|||
break; |
|||
case "screenWindowCenter": |
|||
float screenWindowCenterX = stream.ReadSingle(this.buffer); |
|||
float screenWindowCenterY = stream.ReadSingle(this.buffer); |
|||
header.ScreenWindowCenter = new PointF(screenWindowCenterX, screenWindowCenterY); |
|||
break; |
|||
case "screenWindowWidth": |
|||
float screenWindowWidth = stream.ReadSingle(this.buffer); |
|||
header.ScreenWindowWidth = screenWindowWidth; |
|||
break; |
|||
default: |
|||
// Skip unknown attribute bytes.
|
|||
stream.Skip(attribute.Length); |
|||
break; |
|||
} |
|||
|
|||
attribute = this.ReadAttribute(stream); |
|||
} |
|||
|
|||
return header; |
|||
} |
|||
|
|||
private ExrAttribute ReadAttribute(BufferedReadStream stream) |
|||
{ |
|||
string attributeName = ReadString(stream); |
|||
if (attributeName.Equals(string.Empty)) |
|||
{ |
|||
return ExrAttribute.EmptyAttribute; |
|||
} |
|||
|
|||
string attributeType = ReadString(stream); |
|||
|
|||
stream.Read(this.buffer, 0, 4); |
|||
int attributeSize = BinaryPrimitives.ReadInt32LittleEndian(this.buffer); |
|||
|
|||
return new ExrAttribute(attributeName, attributeType, attributeSize); |
|||
} |
|||
|
|||
private ExrBox2i ReadBox2i(BufferedReadStream stream) |
|||
{ |
|||
stream.Read(this.buffer, 0, 4); |
|||
int xMin = BinaryPrimitives.ReadInt32LittleEndian(this.buffer); |
|||
|
|||
stream.Read(this.buffer, 0, 4); |
|||
int yMin = BinaryPrimitives.ReadInt32LittleEndian(this.buffer); |
|||
|
|||
stream.Read(this.buffer, 0, 4); |
|||
int xMax = BinaryPrimitives.ReadInt32LittleEndian(this.buffer); |
|||
|
|||
stream.Read(this.buffer, 0, 4); |
|||
int yMax = BinaryPrimitives.ReadInt32LittleEndian(this.buffer); |
|||
|
|||
return new ExrBox2i(xMin, yMin, xMax, yMax); |
|||
} |
|||
|
|||
private List<ExrChannelInfo> ParseChannelList(BufferedReadStream stream, int attributeSize) |
|||
{ |
|||
var channels = new List<ExrChannelInfo>(); |
|||
while (attributeSize > 1) |
|||
{ |
|||
ExrChannelInfo channelInfo = this.ReadChannelInfo(stream, out int bytesRead); |
|||
channels.Add(channelInfo); |
|||
attributeSize -= bytesRead; |
|||
} |
|||
|
|||
// Last byte should be a null byte.
|
|||
int byteRead = stream.ReadByte(); |
|||
|
|||
return channels; |
|||
} |
|||
|
|||
private ExrChannelInfo ReadChannelInfo(BufferedReadStream stream, out int bytesRead) |
|||
{ |
|||
string channelName = ReadString(stream); |
|||
bytesRead = channelName.Length + 1; |
|||
|
|||
stream.Read(this.buffer, 0, 4); |
|||
bytesRead += 4; |
|||
var pixelType = (ExrPixelType)BinaryPrimitives.ReadInt32LittleEndian(this.buffer); |
|||
|
|||
byte pLinear = (byte)stream.ReadByte(); |
|||
byte reserved0 = (byte)stream.ReadByte(); |
|||
byte reserved1 = (byte)stream.ReadByte(); |
|||
byte reserved2 = (byte)stream.ReadByte(); |
|||
bytesRead += 4; |
|||
|
|||
stream.Read(this.buffer, 0, 4); |
|||
bytesRead += 4; |
|||
int xSampling = BinaryPrimitives.ReadInt32LittleEndian(this.buffer); |
|||
|
|||
stream.Read(this.buffer, 0, 4); |
|||
bytesRead += 4; |
|||
int ySampling = BinaryPrimitives.ReadInt32LittleEndian(this.buffer); |
|||
|
|||
return new ExrChannelInfo(channelName, pixelType, pLinear, xSampling, ySampling); |
|||
} |
|||
|
|||
private static string ReadString(BufferedReadStream stream) |
|||
{ |
|||
var str = new StringBuilder(); |
|||
int character = stream.ReadByte(); |
|||
if (character == 0) |
|||
{ |
|||
// End of file header reached.
|
|||
return string.Empty; |
|||
} |
|||
|
|||
while (character != 0) |
|||
{ |
|||
if (character == -1) |
|||
{ |
|||
ExrThrowHelper.ThrowInvalidImageHeader(); |
|||
} |
|||
|
|||
str.Append((char)character); |
|||
character = stream.ReadByte(); |
|||
} |
|||
|
|||
return str.ToString(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,38 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Collections.Generic; |
|||
using SixLabors.ImageSharp.Formats.Bmp; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.OpenExr |
|||
{ |
|||
/// <summary>
|
|||
/// Registers the image encoders, decoders and mime type detectors for the OpenExr format.
|
|||
/// </summary>
|
|||
public sealed class ExrFormat : IImageFormat<ExrMetadata> |
|||
{ |
|||
private ExrFormat() |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the current instance.
|
|||
/// </summary>
|
|||
public static ExrFormat Instance { get; } = new(); |
|||
|
|||
/// <inheritdoc/>
|
|||
public string Name => "EXR"; |
|||
|
|||
/// <inheritdoc/>
|
|||
public string DefaultMimeType => "image/x-exr"; |
|||
|
|||
/// <inheritdoc/>
|
|||
public IEnumerable<string> MimeTypes => ExrConstants.MimeTypes; |
|||
|
|||
/// <inheritdoc/>
|
|||
public IEnumerable<string> FileExtensions => ExrConstants.FileExtensions; |
|||
|
|||
/// <inheritdoc/>
|
|||
public ExrMetadata CreateDefaultFormatMetadata() => new(); |
|||
} |
|||
} |
|||
@ -0,0 +1,71 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System.Collections.Generic; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.OpenExr |
|||
{ |
|||
internal class ExrHeader |
|||
{ |
|||
public IList<ExrChannelInfo> Channels { get; set; } |
|||
|
|||
public ExrCompression? Compression { get; set; } |
|||
|
|||
public ExrBox2i? DataWindow { get; set; } |
|||
|
|||
public ExrBox2i? DisplayWindow { get; set; } |
|||
|
|||
public ExrLineOrder? LineOrder { get; set; } |
|||
|
|||
public float? AspectRatio { get; set; } |
|||
|
|||
public float? ScreenWindowWidth { get; set; } |
|||
|
|||
public PointF? ScreenWindowCenter { get; set; } |
|||
|
|||
public bool IsValid() |
|||
{ |
|||
if (!this.Compression.HasValue) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (!this.DataWindow.HasValue) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (!this.DisplayWindow.HasValue) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (!this.LineOrder.HasValue) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (!this.AspectRatio.HasValue) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (!this.ScreenWindowWidth.HasValue) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (!this.ScreenWindowCenter.HasValue) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
if (this.Channels is null) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,31 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Buffers.Binary; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.OpenExr |
|||
{ |
|||
/// <summary>
|
|||
/// Detects OpenExr file headers.
|
|||
/// </summary>
|
|||
public sealed class ExrImageFormatDetector : IImageFormatDetector |
|||
{ |
|||
/// <inheritdoc/>
|
|||
public int HeaderSize => 4; |
|||
|
|||
/// <inheritdoc/>
|
|||
public IImageFormat DetectFormat(ReadOnlySpan<byte> header) => this.IsSupportedFileFormat(header) ? ExrFormat.Instance : null; |
|||
|
|||
private bool IsSupportedFileFormat(ReadOnlySpan<byte> header) |
|||
{ |
|||
if (header.Length >= this.HeaderSize) |
|||
{ |
|||
int fileTypeMarker = BinaryPrimitives.ReadInt32LittleEndian(header); |
|||
return fileTypeMarker == ExrConstants.MagickBytes; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,14 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.OpenExr |
|||
{ |
|||
internal enum ExrLineOrder : byte |
|||
{ |
|||
IncreasingY = 0, |
|||
|
|||
DecreasingY = 1, |
|||
|
|||
RandomY = 2 |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.OpenExr |
|||
{ |
|||
/// <summary>
|
|||
/// Provides OpenExr specific metadata information for the image.
|
|||
/// </summary>
|
|||
public class ExrMetadata : IDeepCloneable |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ExrMetadata"/> class.
|
|||
/// </summary>
|
|||
public ExrMetadata() |
|||
{ |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="ExrMetadata"/> class.
|
|||
/// </summary>
|
|||
/// <param name="other">The metadata to create an instance from.</param>
|
|||
private ExrMetadata(ExrMetadata other) |
|||
{ |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public IDeepCloneable DeepClone() => new ExrMetadata(this); |
|||
} |
|||
} |
|||
@ -0,0 +1,23 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.OpenExr |
|||
{ |
|||
internal enum ExrPixelType : int |
|||
{ |
|||
/// <summary>
|
|||
/// unsigned int (32 bit).
|
|||
/// </summary>
|
|||
Uint = 0, |
|||
|
|||
/// <summary>
|
|||
/// half (16 bit floating point).
|
|||
/// </summary>
|
|||
Half = 1, |
|||
|
|||
/// <summary>
|
|||
/// float (32 bit floating point).
|
|||
/// </summary>
|
|||
Float = 2 |
|||
} |
|||
} |
|||
@ -0,0 +1,26 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
using System; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
namespace SixLabors.ImageSharp.Formats.OpenExr |
|||
{ |
|||
/// <summary>
|
|||
/// Cold path optimizations for throwing exr format based exceptions.
|
|||
/// </summary>
|
|||
internal static class ExrThrowHelper |
|||
{ |
|||
[MethodImpl(InliningOptions.ColdPath)] |
|||
public static void ThrowNotSupportedVersion() => throw new NotSupportedException("Unsupported EXR version"); |
|||
|
|||
[MethodImpl(InliningOptions.ColdPath)] |
|||
public static void ThrowNotSupported(string msg) => throw new NotSupportedException(msg); |
|||
|
|||
[MethodImpl(InliningOptions.ColdPath)] |
|||
public static void ThrowInvalidImageHeader() => throw new InvalidImageContentException("Invalid EXR image header"); |
|||
|
|||
[MethodImpl(InliningOptions.ColdPath)] |
|||
public static void ThrowInvalidImageHeader(string msg) => throw new InvalidImageContentException(msg); |
|||
} |
|||
} |
|||
@ -0,0 +1,12 @@ |
|||
// Copyright (c) Six Labors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
|
|||
namespace SixLabors.ImageSharp.Formats.OpenExr |
|||
{ |
|||
/// <summary>
|
|||
/// Image decoder options for decoding OpenExr streams.
|
|||
/// </summary>
|
|||
internal interface IExrDecoderOptions |
|||
{ |
|||
} |
|||
} |
|||
@ -0,0 +1,4 @@ |
|||
### Some useful links for documentation about the OpenEXR format: |
|||
|
|||
- [Technical Introduction](https://openexr.readthedocs.io/en/latest/TechnicalIntroduction.html) |
|||
- [OpenExr file layout](https://openexr.readthedocs.io/en/latest/OpenEXRFileLayout.html) |
|||
Loading…
Reference in new issue