|
3 | 3 | #nullable disable
|
4 | 4 |
|
5 | 5 | using System.Buffers.Binary;
|
| 6 | +using System.Collections; |
6 | 7 | using System.Text;
|
7 | 8 | using SixLabors.ImageSharp.Common.Helpers;
|
8 | 9 | using SixLabors.ImageSharp.Formats.Jpeg.Components;
|
@@ -184,39 +185,55 @@ private void WriteComment(JpegMetadata metadata)
|
184 | 185 | return;
|
185 | 186 | }
|
186 | 187 |
|
187 |
| - for (int i = 0; i < metadata.Comments.Count; i++) |
| 188 | + // We don't want to modify original metadata |
| 189 | + List<JpegComData> comments = new(metadata.Comments); |
| 190 | + |
| 191 | + int totalPayloadLength = 0; |
| 192 | + for (int i = 0; i < comments.Count; i++) |
188 | 193 | {
|
189 |
| - string comment = metadata.Comments[i].ToString(); |
| 194 | + JpegComData comment = comments[i]; |
| 195 | + ReadOnlyMemory<char> currentComment = comment.Value; |
190 | 196 |
|
191 |
| - if (comment.Length > maxCommentLength) |
| 197 | + if (comment.Value.Length > maxCommentLength) |
192 | 198 | {
|
193 |
| - string splitComment = comment.Substring(maxCommentLength, comment.Length - maxCommentLength); |
194 |
| - metadata.Comments.Insert(i + 1, JpegComData.FromString(splitComment)); |
| 199 | + ReadOnlyMemory<char> splitComment = |
| 200 | + currentComment.Slice(maxCommentLength, currentComment.Length - maxCommentLength); |
| 201 | + comments.Insert(i + 1, new JpegComData(splitComment)); |
195 | 202 |
|
196 | 203 | // We don't want to keep the extra bytes
|
197 |
| - comment = comment.Substring(0, maxCommentLength); |
| 204 | + comments[i] = new JpegComData(currentComment.Slice(0, maxCommentLength)); |
198 | 205 | }
|
199 | 206 |
|
200 |
| - int commentLength = comment.Length + 4; |
| 207 | + totalPayloadLength += comment.Value.Length + 4; |
| 208 | + } |
| 209 | + |
| 210 | + Span<byte> payload = new byte[totalPayloadLength]; |
| 211 | + int currentCommentStartingIndex = 0; |
201 | 212 |
|
202 |
| - Span<byte> commentSpan = new byte[commentLength]; |
203 |
| - Span<byte> markers = commentSpan.Slice(0, 2); |
204 |
| - Span<byte> payloadSize = commentSpan.Slice(2, 2); |
205 |
| - Span<byte> payload = commentSpan.Slice(4, comment.Length); |
| 213 | + for (int i = 0; i < comments.Count; i++) |
| 214 | + { |
| 215 | + ReadOnlyMemory<char> comment = comments[i].Value; |
206 | 216 |
|
207 | 217 | // Beginning of comment ff fe
|
208 |
| - markers[0] = JpegConstants.Markers.XFF; |
209 |
| - markers[1] = JpegConstants.Markers.COM; |
| 218 | + payload[currentCommentStartingIndex] = JpegConstants.Markers.XFF; |
| 219 | + payload[currentCommentStartingIndex + 1] = JpegConstants.Markers.COM; |
210 | 220 |
|
211 | 221 | // Write payload size
|
212 |
| - int comWithoutMarker = commentLength - 2; |
213 |
| - payloadSize[0] = (byte)((comWithoutMarker >> 8) & 0xFF); |
214 |
| - payloadSize[1] = (byte)(comWithoutMarker & 0xFF); |
| 222 | + int comWithoutMarker = comment.Length + 2; |
| 223 | + payload[currentCommentStartingIndex + 2] = (byte)((comWithoutMarker >> 8) & 0xFF); |
| 224 | + payload[currentCommentStartingIndex + 3] = (byte)(comWithoutMarker & 0xFF); |
215 | 225 |
|
216 |
| - Encoding.ASCII.GetBytes(comment, payload); |
| 226 | + char[] commentChars = comment.ToArray(); |
| 227 | + for (int j = 0; j < commentChars.Length; j++) |
| 228 | + { |
| 229 | + // Initial 4 bytes are always reserved |
| 230 | + payload[4 + currentCommentStartingIndex + j] = (byte)commentChars[j]; |
| 231 | + } |
217 | 232 |
|
218 |
| - this.outputStream.Write(commentSpan, 0, commentSpan.Length); |
| 233 | + currentCommentStartingIndex += comment.Length + 4; |
219 | 234 | }
|
| 235 | + |
| 236 | + this.outputStream.Write(payload, 0, payload.Length); |
220 | 237 | }
|
221 | 238 |
|
222 | 239 | /// <summary>
|
|
0 commit comments