diff --git a/src/ImageSharp/Common/Extensions/ByteExtensions.cs b/src/ImageSharp/Common/Extensions/ByteExtensions.cs
index a6dc19ded..f1161eb6f 100644
--- a/src/ImageSharp/Common/Extensions/ByteExtensions.cs
+++ b/src/ImageSharp/Common/Extensions/ByteExtensions.cs
@@ -5,10 +5,13 @@
namespace ImageSharp
{
+ using System;
using System.Runtime.CompilerServices;
+ using ImageSharp.PixelFormats;
+
///
- /// Extension methods for the struct.
+ /// Extension methods for the struct buffers.
///
internal static class ByteExtensions
{
@@ -44,5 +47,45 @@ namespace ImageSharp
j--;
}
}
+
+ ///
+ /// Returns a reference to the given position of the array unsafe casted to .
+ ///
+ /// The byte array.
+ /// The offset in bytes.
+ /// The reference at the given offset.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ref Rgb24 GetRgb24(this byte[] bytes, int offset)
+ {
+ DebugGuard.MustBeLessThan(offset + 2, bytes.Length, nameof(offset));
+
+ return ref Unsafe.As(ref bytes[offset]);
+ }
+
+ ///
+ /// Returns a reference to the given position of the span unsafe casted to .
+ ///
+ /// The byte span.
+ /// The offset in bytes.
+ /// The reference at the given offset.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ref Rgb24 GetRgb24(this Span bytes, int offset)
+ {
+ DebugGuard.MustBeLessThan(offset + 2, bytes.Length, nameof(offset));
+
+ return ref Unsafe.As(ref bytes[offset]);
+ }
+
+ ///
+ /// Returns a reference to the given position of the buffer pointed by `baseRef` unsafe casted to .
+ ///
+ /// A reference to the beginning of the buffer
+ /// The offset in bytes.
+ /// The reference at the given offset.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static ref Rgb24 GetRgb24(ref byte baseRef, int offset)
+ {
+ return ref Unsafe.As(ref Unsafe.Add(ref baseRef, offset));
+ }
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Common/Helpers/Guard.cs b/src/ImageSharp/Common/Helpers/Guard.cs
index a4b392fcf..8e55c18af 100644
--- a/src/ImageSharp/Common/Helpers/Guard.cs
+++ b/src/ImageSharp/Common/Helpers/Guard.cs
@@ -242,7 +242,6 @@ namespace ImageSharp
/// is true
///
public static void MustBeSizedAtLeast(Span target, int minLength, string parameterName)
- where T : struct
{
if (target.Length < minLength)
{
diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
index dd91aa11d..997a77d6c 100644
--- a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
@@ -6,7 +6,8 @@ namespace ImageSharp.Formats
{
using System;
using System.IO;
-
+ using System.Runtime.CompilerServices;
+ using ImageSharp.Memory;
using ImageSharp.PixelFormats;
///
@@ -243,13 +244,16 @@ namespace ImageSharp.Formats
byte[] row = new byte[arrayWidth + padding];
TPixel color = default(TPixel);
+ Rgba32 rgba = default(Rgba32);
+
for (int y = 0; y < height; y++)
{
int newY = Invert(y, height, inverted);
-
this.currentStream.Read(row, 0, row.Length);
-
int offset = 0;
+ Span pixelRow = pixels.GetRowSpan(y);
+
+ // TODO: Could use PixelOperations here!
for (int x = 0; x < arrayWidth; x++)
{
int colOffset = x * ppb;
@@ -260,8 +264,9 @@ namespace ImageSharp.Formats
int newX = colOffset + shift;
// Stored in b-> g-> r order.
- color.PackFromBytes(colors[colorIndex + 2], colors[colorIndex + 1], colors[colorIndex], 255);
- pixels[newX, newY] = color;
+ rgba.Bgr = Unsafe.As(ref colors[colorIndex]);
+ color.PackFromRgba32(rgba);
+ pixelRow[newX] = color;
}
offset++;
@@ -286,6 +291,8 @@ namespace ImageSharp.Formats
const int ComponentCount = 2;
TPixel color = default(TPixel);
+ Rgba32 rgba = new Rgba32(0, 0, 0, 255);
+
using (PixelArea row = new PixelArea(width, ComponentOrder.Xyz))
{
for (int y = 0; y < height; y++)
@@ -294,17 +301,19 @@ namespace ImageSharp.Formats
int newY = Invert(y, height, inverted);
+ Span pixelRow = pixels.GetRowSpan(newY);
+
int offset = 0;
for (int x = 0; x < width; x++)
{
short temp = BitConverter.ToInt16(row.Bytes, offset);
- byte r = (byte)(((temp & Rgb16RMask) >> 11) * ScaleR);
- byte g = (byte)(((temp & Rgb16GMask) >> 5) * ScaleG);
- byte b = (byte)((temp & Rgb16BMask) * ScaleR);
+ rgba.R = (byte)(((temp & Rgb16RMask) >> 11) * ScaleR);
+ rgba.G = (byte)(((temp & Rgb16GMask) >> 5) * ScaleG);
+ rgba.B = (byte)((temp & Rgb16BMask) * ScaleR);
- color.PackFromBytes(r, g, b, 255);
- pixels[x, newY] = color;
+ color.PackFromRgba32(rgba);
+ pixelRow[x] = color;
offset += ComponentCount;
}
}
diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
index 618d268f7..5b56c4c02 100644
--- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
+++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
@@ -435,6 +435,8 @@ namespace ImageSharp.Formats
Span rowSpan = image.GetRowSpan(writeY);
+ Rgba32 rgba = new Rgba32(0, 0, 0, 255);
+
for (int x = descriptor.Left; x < descriptor.Left + descriptor.Width; x++)
{
int index = indices[i];
@@ -446,7 +448,9 @@ namespace ImageSharp.Formats
int indexOffset = index * 3;
ref TPixel pixel = ref rowSpan[x];
- pixel.PackFromBytes(colorTable[indexOffset], colorTable[indexOffset + 1], colorTable[indexOffset + 2], 255);
+ rgba.Rgb = colorTable.GetRgb24(indexOffset);
+
+ pixel.PackFromRgba32(rgba);
}
i++;
diff --git a/src/ImageSharp/Formats/Jpeg/Components/Decoder/YCbCrToRgbTables.cs b/src/ImageSharp/Formats/Jpeg/Components/Decoder/YCbCrToRgbTables.cs
index 27324b5f6..5c9e8f9fc 100644
--- a/src/ImageSharp/Formats/Jpeg/Components/Decoder/YCbCrToRgbTables.cs
+++ b/src/ImageSharp/Formats/Jpeg/Components/Decoder/YCbCrToRgbTables.cs
@@ -91,7 +91,7 @@ namespace ImageSharp.Formats.Jpg
// float b = MathF.Round(y + (1.772F * cb), MidpointRounding.AwayFromZero);
byte b = (byte)(y + tables->CbBTable[cb]).Clamp(0, 255);
- packed.PackFromBytes(r, g, b, byte.MaxValue);
+ packed.PackFromRgba32(new Rgba32(r, g, b, 255));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
diff --git a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
index d65c095da..971684371 100644
--- a/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
@@ -613,25 +613,23 @@ namespace ImageSharp.Formats
private void ConvertFromGrayScale(Image image)
where TPixel : struct, IPixel
{
- using (PixelAccessor pixels = image.Lock())
- {
- Parallel.For(
- 0,
- image.Height,
- image.Configuration.ParallelOptions,
- y =>
+ Parallel.For(
+ 0,
+ image.Height,
+ image.Configuration.ParallelOptions,
+ y =>
{
+ ref TPixel pixelRowBaseRef = ref image.GetPixelReference(0, y);
+
int yoff = this.grayImage.GetRowOffset(y);
+
for (int x = 0; x < image.Width; x++)
{
byte rgb = this.grayImage.Pixels[yoff + x];
-
- TPixel packed = default(TPixel);
- packed.PackFromBytes(rgb, rgb, rgb, 255);
- pixels[x, y] = packed;
+ ref TPixel pixel = ref Unsafe.Add(ref pixelRowBaseRef, x);
+ pixel.PackFromRgba32(new Rgba32(rgb, rgb, rgb, 255));
}
});
- }
this.AssignResolution(image);
}
@@ -646,30 +644,29 @@ namespace ImageSharp.Formats
{
int scale = this.ComponentArray[0].HorizontalFactor / this.ComponentArray[1].HorizontalFactor;
- using (PixelAccessor pixels = image.Lock())
- {
- Parallel.For(
- 0,
- image.Height,
- image.Configuration.ParallelOptions,
- y =>
+ Parallel.For(
+ 0,
+ image.Height,
+ image.Configuration.ParallelOptions,
+ y =>
{
// TODO: Simplify + optimize + share duplicate code across converter methods
int yo = this.ycbcrImage.GetRowYOffset(y);
int co = this.ycbcrImage.GetRowCOffset(y);
+ ref TPixel pixelRowBaseRef = ref image.GetPixelReference(0, y);
+
+ Rgba32 rgba = new Rgba32(0, 0, 0, 255);
for (int x = 0; x < image.Width; x++)
{
- byte red = this.ycbcrImage.YChannel[yo + x];
- byte green = this.ycbcrImage.CbChannel[co + (x / scale)];
- byte blue = this.ycbcrImage.CrChannel[co + (x / scale)];
+ rgba.R = this.ycbcrImage.YChannel[yo + x];
+ rgba.G = this.ycbcrImage.CbChannel[co + (x / scale)];
+ rgba.B = this.ycbcrImage.CrChannel[co + (x / scale)];
- TPixel packed = default(TPixel);
- packed.PackFromBytes(red, green, blue, 255);
- pixels[x, y] = packed;
+ ref TPixel pixel = ref Unsafe.Add(ref pixelRowBaseRef, x);
+ pixel.PackFromRgba32(rgba);
}
});
- }
this.AssignResolution(image);
}
@@ -729,16 +726,15 @@ namespace ImageSharp.Formats
{
int scale = this.ComponentArray[0].HorizontalFactor / this.ComponentArray[1].HorizontalFactor;
- using (PixelAccessor pixels = image.Lock())
- {
- Parallel.For(
- 0,
- image.Height,
- y =>
+ Parallel.For(
+ 0,
+ image.Height,
+ y =>
{
// TODO: Simplify + optimize + share duplicate code across converter methods
int yo = this.ycbcrImage.GetRowYOffset(y);
int co = this.ycbcrImage.GetRowCOffset(y);
+ ref TPixel pixelRowBaseRef = ref image.GetPixelReference(0, y);
for (int x = 0; x < image.Width; x++)
{
@@ -746,12 +742,10 @@ namespace ImageSharp.Formats
byte cb = this.ycbcrImage.CbChannel[co + (x / scale)];
byte cr = this.ycbcrImage.CrChannel[co + (x / scale)];
- TPixel packed = default(TPixel);
- this.PackYcck(ref packed, yy, cb, cr, x, y);
- pixels[x, y] = packed;
+ ref TPixel pixel = ref Unsafe.Add(ref pixelRowBaseRef, x);
+ this.PackYcck(ref pixel, yy, cb, cr, x, y);
}
});
- }
this.AssignResolution(image);
}
@@ -860,7 +854,7 @@ namespace ImageSharp.Formats
byte g = (byte)(((m / 255F) * (1F - keyline)).Clamp(0, 1) * 255);
byte b = (byte)(((y / 255F) * (1F - keyline)).Clamp(0, 1) * 255);
- packed.PackFromBytes(r, g, b, 255);
+ packed.PackFromRgba32(new Rgba32(r, g, b));
}
///
@@ -904,7 +898,7 @@ namespace ImageSharp.Formats
byte g = (byte)(((1 - magenta) * (1 - keyline)).Clamp(0, 1) * 255);
byte b = (byte)(((1 - yellow) * (1 - keyline)).Clamp(0, 1) * 255);
- packed.PackFromBytes(r, g, b, 255);
+ packed.PackFromRgba32(new Rgba32(r, g, b));
}
///
diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
index b18845aaa..e0bd153e6 100644
--- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
@@ -574,7 +574,7 @@ namespace ImageSharp.Formats
for (int x = 0; x < this.header.Width; x++)
{
byte intensity = (byte)(newScanline1[x] * factor);
- color.PackFromBytes(intensity, intensity, intensity, 255);
+ color.PackFromRgba32(new Rgba32(intensity, intensity, intensity));
rowSpan[x] = color;
}
@@ -589,7 +589,7 @@ namespace ImageSharp.Formats
byte intensity = defilteredScanline[offset];
byte alpha = defilteredScanline[offset + this.bytesPerSample];
- color.PackFromBytes(intensity, intensity, intensity, alpha);
+ color.PackFromRgba32(new Rgba32(intensity, intensity, intensity));
rowSpan[x] = color;
}
@@ -603,13 +603,13 @@ namespace ImageSharp.Formats
case PngColorType.Rgb:
- PixelOperations.Instance.PackFromXyzBytes(scanlineBuffer, rowSpan, this.header.Width);
+ PixelOperations.Instance.PackFromRgb24Bytes(scanlineBuffer, rowSpan, this.header.Width);
break;
case PngColorType.RgbWithAlpha:
- PixelOperations.Instance.PackFromXyzwBytes(scanlineBuffer, rowSpan, this.header.Width);
+ PixelOperations.Instance.PackFromRgba32Bytes(scanlineBuffer, rowSpan, this.header.Width);
break;
}
@@ -628,6 +628,8 @@ namespace ImageSharp.Formats
byte[] palette = this.palette;
var color = default(TPixel);
+ Rgba32 rgba = default(Rgba32);
+
if (this.paletteAlpha != null && this.paletteAlpha.Length > 0)
{
// If the alpha palette is not null and has one or more entries, this means, that the image contains an alpha
@@ -637,35 +639,33 @@ namespace ImageSharp.Formats
int index = newScanline[x + 1];
int pixelOffset = index * 3;
- byte a = this.paletteAlpha.Length > index ? this.paletteAlpha[index] : (byte)255;
+ rgba.A = this.paletteAlpha.Length > index ? this.paletteAlpha[index] : (byte)255;
- if (a > 0)
+ if (rgba.A > 0)
{
- byte r = palette[pixelOffset];
- byte g = palette[pixelOffset + 1];
- byte b = palette[pixelOffset + 2];
- color.PackFromBytes(r, g, b, a);
+ rgba.Rgb = palette.GetRgb24(pixelOffset);
}
else
{
- color.PackFromBytes(0, 0, 0, 0);
+ rgba = default(Rgba32);
}
+ color.PackFromRgba32(rgba);
row[x] = color;
}
}
else
{
+ rgba.A = 255;
+
for (int x = 0; x < this.header.Width; x++)
{
int index = newScanline[x + 1];
int pixelOffset = index * 3;
- byte r = palette[pixelOffset];
- byte g = palette[pixelOffset + 1];
- byte b = palette[pixelOffset + 2];
+ rgba.Rgb = palette.GetRgb24(pixelOffset);
- color.PackFromBytes(r, g, b, 255);
+ color.PackFromRgba32(rgba);
row[x] = color;
}
}
@@ -692,7 +692,7 @@ namespace ImageSharp.Formats
for (int x = pixelOffset, o = 1; x < this.header.Width; x += increment, o++)
{
byte intensity = (byte)(newScanline1[o] * factor);
- color.PackFromBytes(intensity, intensity, intensity, 255);
+ color.PackFromRgba32(new Rgba32(intensity, intensity, intensity));
rowSpan[x] = color;
}
@@ -704,8 +704,7 @@ namespace ImageSharp.Formats
{
byte intensity = defilteredScanline[o];
byte alpha = defilteredScanline[o + this.bytesPerSample];
-
- color.PackFromBytes(intensity, intensity, intensity, alpha);
+ color.PackFromRgba32(new Rgba32(intensity, intensity, intensity, alpha));
rowSpan[x] = color;
}
@@ -714,6 +713,7 @@ namespace ImageSharp.Formats
case PngColorType.Palette:
byte[] newScanline = ToArrayByBitsLength(defilteredScanline, this.bytesPerScanline, this.header.BitDepth);
+ Rgba32 rgba = default(Rgba32);
if (this.paletteAlpha != null && this.paletteAlpha.Length > 0)
{
@@ -724,35 +724,33 @@ namespace ImageSharp.Formats
int index = newScanline[o];
int offset = index * 3;
- byte a = this.paletteAlpha.Length > index ? this.paletteAlpha[index] : (byte)255;
+ rgba.A = this.paletteAlpha.Length > index ? this.paletteAlpha[index] : (byte)255;
- if (a > 0)
+ if (rgba.A > 0)
{
- byte r = this.palette[offset];
- byte g = this.palette[offset + 1];
- byte b = this.palette[offset + 2];
- color.PackFromBytes(r, g, b, a);
+ rgba.Rgb = this.palette.GetRgb24(offset);
}
else
{
- color.PackFromBytes(0, 0, 0, 0);
+ rgba = default(Rgba32);
}
+ color.PackFromRgba32(rgba);
rowSpan[x] = color;
}
}
else
{
+ rgba.A = 255;
+
for (int x = pixelOffset, o = 1; x < this.header.Width; x += increment, o++)
{
int index = newScanline[o];
int offset = index * 3;
- byte r = this.palette[offset];
- byte g = this.palette[offset + 1];
- byte b = this.palette[offset + 2];
+ rgba.Rgb = this.palette.GetRgb24(offset);
- color.PackFromBytes(r, g, b, 255);
+ color.PackFromRgba32(rgba);
rowSpan[x] = color;
}
}
@@ -761,13 +759,14 @@ namespace ImageSharp.Formats
case PngColorType.Rgb:
+ rgba.A = 255;
for (int x = pixelOffset, o = 1; x < this.header.Width; x += increment, o += this.bytesPerPixel)
{
- byte r = defilteredScanline[o];
- byte g = defilteredScanline[o + this.bytesPerSample];
- byte b = defilteredScanline[o + (2 * this.bytesPerSample)];
+ rgba.R = defilteredScanline[o];
+ rgba.G = defilteredScanline[o + this.bytesPerSample];
+ rgba.B = defilteredScanline[o + (2 * this.bytesPerSample)];
- color.PackFromBytes(r, g, b, 255);
+ color.PackFromRgba32(rgba);
rowSpan[x] = color;
}
@@ -777,12 +776,12 @@ namespace ImageSharp.Formats
for (int x = pixelOffset, o = 1; x < this.header.Width; x += increment, o += this.bytesPerPixel)
{
- byte r = defilteredScanline[o];
- byte g = defilteredScanline[o + this.bytesPerSample];
- byte b = defilteredScanline[o + (2 * this.bytesPerSample)];
- byte a = defilteredScanline[o + (3 * this.bytesPerSample)];
+ rgba.R = defilteredScanline[o];
+ rgba.G = defilteredScanline[o + this.bytesPerSample];
+ rgba.B = defilteredScanline[o + (2 * this.bytesPerSample)];
+ rgba.A = defilteredScanline[o + (3 * this.bytesPerSample)];
- color.PackFromBytes(r, g, b, a);
+ color.PackFromRgba32(rgba);
rowSpan[x] = color;
}
diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
index 3fcf1fc81..645df0548 100644
--- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
@@ -338,11 +338,11 @@ namespace ImageSharp.Formats
{
if (this.bytesPerPixel == 4)
{
- PixelOperations.Instance.ToXyzwBytes(rowSpan, this.rawScanline, this.width);
+ PixelOperations.Instance.ToRgba32Bytes(rowSpan, this.rawScanline, this.width);
}
else
{
- PixelOperations.Instance.ToXyzBytes(rowSpan, this.rawScanline, this.width);
+ PixelOperations.Instance.ToRgb24Bytes(rowSpan, this.rawScanline, this.width);
}
}
diff --git a/src/ImageSharp/Image/PixelAccessor{TPixel}.cs b/src/ImageSharp/Image/PixelAccessor{TPixel}.cs
index 4baae8615..3902ba425 100644
--- a/src/ImageSharp/Image/PixelAccessor{TPixel}.cs
+++ b/src/ImageSharp/Image/PixelAccessor{TPixel}.cs
@@ -275,7 +275,7 @@ namespace ImageSharp
Span source = area.GetRowSpan(y);
Span destination = this.GetRowSpan(targetX, targetY + y);
- Operations.PackFromZyxBytes(source, destination, width);
+ Operations.PackFromBgr24Bytes(source, destination, width);
}
}
@@ -295,7 +295,7 @@ namespace ImageSharp
Span source = area.GetRowSpan(y);
Span destination = this.GetRowSpan(targetX, targetY + y);
- Operations.PackFromZyxwBytes(source, destination, width);
+ Operations.PackFromBgra32Bytes(source, destination, width);
}
}
@@ -315,7 +315,7 @@ namespace ImageSharp
Span source = area.GetRowSpan(y);
Span destination = this.GetRowSpan(targetX, targetY + y);
- Operations.PackFromXyzBytes(source, destination, width);
+ Operations.PackFromRgb24Bytes(source, destination, width);
}
}
@@ -334,7 +334,7 @@ namespace ImageSharp
{
Span source = area.GetRowSpan(y);
Span destination = this.GetRowSpan(targetX, targetY + y);
- Operations.PackFromXyzwBytes(source, destination, width);
+ Operations.PackFromRgba32Bytes(source, destination, width);
}
}
@@ -353,7 +353,7 @@ namespace ImageSharp
{
Span source = this.GetRowSpan(sourceX, sourceY + y);
Span destination = area.GetRowSpan(y);
- Operations.ToZyxBytes(source, destination, width);
+ Operations.ToBgr24Bytes(source, destination, width);
}
}
@@ -372,7 +372,7 @@ namespace ImageSharp
{
Span source = this.GetRowSpan(sourceX, sourceY + y);
Span destination = area.GetRowSpan(y);
- Operations.ToZyxwBytes(source, destination, width);
+ Operations.ToBgra32Bytes(source, destination, width);
}
}
@@ -391,7 +391,7 @@ namespace ImageSharp
{
Span source = this.GetRowSpan(sourceX, sourceY + y);
Span destination = area.GetRowSpan(y);
- Operations.ToXyzBytes(source, destination, width);
+ Operations.ToRgb24Bytes(source, destination, width);
}
}
@@ -410,7 +410,7 @@ namespace ImageSharp
{
Span source = this.GetRowSpan(sourceX, sourceY + y);
Span destination = area.GetRowSpan(y);
- Operations.ToXyzwBytes(source, destination, width);
+ Operations.ToRgba32Bytes(source, destination, width);
}
}
diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj
index 6194be1bf..17f7bf58f 100644
--- a/src/ImageSharp/ImageSharp.csproj
+++ b/src/ImageSharp/ImageSharp.csproj
@@ -53,6 +53,35 @@
TextTemplatingFileGenerator
+ Block8x8F.Generated.cs
+
+ TextTemplatingFileGenerator
+ PixelOperations{TPixel}.Generated.cs
+
+
+ TextTemplatingFileGenerator
+ Rgba32.PixelOperations.Generated.cs
+
+
+
+
+
+
+
+ True
+ True
+ Block8x8F.Generated.tt
+
+
+ True
+ True
+ PixelOperations{TPixel}.Generated.tt
+
+
+ True
+ True
+ Rgba32.PixelOperations.Generated.tt
+
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/Alpha8.cs b/src/ImageSharp/PixelFormats/Alpha8.cs
index c184ed9cf..59934fdc6 100644
--- a/src/ImageSharp/PixelFormats/Alpha8.cs
+++ b/src/ImageSharp/PixelFormats/Alpha8.cs
@@ -62,7 +62,7 @@ namespace ImageSharp.PixelFormats
}
///
- public PixelOperations CreateBulkOperations() => new PixelOperations();
+ public PixelOperations CreatePixelOperations() => new PixelOperations();
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -80,47 +80,43 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void PackFromBytes(byte x, byte y, byte z, byte w)
+ public void PackFromRgba32(Rgba32 source)
{
- this.PackedValue = w;
+ this.PackedValue = source.A;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzBytes(Span bytes, int startIndex)
+ public void ToRgb24(ref Rgb24 dest)
{
- bytes[startIndex] = 0;
- bytes[startIndex + 1] = 0;
- bytes[startIndex + 2] = 0;
+ dest = default(Rgb24);
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzwBytes(Span bytes, int startIndex)
+ public void ToRgba32(ref Rgba32 dest)
{
- bytes[startIndex] = 0;
- bytes[startIndex + 1] = 0;
- bytes[startIndex + 2] = 0;
- bytes[startIndex + 3] = this.PackedValue;
+ dest.R = 0;
+ dest.G = 0;
+ dest.B = 0;
+ dest.A = this.PackedValue;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxBytes(Span bytes, int startIndex)
+ public void ToBgr24(ref Bgr24 dest)
{
- bytes[startIndex] = 0;
- bytes[startIndex + 1] = 0;
- bytes[startIndex + 2] = 0;
+ dest = default(Bgr24);
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxwBytes(Span bytes, int startIndex)
+ public void ToBgra32(ref Bgra32 dest)
{
- bytes[startIndex] = 0;
- bytes[startIndex + 1] = 0;
- bytes[startIndex + 2] = 0;
- bytes[startIndex + 3] = this.PackedValue;
+ dest.R = 0;
+ dest.G = 0;
+ dest.B = 0;
+ dest.A = this.PackedValue;
}
///
diff --git a/src/ImageSharp/PixelFormats/Argb32.cs b/src/ImageSharp/PixelFormats/Argb32.cs
index bd47f72f9..f389723dc 100644
--- a/src/ImageSharp/PixelFormats/Argb32.cs
+++ b/src/ImageSharp/PixelFormats/Argb32.cs
@@ -59,11 +59,24 @@ namespace ImageSharp.PixelFormats
/// The green component.
/// The blue component.
/// The alpha component.
- public Argb32(byte r, byte g, byte b, byte a = 255)
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Argb32(byte r, byte g, byte b, byte a)
{
this.PackedValue = Pack(r, g, b, a);
}
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The red component.
+ /// The green component.
+ /// The blue component.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Argb32(byte r, byte g, byte b)
+ {
+ this.PackedValue = Pack(r, g, b, 255);
+ }
+
///
/// Initializes a new instance of the struct.
///
@@ -224,7 +237,7 @@ namespace ImageSharp.PixelFormats
}
///
- public PixelOperations CreateBulkOperations() => new PixelOperations();
+ public PixelOperations CreatePixelOperations() => new PixelOperations();
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -235,47 +248,47 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void PackFromBytes(byte x, byte y, byte z, byte w)
+ public void PackFromRgba32(Rgba32 source)
{
- this.PackedValue = Pack(x, y, z, w);
+ this.PackedValue = Pack(source.R, source.G, source.B, source.A);
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzBytes(Span bytes, int startIndex)
+ public void ToRgb24(ref Rgb24 dest)
{
- bytes[startIndex] = this.R;
- bytes[startIndex + 1] = this.G;
- bytes[startIndex + 2] = this.B;
+ dest.R = this.R;
+ dest.G = this.G;
+ dest.B = this.B;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzwBytes(Span bytes, int startIndex)
+ public void ToRgba32(ref Rgba32 dest)
{
- bytes[startIndex] = this.R;
- bytes[startIndex + 1] = this.G;
- bytes[startIndex + 2] = this.B;
- bytes[startIndex + 3] = this.A;
+ dest.R = this.R;
+ dest.G = this.G;
+ dest.B = this.B;
+ dest.A = this.A;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxBytes(Span bytes, int startIndex)
+ public void ToBgr24(ref Bgr24 dest)
{
- bytes[startIndex] = this.B;
- bytes[startIndex + 1] = this.G;
- bytes[startIndex + 2] = this.R;
+ dest.R = this.R;
+ dest.G = this.G;
+ dest.B = this.B;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxwBytes(Span bytes, int startIndex)
+ public void ToBgra32(ref Bgra32 dest)
{
- bytes[startIndex] = this.B;
- bytes[startIndex + 1] = this.G;
- bytes[startIndex + 2] = this.R;
- bytes[startIndex + 3] = this.A;
+ dest.R = this.R;
+ dest.G = this.G;
+ dest.B = this.B;
+ dest.A = this.A;
}
///
diff --git a/src/ImageSharp/PixelFormats/Bgr24.cs b/src/ImageSharp/PixelFormats/Bgr24.cs
new file mode 100644
index 000000000..aaed5c385
--- /dev/null
+++ b/src/ImageSharp/PixelFormats/Bgr24.cs
@@ -0,0 +1,135 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.PixelFormats
+{
+ using System;
+ using System.Numerics;
+ using System.Runtime.CompilerServices;
+ using System.Runtime.InteropServices;
+
+ ///
+ /// Pixel type containing three 8-bit unsigned normalized values ranging from 0 to 255.
+ /// The color components are stored in blue, green, red order.
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Bgr24 : IPixel
+ {
+ ///
+ /// The blue component.
+ ///
+ public byte B;
+
+ ///
+ /// The green component.
+ ///
+ public byte G;
+
+ ///
+ /// The red component.
+ ///
+ public byte R;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The red component.
+ /// The green component.
+ /// The blue component.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Bgr24(byte r, byte g, byte b)
+ {
+ this.R = r;
+ this.G = g;
+ this.B = b;
+ }
+
+ ///
+ public PixelOperations CreatePixelOperations() => new PixelOperations();
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public bool Equals(Bgr24 other)
+ {
+ return this.R == other.R && this.G == other.G && this.B == other.B;
+ }
+
+ ///
+ public override bool Equals(object obj)
+ {
+ return obj?.GetType() == typeof(Bgr24) && this.Equals((Bgr24)obj);
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ int hashCode = this.B;
+ hashCode = (hashCode * 397) ^ this.G;
+ hashCode = (hashCode * 397) ^ this.R;
+ return hashCode;
+ }
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void PackFromRgba32(Rgba32 source)
+ {
+ this = source.Bgr;
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void PackFromVector4(Vector4 vector)
+ {
+ var rgba = default(Rgba32);
+ rgba.PackFromVector4(vector);
+ this.PackFromRgba32(rgba);
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Vector4 ToVector4()
+ {
+ return new Rgba32(this.R, this.G, this.B, 255).ToVector4();
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void ToRgb24(ref Rgb24 dest)
+ {
+ dest.R = this.R;
+ dest.G = this.G;
+ dest.B = this.B;
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void ToRgba32(ref Rgba32 dest)
+ {
+ dest.R = this.R;
+ dest.G = this.G;
+ dest.B = this.B;
+ dest.A = 255;
+ }
+
+ ///
+ public void ToBgr24(ref Bgr24 dest)
+ {
+ dest = this;
+ }
+
+ ///
+ public void ToBgra32(ref Bgra32 dest)
+ {
+ dest.R = this.R;
+ dest.G = this.G;
+ dest.B = this.B;
+ dest.A = 255;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/Bgr565.cs b/src/ImageSharp/PixelFormats/Bgr565.cs
index 92bbac14c..af22b14a0 100644
--- a/src/ImageSharp/PixelFormats/Bgr565.cs
+++ b/src/ImageSharp/PixelFormats/Bgr565.cs
@@ -71,7 +71,7 @@ namespace ImageSharp.PixelFormats
}
///
- public PixelOperations CreateBulkOperations() => new PixelOperations();
+ public PixelOperations CreatePixelOperations() => new PixelOperations();
///
/// Expands the packed representation into a .
@@ -103,51 +103,51 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void PackFromBytes(byte x, byte y, byte z, byte w)
+ public void PackFromRgba32(Rgba32 source)
{
- this.PackFromVector4(new Vector4(x, y, z, w) / 255F);
+ this.PackFromVector4(source.ToVector4());
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzBytes(Span bytes, int startIndex)
+ public void ToRgb24(ref Rgb24 dest)
{
Vector4 vector = this.ToVector4() * 255F;
- bytes[startIndex] = (byte)MathF.Round(vector.X);
- bytes[startIndex + 1] = (byte)MathF.Round(vector.Y);
- bytes[startIndex + 2] = (byte)MathF.Round(vector.Z);
+ dest.R = (byte)MathF.Round(vector.X);
+ dest.G = (byte)MathF.Round(vector.Y);
+ dest.B = (byte)MathF.Round(vector.Z);
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzwBytes(Span bytes, int startIndex)
+ public void ToRgba32(ref Rgba32 dest)
{
Vector4 vector = this.ToVector4() * 255F;
- bytes[startIndex] = (byte)MathF.Round(vector.X);
- bytes[startIndex + 1] = (byte)MathF.Round(vector.Y);
- bytes[startIndex + 2] = (byte)MathF.Round(vector.Z);
- bytes[startIndex + 3] = (byte)MathF.Round(vector.W);
+ dest.R = (byte)MathF.Round(vector.X);
+ dest.G = (byte)MathF.Round(vector.Y);
+ dest.B = (byte)MathF.Round(vector.Z);
+ dest.A = (byte)MathF.Round(vector.W);
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxBytes(Span bytes, int startIndex)
+ public void ToBgr24(ref Bgr24 dest)
{
Vector4 vector = this.ToVector4() * 255F;
- bytes[startIndex] = (byte)MathF.Round(vector.Z);
- bytes[startIndex + 1] = (byte)MathF.Round(vector.Y);
- bytes[startIndex + 2] = (byte)MathF.Round(vector.X);
+ dest.R = (byte)MathF.Round(vector.X);
+ dest.G = (byte)MathF.Round(vector.Y);
+ dest.B = (byte)MathF.Round(vector.Z);
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxwBytes(Span bytes, int startIndex)
+ public void ToBgra32(ref Bgra32 dest)
{
Vector4 vector = this.ToVector4() * 255F;
- bytes[startIndex] = (byte)MathF.Round(vector.Z);
- bytes[startIndex + 1] = (byte)MathF.Round(vector.Y);
- bytes[startIndex + 2] = (byte)MathF.Round(vector.X);
- bytes[startIndex + 3] = (byte)MathF.Round(vector.W);
+ dest.R = (byte)MathF.Round(vector.X);
+ dest.G = (byte)MathF.Round(vector.Y);
+ dest.B = (byte)MathF.Round(vector.Z);
+ dest.A = (byte)MathF.Round(vector.W);
}
///
diff --git a/src/ImageSharp/PixelFormats/Bgra32.cs b/src/ImageSharp/PixelFormats/Bgra32.cs
new file mode 100644
index 000000000..f1ac20b56
--- /dev/null
+++ b/src/ImageSharp/PixelFormats/Bgra32.cs
@@ -0,0 +1,187 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.PixelFormats
+{
+ using System;
+ using System.Numerics;
+ using System.Runtime.CompilerServices;
+ using System.Runtime.InteropServices;
+
+ ///
+ /// Packed pixel type containing four 8-bit unsigned normalized values ranging from 0 to 255.
+ /// The color components are stored in blue, green, red, and alpha order.
+ ///
+ [StructLayout(LayoutKind.Sequential)]
+ public struct Bgra32 : IPixel, IPackedVector
+ {
+ ///
+ /// Gets or sets the blue component.
+ ///
+ public byte B;
+
+ ///
+ /// Gets or sets the green component.
+ ///
+ public byte G;
+
+ ///
+ /// Gets or sets the red component.
+ ///
+ public byte R;
+
+ ///
+ /// Gets or sets the alpha component.
+ ///
+ public byte A;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The red component.
+ /// The green component.
+ /// The blue component.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Bgra32(byte r, byte g, byte b)
+ {
+ this.R = r;
+ this.G = g;
+ this.B = b;
+ this.A = 255;
+ }
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ /// The red component.
+ /// The green component.
+ /// The blue component.
+ /// The alpha component.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Bgra32(byte r, byte g, byte b, byte a)
+ {
+ this.R = r;
+ this.G = g;
+ this.B = b;
+ this.A = a;
+ }
+
+ ///
+ /// Gets or sets the packed representation of the Bgra32 struct.
+ ///
+ public uint Bgra
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get
+ {
+ return Unsafe.As(ref this);
+ }
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ set
+ {
+ Unsafe.As(ref this) = value;
+ }
+ }
+
+ ///
+ public uint PackedValue
+ {
+ get => this.Bgra;
+ set => this.Bgra = value;
+ }
+
+ ///
+ public PixelOperations CreatePixelOperations() => new PixelOperations();
+
+ ///
+ public bool Equals(Bgra32 other)
+ {
+ return this.R == other.R && this.G == other.G && this.B == other.B && this.A == other.A;
+ }
+
+ ///
+ public override bool Equals(object obj) => obj?.GetType() == typeof(Bgra32) && this.Equals((Bgra32)obj);
+
+ ///
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ int hashCode = this.B;
+ hashCode = (hashCode * 397) ^ this.G;
+ hashCode = (hashCode * 397) ^ this.R;
+ hashCode = (hashCode * 397) ^ this.A;
+ return hashCode;
+ }
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void PackFromVector4(Vector4 vector)
+ {
+ var rgba = default(Rgba32);
+ rgba.PackFromVector4(vector);
+ this.PackFromRgba32(rgba);
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Vector4 ToVector4()
+ {
+ return this.ToRgba32().ToVector4();
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void PackFromRgba32(Rgba32 source)
+ {
+ this.R = source.R;
+ this.G = source.G;
+ this.B = source.B;
+ this.A = source.A;
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void ToRgb24(ref Rgb24 dest)
+ {
+ dest.R = this.R;
+ dest.G = this.G;
+ dest.B = this.B;
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void ToRgba32(ref Rgba32 dest)
+ {
+ dest.R = this.R;
+ dest.G = this.G;
+ dest.B = this.B;
+ dest.A = this.A;
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void ToBgr24(ref Bgr24 dest)
+ {
+ dest = Unsafe.As(ref this);
+ }
+
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public void ToBgra32(ref Bgra32 dest)
+ {
+ dest = this;
+ }
+
+ ///
+ /// Converts the pixel to format.
+ ///
+ /// The RGBA value
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, this.A);
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/Bgra4444.cs b/src/ImageSharp/PixelFormats/Bgra4444.cs
index 0bac00dfe..746e1062b 100644
--- a/src/ImageSharp/PixelFormats/Bgra4444.cs
+++ b/src/ImageSharp/PixelFormats/Bgra4444.cs
@@ -70,7 +70,7 @@ namespace ImageSharp.PixelFormats
}
///
- public PixelOperations CreateBulkOperations() => new PixelOperations();
+ public PixelOperations CreatePixelOperations() => new PixelOperations();
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -79,10 +79,10 @@ namespace ImageSharp.PixelFormats
const float Max = 1 / 15F;
return new Vector4(
- ((this.PackedValue >> 8) & 0x0F) * Max,
- ((this.PackedValue >> 4) & 0x0F) * Max,
- (this.PackedValue & 0x0F) * Max,
- ((this.PackedValue >> 12) & 0x0F) * Max);
+ ((this.PackedValue >> 8) & 0x0F) * Max,
+ ((this.PackedValue >> 4) & 0x0F) * Max,
+ (this.PackedValue & 0x0F) * Max,
+ ((this.PackedValue >> 12) & 0x0F) * Max);
}
///
@@ -94,51 +94,51 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void PackFromBytes(byte x, byte y, byte z, byte w)
+ public void PackFromRgba32(Rgba32 source)
{
- this.PackFromVector4(new Vector4(x, y, z, w) / 255F);
+ this.PackFromVector4(source.ToVector4());
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzBytes(Span bytes, int startIndex)
+ public void ToRgb24(ref Rgb24 dest)
{
Vector4 vector = this.ToVector4() * 255F;
- bytes[startIndex] = (byte)vector.X;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.Z;
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzwBytes(Span bytes, int startIndex)
+ public void ToRgba32(ref Rgba32 dest)
{
Vector4 vector = this.ToVector4() * 255F;
- bytes[startIndex] = (byte)vector.X;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.Z;
- bytes[startIndex + 3] = (byte)vector.W;
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
+ dest.A = (byte)vector.W;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxBytes(Span bytes, int startIndex)
+ public void ToBgr24(ref Bgr24 dest)
{
Vector4 vector = this.ToVector4() * 255F;
- bytes[startIndex] = (byte)vector.Z;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.X;
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxwBytes(Span bytes, int startIndex)
+ public void ToBgra32(ref Bgra32 dest)
{
Vector4 vector = this.ToVector4() * 255F;
- bytes[startIndex] = (byte)vector.Z;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.X;
- bytes[startIndex + 3] = (byte)vector.W;
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
+ dest.A = (byte)vector.W;
}
///
@@ -179,9 +179,9 @@ namespace ImageSharp.PixelFormats
private static ushort Pack(float x, float y, float z, float w)
{
return (ushort)((((int)Math.Round(w.Clamp(0, 1) * 15F) & 0x0F) << 12) |
- (((int)Math.Round(x.Clamp(0, 1) * 15F) & 0x0F) << 8) |
- (((int)Math.Round(y.Clamp(0, 1) * 15F) & 0x0F) << 4) |
- ((int)Math.Round(z.Clamp(0, 1) * 15F) & 0x0F));
+ (((int)Math.Round(x.Clamp(0, 1) * 15F) & 0x0F) << 8) |
+ (((int)Math.Round(y.Clamp(0, 1) * 15F) & 0x0F) << 4) |
+ ((int)Math.Round(z.Clamp(0, 1) * 15F) & 0x0F));
}
}
}
diff --git a/src/ImageSharp/PixelFormats/Bgra5551.cs b/src/ImageSharp/PixelFormats/Bgra5551.cs
index f151db644..198f91108 100644
--- a/src/ImageSharp/PixelFormats/Bgra5551.cs
+++ b/src/ImageSharp/PixelFormats/Bgra5551.cs
@@ -72,7 +72,7 @@ namespace ImageSharp.PixelFormats
}
///
- public PixelOperations CreateBulkOperations() => new PixelOperations();
+ public PixelOperations CreatePixelOperations() => new PixelOperations();
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -94,51 +94,51 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void PackFromBytes(byte x, byte y, byte z, byte w)
+ public void PackFromRgba32(Rgba32 source)
{
- this.PackFromVector4(new Vector4(x, y, z, w) / 255F);
+ this.PackFromVector4(source.ToVector4());
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzBytes(Span bytes, int startIndex)
+ public void ToRgb24(ref Rgb24 dest)
{
- Vector4 vector = this.ToVector4() * 255F;
- bytes[startIndex] = (byte)vector.X;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.Z;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzwBytes(Span bytes, int startIndex)
+ public void ToRgba32(ref Rgba32 dest)
{
- Vector4 vector = this.ToVector4() * 255F;
- bytes[startIndex] = (byte)vector.X;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.Z;
- bytes[startIndex + 3] = (byte)vector.W;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
+ dest.A = (byte)vector.W;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxBytes(Span bytes, int startIndex)
+ public void ToBgr24(ref Bgr24 dest)
{
- Vector4 vector = this.ToVector4() * 255F;
- bytes[startIndex] = (byte)vector.Z;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.X;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxwBytes(Span bytes, int startIndex)
+ public void ToBgra32(ref Bgra32 dest)
{
- Vector4 vector = this.ToVector4() * 255F;
- bytes[startIndex] = (byte)vector.Z;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.X;
- bytes[startIndex + 3] = (byte)vector.W;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
+ dest.A = (byte)vector.W;
}
///
@@ -190,5 +190,8 @@ namespace ImageSharp.PixelFormats
(((int)Math.Round(z.Clamp(0, 1) * 31F) & 0x1F) << 0) |
(((int)Math.Round(w.Clamp(0, 1)) & 0x1) << 15));
}
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private Vector4 ToScaledVector4() => this.ToVector4() * 255f;
}
}
diff --git a/src/ImageSharp/PixelFormats/Byte4.cs b/src/ImageSharp/PixelFormats/Byte4.cs
index 264bc7497..14053ba12 100644
--- a/src/ImageSharp/PixelFormats/Byte4.cs
+++ b/src/ImageSharp/PixelFormats/Byte4.cs
@@ -73,7 +73,7 @@ namespace ImageSharp.PixelFormats
}
///
- public PixelOperations CreateBulkOperations() => new PixelOperations();
+ public PixelOperations CreatePixelOperations() => new PixelOperations();
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -95,51 +95,51 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void PackFromBytes(byte x, byte y, byte z, byte w)
+ public void PackFromRgba32(Rgba32 source)
{
- this.PackFromVector4(new Vector4(x, y, z, w));
+ this.PackFromVector4(source.ToUnscaledVector4());
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzBytes(Span bytes, int startIndex)
+ public void ToRgb24(ref Rgb24 dest)
{
Vector4 vector = this.ToVector4();
- bytes[startIndex] = (byte)vector.X;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.Z;
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzwBytes(Span bytes, int startIndex)
+ public void ToRgba32(ref Rgba32 dest)
{
Vector4 vector = this.ToVector4();
- bytes[startIndex] = (byte)vector.X;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.Z;
- bytes[startIndex + 3] = (byte)vector.W;
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
+ dest.A = (byte)vector.W;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxBytes(Span bytes, int startIndex)
+ public void ToBgr24(ref Bgr24 dest)
{
Vector4 vector = this.ToVector4();
- bytes[startIndex] = (byte)vector.Z;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.X;
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxwBytes(Span bytes, int startIndex)
+ public void ToBgra32(ref Bgra32 dest)
{
Vector4 vector = this.ToVector4();
- bytes[startIndex] = (byte)vector.Z;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.X;
- bytes[startIndex + 3] = (byte)vector.W;
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
+ dest.A = (byte)vector.W;
}
///
diff --git a/src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs b/src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs
index 4b21130c0..92fb006ab 100644
--- a/src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs
+++ b/src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs
@@ -35,12 +35,13 @@ namespace ImageSharp.PixelFormats
}
TPixel result = default(TPixel);
-
- result.PackFromBytes(
+ Rgba32 rgba = new Rgba32(
(byte)(packedValue >> 24),
(byte)(packedValue >> 16),
(byte)(packedValue >> 8),
(byte)(packedValue >> 0));
+
+ result.PackFromRgba32(rgba);
return result;
}
@@ -51,12 +52,7 @@ namespace ImageSharp.PixelFormats
/// The green intensity.
/// The blue intensity.
/// Returns a that represents the color defined by the provided RGB values with 100% opacity.
- public static TPixel FromRGB(byte red, byte green, byte blue)
- {
- TPixel color = default(TPixel);
- color.PackFromBytes(red, green, blue, 255);
- return color;
- }
+ public static TPixel FromRGB(byte red, byte green, byte blue) => FromRGBA(red, green, blue, 255);
///
/// Creates a new representation from standard RGBA bytes.
@@ -69,7 +65,7 @@ namespace ImageSharp.PixelFormats
public static TPixel FromRGBA(byte red, byte green, byte blue, byte alpha)
{
TPixel color = default(TPixel);
- color.PackFromBytes(red, green, blue, alpha);
+ color.PackFromRgba32(new Rgba32(red, green, blue, alpha));
return color;
}
diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs
new file mode 100644
index 000000000..c042d7678
--- /dev/null
+++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.cs
@@ -0,0 +1,302 @@
+//
+
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.PixelFormats
+{
+ using System;
+ using System.Numerics;
+ using System.Runtime.CompilerServices;
+
+ public partial class PixelOperations
+ {
+
+ ///
+ /// Converts 'count' elements in 'source` span of data to a span of -s.
+ ///
+ /// The source of data.
+ /// The to the destination pixels.
+ /// The number of pixels to convert.
+ internal virtual void PackFromRgba32(Span source, Span destPixels, int count)
+ {
+ GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count);
+
+ ref Rgba32 sourceRef = ref source.DangerousGetPinnableReference();
+ ref TPixel destRef = ref destPixels.DangerousGetPinnableReference();
+
+ Rgba32 rgba = new Rgba32(0, 0, 0, 255);
+
+ for (int i = 0; i < count; i++)
+ {
+ ref TPixel dp = ref Unsafe.Add(ref destRef, i);
+ rgba = Unsafe.Add(ref sourceRef, i);
+ dp.PackFromRgba32(rgba);
+ }
+ }
+
+ ///
+ /// A helper for that expects a byte span.
+ /// The layout of the data in 'sourceBytes' must be compatible with layout.
+ ///
+ /// The to the source bytes.
+ /// The to the destination pixels.
+ /// The number of pixels to convert.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal void PackFromRgba32Bytes(Span sourceBytes, Span destPixels, int count)
+ {
+ this.PackFromRgba32(sourceBytes.NonPortableCast(), destPixels, count);
+ }
+
+ ///
+ /// Converts 'count' pixels in 'sourcePixels` span to a span of -s.
+ /// Bulk version of .
+ ///
+ /// The span of source pixels
+ /// The destination span of data.
+ /// The number of pixels to convert.
+ internal virtual void ToRgba32(Span sourcePixels, Span dest, int count)
+ {
+ GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count);
+
+ ref TPixel sourceBaseRef = ref sourcePixels.DangerousGetPinnableReference();
+ ref Rgba32 destBaseRef = ref dest.DangerousGetPinnableReference();
+
+ for (int i = 0; i < count; i++)
+ {
+ ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i);
+ ref Rgba32 dp = ref Unsafe.Add(ref destBaseRef, i);
+ sp.ToRgba32(ref dp);
+ }
+ }
+
+ ///
+ /// A helper for that expects a byte span as destination.
+ /// The layout of the data in 'destBytes' must be compatible with layout.
+ ///
+ /// The to the source colors.
+ /// The to the destination bytes.
+ /// The number of pixels to convert.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal void ToRgba32Bytes(Span sourceColors, Span destBytes, int count)
+ {
+ this.ToRgba32(sourceColors, destBytes.NonPortableCast(), count);
+ }
+
+ ///
+ /// Converts 'count' elements in 'source` span of data to a span of -s.
+ ///
+ /// The source of data.
+ /// The to the destination pixels.
+ /// The number of pixels to convert.
+ internal virtual void PackFromBgra32(Span source, Span destPixels, int count)
+ {
+ GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count);
+
+ ref Bgra32 sourceRef = ref source.DangerousGetPinnableReference();
+ ref TPixel destRef = ref destPixels.DangerousGetPinnableReference();
+
+ Rgba32 rgba = new Rgba32(0, 0, 0, 255);
+
+ for (int i = 0; i < count; i++)
+ {
+ ref TPixel dp = ref Unsafe.Add(ref destRef, i);
+ rgba = Unsafe.Add(ref sourceRef, i).ToRgba32();
+ dp.PackFromRgba32(rgba);
+ }
+ }
+
+ ///
+ /// A helper for that expects a byte span.
+ /// The layout of the data in 'sourceBytes' must be compatible with layout.
+ ///
+ /// The to the source bytes.
+ /// The to the destination pixels.
+ /// The number of pixels to convert.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal void PackFromBgra32Bytes(Span sourceBytes, Span destPixels, int count)
+ {
+ this.PackFromBgra32(sourceBytes.NonPortableCast(), destPixels, count);
+ }
+
+ ///
+ /// Converts 'count' pixels in 'sourcePixels` span to a span of -s.
+ /// Bulk version of .
+ ///
+ /// The span of source pixels
+ /// The destination span of data.
+ /// The number of pixels to convert.
+ internal virtual void ToBgra32(Span sourcePixels, Span dest, int count)
+ {
+ GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count);
+
+ ref TPixel sourceBaseRef = ref sourcePixels.DangerousGetPinnableReference();
+ ref Bgra32 destBaseRef = ref dest.DangerousGetPinnableReference();
+
+ for (int i = 0; i < count; i++)
+ {
+ ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i);
+ ref Bgra32 dp = ref Unsafe.Add(ref destBaseRef, i);
+ sp.ToBgra32(ref dp);
+ }
+ }
+
+ ///
+ /// A helper for that expects a byte span as destination.
+ /// The layout of the data in 'destBytes' must be compatible with layout.
+ ///
+ /// The to the source colors.
+ /// The to the destination bytes.
+ /// The number of pixels to convert.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal void ToBgra32Bytes(Span sourceColors, Span destBytes, int count)
+ {
+ this.ToBgra32(sourceColors, destBytes.NonPortableCast(), count);
+ }
+
+ ///
+ /// Converts 'count' elements in 'source` span of data to a span of -s.
+ ///
+ /// The source of data.
+ /// The to the destination pixels.
+ /// The number of pixels to convert.
+ internal virtual void PackFromRgb24(Span source, Span destPixels, int count)
+ {
+ GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count);
+
+ ref Rgb24 sourceRef = ref source.DangerousGetPinnableReference();
+ ref TPixel destRef = ref destPixels.DangerousGetPinnableReference();
+
+ Rgba32 rgba = new Rgba32(0, 0, 0, 255);
+
+ for (int i = 0; i < count; i++)
+ {
+ ref TPixel dp = ref Unsafe.Add(ref destRef, i);
+ rgba.Rgb = Unsafe.Add(ref sourceRef, i);
+ dp.PackFromRgba32(rgba);
+ }
+ }
+
+ ///
+ /// A helper for that expects a byte span.
+ /// The layout of the data in 'sourceBytes' must be compatible with layout.
+ ///
+ /// The to the source bytes.
+ /// The to the destination pixels.
+ /// The number of pixels to convert.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal void PackFromRgb24Bytes(Span sourceBytes, Span destPixels, int count)
+ {
+ this.PackFromRgb24(sourceBytes.NonPortableCast(), destPixels, count);
+ }
+
+ ///
+ /// Converts 'count' pixels in 'sourcePixels` span to a span of -s.
+ /// Bulk version of .
+ ///
+ /// The span of source pixels
+ /// The destination span of data.
+ /// The number of pixels to convert.
+ internal virtual void ToRgb24(Span sourcePixels, Span dest, int count)
+ {
+ GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count);
+
+ ref TPixel sourceBaseRef = ref sourcePixels.DangerousGetPinnableReference();
+ ref Rgb24 destBaseRef = ref dest.DangerousGetPinnableReference();
+
+ for (int i = 0; i < count; i++)
+ {
+ ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i);
+ ref Rgb24 dp = ref Unsafe.Add(ref destBaseRef, i);
+ sp.ToRgb24(ref dp);
+ }
+ }
+
+ ///
+ /// A helper for that expects a byte span as destination.
+ /// The layout of the data in 'destBytes' must be compatible with layout.
+ ///
+ /// The to the source colors.
+ /// The to the destination bytes.
+ /// The number of pixels to convert.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal void ToRgb24Bytes(Span sourceColors, Span destBytes, int count)
+ {
+ this.ToRgb24(sourceColors, destBytes.NonPortableCast(), count);
+ }
+
+ ///
+ /// Converts 'count' elements in 'source` span of data to a span of -s.
+ ///
+ /// The source of data.
+ /// The to the destination pixels.
+ /// The number of pixels to convert.
+ internal virtual void PackFromBgr24(Span source, Span destPixels, int count)
+ {
+ GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count);
+
+ ref Bgr24 sourceRef = ref source.DangerousGetPinnableReference();
+ ref TPixel destRef = ref destPixels.DangerousGetPinnableReference();
+
+ Rgba32 rgba = new Rgba32(0, 0, 0, 255);
+
+ for (int i = 0; i < count; i++)
+ {
+ ref TPixel dp = ref Unsafe.Add(ref destRef, i);
+ rgba.Bgr = Unsafe.Add(ref sourceRef, i);
+ dp.PackFromRgba32(rgba);
+ }
+ }
+
+ ///
+ /// A helper for that expects a byte span.
+ /// The layout of the data in 'sourceBytes' must be compatible with layout.
+ ///
+ /// The to the source bytes.
+ /// The to the destination pixels.
+ /// The number of pixels to convert.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal void PackFromBgr24Bytes(Span sourceBytes, Span destPixels, int count)
+ {
+ this.PackFromBgr24(sourceBytes.NonPortableCast(), destPixels, count);
+ }
+
+ ///
+ /// Converts 'count' pixels in 'sourcePixels` span to a span of -s.
+ /// Bulk version of .
+ ///
+ /// The span of source pixels
+ /// The destination span of data.
+ /// The number of pixels to convert.
+ internal virtual void ToBgr24(Span sourcePixels, Span dest, int count)
+ {
+ GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count);
+
+ ref TPixel sourceBaseRef = ref sourcePixels.DangerousGetPinnableReference();
+ ref Bgr24 destBaseRef = ref dest.DangerousGetPinnableReference();
+
+ for (int i = 0; i < count; i++)
+ {
+ ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i);
+ ref Bgr24 dp = ref Unsafe.Add(ref destBaseRef, i);
+ sp.ToBgr24(ref dp);
+ }
+ }
+
+ ///
+ /// A helper for that expects a byte span as destination.
+ /// The layout of the data in 'destBytes' must be compatible with layout.
+ ///
+ /// The to the source colors.
+ /// The to the destination bytes.
+ /// The number of pixels to convert.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal void ToBgr24Bytes(Span sourceColors, Span destBytes, int count)
+ {
+ this.ToBgr24(sourceColors, destBytes.NonPortableCast(), count);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt
new file mode 100644
index 000000000..16292489f
--- /dev/null
+++ b/src/ImageSharp/PixelFormats/Generated/PixelOperations{TPixel}.Generated.tt
@@ -0,0 +1,130 @@
+<#
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+#>
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ assembly name="System.Core" #>
+<#@ import namespace="System.Linq" #>
+<#@ import namespace="System.Text" #>
+<#@ import namespace="System.Collections.Generic" #>
+<#@ output extension=".cs" #>
+<#
+ void GenerateToDestFormatMethods(string pixelType)
+ {
+ #>
+
+ ///
+ /// Converts 'count' pixels in 'sourcePixels` span to a span of -s.
+ /// Bulk version of .
+ ///
+ /// The span of source pixels
+ /// The destination span of data.
+ /// The number of pixels to convert.
+ internal virtual void To<#=pixelType#>(Span sourcePixels, Span<<#=pixelType#>> dest, int count)
+ {
+ GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count);
+
+ ref TPixel sourceBaseRef = ref sourcePixels.DangerousGetPinnableReference();
+ ref <#=pixelType#> destBaseRef = ref dest.DangerousGetPinnableReference();
+
+ for (int i = 0; i < count; i++)
+ {
+ ref TPixel sp = ref Unsafe.Add(ref sourceBaseRef, i);
+ ref <#=pixelType#> dp = ref Unsafe.Add(ref destBaseRef, i);
+ sp.To<#=pixelType#>(ref dp);
+ }
+ }
+
+ ///
+ /// A helper for that expects a byte span as destination.
+ /// The layout of the data in 'destBytes' must be compatible with layout.
+ ///
+ /// The to the source colors.
+ /// The to the destination bytes.
+ /// The number of pixels to convert.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal void To<#=pixelType#>Bytes(Span sourceColors, Span destBytes, int count)
+ {
+ this.To<#=pixelType#>(sourceColors, destBytes.NonPortableCast>(), count);
+ }
+ <#
+ }
+
+ void GeneratePackFromMethodUsingPackFromRgba32(string pixelType, string rgbaOperationCode)
+ {
+ #>
+
+ ///
+ /// Converts 'count' elements in 'source` span of data to a span of -s.
+ ///
+ /// The source of data.
+ /// The to the destination pixels.
+ /// The number of pixels to convert.
+ internal virtual void PackFrom<#=pixelType#>(Span<<#=pixelType#>> source, Span destPixels, int count)
+ {
+ GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count);
+
+ ref <#=pixelType#> sourceRef = ref source.DangerousGetPinnableReference();
+ ref TPixel destRef = ref destPixels.DangerousGetPinnableReference();
+
+ Rgba32 rgba = new Rgba32(0, 0, 0, 255);
+
+ for (int i = 0; i < count; i++)
+ {
+ ref TPixel dp = ref Unsafe.Add(ref destRef, i);
+ <#=rgbaOperationCode#>
+ dp.PackFromRgba32(rgba);
+ }
+ }
+
+ ///
+ /// A helper for that expects a byte span.
+ /// The layout of the data in 'sourceBytes' must be compatible with layout.
+ ///
+ /// The to the source bytes.
+ /// The to the destination pixels.
+ /// The number of pixels to convert.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ internal void PackFrom<#=pixelType#>Bytes(Span sourceBytes, Span destPixels, int count)
+ {
+ this.PackFrom<#=pixelType#>(sourceBytes.NonPortableCast>(), destPixels, count);
+ }
+ <#
+ }
+
+#>
+//
+
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp.PixelFormats
+{
+ using System;
+ using System.Numerics;
+ using System.Runtime.CompilerServices;
+
+ public partial class PixelOperations
+ {
+ <#
+
+ GeneratePackFromMethodUsingPackFromRgba32("Rgba32", "rgba = Unsafe.Add(ref sourceRef, i);");
+ GenerateToDestFormatMethods("Rgba32");
+
+ GeneratePackFromMethodUsingPackFromRgba32("Bgra32", "rgba = Unsafe.Add(ref sourceRef, i).ToRgba32();");
+ GenerateToDestFormatMethods("Bgra32");
+
+ GeneratePackFromMethodUsingPackFromRgba32("Rgb24", "rgba.Rgb = Unsafe.Add(ref sourceRef, i);");
+ GenerateToDestFormatMethods("Rgb24");
+
+ GeneratePackFromMethodUsingPackFromRgba32("Bgr24", "rgba.Bgr = Unsafe.Add(ref sourceRef, i);");
+ GenerateToDestFormatMethods("Bgr24");
+
+ #>
+
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs
new file mode 100644
index 000000000..e42c575d8
--- /dev/null
+++ b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.cs
@@ -0,0 +1,130 @@
+//
+
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp
+{
+ using System;
+ using System.Numerics;
+ using System.Runtime.CompilerServices;
+ using System.Runtime.InteropServices;
+
+ using ImageSharp.Memory;
+ using ImageSharp.PixelFormats;
+
+ ///
+ /// Provides optimized overrides for bulk operations.
+ ///
+ public partial struct Rgba32
+ {
+ internal partial class PixelOperations : PixelOperations
+ {
+
+ ///
+ internal override void PackFromRgb24(Span source, Span destPixels, int count)
+ {
+ GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count);
+
+ ref Rgb24 sourceRef = ref source.DangerousGetPinnableReference();
+ ref Rgba32 destRef = ref destPixels.DangerousGetPinnableReference();
+
+ for (int i = 0; i < count; i++)
+ {
+ ref Rgb24 sp = ref Unsafe.Add(ref sourceRef, i);
+ ref Rgba32 dp = ref Unsafe.Add(ref destRef, i);
+ Unsafe.As(ref dp) = sp; dp.A = 255;
+ }
+ }
+
+
+ ///
+ internal override void ToRgb24(Span sourcePixels, Span dest, int count)
+ {
+ GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count);
+
+ ref Rgba32 sourceRef = ref sourcePixels.DangerousGetPinnableReference();
+ ref Rgb24 destRef = ref dest.DangerousGetPinnableReference();
+
+ for (int i = 0; i < count; i++)
+ {
+ ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i);
+ ref Rgb24 dp = ref Unsafe.Add(ref destRef, i);
+ dp = Unsafe.As(ref sp);
+ }
+ }
+
+
+ ///
+ internal override void PackFromBgr24(Span source, Span destPixels, int count)
+ {
+ GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count);
+
+ ref Bgr24 sourceRef = ref source.DangerousGetPinnableReference();
+ ref Rgba32 destRef = ref destPixels.DangerousGetPinnableReference();
+
+ for (int i = 0; i < count; i++)
+ {
+ ref Bgr24 sp = ref Unsafe.Add(ref sourceRef, i);
+ ref Rgba32 dp = ref Unsafe.Add(ref destRef, i);
+ dp.Bgr = sp; dp.A = 255;
+ }
+ }
+
+
+ ///
+ internal override void ToBgr24(Span sourcePixels, Span dest, int count)
+ {
+ GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count);
+
+ ref Rgba32 sourceRef = ref sourcePixels.DangerousGetPinnableReference();
+ ref Bgr24 destRef = ref dest.DangerousGetPinnableReference();
+
+ for (int i = 0; i < count; i++)
+ {
+ ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i);
+ ref Bgr24 dp = ref Unsafe.Add(ref destRef, i);
+ dp = sp.Bgr;
+ }
+ }
+
+
+ ///
+ internal override void PackFromBgra32(Span source, Span destPixels, int count)
+ {
+ GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count);
+
+ ref Bgra32 sourceRef = ref source.DangerousGetPinnableReference();
+ ref Rgba32 destRef = ref destPixels.DangerousGetPinnableReference();
+
+ for (int i = 0; i < count; i++)
+ {
+ ref Bgra32 sp = ref Unsafe.Add(ref sourceRef, i);
+ ref Rgba32 dp = ref Unsafe.Add(ref destRef, i);
+ dp = sp.ToRgba32();
+ }
+ }
+
+
+ ///
+ internal override void ToBgra32(Span sourcePixels, Span dest, int count)
+ {
+ GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count);
+
+ ref Rgba32 sourceRef = ref sourcePixels.DangerousGetPinnableReference();
+ ref Bgra32 destRef = ref dest.DangerousGetPinnableReference();
+
+ for (int i = 0; i < count; i++)
+ {
+ ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i);
+ ref Bgra32 dp = ref Unsafe.Add(ref destRef, i);
+ dp = sp.ToBgra32();
+ }
+ }
+
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt
new file mode 100644
index 000000000..9c01fa915
--- /dev/null
+++ b/src/ImageSharp/PixelFormats/Generated/Rgba32.PixelOperations.Generated.tt
@@ -0,0 +1,99 @@
+<#
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+#>
+<#@ template debug="false" hostspecific="false" language="C#" #>
+<#@ assembly name="System.Core" #>
+<#@ import namespace="System.Linq" #>
+<#@ import namespace="System.Text" #>
+<#@ import namespace="System.Collections.Generic" #>
+<#@ output extension=".cs" #>
+<#
+
+ void GeneratePackFromMethod(string pixelType, string converterCode)
+ {
+ #>
+
+ ///
+ internal override void PackFrom<#=pixelType#>(Span<<#=pixelType#>> source, Span destPixels, int count)
+ {
+ GuardSpans(source, nameof(source), destPixels, nameof(destPixels), count);
+
+ ref <#=pixelType#> sourceRef = ref source.DangerousGetPinnableReference();
+ ref Rgba32 destRef = ref destPixels.DangerousGetPinnableReference();
+
+ for (int i = 0; i < count; i++)
+ {
+ ref <#=pixelType#> sp = ref Unsafe.Add(ref sourceRef, i);
+ ref Rgba32 dp = ref Unsafe.Add(ref destRef, i);
+ <#=converterCode#>
+ }
+ }
+
+ <#
+ }
+
+ void GenerateConvertToMethod(string pixelType, string converterCode)
+ {
+ #>
+
+ ///
+ internal override void To<#=pixelType#>(Span sourcePixels, Span<<#=pixelType#>> dest, int count)
+ {
+ GuardSpans(sourcePixels, nameof(sourcePixels), dest, nameof(dest), count);
+
+ ref Rgba32 sourceRef = ref sourcePixels.DangerousGetPinnableReference();
+ ref <#=pixelType#> destRef = ref dest.DangerousGetPinnableReference();
+
+ for (int i = 0; i < count; i++)
+ {
+ ref Rgba32 sp = ref Unsafe.Add(ref sourceRef, i);
+ ref <#=pixelType#> dp = ref Unsafe.Add(ref destRef, i);
+ <#=converterCode#>
+ }
+ }
+
+ <#
+ }
+
+#>
+//
+
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageSharp
+{
+ using System;
+ using System.Numerics;
+ using System.Runtime.CompilerServices;
+ using System.Runtime.InteropServices;
+
+ using ImageSharp.Memory;
+ using ImageSharp.PixelFormats;
+
+ ///
+ /// Provides optimized overrides for bulk operations.
+ ///
+ public partial struct Rgba32
+ {
+ internal partial class PixelOperations : PixelOperations
+ {
+ <#
+ GeneratePackFromMethod("Rgb24", "Unsafe.As(ref dp) = sp; dp.A = 255;");
+ GenerateConvertToMethod("Rgb24", "dp = Unsafe.As(ref sp);");
+
+ GeneratePackFromMethod("Bgr24", "dp.Bgr = sp; dp.A = 255;");
+ GenerateConvertToMethod("Bgr24", "dp = sp.Bgr;");
+
+ GeneratePackFromMethod("Bgra32", "dp = sp.ToRgba32();");
+ GenerateConvertToMethod("Bgra32", "dp = sp.ToBgra32();");
+ #>
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/HalfSingle.cs b/src/ImageSharp/PixelFormats/HalfSingle.cs
index 4cc9acc22..3bdfc9f1c 100644
--- a/src/ImageSharp/PixelFormats/HalfSingle.cs
+++ b/src/ImageSharp/PixelFormats/HalfSingle.cs
@@ -76,7 +76,7 @@ namespace ImageSharp.PixelFormats
}
///
- public PixelOperations CreateBulkOperations() => new PixelOperations();
+ public PixelOperations CreatePixelOperations() => new PixelOperations();
///
/// Expands the packed representation into a .
@@ -104,67 +104,51 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void PackFromBytes(byte x, byte y, byte z, byte w)
+ public void PackFromRgba32(Rgba32 source)
{
- this.PackFromVector4(new Vector4(x, y, z, w) / MaxBytes);
+ this.PackFromVector4(source.ToVector4());
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzBytes(Span bytes, int startIndex)
+ public void ToRgb24(ref Rgb24 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= MaxBytes;
- vector += Half;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.X;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.Z;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzwBytes(Span bytes, int startIndex)
+ public void ToRgba32(ref Rgba32 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= MaxBytes;
- vector += Half;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.X;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.Z;
- bytes[startIndex + 3] = (byte)vector.W;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
+ dest.A = (byte)vector.W;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxBytes(Span bytes, int startIndex)
+ public void ToBgr24(ref Bgr24 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= MaxBytes;
- vector += Half;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.Z;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.X;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxwBytes(Span bytes, int startIndex)
+ public void ToBgra32(ref Bgra32 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= MaxBytes;
- vector += Half;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.Z;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.X;
- bytes[startIndex + 3] = (byte)vector.W;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
+ dest.A = (byte)vector.W;
}
///
@@ -192,5 +176,15 @@ namespace ImageSharp.PixelFormats
{
return this.PackedValue.GetHashCode();
}
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private Vector4 ToScaledVector4()
+ {
+ Vector4 vector = this.ToVector4();
+ vector *= MaxBytes;
+ vector += Half;
+ vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
+ return vector;
+ }
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/HalfVector2.cs b/src/ImageSharp/PixelFormats/HalfVector2.cs
index f490f7169..7f1fe4ebd 100644
--- a/src/ImageSharp/PixelFormats/HalfVector2.cs
+++ b/src/ImageSharp/PixelFormats/HalfVector2.cs
@@ -86,7 +86,7 @@ namespace ImageSharp.PixelFormats
}
///
- public PixelOperations CreateBulkOperations() => new PixelOperations();
+ public PixelOperations CreatePixelOperations() => new PixelOperations();
///
/// Expands the packed representation into a .
@@ -118,67 +118,51 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void PackFromBytes(byte x, byte y, byte z, byte w)
+ public void PackFromRgba32(Rgba32 source)
{
- this.PackFromVector4(new Vector4(x, y, z, w) / MaxBytes);
+ this.PackFromVector4(source.ToVector4());
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzBytes(Span bytes, int startIndex)
+ public void ToRgb24(ref Rgb24 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= MaxBytes;
- vector += Half;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.X;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.Z;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = 0;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzwBytes(Span bytes, int startIndex)
+ public void ToRgba32(ref Rgba32 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= MaxBytes;
- vector += Half;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.X;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.Z;
- bytes[startIndex + 3] = (byte)vector.W;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = 0;
+ dest.A = 255;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxBytes(Span bytes, int startIndex)
+ public void ToBgr24(ref Bgr24 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= MaxBytes;
- vector += Half;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.Z;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.X;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = 0;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxwBytes(Span bytes, int startIndex)
+ public void ToBgra32(ref Bgra32 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= MaxBytes;
- vector += Half;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.Z;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.X;
- bytes[startIndex + 3] = (byte)vector.W;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = 0;
+ dest.A = 255;
}
///
@@ -220,5 +204,15 @@ namespace ImageSharp.PixelFormats
uint num = (uint)(HalfTypeHelper.Pack(y) << 0x10);
return num2 | num;
}
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private Vector4 ToScaledVector4()
+ {
+ Vector4 vector = this.ToVector4();
+ vector *= MaxBytes;
+ vector += Half;
+ vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
+ return vector;
+ }
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/HalfVector4.cs b/src/ImageSharp/PixelFormats/HalfVector4.cs
index 7c496c161..062287dbe 100644
--- a/src/ImageSharp/PixelFormats/HalfVector4.cs
+++ b/src/ImageSharp/PixelFormats/HalfVector4.cs
@@ -89,7 +89,7 @@ namespace ImageSharp.PixelFormats
}
///
- public PixelOperations CreateBulkOperations() => new PixelOperations();
+ public PixelOperations CreatePixelOperations() => new PixelOperations();
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -111,67 +111,51 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void PackFromBytes(byte x, byte y, byte z, byte w)
+ public void PackFromRgba32(Rgba32 source)
{
- this.PackFromVector4(new Vector4(x, y, z, w) / MaxBytes);
+ this.PackFromVector4(source.ToVector4());
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzBytes(Span bytes, int startIndex)
+ public void ToRgb24(ref Rgb24 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= MaxBytes;
- vector += Half;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.X;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.Z;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzwBytes(Span bytes, int startIndex)
+ public void ToRgba32(ref Rgba32 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= MaxBytes;
- vector += Half;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.X;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.Z;
- bytes[startIndex + 3] = (byte)vector.W;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
+ dest.A = (byte)vector.W;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxBytes(Span bytes, int startIndex)
+ public void ToBgr24(ref Bgr24 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= MaxBytes;
- vector += Half;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.Z;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.X;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxwBytes(Span bytes, int startIndex)
+ public void ToBgra32(ref Bgra32 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= MaxBytes;
- vector += Half;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.Z;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.X;
- bytes[startIndex + 3] = (byte)vector.W;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
+ dest.A = (byte)vector.W;
}
///
@@ -214,5 +198,15 @@ namespace ImageSharp.PixelFormats
ulong num1 = (ulong)HalfTypeHelper.Pack(vector.W) << 0x30;
return num4 | num3 | num2 | num1;
}
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private Vector4 ToScaledVector4()
+ {
+ Vector4 vector = this.ToVector4();
+ vector *= MaxBytes;
+ vector += Half;
+ vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
+ return vector;
+ }
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/IPixel.cs b/src/ImageSharp/PixelFormats/IPixel.cs
index 030cb93f4..9090e1210 100644
--- a/src/ImageSharp/PixelFormats/IPixel.cs
+++ b/src/ImageSharp/PixelFormats/IPixel.cs
@@ -20,7 +20,7 @@ namespace ImageSharp.PixelFormats
/// This method is not intended to be consumed directly. Use instead.
///
/// The instance.
- PixelOperations CreateBulkOperations();
+ PixelOperations CreatePixelOperations();
}
///
@@ -42,44 +42,33 @@ namespace ImageSharp.PixelFormats
Vector4 ToVector4();
///
- /// Sets the packed representation from the given byte array.
+ /// Packs the pixel from an value.
///
- /// The x-component.
- /// The y-component.
- /// The z-component.
- /// The w-component.
- void PackFromBytes(byte x, byte y, byte z, byte w);
+ /// The value.
+ void PackFromRgba32(Rgba32 source);
///
- /// Expands the packed representation into a given byte array.
- /// Output is expanded to X-> Y-> Z order. Equivalent to R-> G-> B in
+ /// Converts the pixel to format.
///
- /// The bytes to set the color in.
- /// The starting index of the .
- void ToXyzBytes(Span bytes, int startIndex);
+ /// The destination pixel to write to
+ void ToRgb24(ref Rgb24 dest);
///
- /// Expands the packed representation into a given byte array.
- /// Output is expanded to X-> Y-> Z-> W order. Equivalent to R-> G-> B-> A in
+ /// Converts the pixel to format.
///
- /// The bytes to set the color in.
- /// The starting index of the .
- void ToXyzwBytes(Span bytes, int startIndex);
+ /// The destination pixel to write to
+ void ToRgba32(ref Rgba32 dest);
///
- /// Expands the packed representation into a given byte array.
- /// Output is expanded to Z-> Y-> X order. Equivalent to B-> G-> R in
+ /// Converts the pixel to format.
///
- /// The bytes to set the color in.
- /// The starting index of the .
- void ToZyxBytes(Span bytes, int startIndex);
+ /// The destination pixel to write to
+ void ToBgr24(ref Bgr24 dest);
///
- /// Expands the packed representation into a given byte array.
- /// Output is expanded to Z-> Y-> X-> W order. Equivalent to B-> G-> R-> A in
+ /// Converts the pixel to format.
///
- /// The bytes to set the color in.
- /// The starting index of the .
- void ToZyxwBytes(Span bytes, int startIndex);
+ /// The destination pixel to write to
+ void ToBgra32(ref Bgra32 dest);
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/NormalizedByte2.cs b/src/ImageSharp/PixelFormats/NormalizedByte2.cs
index 47a4f3005..992986f92 100644
--- a/src/ImageSharp/PixelFormats/NormalizedByte2.cs
+++ b/src/ImageSharp/PixelFormats/NormalizedByte2.cs
@@ -91,7 +91,7 @@ namespace ImageSharp.PixelFormats
}
///
- public PixelOperations CreateBulkOperations() => new PixelOperations();
+ public PixelOperations CreatePixelOperations() => new PixelOperations();
///
/// Expands the packed representation into a .
@@ -122,9 +122,9 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void PackFromBytes(byte x, byte y, byte z, byte w)
+ public void PackFromRgba32(Rgba32 source)
{
- Vector4 vector = new Vector4(x, y, z, w);
+ Vector4 vector = source.ToUnscaledVector4();
vector -= Round;
vector -= Half;
vector -= Round;
@@ -134,68 +134,44 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzBytes(Span bytes, int startIndex)
+ public void ToRgb24(ref Rgb24 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= Half;
- vector += Round;
- vector += Half;
- vector += Round;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.X;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = 0;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = 0;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzwBytes(Span bytes, int startIndex)
+ public void ToRgba32(ref Rgba32 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= Half;
- vector += Round;
- vector += Half;
- vector += Round;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.X;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = 0;
- bytes[startIndex + 3] = 255;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = 0;
+ dest.A = 255;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxBytes(Span bytes, int startIndex)
+ public void ToBgr24(ref Bgr24 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= Half;
- vector += Round;
- vector += Half;
- vector += Round;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = 0;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.X;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = 0;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxwBytes(Span bytes, int startIndex)
+ public void ToBgra32(ref Bgra32 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= Half;
- vector += Round;
- vector += Half;
- vector += Round;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = 0;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.X;
- bytes[startIndex + 3] = 255;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = 0;
+ dest.A = 255;
}
///
@@ -238,5 +214,17 @@ namespace ImageSharp.PixelFormats
return (ushort)(byte2 | byte1);
}
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private Vector4 ToScaledVector4()
+ {
+ Vector4 vector = this.ToVector4();
+ vector *= Half;
+ vector += Round;
+ vector += Half;
+ vector += Round;
+ vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
+ return vector;
+ }
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/NormalizedByte4.cs b/src/ImageSharp/PixelFormats/NormalizedByte4.cs
index 4559bd082..99f603f69 100644
--- a/src/ImageSharp/PixelFormats/NormalizedByte4.cs
+++ b/src/ImageSharp/PixelFormats/NormalizedByte4.cs
@@ -93,7 +93,7 @@ namespace ImageSharp.PixelFormats
}
///
- public PixelOperations CreateBulkOperations() => new PixelOperations();
+ public PixelOperations CreatePixelOperations() => new PixelOperations();
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -115,9 +115,9 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void PackFromBytes(byte x, byte y, byte z, byte w)
+ public void PackFromRgba32(Rgba32 source)
{
- Vector4 vector = new Vector4(x, y, z, w);
+ Vector4 vector = source.ToUnscaledVector4();
vector -= Round;
vector -= Half;
vector -= Round;
@@ -127,68 +127,44 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzBytes(Span bytes, int startIndex)
+ public void ToRgb24(ref Rgb24 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= Half;
- vector += Round;
- vector += Half;
- vector += Round;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.X;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.Z;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzwBytes(Span bytes, int startIndex)
+ public void ToRgba32(ref Rgba32 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= Half;
- vector += Round;
- vector += Half;
- vector += Round;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.X;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.Z;
- bytes[startIndex + 3] = (byte)vector.W;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
+ dest.A = (byte)vector.W;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxBytes(Span bytes, int startIndex)
+ public void ToBgr24(ref Bgr24 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= Half;
- vector += Round;
- vector += Half;
- vector += Round;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.Z;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.X;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxwBytes(Span bytes, int startIndex)
+ public void ToBgra32(ref Bgra32 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= Half;
- vector += Round;
- vector += Half;
- vector += Round;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)vector.Z;
- bytes[startIndex + 1] = (byte)vector.Y;
- bytes[startIndex + 2] = (byte)vector.X;
- bytes[startIndex + 3] = (byte)vector.W;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)vector.X;
+ dest.G = (byte)vector.Y;
+ dest.B = (byte)vector.Z;
+ dest.A = (byte)vector.W;
}
///
@@ -235,5 +211,17 @@ namespace ImageSharp.PixelFormats
return byte4 | byte3 | byte2 | byte1;
}
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private Vector4 ToScaledVector4()
+ {
+ Vector4 vector = this.ToVector4();
+ vector *= Half;
+ vector += Round;
+ vector += Half;
+ vector += Round;
+ vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
+ return vector;
+ }
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/NormalizedShort2.cs b/src/ImageSharp/PixelFormats/NormalizedShort2.cs
index 648b68905..a0615563f 100644
--- a/src/ImageSharp/PixelFormats/NormalizedShort2.cs
+++ b/src/ImageSharp/PixelFormats/NormalizedShort2.cs
@@ -91,7 +91,7 @@ namespace ImageSharp.PixelFormats
}
///
- public PixelOperations CreateBulkOperations() => new PixelOperations();
+ public PixelOperations CreatePixelOperations() => new PixelOperations();
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -109,9 +109,9 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void PackFromBytes(byte x, byte y, byte z, byte w)
+ public void PackFromRgba32(Rgba32 source)
{
- Vector4 vector = new Vector4(x, y, z, w);
+ Vector4 vector = source.ToUnscaledVector4();
vector -= Round;
vector -= Half;
vector -= Round;
@@ -121,68 +121,44 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzBytes(Span bytes, int startIndex)
+ public void ToRgb24(ref Rgb24 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= Half;
- vector += Round;
- vector += Half;
- vector += Round;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)MathF.Round(vector.X);
- bytes[startIndex + 1] = (byte)MathF.Round(vector.Y);
- bytes[startIndex + 2] = 0;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)MathF.Round(vector.X);
+ dest.G = (byte)MathF.Round(vector.Y);
+ dest.B = 0;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzwBytes(Span bytes, int startIndex)
+ public void ToRgba32(ref Rgba32 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= Half;
- vector += Round;
- vector += Half;
- vector += Round;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)MathF.Round(vector.X);
- bytes[startIndex + 1] = (byte)MathF.Round(vector.Y);
- bytes[startIndex + 2] = 0;
- bytes[startIndex + 3] = 255;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)MathF.Round(vector.X);
+ dest.G = (byte)MathF.Round(vector.Y);
+ dest.B = 0;
+ dest.A = 255;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxBytes(Span bytes, int startIndex)
+ public void ToBgr24(ref Bgr24 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= Half;
- vector += Round;
- vector += Half;
- vector += Round;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = 0;
- bytes[startIndex + 1] = (byte)MathF.Round(vector.Y);
- bytes[startIndex + 2] = (byte)MathF.Round(vector.X);
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)MathF.Round(vector.X);
+ dest.G = (byte)MathF.Round(vector.Y);
+ dest.B = 0;
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxwBytes(Span bytes, int startIndex)
+ public void ToBgra32(ref Bgra32 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= Half;
- vector += Round;
- vector += Half;
- vector += Round;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = 0;
- bytes[startIndex + 1] = (byte)MathF.Round(vector.Y);
- bytes[startIndex + 2] = (byte)MathF.Round(vector.X);
- bytes[startIndex + 3] = 255;
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)MathF.Round(vector.X);
+ dest.G = (byte)MathF.Round(vector.Y);
+ dest.B = 0;
+ dest.A = 255;
}
///
@@ -245,5 +221,17 @@ namespace ImageSharp.PixelFormats
return word2 | word1;
}
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private Vector4 ToScaledVector4()
+ {
+ Vector4 vector = this.ToVector4();
+ vector *= Half;
+ vector += Round;
+ vector += Half;
+ vector += Round;
+ vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
+ return vector;
+ }
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/NormalizedShort4.cs b/src/ImageSharp/PixelFormats/NormalizedShort4.cs
index 7b520aace..f35fb6368 100644
--- a/src/ImageSharp/PixelFormats/NormalizedShort4.cs
+++ b/src/ImageSharp/PixelFormats/NormalizedShort4.cs
@@ -93,7 +93,7 @@ namespace ImageSharp.PixelFormats
}
///
- public PixelOperations CreateBulkOperations() => new PixelOperations();
+ public PixelOperations CreatePixelOperations() => new PixelOperations();
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -117,9 +117,9 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void PackFromBytes(byte x, byte y, byte z, byte w)
+ public void PackFromRgba32(Rgba32 source)
{
- Vector4 vector = new Vector4(x, y, z, w);
+ Vector4 vector = source.ToUnscaledVector4();
vector -= Round;
vector -= Half;
vector -= Round;
@@ -129,68 +129,44 @@ namespace ImageSharp.PixelFormats
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzBytes(Span bytes, int startIndex)
+ public void ToRgb24(ref Rgb24 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= Half;
- vector += Round;
- vector += Half;
- vector += Round;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)MathF.Round(vector.X);
- bytes[startIndex + 1] = (byte)MathF.Round(vector.Y);
- bytes[startIndex + 2] = (byte)MathF.Round(vector.Z);
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)MathF.Round(vector.X);
+ dest.G = (byte)MathF.Round(vector.Y);
+ dest.B = (byte)MathF.Round(vector.Z);
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToXyzwBytes(Span bytes, int startIndex)
+ public void ToRgba32(ref Rgba32 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= Half;
- vector += Round;
- vector += Half;
- vector += Round;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)MathF.Round(vector.X);
- bytes[startIndex + 1] = (byte)MathF.Round(vector.Y);
- bytes[startIndex + 2] = (byte)MathF.Round(vector.Z);
- bytes[startIndex + 3] = (byte)MathF.Round(vector.W);
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)MathF.Round(vector.X);
+ dest.G = (byte)MathF.Round(vector.Y);
+ dest.B = (byte)MathF.Round(vector.Z);
+ dest.A = (byte)MathF.Round(vector.W);
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxBytes(Span bytes, int startIndex)
+ public void ToBgr24(ref Bgr24 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= Half;
- vector += Round;
- vector += Half;
- vector += Round;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)MathF.Round(vector.Z);
- bytes[startIndex + 1] = (byte)MathF.Round(vector.Y);
- bytes[startIndex + 2] = (byte)MathF.Round(vector.X);
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)MathF.Round(vector.X);
+ dest.G = (byte)MathF.Round(vector.Y);
+ dest.B = (byte)MathF.Round(vector.Z);
}
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void ToZyxwBytes(Span bytes, int startIndex)
+ public void ToBgra32(ref Bgra32 dest)
{
- Vector4 vector = this.ToVector4();
- vector *= Half;
- vector += Round;
- vector += Half;
- vector += Round;
- vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
-
- bytes[startIndex] = (byte)MathF.Round(vector.Z);
- bytes[startIndex + 1] = (byte)MathF.Round(vector.Y);
- bytes[startIndex + 2] = (byte)MathF.Round(vector.X);
- bytes[startIndex + 3] = (byte)MathF.Round(vector.W);
+ Vector4 vector = this.ToScaledVector4();
+ dest.R = (byte)MathF.Round(vector.X);
+ dest.G = (byte)MathF.Round(vector.Y);
+ dest.B = (byte)MathF.Round(vector.Z);
+ dest.A = (byte)MathF.Round(vector.W);
}
///
@@ -241,5 +217,17 @@ namespace ImageSharp.PixelFormats
return word4 | word3 | word2 | word1;
}
+
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ private Vector4 ToScaledVector4()
+ {
+ Vector4 vector = this.ToVector4();
+ vector *= Half;
+ vector += Round;
+ vector += Half;
+ vector += Round;
+ vector = Vector4.Clamp(vector, Vector4.Zero, MaxBytes);
+ return vector;
+ }
}
}
diff --git a/src/ImageSharp/PixelFormats/PixelConversionExtensions.cs b/src/ImageSharp/PixelFormats/PixelConversionExtensions.cs
new file mode 100644
index 000000000..1ea262895
--- /dev/null
+++ b/src/ImageSharp/PixelFormats/PixelConversionExtensions.cs
@@ -0,0 +1,76 @@
+namespace ImageSharp.PixelFormats
+{
+ using System;
+ using System.Runtime.CompilerServices;
+
+ ///
+ /// Extension methods for copying single pixel data into byte Spans.
+ /// TODO: This utility class exists for legacy reasons. Need to do a lot of chore work to remove it (mostly in test classes).
+ ///
+ internal static class PixelConversionExtensions
+ {
+ ///
+ /// Expands the packed representation into a given byte array.
+ /// Output is expanded to X-> Y-> Z order. Equivalent to R-> G-> B in
+ ///
+ /// The pixel type.
+ /// The pixel to copy the data from.
+ /// The bytes to set the color in.
+ /// The starting index of the .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void ToXyzBytes(this TPixel pixel, Span bytes, int startIndex)
+ where TPixel : struct, IPixel
+ {
+ ref Rgb24 dest = ref bytes.GetRgb24(startIndex);
+ pixel.ToRgb24(ref dest);
+ }
+
+ ///
+ /// Expands the packed representation into a given byte array.
+ /// Output is expanded to X-> Y-> Z-> W order. Equivalent to R-> G-> B-> A in
+ ///
+ /// The pixel type.
+ /// The pixel to copy the data from.
+ /// The bytes to set the color in.
+ /// The starting index of the .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void ToXyzwBytes(this TPixel pixel, Span bytes, int startIndex)
+ where TPixel : struct, IPixel
+ {
+ ref Rgba32 dest = ref Unsafe.As(ref bytes[startIndex]);
+ pixel.ToRgba32(ref dest);
+ }
+
+ ///
+ /// Expands the packed representation into a given byte array.
+ /// Output is expanded to Z-> Y-> X order. Equivalent to B-> G-> R in
+ ///
+ /// The pixel type.
+ /// The pixel to copy the data from.
+ /// The bytes to set the color in.
+ /// The starting index of the .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void ToZyxBytes(this TPixel pixel, Span bytes, int startIndex)
+ where TPixel : struct, IPixel
+ {
+ ref Bgr24 dest = ref Unsafe.As(ref bytes[startIndex]);
+ pixel.ToBgr24(ref dest);
+ }
+
+ ///
+ /// Expands the packed representation into a given byte array.
+ /// Output is expanded to Z-> Y-> X-> W order. Equivalent to B-> G-> R-> A in
+ ///
+ /// The pixel type.
+ /// The pixel to copy the data from.
+ /// The bytes to set the color in.
+ /// The starting index of the .
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static void ToZyxwBytes(this TPixel pixel, Span bytes, int startIndex)
+ where TPixel : struct, IPixel
+ {
+ ref Bgra32 dest = ref Unsafe.As(ref bytes[startIndex]);
+ pixel.ToBgra32(ref dest);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs
index 993a11232..a62d14527 100644
--- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs
+++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs
@@ -20,7 +20,7 @@ namespace ImageSharp.PixelFormats
///
/// Gets the global instance for the pixel type
///
- public static PixelOperations Instance { get; } = default(TPixel).CreateBulkOperations();
+ public static PixelOperations Instance { get; } = default(TPixel).CreatePixelOperations();
///
/// Bulk version of
@@ -30,8 +30,7 @@ namespace ImageSharp.PixelFormats
/// The number of pixels to convert.
internal virtual void PackFromVector4(Span sourceVectors, Span destColors, int count)
{
- Guard.MustBeSizedAtLeast(sourceVectors, count, nameof(sourceVectors));
- Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors));
+ GuardSpans(sourceVectors, nameof(sourceVectors), destColors, nameof(destColors), count);
ref Vector4 sourceRef = ref sourceVectors.DangerousGetPinnableReference();
ref TPixel destRef = ref destColors.DangerousGetPinnableReference();
@@ -52,8 +51,7 @@ namespace ImageSharp.PixelFormats
/// The number of pixels to convert.
internal virtual void ToVector4(Span sourceColors, Span destVectors, int count)
{
- Guard.MustBeSizedAtLeast(sourceColors, count, nameof(sourceColors));
- Guard.MustBeSizedAtLeast(destVectors, count, nameof(destVectors));
+ GuardSpans(sourceColors, nameof(sourceColors), destVectors, nameof(destVectors), count);
ref TPixel sourceRef = ref sourceColors.DangerousGetPinnableReference();
ref Vector4 destRef = ref destVectors.DangerousGetPinnableReference();
@@ -67,187 +65,25 @@ namespace ImageSharp.PixelFormats
}
///
- /// Bulk version of that converts data in .
+ /// Verifies that the given 'source' and 'dest' spans are at least of 'minLength' size.
+ /// Throwing an if the condition is not met.
///
- /// The to the source bytes.
- /// The to the destination colors.
- /// The number of pixels to convert.
- internal virtual void PackFromXyzBytes(Span sourceBytes, Span destColors, int count)
- {
- Guard.MustBeSizedAtLeast(sourceBytes, count * 3, nameof(sourceBytes));
- Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors));
-
- ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference();
- ref TPixel destRef = ref destColors.DangerousGetPinnableReference();
-
- for (int i = 0; i < count; i++)
- {
- int i3 = i * 3;
- ref TPixel dp = ref Unsafe.Add(ref destRef, i);
- dp.PackFromBytes(
- Unsafe.Add(ref sourceRef, i3),
- Unsafe.Add(ref sourceRef, i3 + 1),
- Unsafe.Add(ref sourceRef, i3 + 2),
- 255);
- }
- }
-
- ///