-
-
Notifications
You must be signed in to change notification settings - Fork 860
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1537 from IldarKhayrutdinov/tiff-format
#12 Support multi strip encoding. Improve performance and memory usage.
- Loading branch information
Showing
49 changed files
with
1,106 additions
and
1,127 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
src/ImageSharp/Formats/Tiff/Compression/Compressors/DeflateCompressor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Copyright (c) Six Labors. | ||
// Licensed under the Apache License, Version 2.0. | ||
|
||
using System; | ||
using System.IO; | ||
using SixLabors.ImageSharp.Compression.Zlib; | ||
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; | ||
using SixLabors.ImageSharp.Memory; | ||
|
||
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors | ||
{ | ||
internal class DeflateCompressor : TiffBaseCompressor | ||
{ | ||
private readonly DeflateCompressionLevel compressionLevel; | ||
|
||
private readonly MemoryStream memoryStream = new MemoryStream(); | ||
|
||
public DeflateCompressor(Stream output, MemoryAllocator allocator, int width, int bitsPerPixel, TiffPredictor predictor, DeflateCompressionLevel compressionLevel) | ||
: base(output, allocator, width, bitsPerPixel, predictor) | ||
=> this.compressionLevel = compressionLevel; | ||
|
||
/// <inheritdoc/> | ||
public override TiffEncoderCompression Method => TiffEncoderCompression.Deflate; | ||
|
||
/// <inheritdoc/> | ||
public override void Initialize(int rowsPerStrip) | ||
{ | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override void CompressStrip(Span<byte> rows, int height) | ||
{ | ||
this.memoryStream.Seek(0, SeekOrigin.Begin); | ||
using var stream = new ZlibDeflateStream(this.Allocator, this.memoryStream, this.compressionLevel); | ||
|
||
if (this.Predictor == TiffPredictor.Horizontal) | ||
{ | ||
HorizontalPredictor.ApplyHorizontalPrediction(rows, this.BytesPerRow, this.BitsPerPixel); | ||
} | ||
|
||
stream.Write(rows); | ||
|
||
stream.Flush(); | ||
stream.Dispose(); | ||
|
||
int size = (int)this.memoryStream.Position; | ||
|
||
#if !NETSTANDARD1_3 | ||
byte[] buffer = this.memoryStream.GetBuffer(); | ||
this.Output.Write(buffer, 0, size); | ||
#else | ||
this.memoryStream.SetLength(size); | ||
this.memoryStream.Position = 0; | ||
this.memoryStream.CopyTo(this.Output); | ||
#endif | ||
} | ||
|
||
/// <inheritdoc/> | ||
protected override void Dispose(bool disposing) | ||
{ | ||
} | ||
} | ||
} |
40 changes: 40 additions & 0 deletions
40
src/ImageSharp/Formats/Tiff/Compression/Compressors/LzwCompressor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// Copyright (c) Six Labors. | ||
// Licensed under the Apache License, Version 2.0. | ||
|
||
using System; | ||
using System.IO; | ||
using SixLabors.ImageSharp.Formats.Experimental.Tiff.Constants; | ||
using SixLabors.ImageSharp.Memory; | ||
|
||
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors | ||
{ | ||
internal class LzwCompressor : TiffBaseCompressor | ||
{ | ||
private TiffLzwEncoder lzwEncoder; | ||
|
||
public LzwCompressor(Stream output, MemoryAllocator allocator, int width, int bitsPerPixel, TiffPredictor predictor) | ||
: base(output, allocator, width, bitsPerPixel, predictor) | ||
{ | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override TiffEncoderCompression Method => TiffEncoderCompression.Lzw; | ||
|
||
/// <inheritdoc/> | ||
public override void Initialize(int rowsPerStrip) => this.lzwEncoder = new TiffLzwEncoder(this.Allocator); | ||
|
||
/// <inheritdoc/> | ||
public override void CompressStrip(Span<byte> rows, int height) | ||
{ | ||
if (this.Predictor == TiffPredictor.Horizontal) | ||
{ | ||
HorizontalPredictor.ApplyHorizontalPrediction(rows, this.BytesPerRow, this.BitsPerPixel); | ||
} | ||
|
||
this.lzwEncoder.Encode(rows, this.Output); | ||
} | ||
|
||
/// <inheritdoc/> | ||
protected override void Dispose(bool disposing) => this.lzwEncoder?.Dispose(); | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
src/ImageSharp/Formats/Tiff/Compression/Compressors/NoCompressor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// Copyright (c) Six Labors. | ||
// Licensed under the Apache License, Version 2.0. | ||
|
||
using System; | ||
using System.IO; | ||
|
||
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors | ||
{ | ||
internal class NoCompressor : TiffBaseCompressor | ||
{ | ||
public NoCompressor(Stream output) | ||
: base(output, default, default, default) | ||
{ | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override TiffEncoderCompression Method => TiffEncoderCompression.None; | ||
|
||
/// <inheritdoc/> | ||
public override void Initialize(int rowsPerStrip) | ||
{ | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override void CompressStrip(Span<byte> rows, int height) => this.Output.Write(rows); | ||
|
||
/// <inheritdoc/> | ||
protected override void Dispose(bool disposing) | ||
{ | ||
} | ||
} | ||
} |
47 changes: 47 additions & 0 deletions
47
src/ImageSharp/Formats/Tiff/Compression/Compressors/PackBitsCompressor.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// Copyright (c) Six Labors. | ||
// Licensed under the Apache License, Version 2.0. | ||
|
||
using System; | ||
using System.IO; | ||
using SixLabors.ImageSharp.Memory; | ||
|
||
namespace SixLabors.ImageSharp.Formats.Experimental.Tiff.Compression.Compressors | ||
{ | ||
internal class PackBitsCompressor : TiffBaseCompressor | ||
{ | ||
private IManagedByteBuffer pixelData; | ||
|
||
public PackBitsCompressor(Stream output, MemoryAllocator allocator, int width, int bitsPerPixel) | ||
: base(output, allocator, width, bitsPerPixel) | ||
{ | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override TiffEncoderCompression Method => TiffEncoderCompression.PackBits; | ||
|
||
/// <inheritdoc/> | ||
public override void Initialize(int rowsPerStrip) | ||
{ | ||
int additionalBytes = ((this.BytesPerRow + 126) / 127) + 1; | ||
this.pixelData = this.Allocator.AllocateManagedByteBuffer(this.BytesPerRow + additionalBytes); | ||
} | ||
|
||
/// <inheritdoc/> | ||
public override void CompressStrip(Span<byte> rows, int height) | ||
{ | ||
DebugGuard.IsTrue(rows.Length % height == 0, "Invalid height"); | ||
DebugGuard.IsTrue(this.BytesPerRow == rows.Length / height, "The widths must match"); | ||
|
||
Span<byte> span = this.pixelData.GetSpan(); | ||
for (int i = 0; i < height; i++) | ||
{ | ||
Span<byte> row = rows.Slice(i * this.BytesPerRow, this.BytesPerRow); | ||
int size = PackBitsWriter.PackBits(row, span); | ||
this.Output.Write(span.Slice(0, size)); | ||
} | ||
} | ||
|
||
/// <inheritdoc/> | ||
protected override void Dispose(bool disposing) => this.pixelData?.Dispose(); | ||
} | ||
} |
Oops, something went wrong.