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