Browse Source

Use memory allocator for all text chunks

pull/1918/head
Ynse Hoornenborg 4 years ago
parent
commit
4904f325fa
  1. 69
      src/ImageSharp/Formats/Png/PngEncoderCore.cs

69
src/ImageSharp/Formats/Png/PngEncoderCore.cs

@ -739,21 +739,33 @@ namespace SixLabors.ImageSharp.Formats.Png
byte[] translatedKeyword = PngConstants.TranslatedEncoding.GetBytes(textData.TranslatedKeyword);
byte[] languageTag = PngConstants.LanguageEncoding.GetBytes(textData.LanguageTag);
Span<byte> outputBytes = new byte[keywordBytes.Length + textBytes.Length +
translatedKeyword.Length + languageTag.Length + 5];
keywordBytes.CopyTo(outputBytes);
if (textData.Value.Length > this.options.TextCompressionThreshold)
int payloadLength = keywordBytes.Length + textBytes.Length + translatedKeyword.Length + languageTag.Length + 5;
using (IMemoryOwner<byte> owner = this.memoryAllocator.Allocate<byte>(payloadLength))
{
// Indicate that the text is compressed.
outputBytes[keywordBytes.Length + 1] = 1;
}
Span<byte> outputBytes = owner.GetSpan();
keywordBytes.CopyTo(outputBytes);
int bytesWritten = keywordBytes.Length;
outputBytes[bytesWritten++] = 0;
if (textData.Value.Length > this.options.TextCompressionThreshold)
{
// Indicate that the text is compressed.
outputBytes[bytesWritten++] = 1;
}
else
{
outputBytes[bytesWritten++] = 0;
}
int keywordStart = keywordBytes.Length + 3;
languageTag.CopyTo(outputBytes.Slice(keywordStart));
int translatedKeywordStart = keywordStart + languageTag.Length + 1;
translatedKeyword.CopyTo(outputBytes.Slice(translatedKeywordStart));
textBytes.CopyTo(outputBytes.Slice(translatedKeywordStart + translatedKeyword.Length + 1));
this.WriteChunk(stream, PngChunkType.InternationalText, outputBytes.ToArray());
outputBytes[bytesWritten++] = 0;
languageTag.CopyTo(outputBytes.Slice(bytesWritten));
bytesWritten += languageTag.Length;
outputBytes[bytesWritten++] = 0;
translatedKeyword.CopyTo(outputBytes.Slice(bytesWritten));
bytesWritten += translatedKeyword.Length;
outputBytes[bytesWritten++] = 0;
textBytes.CopyTo(outputBytes.Slice(bytesWritten));
this.WriteChunk(stream, PngChunkType.InternationalText, outputBytes);
}
}
else
{
@ -762,19 +774,32 @@ namespace SixLabors.ImageSharp.Formats.Png
// Write zTXt chunk.
byte[] compressedData =
this.GetCompressedTextBytes(PngConstants.Encoding.GetBytes(textData.Value));
Span<byte> outputBytes = new byte[textData.Keyword.Length + compressedData.Length + 2];
PngConstants.Encoding.GetBytes(textData.Keyword).CopyTo(outputBytes);
compressedData.CopyTo(outputBytes.Slice(textData.Keyword.Length + 2));
this.WriteChunk(stream, PngChunkType.CompressedText, outputBytes.ToArray());
int payloadLength = textData.Keyword.Length + compressedData.Length + 2;
using (IMemoryOwner<byte> owner = this.memoryAllocator.Allocate<byte>(payloadLength))
{
Span<byte> outputBytes = owner.GetSpan();
PngConstants.Encoding.GetBytes(textData.Keyword).CopyTo(outputBytes);
int bytesWritten = textData.Keyword.Length;
outputBytes[bytesWritten++] = 0;
outputBytes[bytesWritten++] = 0;
compressedData.CopyTo(outputBytes.Slice(bytesWritten));
this.WriteChunk(stream, PngChunkType.CompressedText, outputBytes.ToArray());
}
}
else
{
// Write tEXt chunk.
Span<byte> outputBytes = new byte[textData.Keyword.Length + textData.Value.Length + 1];
PngConstants.Encoding.GetBytes(textData.Keyword).CopyTo(outputBytes);
PngConstants.Encoding.GetBytes(textData.Value)
.CopyTo(outputBytes.Slice(textData.Keyword.Length + 1));
this.WriteChunk(stream, PngChunkType.Text, outputBytes.ToArray());
int payloadLength = textData.Keyword.Length + textData.Value.Length + 1;
using (IMemoryOwner<byte> owner = this.memoryAllocator.Allocate<byte>(payloadLength))
{
Span<byte> outputBytes = owner.GetSpan();
PngConstants.Encoding.GetBytes(textData.Keyword).CopyTo(outputBytes);
int bytesWritten = textData.Keyword.Length;
outputBytes[bytesWritten++] = 0;
PngConstants.Encoding.GetBytes(textData.Value)
.CopyTo(outputBytes.Slice(bytesWritten));
this.WriteChunk(stream, PngChunkType.Text, outputBytes.ToArray());
}
}
}
}

Loading…
Cancel
Save