Skip to content

Commit 4aed9f4

Browse files
authored
Merge pull request #1443 from SixLabors/bp/bmpEnsureSpanLengthIsEqual
Ensure Span length of source and destination are equal during pixel conversion
2 parents 976bdd5 + 7c77e7e commit 4aed9f4

14 files changed

+62
-217
lines changed

src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs

+11-6
Original file line numberDiff line numberDiff line change
@@ -262,16 +262,18 @@ private void Write32Bit<TPixel>(Stream stream, Buffer2D<TPixel> pixels)
262262
private void Write24Bit<TPixel>(Stream stream, Buffer2D<TPixel> pixels)
263263
where TPixel : unmanaged, IPixel<TPixel>
264264
{
265-
using (IManagedByteBuffer row = this.AllocateRow(pixels.Width, 3))
265+
int width = pixels.Width;
266+
int rowBytesWithoutPadding = width * 3;
267+
using (IManagedByteBuffer row = this.AllocateRow(width, 3))
266268
{
267269
for (int y = pixels.Height - 1; y >= 0; y--)
268270
{
269271
Span<TPixel> pixelSpan = pixels.GetRowSpan(y);
270272
PixelOperations<TPixel>.Instance.ToBgr24Bytes(
271273
this.configuration,
272274
pixelSpan,
273-
row.GetSpan(),
274-
pixelSpan.Length);
275+
row.Slice(0, rowBytesWithoutPadding),
276+
width);
275277
stream.Write(row.Array, 0, row.Length());
276278
}
277279
}
@@ -286,7 +288,9 @@ private void Write24Bit<TPixel>(Stream stream, Buffer2D<TPixel> pixels)
286288
private void Write16Bit<TPixel>(Stream stream, Buffer2D<TPixel> pixels)
287289
where TPixel : unmanaged, IPixel<TPixel>
288290
{
289-
using (IManagedByteBuffer row = this.AllocateRow(pixels.Width, 2))
291+
int width = pixels.Width;
292+
int rowBytesWithoutPadding = width * 2;
293+
using (IManagedByteBuffer row = this.AllocateRow(width, 2))
290294
{
291295
for (int y = pixels.Height - 1; y >= 0; y--)
292296
{
@@ -295,7 +299,7 @@ private void Write16Bit<TPixel>(Stream stream, Buffer2D<TPixel> pixels)
295299
PixelOperations<TPixel>.Instance.ToBgra5551Bytes(
296300
this.configuration,
297301
pixelSpan,
298-
row.GetSpan(),
302+
row.Slice(0, rowBytesWithoutPadding),
299303
pixelSpan.Length);
300304

301305
stream.Write(row.Array, 0, row.Length());
@@ -341,7 +345,8 @@ private void Write8BitColor<TPixel>(Stream stream, ImageFrame<TPixel> image, Spa
341345
using IndexedImageFrame<TPixel> quantized = frameQuantizer.BuildPaletteAndQuantizeFrame(image, image.Bounds());
342346

343347
ReadOnlySpan<TPixel> quantizedColors = quantized.Palette.Span;
344-
PixelOperations<TPixel>.Instance.ToBgra32(this.configuration, quantizedColors, MemoryMarshal.Cast<byte, Bgra32>(colorPalette));
348+
var quantizedColorBytes = quantizedColors.Length * 4;
349+
PixelOperations<TPixel>.Instance.ToBgra32(this.configuration, quantizedColors, MemoryMarshal.Cast<byte, Bgra32>(colorPalette.Slice(0, quantizedColorBytes)));
345350
Span<uint> colorPaletteAsUInt = MemoryMarshal.Cast<byte, uint>(colorPalette);
346351
for (int i = 0; i < colorPaletteAsUInt.Length; i++)
347352
{

src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Generated/Argb32.PixelOperations.Generated.cs

+4-18
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,13 @@ public partial struct Argb32
2121
/// </summary>
2222
internal partial class PixelOperations : PixelOperations<Argb32>
2323
{
24-
25-
/// <inheritdoc />
24+
/// <inheritdoc />
2625
public override void FromArgb32(Configuration configuration, ReadOnlySpan<Argb32> source, Span<Argb32> destinationPixels)
2726
{
2827
Guard.NotNull(configuration, nameof(configuration));
2928
Guard.DestinationShouldNotBeTooShort(source, destinationPixels, nameof(destinationPixels));
3029

31-
source.CopyTo(destinationPixels);
30+
source.CopyTo(destinationPixels.Slice(0, source.Length));
3231
}
3332

3433
/// <inheritdoc />
@@ -37,9 +36,8 @@ public override void ToArgb32(Configuration configuration, ReadOnlySpan<Argb32>
3736
Guard.NotNull(configuration, nameof(configuration));
3837
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels));
3938

40-
sourcePixels.CopyTo(destinationPixels);
39+
sourcePixels.CopyTo(destinationPixels.Slice(0, sourcePixels.Length));
4140
}
42-
4341
/// <inheritdoc />
4442
public override void FromVector4Destructive(
4543
Configuration configuration,
@@ -59,7 +57,6 @@ public override void ToVector4(
5957
{
6058
Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, modifiers.Remove(PixelConversionModifiers.Scale));
6159
}
62-
6360
/// <inheritdoc />
6461
public override void ToRgba32(
6562
Configuration configuration,
@@ -87,7 +84,6 @@ public override void FromRgba32(
8784
Span<byte> dest = MemoryMarshal.Cast<Argb32, byte>(destinationPixels);
8885
PixelConverter.FromRgba32.ToArgb32(source, dest);
8986
}
90-
9187
/// <inheritdoc />
9288
public override void ToBgra32(
9389
Configuration configuration,
@@ -115,7 +111,6 @@ public override void FromBgra32(
115111
Span<byte> dest = MemoryMarshal.Cast<Argb32, byte>(destinationPixels);
116112
PixelConverter.FromBgra32.ToArgb32(source, dest);
117113
}
118-
119114
/// <inheritdoc />
120115
public override void ToRgb24(
121116
Configuration configuration,
@@ -143,7 +138,6 @@ public override void FromRgb24(
143138
Span<byte> dest = MemoryMarshal.Cast<Argb32, byte>(destinationPixels);
144139
PixelConverter.FromRgb24.ToArgb32(source, dest);
145140
}
146-
147141
/// <inheritdoc />
148142
public override void ToBgr24(
149143
Configuration configuration,
@@ -171,7 +165,6 @@ public override void FromBgr24(
171165
Span<byte> dest = MemoryMarshal.Cast<Argb32, byte>(destinationPixels);
172166
PixelConverter.FromBgr24.ToArgb32(source, dest);
173167
}
174-
175168
/// <inheritdoc />
176169
public override void ToL8(
177170
Configuration configuration,
@@ -192,7 +185,6 @@ public override void ToL8(
192185
dp.FromArgb32(sp);
193186
}
194187
}
195-
196188
/// <inheritdoc />
197189
public override void ToL16(
198190
Configuration configuration,
@@ -213,7 +205,6 @@ public override void ToL16(
213205
dp.FromArgb32(sp);
214206
}
215207
}
216-
217208
/// <inheritdoc />
218209
public override void ToLa16(
219210
Configuration configuration,
@@ -234,7 +225,6 @@ public override void ToLa16(
234225
dp.FromArgb32(sp);
235226
}
236227
}
237-
238228
/// <inheritdoc />
239229
public override void ToLa32(
240230
Configuration configuration,
@@ -255,7 +245,6 @@ public override void ToLa32(
255245
dp.FromArgb32(sp);
256246
}
257247
}
258-
259248
/// <inheritdoc />
260249
public override void ToRgb48(
261250
Configuration configuration,
@@ -276,7 +265,6 @@ public override void ToRgb48(
276265
dp.FromArgb32(sp);
277266
}
278267
}
279-
280268
/// <inheritdoc />
281269
public override void ToRgba64(
282270
Configuration configuration,
@@ -297,7 +285,6 @@ public override void ToRgba64(
297285
dp.FromArgb32(sp);
298286
}
299287
}
300-
301288
/// <inheritdoc />
302289
public override void ToBgra5551(
303290
Configuration configuration,
@@ -318,14 +305,13 @@ public override void ToBgra5551(
318305
dp.FromArgb32(sp);
319306
}
320307
}
321-
322308
/// <inheritdoc />
323309
public override void From<TSourcePixel>(
324310
Configuration configuration,
325311
ReadOnlySpan<TSourcePixel> sourcePixels,
326312
Span<Argb32> destinationPixels)
327313
{
328-
PixelOperations<TSourcePixel>.Instance.ToArgb32(configuration, sourcePixels, destinationPixels);
314+
PixelOperations<TSourcePixel>.Instance.ToArgb32(configuration, sourcePixels, destinationPixels.Slice(0, sourcePixels.Length));
329315
}
330316

331317
}

src/ImageSharp/PixelFormats/PixelImplementations/PixelOperations/Generated/Bgr24.PixelOperations.Generated.cs

+4-18
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,13 @@ public partial struct Bgr24
2121
/// </summary>
2222
internal partial class PixelOperations : PixelOperations<Bgr24>
2323
{
24-
25-
/// <inheritdoc />
24+
/// <inheritdoc />
2625
public override void FromBgr24(Configuration configuration, ReadOnlySpan<Bgr24> source, Span<Bgr24> destinationPixels)
2726
{
2827
Guard.NotNull(configuration, nameof(configuration));
2928
Guard.DestinationShouldNotBeTooShort(source, destinationPixels, nameof(destinationPixels));
3029

31-
source.CopyTo(destinationPixels);
30+
source.CopyTo(destinationPixels.Slice(0, source.Length));
3231
}
3332

3433
/// <inheritdoc />
@@ -37,9 +36,8 @@ public override void ToBgr24(Configuration configuration, ReadOnlySpan<Bgr24> so
3736
Guard.NotNull(configuration, nameof(configuration));
3837
Guard.DestinationShouldNotBeTooShort(sourcePixels, destinationPixels, nameof(destinationPixels));
3938

40-
sourcePixels.CopyTo(destinationPixels);
39+
sourcePixels.CopyTo(destinationPixels.Slice(0, sourcePixels.Length));
4140
}
42-
4341
/// <inheritdoc />
4442
public override void FromVector4Destructive(
4543
Configuration configuration,
@@ -59,7 +57,6 @@ public override void ToVector4(
5957
{
6058
Vector4Converters.RgbaCompatible.ToVector4(configuration, this, sourcePixels, destVectors, modifiers.Remove(PixelConversionModifiers.Scale | PixelConversionModifiers.Premultiply));
6159
}
62-
6360
/// <inheritdoc />
6461
public override void ToRgba32(
6562
Configuration configuration,
@@ -87,7 +84,6 @@ public override void FromRgba32(
8784
Span<byte> dest = MemoryMarshal.Cast<Bgr24, byte>(destinationPixels);
8885
PixelConverter.FromRgba32.ToBgr24(source, dest);
8986
}
90-
9187
/// <inheritdoc />
9288
public override void ToArgb32(
9389
Configuration configuration,
@@ -115,7 +111,6 @@ public override void FromArgb32(
115111
Span<byte> dest = MemoryMarshal.Cast<Bgr24, byte>(destinationPixels);
116112
PixelConverter.FromArgb32.ToBgr24(source, dest);
117113
}
118-
119114
/// <inheritdoc />
120115
public override void ToBgra32(
121116
Configuration configuration,
@@ -143,7 +138,6 @@ public override void FromBgra32(
143138
Span<byte> dest = MemoryMarshal.Cast<Bgr24, byte>(destinationPixels);
144139
PixelConverter.FromBgra32.ToBgr24(source, dest);
145140
}
146-
147141
/// <inheritdoc />
148142
public override void ToRgb24(
149143
Configuration configuration,
@@ -171,7 +165,6 @@ public override void FromRgb24(
171165
Span<byte> dest = MemoryMarshal.Cast<Bgr24, byte>(destinationPixels);
172166
PixelConverter.FromRgb24.ToBgr24(source, dest);
173167
}
174-
175168
/// <inheritdoc />
176169
public override void ToL8(
177170
Configuration configuration,
@@ -192,7 +185,6 @@ public override void ToL8(
192185
dp.FromBgr24(sp);
193186
}
194187
}
195-
196188
/// <inheritdoc />
197189
public override void ToL16(
198190
Configuration configuration,
@@ -213,7 +205,6 @@ public override void ToL16(
213205
dp.FromBgr24(sp);
214206
}
215207
}
216-
217208
/// <inheritdoc />
218209
public override void ToLa16(
219210
Configuration configuration,
@@ -234,7 +225,6 @@ public override void ToLa16(
234225
dp.FromBgr24(sp);
235226
}
236227
}
237-
238228
/// <inheritdoc />
239229
public override void ToLa32(
240230
Configuration configuration,
@@ -255,7 +245,6 @@ public override void ToLa32(
255245
dp.FromBgr24(sp);
256246
}
257247
}
258-
259248
/// <inheritdoc />
260249
public override void ToRgb48(
261250
Configuration configuration,
@@ -276,7 +265,6 @@ public override void ToRgb48(
276265
dp.FromBgr24(sp);
277266
}
278267
}
279-
280268
/// <inheritdoc />
281269
public override void ToRgba64(
282270
Configuration configuration,
@@ -297,7 +285,6 @@ public override void ToRgba64(
297285
dp.FromBgr24(sp);
298286
}
299287
}
300-
301288
/// <inheritdoc />
302289
public override void ToBgra5551(
303290
Configuration configuration,
@@ -318,14 +305,13 @@ public override void ToBgra5551(
318305
dp.FromBgr24(sp);
319306
}
320307
}
321-
322308
/// <inheritdoc />
323309
public override void From<TSourcePixel>(
324310
Configuration configuration,
325311
ReadOnlySpan<TSourcePixel> sourcePixels,
326312
Span<Bgr24> destinationPixels)
327313
{
328-
PixelOperations<TSourcePixel>.Instance.ToBgr24(configuration, sourcePixels, destinationPixels);
314+
PixelOperations<TSourcePixel>.Instance.ToBgr24(configuration, sourcePixels, destinationPixels.Slice(0, sourcePixels.Length));
329315
}
330316

331317
}

0 commit comments

Comments
 (0)