mirror of https://github.com/SixLabors/ImageSharp
5 changed files with 147 additions and 52 deletions
@ -0,0 +1,35 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Six Labors Split License.
|
||||
|
|
||||
|
using System.Runtime.InteropServices; |
||||
|
using SixLabors.ImageSharp.Memory; |
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors; |
||||
|
|
||||
|
internal static class JpegCompressionUtils |
||||
|
{ |
||||
|
public static void CopyImageBytesToBuffer(Span<byte> buffer, Buffer2D<Rgb24> pixelBuffer) |
||||
|
{ |
||||
|
int offset = 0; |
||||
|
for (int y = 0; y < pixelBuffer.Height; y++) |
||||
|
{ |
||||
|
Span<Rgb24> pixelRowSpan = pixelBuffer.DangerousGetRowSpan(y); |
||||
|
Span<byte> rgbBytes = MemoryMarshal.AsBytes(pixelRowSpan); |
||||
|
rgbBytes.CopyTo(buffer[offset..]); |
||||
|
offset += rgbBytes.Length; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static void CopyImageBytesToBuffer(Span<byte> buffer, Buffer2D<L8> pixelBuffer) |
||||
|
{ |
||||
|
int offset = 0; |
||||
|
for (int y = 0; y < pixelBuffer.Height; y++) |
||||
|
{ |
||||
|
Span<L8> pixelRowSpan = pixelBuffer.DangerousGetRowSpan(y); |
||||
|
Span<byte> rgbBytes = MemoryMarshal.AsBytes(pixelRowSpan); |
||||
|
rgbBytes.CopyTo(buffer[offset..]); |
||||
|
offset += rgbBytes.Length; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,45 @@ |
|||||
|
// Copyright (c) Six Labors.
|
||||
|
// Licensed under the Six Labors Split License.
|
||||
|
|
||||
|
using SixLabors.ImageSharp.Formats.Jpeg.Components; |
||||
|
using SixLabors.ImageSharp.Formats.Jpeg.Components.Decoder; |
||||
|
using SixLabors.ImageSharp.Formats.Tiff.Constants; |
||||
|
using SixLabors.ImageSharp.PixelFormats; |
||||
|
|
||||
|
namespace SixLabors.ImageSharp.Formats.Tiff.Compression.Decompressors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Spectral converter for YCbCr TIFF's which use the OldJPEG compression.
|
||||
|
/// The jpeg data should be always treated as YCbCr color space.
|
||||
|
/// </summary>
|
||||
|
/// <typeparam name="TPixel">The type of the pixel.</typeparam>
|
||||
|
internal sealed class TiffOldJpegSpectralConverter<TPixel> : SpectralConverter<TPixel> |
||||
|
where TPixel : unmanaged, IPixel<TPixel> |
||||
|
{ |
||||
|
private readonly TiffPhotometricInterpretation photometricInterpretation; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="TiffOldJpegSpectralConverter{TPixel}"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="configuration">The configuration.</param>
|
||||
|
/// <param name="photometricInterpretation">Tiff photometric interpretation.</param>
|
||||
|
public TiffOldJpegSpectralConverter(Configuration configuration, TiffPhotometricInterpretation photometricInterpretation) |
||||
|
: base(configuration) |
||||
|
=> this.photometricInterpretation = photometricInterpretation; |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
protected override JpegColorConverterBase GetColorConverter(JpegFrame frame, IRawJpegData jpegData) |
||||
|
{ |
||||
|
JpegColorSpace colorSpace = GetJpegColorSpaceFromPhotometricInterpretation(this.photometricInterpretation); |
||||
|
return JpegColorConverterBase.GetConverter(colorSpace, frame.Precision); |
||||
|
} |
||||
|
|
||||
|
private static JpegColorSpace GetJpegColorSpaceFromPhotometricInterpretation(TiffPhotometricInterpretation interpretation) |
||||
|
=> interpretation switch |
||||
|
{ |
||||
|
// Like libtiff: Always treat the pixel data as YCbCr when the data is compressed with old jpeg compression.
|
||||
|
TiffPhotometricInterpretation.Rgb => JpegColorSpace.YCbCr, |
||||
|
TiffPhotometricInterpretation.YCbCr => JpegColorSpace.YCbCr, |
||||
|
_ => throw new InvalidImageContentException($"Invalid tiff photometric interpretation for jpeg encoding: {interpretation}"), |
||||
|
}; |
||||
|
} |
||||
Loading…
Reference in new issue