From 5d502980c27fa8cabbe3ee1d706d729aefbdcc8f Mon Sep 17 00:00:00 2001 From: Ildar Khayrutdinov Date: Tue, 1 Feb 2022 15:08:29 +0300 Subject: [PATCH] memory improvements --- .../Profiles/Exif/ExifEncodedStringHelpers.cs | 22 +++++++++++++------ .../Profiles/Exif/ExifUcs2StringHelpers.cs | 2 ++ .../Metadata/Profiles/Exif/ExifWriter.cs | 19 ++++------------ 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs b/src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs index 71aeb9db3..5fd613b1f 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifEncodedStringHelpers.cs @@ -69,17 +69,25 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif public static uint GetDataLength(EncodedString encodedString) => (uint)GetEncoding(encodedString.Code).GetByteCount(encodedString.Text) + CharacterCodeBytesLength; - public static byte[] GetData(EncodedString encodedString) + public static int Write(EncodedString encodedString, Span destination) { - int length = (int)GetDataLength(encodedString); - byte[] buffer = new byte[length]; - - GetCodeBytes(encodedString.Code).CopyTo(buffer); + GetCodeBytes(encodedString.Code).CopyTo(destination); string text = encodedString.Text; - GetEncoding(encodedString.Code).GetBytes(text, 0, text.Length, buffer, CharacterCodeBytesLength); + int count = Write(GetEncoding(encodedString.Code), text, destination.Slice(CharacterCodeBytesLength)); + + return CharacterCodeBytesLength + count; + } - return buffer; + public static unsafe int Write(Encoding encoding, string value, Span destination) + { + fixed (char* c = value) + { + fixed (byte* b = destination) + { + return encoding.GetBytes(c, value.Length, b, destination.Length); + } + } } private static bool TryDetect(ReadOnlySpan buffer, out CharacterCode code) diff --git a/src/ImageSharp/Metadata/Profiles/Exif/ExifUcs2StringHelpers.cs b/src/ImageSharp/Metadata/Profiles/Exif/ExifUcs2StringHelpers.cs index 82ea0eaba..ccc1c80ad 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/ExifUcs2StringHelpers.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifUcs2StringHelpers.cs @@ -15,5 +15,7 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif ExifTagValue.XPAuthor or ExifTagValue.XPComment or ExifTagValue.XPKeywords or ExifTagValue.XPSubject or ExifTagValue.XPTitle => true, _ => false, }; + + public static int Write(string value, Span destination) => ExifEncodedStringHelpers.Write(Ucs2Encoding, value, destination); } } diff --git a/src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs b/src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs index 7baff7513..a14539bca 100644 --- a/src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs +++ b/src/ImageSharp/Metadata/Profiles/Exif/ExifWriter.cs @@ -4,7 +4,6 @@ using System; using System.Buffers.Binary; using System.Collections.Generic; -using System.Text; namespace SixLabors.ImageSharp.Metadata.Profiles.Exif { @@ -388,18 +387,8 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif return offset + 1; case ExifDataType.Byte: case ExifDataType.Undefined: - if (value is byte[] array) - { - // used by encoded strings (which dataType is Byte/Undefined) - offset = Write(array, destination, offset); - return offset; - } - else - { - destination[offset] = (byte)value; - return offset + 1; - } - + destination[offset] = (byte)value; + return offset + 1; case ExifDataType.DoubleFloat: return WriteDouble((double)value, destination, offset); case ExifDataType.Short: @@ -446,11 +435,11 @@ namespace SixLabors.ImageSharp.Metadata.Profiles.Exif if (ExifUcs2StringHelpers.IsUcs2Tag((ExifTagValue)(ushort)exifValue.Tag)) { - value = ExifUcs2StringHelpers.Ucs2Encoding.GetBytes((string)value); + return offset + ExifUcs2StringHelpers.Write((string)value, destination.Slice(offset)); } else if (value is EncodedString encodedString) { - value = ExifEncodedStringHelpers.GetData(encodedString); + return offset + ExifEncodedStringHelpers.Write(encodedString, destination.Slice(offset)); } if (exifValue.IsArray)