|
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