Browse Source

Port Tga and Png

pull/2180/head
James Jackson-South 4 years ago
parent
commit
c9beb02c0e
  1. 16
      src/ImageSharp/Formats/Png/IPngDecoderOptions.cs
  2. 59
      src/ImageSharp/Formats/Png/PngDecoder.cs
  3. 57
      src/ImageSharp/Formats/Png/PngDecoderCore.cs
  4. 14
      src/ImageSharp/Formats/Png/PngDecoderOptions.cs
  5. 12
      src/ImageSharp/Formats/Tga/ITgaDecoderOptions.cs
  6. 23
      src/ImageSharp/Formats/Tga/TgaDecoder.cs
  7. 43
      src/ImageSharp/Formats/Tga/TgaDecoderCore.cs
  8. 14
      src/ImageSharp/Formats/Tga/TgaDecoderOptions.cs

16
src/ImageSharp/Formats/Png/IPngDecoderOptions.cs

@ -1,16 +0,0 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp.Formats.Png
{
/// <summary>
/// The options for decoding png images
/// </summary>
internal interface IPngDecoderOptions
{
/// <summary>
/// Gets a value indicating whether the metadata should be ignored when the image is being decoded.
/// </summary>
bool IgnoreMetadata { get; }
}
}

59
src/ImageSharp/Formats/Png/PngDecoder.cs

@ -10,24 +10,24 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <summary> /// <summary>
/// Decoder for generating an image out of a png encoded stream. /// Decoder for generating an image out of a png encoded stream.
/// </summary> /// </summary>
public sealed class PngDecoder : IImageDecoder, IPngDecoderOptions, IImageInfoDetector public sealed class PngDecoder : ImageDecoder<PngDecoderOptions>
{ {
/// <inheritdoc/> /// <inheritdoc/>
public bool IgnoreMetadata { get; set; } public override Image<TPixel> DecodeSpecialized<TPixel>(PngDecoderOptions options, Stream stream, CancellationToken cancellationToken)
/// <inheritdoc/>
public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel>
{ {
PngDecoderCore decoder = new(configuration, this); PngDecoderCore decoder = new(options);
return decoder.Decode<TPixel>(configuration, stream, cancellationToken); Image<TPixel> image = decoder.Decode<PngDecoderOptions, TPixel>(options.GeneralOptions.Configuration, stream, cancellationToken);
Resize(options.GeneralOptions, image);
return image;
} }
/// <inheritdoc /> /// <inheritdoc/>
public Image Decode(Configuration configuration, Stream stream, CancellationToken cancellationToken) public override Image DecodeSpecialized(PngDecoderOptions options, Stream stream, CancellationToken cancellationToken)
{ {
PngDecoderCore decoder = new(configuration, true); PngDecoderCore decoder = new(options, true);
IImageInfo info = decoder.Identify(configuration, stream, cancellationToken); IImageInfo info = decoder.Identify(options.GeneralOptions.Configuration, stream, cancellationToken);
stream.Position = 0; stream.Position = 0;
PngMetadata meta = info.Metadata.GetPngMetadata(); PngMetadata meta = info.Metadata.GetPngMetadata();
@ -39,49 +39,50 @@ namespace SixLabors.ImageSharp.Formats.Png
if (bits == PngBitDepth.Bit16) if (bits == PngBitDepth.Bit16)
{ {
return !meta.HasTransparency return !meta.HasTransparency
? this.Decode<L16>(configuration, stream, cancellationToken) ? this.DecodeSpecialized<L16>(options, stream, cancellationToken)
: this.Decode<La32>(configuration, stream, cancellationToken); : this.DecodeSpecialized<La32>(options, stream, cancellationToken);
} }
return !meta.HasTransparency return !meta.HasTransparency
? this.Decode<L8>(configuration, stream, cancellationToken) ? this.DecodeSpecialized<L8>(options, stream, cancellationToken)
: this.Decode<La16>(configuration, stream, cancellationToken); : this.DecodeSpecialized<La16>(options, stream, cancellationToken);
case PngColorType.Rgb: case PngColorType.Rgb:
if (bits == PngBitDepth.Bit16) if (bits == PngBitDepth.Bit16)
{ {
return !meta.HasTransparency return !meta.HasTransparency
? this.Decode<Rgb48>(configuration, stream, cancellationToken) ? this.DecodeSpecialized<Rgb48>(options, stream, cancellationToken)
: this.Decode<Rgba64>(configuration, stream, cancellationToken); : this.DecodeSpecialized<Rgba64>(options, stream, cancellationToken);
} }
return !meta.HasTransparency return !meta.HasTransparency
? this.Decode<Rgb24>(configuration, stream, cancellationToken) ? this.DecodeSpecialized<Rgb24>(options, stream, cancellationToken)
: this.Decode<Rgba32>(configuration, stream, cancellationToken); : this.DecodeSpecialized<Rgba32>(options, stream, cancellationToken);
case PngColorType.Palette: case PngColorType.Palette:
return this.Decode<Rgba32>(configuration, stream, cancellationToken); return this.DecodeSpecialized<Rgba32>(options, stream, cancellationToken);
case PngColorType.GrayscaleWithAlpha: case PngColorType.GrayscaleWithAlpha:
return (bits == PngBitDepth.Bit16) return (bits == PngBitDepth.Bit16)
? this.Decode<La32>(configuration, stream, cancellationToken) ? this.DecodeSpecialized<La32>(options, stream, cancellationToken)
: this.Decode<La16>(configuration, stream, cancellationToken); : this.DecodeSpecialized<La16>(options, stream, cancellationToken);
case PngColorType.RgbWithAlpha: case PngColorType.RgbWithAlpha:
return (bits == PngBitDepth.Bit16) return (bits == PngBitDepth.Bit16)
? this.Decode<Rgba64>(configuration, stream, cancellationToken) ? this.DecodeSpecialized<Rgba64>(options, stream, cancellationToken)
: this.Decode<Rgba32>(configuration, stream, cancellationToken); : this.DecodeSpecialized<Rgba32>(options, stream, cancellationToken);
default: default:
return this.Decode<Rgba32>(configuration, stream, cancellationToken); return this.DecodeSpecialized<Rgba32>(options, stream, cancellationToken);
} }
} }
/// <inheritdoc/> /// <inheritdoc/>
public IImageInfo Identify(Configuration configuration, Stream stream, CancellationToken cancellationToken) public override IImageInfo IdentifySpecialized(PngDecoderOptions options, Stream stream, CancellationToken cancellationToken)
{ {
PngDecoderCore decoder = new(configuration, this); Guard.NotNull(stream, nameof(stream));
return decoder.Identify(configuration, stream, cancellationToken);
return new PngDecoderCore(options).Identify(options.GeneralOptions.Configuration, stream, cancellationToken);
} }
} }
} }

57
src/ImageSharp/Formats/Png/PngDecoderCore.cs

@ -4,7 +4,6 @@
using System; using System;
using System.Buffers; using System.Buffers;
using System.Buffers.Binary; using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.IO.Compression; using System.IO.Compression;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
@ -28,17 +27,22 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <summary> /// <summary>
/// Performs the png decoding operation. /// Performs the png decoding operation.
/// </summary> /// </summary>
internal sealed class PngDecoderCore : IImageDecoderInternals internal sealed class PngDecoderCore : IImageDecoderInternals<PngDecoderOptions>
{ {
/// <summary> /// <summary>
/// Reusable buffer. /// Reusable buffer.
/// </summary> /// </summary>
private readonly byte[] buffer = new byte[4]; private readonly byte[] buffer = new byte[4];
/// <summary>
/// The general decoder options.
/// </summary>
private readonly Configuration configuration;
/// <summary> /// <summary>
/// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded. /// Gets or sets a value indicating whether the metadata should be ignored when the image is being decoded.
/// </summary> /// </summary>
private readonly bool ignoreMetadata; private readonly bool skipMetadata;
/// <summary> /// <summary>
/// Gets or sets a value indicating whether to read the IHDR and tRNS chunks only. /// Gets or sets a value indicating whether to read the IHDR and tRNS chunks only.
@ -118,29 +122,26 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="PngDecoderCore"/> class. /// Initializes a new instance of the <see cref="PngDecoderCore"/> class.
/// </summary> /// </summary>
/// <param name="configuration">The configuration.</param>
/// <param name="options">The decoder options.</param> /// <param name="options">The decoder options.</param>
public PngDecoderCore(Configuration configuration, IPngDecoderOptions options) public PngDecoderCore(PngDecoderOptions options)
{ {
this.Configuration = configuration ?? Configuration.Default; this.configuration = options.GeneralOptions.Configuration;
this.memoryAllocator = this.Configuration.MemoryAllocator; this.memoryAllocator = this.configuration.MemoryAllocator;
this.ignoreMetadata = options.IgnoreMetadata; this.skipMetadata = options.GeneralOptions.SkipMetadata;
} }
internal PngDecoderCore(Configuration configuration, bool colorMetadataOnly) internal PngDecoderCore(PngDecoderOptions options, bool colorMetadataOnly)
{ {
this.Configuration = configuration ?? Configuration.Default; this.configuration = options.GeneralOptions.Configuration;
this.memoryAllocator = this.Configuration.MemoryAllocator; this.memoryAllocator = this.configuration.MemoryAllocator;
this.colorMetadataOnly = colorMetadataOnly; this.colorMetadataOnly = colorMetadataOnly;
this.ignoreMetadata = true; this.skipMetadata = true;
} }
/// <inheritdoc/> /// <inheritdoc/>
public Configuration Configuration { get; } public PngDecoderOptions Options { get; }
/// <summary> /// <inheritdoc/>
/// Gets the dimensions of the image.
/// </summary>
public Size Dimensions => new(this.header.Width, this.header.Height); public Size Dimensions => new(this.header.Width, this.header.Height);
/// <inheritdoc/> /// <inheritdoc/>
@ -199,7 +200,7 @@ namespace SixLabors.ImageSharp.Formats.Png
this.ReadInternationalTextChunk(metadata, chunk.Data.GetSpan()); this.ReadInternationalTextChunk(metadata, chunk.Data.GetSpan());
break; break;
case PngChunkType.Exif: case PngChunkType.Exif:
if (!this.ignoreMetadata) if (!this.skipMetadata)
{ {
byte[] exifData = new byte[chunk.Length]; byte[] exifData = new byte[chunk.Length];
chunk.Data.GetSpan().CopyTo(exifData); chunk.Data.GetSpan().CopyTo(exifData);
@ -336,7 +337,7 @@ namespace SixLabors.ImageSharp.Formats.Png
break; break;
} }
if (!this.ignoreMetadata) if (!this.skipMetadata)
{ {
byte[] exifData = new byte[chunk.Length]; byte[] exifData = new byte[chunk.Length];
chunk.Data.GetSpan().CopyTo(exifData); chunk.Data.GetSpan().CopyTo(exifData);
@ -469,7 +470,7 @@ namespace SixLabors.ImageSharp.Formats.Png
where TPixel : unmanaged, IPixel<TPixel> where TPixel : unmanaged, IPixel<TPixel>
{ {
image = Image.CreateUninitialized<TPixel>( image = Image.CreateUninitialized<TPixel>(
this.Configuration, this.configuration,
this.header.Width, this.header.Width,
this.header.Height, this.header.Height,
metadata); metadata);
@ -485,7 +486,7 @@ namespace SixLabors.ImageSharp.Formats.Png
this.previousScanline?.Dispose(); this.previousScanline?.Dispose();
this.scanline?.Dispose(); this.scanline?.Dispose();
this.previousScanline = this.memoryAllocator.Allocate<byte>(this.bytesPerScanline, AllocationOptions.Clean); this.previousScanline = this.memoryAllocator.Allocate<byte>(this.bytesPerScanline, AllocationOptions.Clean);
this.scanline = this.Configuration.MemoryAllocator.Allocate<byte>(this.bytesPerScanline, AllocationOptions.Clean); this.scanline = this.configuration.MemoryAllocator.Allocate<byte>(this.bytesPerScanline, AllocationOptions.Clean);
} }
/// <summary> /// <summary>
@ -798,7 +799,7 @@ namespace SixLabors.ImageSharp.Formats.Png
case PngColorType.Rgb: case PngColorType.Rgb:
PngScanlineProcessor.ProcessRgbScanline( PngScanlineProcessor.ProcessRgbScanline(
this.Configuration, this.configuration,
this.header, this.header,
scanlineSpan, scanlineSpan,
rowSpan, rowSpan,
@ -812,7 +813,7 @@ namespace SixLabors.ImageSharp.Formats.Png
case PngColorType.RgbWithAlpha: case PngColorType.RgbWithAlpha:
PngScanlineProcessor.ProcessRgbaScanline( PngScanlineProcessor.ProcessRgbaScanline(
this.Configuration, this.configuration,
this.header, this.header,
scanlineSpan, scanlineSpan,
rowSpan, rowSpan,
@ -1001,7 +1002,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <param name="data">The <see cref="T:Span"/> containing the data.</param> /// <param name="data">The <see cref="T:Span"/> containing the data.</param>
private void ReadTextChunk(ImageMetadata baseMetadata, PngMetadata metadata, ReadOnlySpan<byte> data) private void ReadTextChunk(ImageMetadata baseMetadata, PngMetadata metadata, ReadOnlySpan<byte> data)
{ {
if (this.ignoreMetadata) if (this.skipMetadata)
{ {
return; return;
} }
@ -1036,7 +1037,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <param name="data">The <see cref="T:Span"/> containing the data.</param> /// <param name="data">The <see cref="T:Span"/> containing the data.</param>
private void ReadCompressedTextChunk(ImageMetadata baseMetadata, PngMetadata metadata, ReadOnlySpan<byte> data) private void ReadCompressedTextChunk(ImageMetadata baseMetadata, PngMetadata metadata, ReadOnlySpan<byte> data)
{ {
if (this.ignoreMetadata) if (this.skipMetadata)
{ {
return; return;
} }
@ -1222,10 +1223,10 @@ namespace SixLabors.ImageSharp.Formats.Png
{ {
fixed (byte* compressedDataBase = compressedData) fixed (byte* compressedDataBase = compressedData)
{ {
using (IMemoryOwner<byte> destBuffer = this.memoryAllocator.Allocate<byte>(this.Configuration.StreamProcessingBufferSize)) using (IMemoryOwner<byte> destBuffer = this.memoryAllocator.Allocate<byte>(this.configuration.StreamProcessingBufferSize))
using (var memoryStreamOutput = new MemoryStream(compressedData.Length)) using (var memoryStreamOutput = new MemoryStream(compressedData.Length))
using (var memoryStreamInput = new UnmanagedMemoryStream(compressedDataBase, compressedData.Length)) using (var memoryStreamInput = new UnmanagedMemoryStream(compressedDataBase, compressedData.Length))
using (var bufferedStream = new BufferedReadStream(this.Configuration, memoryStreamInput)) using (var bufferedStream = new BufferedReadStream(this.configuration, memoryStreamInput))
using (var inflateStream = new ZlibInflateStream(bufferedStream)) using (var inflateStream = new ZlibInflateStream(bufferedStream))
{ {
Span<byte> destUncompressedData = destBuffer.GetSpan(); Span<byte> destUncompressedData = destBuffer.GetSpan();
@ -1324,7 +1325,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// <param name="data">The <see cref="T:Span"/> containing the data.</param> /// <param name="data">The <see cref="T:Span"/> containing the data.</param>
private void ReadInternationalTextChunk(ImageMetadata metadata, ReadOnlySpan<byte> data) private void ReadInternationalTextChunk(ImageMetadata metadata, ReadOnlySpan<byte> data)
{ {
if (this.ignoreMetadata) if (this.skipMetadata)
{ {
return; return;
} }
@ -1563,7 +1564,7 @@ namespace SixLabors.ImageSharp.Formats.Png
private IMemoryOwner<byte> ReadChunkData(int length) private IMemoryOwner<byte> ReadChunkData(int length)
{ {
// We rent the buffer here to return it afterwards in Decode() // We rent the buffer here to return it afterwards in Decode()
IMemoryOwner<byte> buffer = this.Configuration.MemoryAllocator.Allocate<byte>(length, AllocationOptions.Clean); IMemoryOwner<byte> buffer = this.configuration.MemoryAllocator.Allocate<byte>(length, AllocationOptions.Clean);
this.currentStream.Read(buffer.GetSpan(), 0, length); this.currentStream.Read(buffer.GetSpan(), 0, length);

14
src/ImageSharp/Formats/Png/PngDecoderOptions.cs

@ -0,0 +1,14 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp.Formats.Png
{
/// <summary>
/// Configuration options for decoding Png images.
/// </summary>
public class PngDecoderOptions : ISpecializedDecoderOptions
{
/// <inheritdoc/>
public DecoderOptions GeneralOptions { get; set; } = new();
}
}

12
src/ImageSharp/Formats/Tga/ITgaDecoderOptions.cs

@ -1,12 +0,0 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp.Formats.Tga
{
/// <summary>
/// The options for decoding tga images. Currently empty, but this may change in the future.
/// </summary>
internal interface ITgaDecoderOptions
{
}
}

23
src/ImageSharp/Formats/Tga/TgaDecoder.cs

@ -10,28 +10,29 @@ namespace SixLabors.ImageSharp.Formats.Tga
/// <summary> /// <summary>
/// Image decoder for Truevision TGA images. /// Image decoder for Truevision TGA images.
/// </summary> /// </summary>
public sealed class TgaDecoder : IImageDecoder, ITgaDecoderOptions, IImageInfoDetector public sealed class TgaDecoder : ImageDecoder<TgaDecoderOptions>
{ {
/// <inheritdoc/> /// <inheritdoc/>
public Image<TPixel> Decode<TPixel>(Configuration configuration, Stream stream, CancellationToken cancellationToken) public override Image<TPixel> DecodeSpecialized<TPixel>(TgaDecoderOptions options, Stream stream, CancellationToken cancellationToken)
where TPixel : unmanaged, IPixel<TPixel>
{ {
Guard.NotNull(stream, nameof(stream)); TgaDecoderCore decoder = new(options);
Image<TPixel> image = decoder.Decode<TgaDecoderOptions, TPixel>(options.GeneralOptions.Configuration, stream, cancellationToken);
Resize(options.GeneralOptions, image);
var decoder = new TgaDecoderCore(configuration, this); return image;
return decoder.Decode<TPixel>(configuration, stream, cancellationToken);
} }
/// <inheritdoc /> /// <inheritdoc/>
public Image Decode(Configuration configuration, Stream stream, CancellationToken cancellationToken) public override Image DecodeSpecialized(TgaDecoderOptions options, Stream stream, CancellationToken cancellationToken)
=> this.Decode<Rgba32>(configuration, stream, cancellationToken); => this.DecodeSpecialized<Rgba32>(options, stream, cancellationToken);
/// <inheritdoc/> /// <inheritdoc/>
public IImageInfo Identify(Configuration configuration, Stream stream, CancellationToken cancellationToken) public override IImageInfo IdentifySpecialized(TgaDecoderOptions options, Stream stream, CancellationToken cancellationToken)
{ {
Guard.NotNull(stream, nameof(stream)); Guard.NotNull(stream, nameof(stream));
return new TgaDecoderCore(configuration, this).Identify(configuration, stream, cancellationToken); return new TgaDecoderCore(options).Identify(options.GeneralOptions.Configuration, stream, cancellationToken);
} }
} }
} }

43
src/ImageSharp/Formats/Tga/TgaDecoderCore.cs

@ -15,13 +15,18 @@ namespace SixLabors.ImageSharp.Formats.Tga
/// <summary> /// <summary>
/// Performs the tga decoding operation. /// Performs the tga decoding operation.
/// </summary> /// </summary>
internal sealed class TgaDecoderCore : IImageDecoderInternals internal sealed class TgaDecoderCore : IImageDecoderInternals<TgaDecoderOptions>
{ {
/// <summary> /// <summary>
/// A scratch buffer to reduce allocations. /// A scratch buffer to reduce allocations.
/// </summary> /// </summary>
private readonly byte[] scratchBuffer = new byte[4]; private readonly byte[] scratchBuffer = new byte[4];
/// <summary>
/// General configuration options.
/// </summary>
private readonly Configuration configuration;
/// <summary> /// <summary>
/// The metadata. /// The metadata.
/// </summary> /// </summary>
@ -47,11 +52,6 @@ namespace SixLabors.ImageSharp.Formats.Tga
/// </summary> /// </summary>
private BufferedReadStream currentStream; private BufferedReadStream currentStream;
/// <summary>
/// The bitmap decoder options.
/// </summary>
private readonly ITgaDecoderOptions options;
/// <summary> /// <summary>
/// Indicates whether there is a alpha channel present. /// Indicates whether there is a alpha channel present.
/// </summary> /// </summary>
@ -60,22 +60,19 @@ namespace SixLabors.ImageSharp.Formats.Tga
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="TgaDecoderCore"/> class. /// Initializes a new instance of the <see cref="TgaDecoderCore"/> class.
/// </summary> /// </summary>
/// <param name="configuration">The configuration.</param>
/// <param name="options">The options.</param> /// <param name="options">The options.</param>
public TgaDecoderCore(Configuration configuration, ITgaDecoderOptions options) public TgaDecoderCore(TgaDecoderOptions options)
{ {
this.Configuration = configuration; this.Options = options;
this.memoryAllocator = configuration.MemoryAllocator; this.configuration = options.GeneralOptions.Configuration;
this.options = options; this.memoryAllocator = this.configuration.MemoryAllocator;
} }
/// <inheritdoc /> /// <inheritdoc />
public Configuration Configuration { get; } public TgaDecoderOptions Options { get; }
/// <summary> /// <inheritdoc />
/// Gets the dimensions of the image. public Size Dimensions => new(this.fileHeader.Width, this.fileHeader.Height);
/// </summary>
public Size Dimensions => new Size(this.fileHeader.Width, this.fileHeader.Height);
/// <inheritdoc /> /// <inheritdoc />
public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken cancellationToken) public Image<TPixel> Decode<TPixel>(BufferedReadStream stream, CancellationToken cancellationToken)
@ -87,7 +84,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
this.currentStream.Skip(this.fileHeader.IdLength); this.currentStream.Skip(this.fileHeader.IdLength);
// Parse the color map, if present. // Parse the color map, if present.
if (this.fileHeader.ColorMapType != 0 && this.fileHeader.ColorMapType != 1) if (this.fileHeader.ColorMapType is not 0 and not 1)
{ {
TgaThrowHelper.ThrowNotSupportedException($"Unknown tga colormap type {this.fileHeader.ColorMapType} found"); TgaThrowHelper.ThrowNotSupportedException($"Unknown tga colormap type {this.fileHeader.ColorMapType} found");
} }
@ -97,7 +94,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
throw new UnknownImageFormatException("Width or height cannot be 0"); throw new UnknownImageFormatException("Width or height cannot be 0");
} }
var image = Image.CreateUninitialized<TPixel>(this.Configuration, this.fileHeader.Width, this.fileHeader.Height, this.metadata); var image = Image.CreateUninitialized<TPixel>(this.configuration, this.fileHeader.Width, this.fileHeader.Height, this.metadata);
Buffer2D<TPixel> pixels = image.GetRootFramePixelBuffer(); Buffer2D<TPixel> pixels = image.GetRootFramePixelBuffer();
if (this.fileHeader.ColorMapType == 1) if (this.fileHeader.ColorMapType == 1)
@ -451,11 +448,11 @@ namespace SixLabors.ImageSharp.Formats.Tga
if (this.fileHeader.ImageType == TgaImageType.BlackAndWhite) if (this.fileHeader.ImageType == TgaImageType.BlackAndWhite)
{ {
PixelOperations<TPixel>.Instance.FromLa16Bytes(this.Configuration, rowSpan, pixelSpan, width); PixelOperations<TPixel>.Instance.FromLa16Bytes(this.configuration, rowSpan, pixelSpan, width);
} }
else else
{ {
PixelOperations<TPixel>.Instance.FromBgra5551Bytes(this.Configuration, rowSpan, pixelSpan, width); PixelOperations<TPixel>.Instance.FromBgra5551Bytes(this.configuration, rowSpan, pixelSpan, width);
} }
} }
} }
@ -655,7 +652,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
{ {
this.currentStream.Read(row); this.currentStream.Read(row);
Span<TPixel> pixelSpan = pixels.DangerousGetRowSpan(y); Span<TPixel> pixelSpan = pixels.DangerousGetRowSpan(y);
PixelOperations<TPixel>.Instance.FromL8Bytes(this.Configuration, row, pixelSpan, width); PixelOperations<TPixel>.Instance.FromL8Bytes(this.configuration, row, pixelSpan, width);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -682,7 +679,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
{ {
this.currentStream.Read(row); this.currentStream.Read(row);
Span<TPixel> pixelSpan = pixels.DangerousGetRowSpan(y); Span<TPixel> pixelSpan = pixels.DangerousGetRowSpan(y);
PixelOperations<TPixel>.Instance.FromBgr24Bytes(this.Configuration, row, pixelSpan, width); PixelOperations<TPixel>.Instance.FromBgr24Bytes(this.configuration, row, pixelSpan, width);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@ -701,7 +698,7 @@ namespace SixLabors.ImageSharp.Formats.Tga
{ {
this.currentStream.Read(row); this.currentStream.Read(row);
Span<TPixel> pixelSpan = pixels.DangerousGetRowSpan(y); Span<TPixel> pixelSpan = pixels.DangerousGetRowSpan(y);
PixelOperations<TPixel>.Instance.FromBgra32Bytes(this.Configuration, row, pixelSpan, width); PixelOperations<TPixel>.Instance.FromBgra32Bytes(this.configuration, row, pixelSpan, width);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]

14
src/ImageSharp/Formats/Tga/TgaDecoderOptions.cs

@ -0,0 +1,14 @@
// Copyright (c) Six Labors.
// Licensed under the Apache License, Version 2.0.
namespace SixLabors.ImageSharp.Formats.Tga
{
/// <summary>
/// Configuration options for decoding Png images.
/// </summary>
public class TgaDecoderOptions : ISpecializedDecoderOptions
{
/// <inheritdoc/>
public DecoderOptions GeneralOptions { get; set; } = new();
}
}
Loading…
Cancel
Save