Browse Source

almost done

pull/242/head
Anton Firszov 9 years ago
parent
commit
4a9c8c80d7
  1. 29
      src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs
  2. 6
      src/ImageSharp/Formats/Gif/GifDecoderCore.cs
  3. 2
      src/ImageSharp/Formats/Jpeg/Components/Decoder/YCbCrToRgbTables.cs
  4. 70
      src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs
  5. 71
      src/ImageSharp/Formats/Png/PngDecoderCore.cs
  6. 11
      src/ImageSharp/ImageSharp.csproj
  7. 4
      src/ImageSharp/PixelFormats/Alpha8.cs
  8. 4
      src/ImageSharp/PixelFormats/Argb32.cs
  9. 8
      src/ImageSharp/PixelFormats/Bgr24.cs
  10. 4
      src/ImageSharp/PixelFormats/Bgr565.cs
  11. 9
      src/ImageSharp/PixelFormats/Bgra32.cs
  12. 4
      src/ImageSharp/PixelFormats/Bgra4444.cs
  13. 4
      src/ImageSharp/PixelFormats/Bgra5551.cs
  14. 4
      src/ImageSharp/PixelFormats/Byte4.cs
  15. 14
      src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs
  16. 4
      src/ImageSharp/PixelFormats/HalfSingle.cs
  17. 4
      src/ImageSharp/PixelFormats/HalfVector2.cs
  18. 4
      src/ImageSharp/PixelFormats/HalfVector4.cs
  19. 9
      src/ImageSharp/PixelFormats/IPixel.cs
  20. 4
      src/ImageSharp/PixelFormats/NormalizedByte2.cs
  21. 4
      src/ImageSharp/PixelFormats/NormalizedByte4.cs
  22. 4
      src/ImageSharp/PixelFormats/NormalizedShort2.cs
  23. 4
      src/ImageSharp/PixelFormats/NormalizedShort4.cs
  24. 2
      src/ImageSharp/PixelFormats/PixelConversionExtensions.cs
  25. 99
      src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs
  26. 4
      src/ImageSharp/PixelFormats/Rg32.cs
  27. 20
      src/ImageSharp/PixelFormats/Rgb24.cs
  28. 4
      src/ImageSharp/PixelFormats/Rgba1010102.cs
  29. 55
      src/ImageSharp/PixelFormats/Rgba32.cs
  30. 4
      src/ImageSharp/PixelFormats/Rgba64.cs
  31. 4
      src/ImageSharp/PixelFormats/RgbaVector.cs
  32. 4
      src/ImageSharp/PixelFormats/Short2.cs
  33. 4
      src/ImageSharp/PixelFormats/Short4.cs
  34. 2
      src/ImageSharp/Quantizers/OctreeQuantizer{TPixel}.cs
  35. 14
      src/ImageSharp/Quantizers/PaletteQuantizer{TPixel}.cs
  36. 8
      src/Shared/stylecop.json
  37. 2
      tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs
  38. 2
      tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj
  39. 1
      tests/ImageSharp.Sandbox46/Program.cs
  40. 4
      tests/ImageSharp.Tests/Formats/Jpg/YCbCrImageTests.cs
  41. 2
      tests/ImageSharp.Tests/ImageSharp.Tests.csproj
  42. 20
      tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs
  43. 8
      tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs
  44. 4
      tests/ImageSharp.Tests/TestUtilities/ImageProviders/SolidProvider.cs

29
src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs

@ -6,7 +6,8 @@ namespace ImageSharp.Formats
{ {
using System; using System;
using System.IO; using System.IO;
using System.Runtime.CompilerServices;
using ImageSharp.Memory;
using ImageSharp.PixelFormats; using ImageSharp.PixelFormats;
/// <summary> /// <summary>
@ -243,13 +244,20 @@ namespace ImageSharp.Formats
byte[] row = new byte[arrayWidth + padding]; byte[] row = new byte[arrayWidth + padding];
TPixel color = default(TPixel); TPixel color = default(TPixel);
Rgba32 rgba = default(Rgba32);
for (int y = 0; y < height; y++) for (int y = 0; y < height; y++)
{ {
int newY = Invert(y, height, inverted); int newY = Invert(y, height, inverted);
// TODO: Could use PixelOperations here!
this.currentStream.Read(row, 0, row.Length); this.currentStream.Read(row, 0, row.Length);
int offset = 0; int offset = 0;
Span<TPixel> pixelRow = pixels.GetRowSpan(y);
for (int x = 0; x < arrayWidth; x++) for (int x = 0; x < arrayWidth; x++)
{ {
int colOffset = x * ppb; int colOffset = x * ppb;
@ -260,8 +268,9 @@ namespace ImageSharp.Formats
int newX = colOffset + shift; int newX = colOffset + shift;
// Stored in b-> g-> r order. // Stored in b-> g-> r order.
color.PackFromBytes(colors[colorIndex + 2], colors[colorIndex + 1], colors[colorIndex], 255); rgba.Bgr = Unsafe.As<byte, Bgr24>(ref colors[colorIndex]);
pixels[newX, newY] = color; color.PackFromRgba32(rgba);
pixelRow[newX] = color;
} }
offset++; offset++;
@ -286,6 +295,8 @@ namespace ImageSharp.Formats
const int ComponentCount = 2; const int ComponentCount = 2;
TPixel color = default(TPixel); TPixel color = default(TPixel);
Rgba32 rgba = new Rgba32(0, 0, 0, 255);
using (PixelArea<TPixel> row = new PixelArea<TPixel>(width, ComponentOrder.Xyz)) using (PixelArea<TPixel> row = new PixelArea<TPixel>(width, ComponentOrder.Xyz))
{ {
for (int y = 0; y < height; y++) for (int y = 0; y < height; y++)
@ -294,17 +305,19 @@ namespace ImageSharp.Formats
int newY = Invert(y, height, inverted); int newY = Invert(y, height, inverted);
Span<TPixel> pixelRow = pixels.GetRowSpan(newY);
int offset = 0; int offset = 0;
for (int x = 0; x < width; x++) for (int x = 0; x < width; x++)
{ {
short temp = BitConverter.ToInt16(row.Bytes, offset); short temp = BitConverter.ToInt16(row.Bytes, offset);
byte r = (byte)(((temp & Rgb16RMask) >> 11) * ScaleR); rgba.R = (byte)(((temp & Rgb16RMask) >> 11) * ScaleR);
byte g = (byte)(((temp & Rgb16GMask) >> 5) * ScaleG); rgba.G = (byte)(((temp & Rgb16GMask) >> 5) * ScaleG);
byte b = (byte)((temp & Rgb16BMask) * ScaleR); rgba.B = (byte)((temp & Rgb16BMask) * ScaleR);
color.PackFromBytes(r, g, b, 255); color.PackFromRgba32(rgba);
pixels[x, newY] = color; pixelRow[x] = color;
offset += ComponentCount; offset += ComponentCount;
} }
} }

6
src/ImageSharp/Formats/Gif/GifDecoderCore.cs

@ -435,6 +435,8 @@ namespace ImageSharp.Formats
Span<TPixel> rowSpan = image.GetRowSpan(writeY); Span<TPixel> rowSpan = image.GetRowSpan(writeY);
Rgba32 rgba = new Rgba32(0, 0, 0, 255);
for (int x = descriptor.Left; x < descriptor.Left + descriptor.Width; x++) for (int x = descriptor.Left; x < descriptor.Left + descriptor.Width; x++)
{ {
int index = indices[i]; int index = indices[i];
@ -446,7 +448,9 @@ namespace ImageSharp.Formats
int indexOffset = index * 3; int indexOffset = index * 3;
ref TPixel pixel = ref rowSpan[x]; ref TPixel pixel = ref rowSpan[x];
pixel.PackFromBytes(colorTable[indexOffset], colorTable[indexOffset + 1], colorTable[indexOffset + 2], 255); rgba.Rgb = Rgb24.AsRgb24(colorTable, indexOffset);
pixel.PackFromRgba32(rgba);
} }
i++; i++;

2
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); // float b = MathF.Round(y + (1.772F * cb), MidpointRounding.AwayFromZero);
byte b = (byte)(y + tables->CbBTable[cb]).Clamp(0, 255); 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)] [MethodImpl(MethodImplOptions.AggressiveInlining)]

70
src/ImageSharp/Formats/Jpeg/JpegDecoderCore.cs

@ -613,25 +613,23 @@ namespace ImageSharp.Formats
private void ConvertFromGrayScale<TPixel>(Image<TPixel> image) private void ConvertFromGrayScale<TPixel>(Image<TPixel> image)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
using (PixelAccessor<TPixel> pixels = image.Lock()) Parallel.For(
{ 0,
Parallel.For( image.Height,
0, image.Configuration.ParallelOptions,
image.Height, y =>
image.Configuration.ParallelOptions,
y =>
{ {
ref TPixel pixelRowBaseRef = ref image.GetPixelReference(0, y);
int yoff = this.grayImage.GetRowOffset(y); int yoff = this.grayImage.GetRowOffset(y);
for (int x = 0; x < image.Width; x++) for (int x = 0; x < image.Width; x++)
{ {
byte rgb = this.grayImage.Pixels[yoff + x]; byte rgb = this.grayImage.Pixels[yoff + x];
ref TPixel pixel = ref Unsafe.Add(ref pixelRowBaseRef, x);
TPixel packed = default(TPixel); pixel.PackFromRgba32(new Rgba32(rgb, rgb, rgb, 255));
packed.PackFromBytes(rgb, rgb, rgb, 255);
pixels[x, y] = packed;
} }
}); });
}
this.AssignResolution(image); this.AssignResolution(image);
} }
@ -646,30 +644,29 @@ namespace ImageSharp.Formats
{ {
int scale = this.ComponentArray[0].HorizontalFactor / this.ComponentArray[1].HorizontalFactor; int scale = this.ComponentArray[0].HorizontalFactor / this.ComponentArray[1].HorizontalFactor;
using (PixelAccessor<TPixel> pixels = image.Lock()) Parallel.For(
{ 0,
Parallel.For( image.Height,
0, image.Configuration.ParallelOptions,
image.Height, y =>
image.Configuration.ParallelOptions,
y =>
{ {
// TODO: Simplify + optimize + share duplicate code across converter methods // TODO: Simplify + optimize + share duplicate code across converter methods
int yo = this.ycbcrImage.GetRowYOffset(y); int yo = this.ycbcrImage.GetRowYOffset(y);
int co = this.ycbcrImage.GetRowCOffset(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++) for (int x = 0; x < image.Width; x++)
{ {
byte red = this.ycbcrImage.YChannel[yo + x]; rgba.R = this.ycbcrImage.YChannel[yo + x];
byte green = this.ycbcrImage.CbChannel[co + (x / scale)]; rgba.G = this.ycbcrImage.CbChannel[co + (x / scale)];
byte blue = this.ycbcrImage.CrChannel[co + (x / scale)]; rgba.B = this.ycbcrImage.CrChannel[co + (x / scale)];
TPixel packed = default(TPixel); ref TPixel pixel = ref Unsafe.Add(ref pixelRowBaseRef, x);
packed.PackFromBytes(red, green, blue, 255); pixel.PackFromRgba32(rgba);
pixels[x, y] = packed;
} }
}); });
}
this.AssignResolution(image); this.AssignResolution(image);
} }
@ -729,16 +726,15 @@ namespace ImageSharp.Formats
{ {
int scale = this.ComponentArray[0].HorizontalFactor / this.ComponentArray[1].HorizontalFactor; int scale = this.ComponentArray[0].HorizontalFactor / this.ComponentArray[1].HorizontalFactor;
using (PixelAccessor<TPixel> pixels = image.Lock()) Parallel.For(
{ 0,
Parallel.For( image.Height,
0, y =>
image.Height,
y =>
{ {
// TODO: Simplify + optimize + share duplicate code across converter methods // TODO: Simplify + optimize + share duplicate code across converter methods
int yo = this.ycbcrImage.GetRowYOffset(y); int yo = this.ycbcrImage.GetRowYOffset(y);
int co = this.ycbcrImage.GetRowCOffset(y); int co = this.ycbcrImage.GetRowCOffset(y);
ref TPixel pixelRowBaseRef = ref image.GetPixelReference(0, y);
for (int x = 0; x < image.Width; x++) for (int x = 0; x < image.Width; x++)
{ {
@ -746,12 +742,10 @@ namespace ImageSharp.Formats
byte cb = this.ycbcrImage.CbChannel[co + (x / scale)]; byte cb = this.ycbcrImage.CbChannel[co + (x / scale)];
byte cr = this.ycbcrImage.CrChannel[co + (x / scale)]; byte cr = this.ycbcrImage.CrChannel[co + (x / scale)];
TPixel packed = default(TPixel); ref TPixel pixel = ref Unsafe.Add(ref pixelRowBaseRef, x);
this.PackYcck(ref packed, yy, cb, cr, x, y); this.PackYcck(ref pixel, yy, cb, cr, x, y);
pixels[x, y] = packed;
} }
}); });
}
this.AssignResolution(image); this.AssignResolution(image);
} }
@ -860,7 +854,7 @@ namespace ImageSharp.Formats
byte g = (byte)(((m / 255F) * (1F - keyline)).Clamp(0, 1) * 255); byte g = (byte)(((m / 255F) * (1F - keyline)).Clamp(0, 1) * 255);
byte b = (byte)(((y / 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));
} }
/// <summary> /// <summary>
@ -904,7 +898,7 @@ namespace ImageSharp.Formats
byte g = (byte)(((1 - magenta) * (1 - keyline)).Clamp(0, 1) * 255); byte g = (byte)(((1 - magenta) * (1 - keyline)).Clamp(0, 1) * 255);
byte b = (byte)(((1 - yellow) * (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));
} }
/// <summary> /// <summary>

71
src/ImageSharp/Formats/Png/PngDecoderCore.cs

@ -574,7 +574,7 @@ namespace ImageSharp.Formats
for (int x = 0; x < this.header.Width; x++) for (int x = 0; x < this.header.Width; x++)
{ {
byte intensity = (byte)(newScanline1[x] * factor); byte intensity = (byte)(newScanline1[x] * factor);
color.PackFromBytes(intensity, intensity, intensity, 255); color.PackFromRgba32(new Rgba32(intensity, intensity, intensity));
rowSpan[x] = color; rowSpan[x] = color;
} }
@ -589,7 +589,7 @@ namespace ImageSharp.Formats
byte intensity = defilteredScanline[offset]; byte intensity = defilteredScanline[offset];
byte alpha = defilteredScanline[offset + this.bytesPerSample]; byte alpha = defilteredScanline[offset + this.bytesPerSample];
color.PackFromBytes(intensity, intensity, intensity, alpha); color.PackFromRgba32(new Rgba32(intensity, intensity, intensity));
rowSpan[x] = color; rowSpan[x] = color;
} }
@ -628,6 +628,8 @@ namespace ImageSharp.Formats
byte[] palette = this.palette; byte[] palette = this.palette;
var color = default(TPixel); var color = default(TPixel);
Rgba32 rgba = default(Rgba32);
if (this.paletteAlpha != null && this.paletteAlpha.Length > 0) 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 // 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 index = newScanline[x + 1];
int pixelOffset = index * 3; 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]; rgba.Rgb = Rgb24.AsRgb24(palette, pixelOffset);
byte g = palette[pixelOffset + 1];
byte b = palette[pixelOffset + 2];
color.PackFromBytes(r, g, b, a);
} }
else else
{ {
color.PackFromBytes(0, 0, 0, 0); rgba = default(Rgba32);
} }
color.PackFromRgba32(rgba);
row[x] = color; row[x] = color;
} }
} }
else else
{ {
rgba.A = 255;
for (int x = 0; x < this.header.Width; x++) for (int x = 0; x < this.header.Width; x++)
{ {
int index = newScanline[x + 1]; int index = newScanline[x + 1];
int pixelOffset = index * 3; int pixelOffset = index * 3;
byte r = palette[pixelOffset]; rgba.Rgb = Rgb24.AsRgb24(palette, pixelOffset);
byte g = palette[pixelOffset + 1];
byte b = palette[pixelOffset + 2];
color.PackFromBytes(r, g, b, 255); color.PackFromRgba32(rgba);
row[x] = color; row[x] = color;
} }
} }
@ -692,7 +692,7 @@ namespace ImageSharp.Formats
for (int x = pixelOffset, o = 1; x < this.header.Width; x += increment, o++) for (int x = pixelOffset, o = 1; x < this.header.Width; x += increment, o++)
{ {
byte intensity = (byte)(newScanline1[o] * factor); byte intensity = (byte)(newScanline1[o] * factor);
color.PackFromBytes(intensity, intensity, intensity, 255); color.PackFromRgba32(new Rgba32(intensity, intensity, intensity));
rowSpan[x] = color; rowSpan[x] = color;
} }
@ -704,8 +704,7 @@ namespace ImageSharp.Formats
{ {
byte intensity = defilteredScanline[o]; byte intensity = defilteredScanline[o];
byte alpha = defilteredScanline[o + this.bytesPerSample]; byte alpha = defilteredScanline[o + this.bytesPerSample];
color.PackFromRgba32(new Rgba32(intensity, intensity, intensity, alpha));
color.PackFromBytes(intensity, intensity, intensity, alpha);
rowSpan[x] = color; rowSpan[x] = color;
} }
@ -714,6 +713,7 @@ namespace ImageSharp.Formats
case PngColorType.Palette: case PngColorType.Palette:
byte[] newScanline = ToArrayByBitsLength(defilteredScanline, this.bytesPerScanline, this.header.BitDepth); byte[] newScanline = ToArrayByBitsLength(defilteredScanline, this.bytesPerScanline, this.header.BitDepth);
Rgba32 rgba = default(Rgba32);
if (this.paletteAlpha != null && this.paletteAlpha.Length > 0) if (this.paletteAlpha != null && this.paletteAlpha.Length > 0)
{ {
@ -724,35 +724,33 @@ namespace ImageSharp.Formats
int index = newScanline[o]; int index = newScanline[o];
int offset = index * 3; 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]; rgba.Rgb = Rgb24.AsRgb24(this.palette, offset);
byte g = this.palette[offset + 1];
byte b = this.palette[offset + 2];
color.PackFromBytes(r, g, b, a);
} }
else else
{ {
color.PackFromBytes(0, 0, 0, 0); rgba = default(Rgba32);
} }
color.PackFromRgba32(rgba);
rowSpan[x] = color; rowSpan[x] = color;
} }
} }
else else
{ {
rgba.A = 255;
for (int x = pixelOffset, o = 1; x < this.header.Width; x += increment, o++) for (int x = pixelOffset, o = 1; x < this.header.Width; x += increment, o++)
{ {
int index = newScanline[o]; int index = newScanline[o];
int offset = index * 3; int offset = index * 3;
byte r = this.palette[offset]; rgba.Rgb = Rgb24.AsRgb24(this.palette, offset);
byte g = this.palette[offset + 1];
byte b = this.palette[offset + 2];
color.PackFromBytes(r, g, b, 255); color.PackFromRgba32(rgba);
rowSpan[x] = color; rowSpan[x] = color;
} }
} }
@ -761,13 +759,14 @@ namespace ImageSharp.Formats
case PngColorType.Rgb: case PngColorType.Rgb:
rgba.A = 255;
for (int x = pixelOffset, o = 1; x < this.header.Width; x += increment, o += this.bytesPerPixel) for (int x = pixelOffset, o = 1; x < this.header.Width; x += increment, o += this.bytesPerPixel)
{ {
byte r = defilteredScanline[o]; rgba.R = defilteredScanline[o];
byte g = defilteredScanline[o + this.bytesPerSample]; rgba.G = defilteredScanline[o + this.bytesPerSample];
byte b = defilteredScanline[o + (2 * this.bytesPerSample)]; rgba.B = defilteredScanline[o + (2 * this.bytesPerSample)];
color.PackFromBytes(r, g, b, 255); color.PackFromRgba32(rgba);
rowSpan[x] = color; 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) for (int x = pixelOffset, o = 1; x < this.header.Width; x += increment, o += this.bytesPerPixel)
{ {
byte r = defilteredScanline[o]; rgba.R = defilteredScanline[o];
byte g = defilteredScanline[o + this.bytesPerSample]; rgba.G = defilteredScanline[o + this.bytesPerSample];
byte b = defilteredScanline[o + (2 * this.bytesPerSample)]; rgba.B = defilteredScanline[o + (2 * this.bytesPerSample)];
byte a = defilteredScanline[o + (3 * this.bytesPerSample)]; rgba.A = defilteredScanline[o + (3 * this.bytesPerSample)];
color.PackFromBytes(r, g, b, a); color.PackFromRgba32(rgba);
rowSpan[x] = color; rowSpan[x] = color;
} }

11
src/ImageSharp/ImageSharp.csproj

@ -53,6 +53,17 @@
<ItemGroup> <ItemGroup>
<None Update="Formats\Jpeg\Components\Block8x8F.Generated.tt"> <None Update="Formats\Jpeg\Components\Block8x8F.Generated.tt">
<Generator>TextTemplatingFileGenerator</Generator> <Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>Block8x8F.Generated.cs</LastGenOutput>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
<ItemGroup>
<Compile Update="Formats\Jpeg\Components\Block8x8F.Generated.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Block8x8F.Generated.tt</DependentUpon>
</Compile>
</ItemGroup>
</Project> </Project>

4
src/ImageSharp/PixelFormats/Alpha8.cs

@ -80,9 +80,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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;
} }
/// <inheritdoc /> /// <inheritdoc />

4
src/ImageSharp/PixelFormats/Argb32.cs

@ -248,9 +248,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc/> /// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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);
} }
/// <inheritdoc /> /// <inheritdoc />

8
src/ImageSharp/PixelFormats/Bgr24.cs

@ -71,7 +71,7 @@
} }
/// <inheritdoc/> /// <inheritdoc/>
public void PackFromBytes(byte x, byte y, byte z, byte w) public void PackFromRgba32(Rgba32 source)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -95,9 +95,13 @@
} }
/// <inheritdoc/> /// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ToRgba32(ref Rgba32 dest) public void ToRgba32(ref Rgba32 dest)
{ {
throw new NotImplementedException(); dest.R = this.R;
dest.G = this.G;
dest.B = this.B;
dest.A = 255;
} }
/// <inheritdoc/> /// <inheritdoc/>

4
src/ImageSharp/PixelFormats/Bgr565.cs

@ -103,9 +103,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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());
} }
/// <inheritdoc /> /// <inheritdoc />

9
src/ImageSharp/PixelFormats/Bgra32.cs

@ -128,7 +128,7 @@
} }
/// <inheritdoc/> /// <inheritdoc/>
public void PackFromBytes(byte x, byte y, byte z, byte w) public void PackFromRgba32(Rgba32 source)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -156,5 +156,12 @@
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
/// <summary>
/// Converts the pixel to <see cref="Rgba32"/> format.
/// </summary>
/// <returns>The RGBA value</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Rgba32 ToRgba32() => new Rgba32(this.R, this.G, this.B, this.A);
} }
} }

4
src/ImageSharp/PixelFormats/Bgra4444.cs

@ -94,9 +94,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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());
} }
/// <inheritdoc /> /// <inheritdoc />

4
src/ImageSharp/PixelFormats/Bgra5551.cs

@ -94,9 +94,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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());
} }
/// <inheritdoc /> /// <inheritdoc />

4
src/ImageSharp/PixelFormats/Byte4.cs

@ -95,9 +95,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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());
} }
/// <inheritdoc /> /// <inheritdoc />

14
src/ImageSharp/PixelFormats/ColorBuilder{TPixel}.cs

@ -35,12 +35,13 @@ namespace ImageSharp.PixelFormats
} }
TPixel result = default(TPixel); TPixel result = default(TPixel);
Rgba32 rgba = new Rgba32(
result.PackFromBytes(
(byte)(packedValue >> 24), (byte)(packedValue >> 24),
(byte)(packedValue >> 16), (byte)(packedValue >> 16),
(byte)(packedValue >> 8), (byte)(packedValue >> 8),
(byte)(packedValue >> 0)); (byte)(packedValue >> 0));
result.PackFromRgba32(rgba);
return result; return result;
} }
@ -51,12 +52,7 @@ namespace ImageSharp.PixelFormats
/// <param name="green">The green intensity.</param> /// <param name="green">The green intensity.</param>
/// <param name="blue">The blue intensity.</param> /// <param name="blue">The blue intensity.</param>
/// <returns>Returns a <typeparamref name="TPixel"/> that represents the color defined by the provided RGB values with 100% opacity.</returns> /// <returns>Returns a <typeparamref name="TPixel"/> that represents the color defined by the provided RGB values with 100% opacity.</returns>
public static TPixel FromRGB(byte red, byte green, byte blue) public static TPixel FromRGB(byte red, byte green, byte blue) => FromRGBA(red, green, blue, 255);
{
TPixel color = default(TPixel);
color.PackFromBytes(red, green, blue, 255);
return color;
}
/// <summary> /// <summary>
/// Creates a new <typeparamref name="TPixel"/> representation from standard RGBA bytes. /// Creates a new <typeparamref name="TPixel"/> representation from standard RGBA bytes.
@ -69,7 +65,7 @@ namespace ImageSharp.PixelFormats
public static TPixel FromRGBA(byte red, byte green, byte blue, byte alpha) public static TPixel FromRGBA(byte red, byte green, byte blue, byte alpha)
{ {
TPixel color = default(TPixel); TPixel color = default(TPixel);
color.PackFromBytes(red, green, blue, alpha); color.PackFromRgba32(new Rgba32(red, green, blue, alpha));
return color; return color;
} }

4
src/ImageSharp/PixelFormats/HalfSingle.cs

@ -104,9 +104,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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());
} }
/// <inheritdoc /> /// <inheritdoc />

4
src/ImageSharp/PixelFormats/HalfVector2.cs

@ -118,9 +118,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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());
} }
/// <inheritdoc /> /// <inheritdoc />

4
src/ImageSharp/PixelFormats/HalfVector4.cs

@ -111,9 +111,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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());
} }
/// <inheritdoc /> /// <inheritdoc />

9
src/ImageSharp/PixelFormats/IPixel.cs

@ -42,13 +42,10 @@ namespace ImageSharp.PixelFormats
Vector4 ToVector4(); Vector4 ToVector4();
/// <summary> /// <summary>
/// Sets the packed representation from the given byte array. /// Packs the pixel from an <see cref="Rgba32"/> value.
/// </summary> /// </summary>
/// <param name="x">The x-component.</param> /// <param name="source">The <see cref="Rgba32"/> value.</param>
/// <param name="y">The y-component.</param> void PackFromRgba32(Rgba32 source);
/// <param name="z">The z-component.</param>
/// <param name="w">The w-component.</param>
void PackFromBytes(byte x, byte y, byte z, byte w);
/// <summary> /// <summary>
/// Converts the pixel to <see cref="Rgb24"/> format. /// Converts the pixel to <see cref="Rgb24"/> format.

4
src/ImageSharp/PixelFormats/NormalizedByte2.cs

@ -122,9 +122,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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 -= Round;
vector -= Half; vector -= Half;
vector -= Round; vector -= Round;

4
src/ImageSharp/PixelFormats/NormalizedByte4.cs

@ -115,9 +115,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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 -= Round;
vector -= Half; vector -= Half;
vector -= Round; vector -= Round;

4
src/ImageSharp/PixelFormats/NormalizedShort2.cs

@ -109,9 +109,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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 -= Round;
vector -= Half; vector -= Half;
vector -= Round; vector -= Round;

4
src/ImageSharp/PixelFormats/NormalizedShort4.cs

@ -117,9 +117,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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 -= Round;
vector -= Half; vector -= Half;
vector -= Round; vector -= Round;

2
src/ImageSharp/PixelFormats/PixelConversionExtensions.cs

@ -21,7 +21,7 @@
public static void ToXyzBytes<TPixel>(this TPixel pixel, Span<byte> bytes, int startIndex) public static void ToXyzBytes<TPixel>(this TPixel pixel, Span<byte> bytes, int startIndex)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
ref Rgb24 dest = ref Unsafe.As<byte, Rgb24>(ref bytes[startIndex]); ref Rgb24 dest = ref Rgb24.AsRgb24(bytes, startIndex);
pixel.ToRgb24(ref dest); pixel.ToRgb24(ref dest);
} }

99
src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs

@ -67,28 +67,31 @@ namespace ImageSharp.PixelFormats
} }
/// <summary> /// <summary>
/// Bulk version of <see cref="IPixel.PackFromBytes(byte, byte, byte, byte)"/> that converts data in <see cref="ComponentOrder.Xyz"/>. /// Bulk version of <see cref="IPixel.PackFromRgba32(Rgba32)"/> that converts data in <see cref="ComponentOrder.Xyz"/>.
/// </summary> /// </summary>
/// <param name="sourceBytes">The <see cref="Span{T}"/> to the source bytes.</param> /// <param name="sourceBytes">The <see cref="Span{T}"/> to the source bytes.</param>
/// <param name="destColors">The <see cref="Span{T}"/> to the destination colors.</param> /// <param name="destColors">The <see cref="Span{T}"/> to the destination colors.</param>
/// <param name="count">The number of pixels to convert.</param> /// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromXyzBytes(Span<byte> sourceBytes, Span<TPixel> destColors, int count) internal virtual void PackFromXyzBytes(Span<byte> sourceBytes, Span<TPixel> destColors, int count)
{ {
Guard.MustBeSizedAtLeast(sourceBytes, count * 3, nameof(sourceBytes)); this.PackFromRgb24(sourceBytes.NonPortableCast<byte, Rgb24>(), destColors, count);
Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors)); }
ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference(); internal virtual void PackFromRgb24(Span<Rgb24> source, Span<TPixel> destPixels, int count)
ref TPixel destRef = ref destColors.DangerousGetPinnableReference(); {
Guard.MustBeSizedAtLeast(source, count, nameof(source));
Guard.MustBeSizedAtLeast(destPixels, count, nameof(destPixels));
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++) for (int i = 0; i < count; i++)
{ {
int i3 = i * 3;
ref TPixel dp = ref Unsafe.Add(ref destRef, i); ref TPixel dp = ref Unsafe.Add(ref destRef, i);
dp.PackFromBytes( rgba.Rgb = Unsafe.Add(ref sourceRef, i);
Unsafe.Add(ref sourceRef, i3), dp.PackFromRgba32(rgba);
Unsafe.Add(ref sourceRef, i3 + 1),
Unsafe.Add(ref sourceRef, i3 + 2),
255);
} }
} }
@ -113,28 +116,31 @@ namespace ImageSharp.PixelFormats
} }
/// <summary> /// <summary>
/// Bulk version of <see cref="IPixel.PackFromBytes(byte, byte, byte, byte)"/> that converts data in <see cref="ComponentOrder.Xyzw"/>. /// Bulk version of <see cref="IPixel.PackFromRgba32(Rgba32)"/> that converts data in <see cref="ComponentOrder.Xyzw"/>.
/// </summary> /// </summary>
/// <param name="sourceBytes">The <see cref="Span{T}"/> to the source bytes.</param> /// <param name="sourceBytes">The <see cref="Span{T}"/> to the source bytes.</param>
/// <param name="destColors">The <see cref="Span{T}"/> to the destination colors.</param> /// <param name="destColors">The <see cref="Span{T}"/> to the destination colors.</param>
/// <param name="count">The number of pixels to convert.</param> /// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromXyzwBytes(Span<byte> sourceBytes, Span<TPixel> destColors, int count) internal virtual void PackFromXyzwBytes(Span<byte> sourceBytes, Span<TPixel> destColors, int count)
{ {
Guard.MustBeSizedAtLeast(sourceBytes, count * 4, nameof(sourceBytes)); this.PackFromRgba32(sourceBytes.NonPortableCast<byte, Rgba32>(), destColors, count);
Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors)); }
ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference(); internal virtual void PackFromRgba32(Span<Rgba32> source, Span<TPixel> destPixels, int count)
ref TPixel destRef = ref destColors.DangerousGetPinnableReference(); {
Guard.MustBeSizedAtLeast(source, count, nameof(source));
Guard.MustBeSizedAtLeast(destPixels, count, nameof(destPixels));
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++) for (int i = 0; i < count; i++)
{ {
int i4 = i * 4;
ref TPixel dp = ref Unsafe.Add(ref destRef, i); ref TPixel dp = ref Unsafe.Add(ref destRef, i);
dp.PackFromBytes( rgba = Unsafe.Add(ref sourceRef, i);
Unsafe.Add(ref sourceRef, i4), dp.PackFromRgba32(rgba);
Unsafe.Add(ref sourceRef, i4 + 1),
Unsafe.Add(ref sourceRef, i4 + 2),
Unsafe.Add(ref sourceRef, i4 + 3));
} }
} }
@ -159,28 +165,31 @@ namespace ImageSharp.PixelFormats
} }
/// <summary> /// <summary>
/// Bulk version of <see cref="IPixel.PackFromBytes(byte, byte, byte, byte)"/> that converts data in <see cref="ComponentOrder.Zyx"/>. /// Bulk version of <see cref="IPixel.PackFromRgba32(Rgba32)"/> that converts data in <see cref="ComponentOrder.Zyx"/>.
/// </summary> /// </summary>
/// <param name="sourceBytes">The <see cref="Span{T}"/> to the source bytes.</param> /// <param name="sourceBytes">The <see cref="Span{T}"/> to the source bytes.</param>
/// <param name="destColors">The <see cref="Span{T}"/> to the destination colors.</param> /// <param name="destColors">The <see cref="Span{T}"/> to the destination colors.</param>
/// <param name="count">The number of pixels to convert.</param> /// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromZyxBytes(Span<byte> sourceBytes, Span<TPixel> destColors, int count) internal virtual void PackFromZyxBytes(Span<byte> sourceBytes, Span<TPixel> destColors, int count)
{ {
Guard.MustBeSizedAtLeast(sourceBytes, count * 3, nameof(sourceBytes)); this.PackFromBgr24(sourceBytes.NonPortableCast<byte, Bgr24>(), destColors, count);
Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors)); }
ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference(); internal virtual void PackFromBgr24(Span<Bgr24> source, Span<TPixel> destPixels, int count)
ref TPixel destRef = ref destColors.DangerousGetPinnableReference(); {
Guard.MustBeSizedAtLeast(source, count, nameof(source));
Guard.MustBeSizedAtLeast(destPixels, count, nameof(destPixels));
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++) for (int i = 0; i < count; i++)
{ {
int i3 = i * 3;
ref TPixel dp = ref Unsafe.Add(ref destRef, i); ref TPixel dp = ref Unsafe.Add(ref destRef, i);
dp.PackFromBytes( rgba.Bgr = Unsafe.Add(ref sourceRef, i);
Unsafe.Add(ref sourceRef, i3 + 2), dp.PackFromRgba32(rgba);
Unsafe.Add(ref sourceRef, i3 + 1),
Unsafe.Add(ref sourceRef, i3),
255);
} }
} }
@ -205,28 +214,30 @@ namespace ImageSharp.PixelFormats
} }
/// <summary> /// <summary>
/// Bulk version of <see cref="IPixel.PackFromBytes(byte, byte, byte, byte)"/> that converts data in <see cref="ComponentOrder.Zyxw"/>. /// Bulk version of <see cref="IPixel.PackFromRgba32(Rgba32)"/> that converts data in <see cref="ComponentOrder.Zyxw"/>.
/// </summary> /// </summary>
/// <param name="sourceBytes">The <see cref="Span{T}"/> to the source bytes.</param> /// <param name="sourceBytes">The <see cref="Span{T}"/> to the source bytes.</param>
/// <param name="destColors">The <see cref="Span{T}"/> to the destination colors.</param> /// <param name="destColors">The <see cref="Span{T}"/> to the destination colors.</param>
/// <param name="count">The number of pixels to convert.</param> /// <param name="count">The number of pixels to convert.</param>
internal virtual void PackFromZyxwBytes(Span<byte> sourceBytes, Span<TPixel> destColors, int count) internal virtual void PackFromZyxwBytes(Span<byte> sourceBytes, Span<TPixel> destColors, int count)
{ {
Guard.MustBeSizedAtLeast(sourceBytes, count * 4, nameof(sourceBytes)); this.PackFromBgra32(sourceBytes.NonPortableCast<byte, Bgra32>(), destColors, count);
Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors)); }
ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference(); internal virtual void PackFromBgra32(Span<Bgra32> source, Span<TPixel> destPixels, int count)
ref TPixel destRef = ref destColors.DangerousGetPinnableReference(); {
Guard.MustBeSizedAtLeast(source, count, nameof(source));
Guard.MustBeSizedAtLeast(destPixels, count, nameof(destPixels));
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++) for (int i = 0; i < count; i++)
{ {
int i4 = i * 4;
ref TPixel dp = ref Unsafe.Add(ref destRef, i); ref TPixel dp = ref Unsafe.Add(ref destRef, i);
dp.PackFromBytes( rgba = Unsafe.Add(ref sourceRef, i).ToRgba32();
Unsafe.Add(ref sourceRef, i4 + 2), dp.PackFromRgba32(rgba);
Unsafe.Add(ref sourceRef, i4 + 1),
Unsafe.Add(ref sourceRef, i4),
Unsafe.Add(ref sourceRef, i4 + 3));
} }
} }

4
src/ImageSharp/PixelFormats/Rg32.cs

@ -107,9 +107,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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());
} }
/// <inheritdoc /> /// <inheritdoc />

20
src/ImageSharp/PixelFormats/Rgb24.cs

@ -71,7 +71,7 @@ namespace ImageSharp.PixelFormats
} }
/// <inheritdoc/> /// <inheritdoc/>
public void PackFromBytes(byte x, byte y, byte z, byte w) public void PackFromRgba32(Rgba32 source)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
@ -111,5 +111,23 @@ namespace ImageSharp.PixelFormats
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref Rgb24 AsRgb24(byte[] bytes, int offset)
{
return ref Unsafe.As<byte, Rgb24>(ref bytes[offset]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static ref Rgb24 AsRgb24(ref byte baseRef, int offset)
{
return ref Unsafe.As<byte, Rgb24>(ref Unsafe.Add(ref baseRef, offset));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ref Rgb24 AsRgb24(Span<byte> bytes, int offset)
{
return ref Unsafe.As<byte, Rgb24>(ref bytes[offset]);
}
} }
} }

4
src/ImageSharp/PixelFormats/Rgba1010102.cs

@ -101,9 +101,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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());
} }
/// <inheritdoc /> /// <inheritdoc />

55
src/ImageSharp/PixelFormats/Rgba32.cs

@ -178,6 +178,44 @@ namespace ImageSharp
} }
} }
/// <summary>
/// Gets or sets the RGB components of this struct as <see cref="Rgb24"/>
/// </summary>
public Rgb24 Rgb
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return Unsafe.As<Rgba32, Rgb24>(ref this);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
Unsafe.As<Rgba32, Rgb24>(ref this) = value;
}
}
/// <summary>
/// Gets or sets the RGB components of this struct as <see cref="Bgr24"/> reverting the component order.
/// </summary>
public Bgr24 Bgr
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
return new Bgr24(this.R, this.G, this.B);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set
{
this.R = value.R;
this.G = value.G;
this.B = value.B;
}
}
/// <inheritdoc/> /// <inheritdoc/>
public uint PackedValue public uint PackedValue
{ {
@ -237,12 +275,9 @@ namespace ImageSharp
/// <inheritdoc/> /// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBytes(byte x, byte y, byte z, byte w) public void PackFromRgba32(Rgba32 source)
{ {
this.R = x; this = source;
this.G = y;
this.B = z;
this.A = w;
} }
/// <summary> /// <summary>
@ -337,6 +372,16 @@ namespace ImageSharp
} }
} }
/// <summary>
/// Gets the <see cref="Vector4"/> representation without normalizing to [0, 1]
/// </summary>
/// <returns>A <see cref="Vector4"/> of values in [0, 255] </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal Vector4 ToUnscaledVector4()
{
return new Vector4(this.R, this.G, this.B, this.A);
}
/// <summary> /// <summary>
/// Packs the four floats into a <see cref="uint"/>. /// Packs the four floats into a <see cref="uint"/>.
/// </summary> /// </summary>

4
src/ImageSharp/PixelFormats/Rgba64.cs

@ -100,9 +100,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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());
} }
/// <inheritdoc /> /// <inheritdoc />

4
src/ImageSharp/PixelFormats/RgbaVector.cs

@ -215,9 +215,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc/> /// <inheritdoc/>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBytes(byte x, byte y, byte z, byte w) public void PackFromRgba32(Rgba32 source)
{ {
this.backingVector = new Vector4(x, y, z, w) / MaxBytes; this.backingVector = source.ToVector4();
} }
/// <summary> /// <summary>

4
src/ImageSharp/PixelFormats/Short2.cs

@ -109,9 +109,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public void PackFromBytes(byte x, byte y, byte z, byte w) public void PackFromRgba32(Rgba32 source)
{ {
Vector2 vector = new Vector2(x, y) / 255; Vector2 vector = new Vector2(source.R, source.G) / 255;
vector *= 65534; vector *= 65534;
vector -= new Vector2(32767); vector -= new Vector2(32767);
this.PackedValue = Pack(vector.X, vector.Y); this.PackedValue = Pack(vector.X, vector.Y);

4
src/ImageSharp/PixelFormats/Short4.cs

@ -115,9 +115,9 @@ namespace ImageSharp.PixelFormats
/// <inheritdoc /> /// <inheritdoc />
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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) / 255; Vector4 vector = source.ToVector4();
vector *= 65534; vector *= 65534;
vector -= new Vector4(32767); vector -= new Vector4(32767);
this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W);

2
src/ImageSharp/Quantizers/OctreeQuantizer{TPixel}.cs

@ -499,7 +499,7 @@ namespace ImageSharp.Quantizers
// And set the color of the palette entry // And set the color of the palette entry
var pixel = default(TPixel); var pixel = default(TPixel);
pixel.PackFromBytes(r, g, b, 255); pixel.PackFromRgba32(new Rgba32(r, g, b, 255));
palette[index] = pixel; palette[index] = pixel;
// Consume the next palette index // Consume the next palette index

14
src/ImageSharp/Quantizers/PaletteQuantizer{TPixel}.cs

@ -18,11 +18,6 @@ namespace ImageSharp.Quantizers
public sealed class PaletteQuantizer<TPixel> : Quantizer<TPixel> public sealed class PaletteQuantizer<TPixel> : Quantizer<TPixel>
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
/// <summary>
/// The pixel buffer, used to reduce allocations.
/// </summary>
private readonly byte[] pixelBuffer = new byte[4];
/// <summary> /// <summary>
/// A lookup table for colors /// A lookup table for colors
/// </summary> /// </summary>
@ -48,14 +43,9 @@ namespace ImageSharp.Quantizers
Rgba32[] constants = ColorConstants.WebSafeColors; Rgba32[] constants = ColorConstants.WebSafeColors;
TPixel[] safe = new TPixel[constants.Length + 1]; TPixel[] safe = new TPixel[constants.Length + 1];
for (int i = 0; i < constants.Length; i++) Span<byte> constantsBytes = constants.AsSpan().NonPortableCast<Rgba32, byte>();
{
constants[i].ToXyzwBytes(this.pixelBuffer, 0);
var packed = default(TPixel);
packed.PackFromBytes(this.pixelBuffer[0], this.pixelBuffer[1], this.pixelBuffer[2], this.pixelBuffer[3]);
safe[i] = packed;
}
PixelOperations<TPixel>.Instance.PackFromXyzwBytes(constantsBytes, safe, constants.Length);
this.colors = safe; this.colors = safe;
} }
else else

8
src/Shared/stylecop.json

@ -3,7 +3,13 @@
"settings": { "settings": {
"documentationRules": { "documentationRules": {
"companyName": "James Jackson-South", "companyName": "James Jackson-South",
"copyrightText": "Copyright (c) James Jackson-South and contributors.\nLicensed under the Apache License, Version 2.0." "copyrightText": "Copyright (c) James Jackson-South and contributors.\nLicensed under the Apache License, Version 2.0.",
"documentInterfaces": false,
"documentInternalElements": false,
"documentExposedElements": false,
"documentPrivateElements": false,
"documentPrivateFields": false
} }
} }
} }

2
tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs

@ -40,7 +40,7 @@ namespace ImageSharp.Benchmarks.Color.Bulk
{ {
int i4 = i * 4; int i4 = i * 4;
TPixel c = default(TPixel); TPixel c = default(TPixel);
c.PackFromBytes(s[i4], s[i4 + 1], s[i4 + 2], s[i4 + 3]); c.PackFromRgba32(new Rgba32(s[i4], s[i4 + 1], s[i4 + 2], s[i4 + 3]));
d[i] = c; d[i] = c;
} }
} }

2
tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj

@ -17,8 +17,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<!--<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />--> <!--<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />-->
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="Moq" Version="4.7.1" /> <PackageReference Include="Moq" Version="4.7.1" />
<PackageReference Include="xunit" Version="2.3.0-beta2-build3683" />
<!--<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />--> <!--<PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />-->
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

1
tests/ImageSharp.Sandbox46/Program.cs

@ -10,6 +10,7 @@ namespace ImageSharp.Sandbox46
using ImageSharp.Tests; using ImageSharp.Tests;
using ImageSharp.Tests.Colors; using ImageSharp.Tests.Colors;
using ImageSharp.Tests.PixelFormats;
using ImageSharp.Tests.Processing.Transforms; using ImageSharp.Tests.Processing.Transforms;
using Xunit.Abstractions; using Xunit.Abstractions;

4
tests/ImageSharp.Tests/Formats/Jpg/YCbCrImageTests.cs

@ -31,7 +31,7 @@ namespace ImageSharp.Tests
[InlineData(YCbCrImage.YCbCrSubsampleRatio.YCbCrSubsampleRatio422, 2, 1)] [InlineData(YCbCrImage.YCbCrSubsampleRatio.YCbCrSubsampleRatio422, 2, 1)]
[InlineData(YCbCrImage.YCbCrSubsampleRatio.YCbCrSubsampleRatio440, 1, 2)] [InlineData(YCbCrImage.YCbCrSubsampleRatio.YCbCrSubsampleRatio440, 1, 2)]
[InlineData(YCbCrImage.YCbCrSubsampleRatio.YCbCrSubsampleRatio444, 1, 1)] [InlineData(YCbCrImage.YCbCrSubsampleRatio.YCbCrSubsampleRatio444, 1, 1)]
public void CalculateChrominanceSize(int ratioValue, int expectedDivX, int expectedDivY) internal void CalculateChrominanceSize(YCbCrImage.YCbCrSubsampleRatio ratioValue, int expectedDivX, int expectedDivY)
{ {
YCbCrImage.YCbCrSubsampleRatio ratio = (YCbCrImage.YCbCrSubsampleRatio)ratioValue; YCbCrImage.YCbCrSubsampleRatio ratio = (YCbCrImage.YCbCrSubsampleRatio)ratioValue;
@ -49,7 +49,7 @@ namespace ImageSharp.Tests
[InlineData(YCbCrImage.YCbCrSubsampleRatio.YCbCrSubsampleRatio422, 2)] [InlineData(YCbCrImage.YCbCrSubsampleRatio.YCbCrSubsampleRatio422, 2)]
[InlineData(YCbCrImage.YCbCrSubsampleRatio.YCbCrSubsampleRatio440, 1)] [InlineData(YCbCrImage.YCbCrSubsampleRatio.YCbCrSubsampleRatio440, 1)]
[InlineData(YCbCrImage.YCbCrSubsampleRatio.YCbCrSubsampleRatio444, 1)] [InlineData(YCbCrImage.YCbCrSubsampleRatio.YCbCrSubsampleRatio444, 1)]
public void Create(int ratioValue, int expectedCStrideDiv) internal void Create(YCbCrImage.YCbCrSubsampleRatio ratioValue, int expectedCStrideDiv)
{ {
YCbCrImage.YCbCrSubsampleRatio ratio = (YCbCrImage.YCbCrSubsampleRatio)ratioValue; YCbCrImage.YCbCrSubsampleRatio ratio = (YCbCrImage.YCbCrSubsampleRatio)ratioValue;

2
tests/ImageSharp.Tests/ImageSharp.Tests.csproj

@ -11,8 +11,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" /> <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
<PackageReference Include="xunit" Version="2.2.0" />
<PackageReference Include="Moq" Version="4.7.1" /> <PackageReference Include="Moq" Version="4.7.1" />
<PackageReference Include="xunit" Version="2.3.0-beta2-build3683" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta2-build1317" /> <PackageReference Include="xunit.runner.visualstudio" Version="2.3.0-beta2-build1317" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

20
tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs

@ -302,7 +302,7 @@ namespace ImageSharp.Tests.Colors
Assert.Equal(bgra, new byte[] { 0, 0, 128, 0 }); Assert.Equal(bgra, new byte[] { 0, 0, 128, 0 });
Byte4 r = new Byte4(); Byte4 r = new Byte4();
r.PackFromBytes(20, 38, 0, 255); r.PackFromRgba32(new Rgba32(20, 38, 0, 255));
r.ToXyzwBytes(rgba, 0); r.ToXyzwBytes(rgba, 0);
Assert.Equal(rgba, new byte[] { 20, 38, 0, 255 }); Assert.Equal(rgba, new byte[] { 20, 38, 0, 255 });
} }
@ -448,7 +448,7 @@ namespace ImageSharp.Tests.Colors
float y = -0.3f; float y = -0.3f;
Assert.Equal(0xda0d, new NormalizedByte2(x, y).PackedValue); Assert.Equal(0xda0d, new NormalizedByte2(x, y).PackedValue);
NormalizedByte2 n = new NormalizedByte2(); NormalizedByte2 n = new NormalizedByte2();
n.PackFromBytes(141, 90, 0, 0); n.PackFromRgba32(new Rgba32(141, 90, 0, 0));
Assert.Equal(0xda0d, n.PackedValue); Assert.Equal(0xda0d, n.PackedValue);
byte[] rgb = new byte[3]; byte[] rgb = new byte[3];
@ -491,7 +491,7 @@ namespace ImageSharp.Tests.Colors
float w = -0.7f; float w = -0.7f;
Assert.Equal(0xA740DA0D, new NormalizedByte4(x, y, z, w).PackedValue); Assert.Equal(0xA740DA0D, new NormalizedByte4(x, y, z, w).PackedValue);
NormalizedByte4 n = new NormalizedByte4(); NormalizedByte4 n = new NormalizedByte4();
n.PackFromBytes(141, 90, 192, 39); n.PackFromRgba32(new Rgba32(141, 90, 192, 39));
Assert.Equal(0xA740DA0D, n.PackedValue); Assert.Equal(0xA740DA0D, n.PackedValue);
Assert.Equal((uint)958796544, new NormalizedByte4(0.0008f, 0.15f, 0.30f, 0.45f).PackedValue); Assert.Equal((uint)958796544, new NormalizedByte4(0.0008f, 0.15f, 0.30f, 0.45f).PackedValue);
@ -515,7 +515,7 @@ namespace ImageSharp.Tests.Colors
// http://community.monogame.net/t/normalizedbyte4-texture2d-gives-different-results-from-xna/8012/8 // http://community.monogame.net/t/normalizedbyte4-texture2d-gives-different-results-from-xna/8012/8
NormalizedByte4 r = new NormalizedByte4(); NormalizedByte4 r = new NormalizedByte4();
r.PackFromBytes(9, 115, 202, 127); r.PackFromRgba32(new Rgba32(9, 115, 202, 127));
r.ToXyzwBytes(rgba, 0); r.ToXyzwBytes(rgba, 0);
Assert.Equal(rgba, new byte[] { 9, 115, 202, 127 }); Assert.Equal(rgba, new byte[] { 9, 115, 202, 127 });
@ -554,7 +554,7 @@ namespace ImageSharp.Tests.Colors
byte[] bgra = new byte[4]; byte[] bgra = new byte[4];
NormalizedShort2 n = new NormalizedShort2(); NormalizedShort2 n = new NormalizedShort2();
n.PackFromBytes(141, 90, 0, 0); n.PackFromRgba32(new Rgba32(141, 90, 0, 0));
n.ToXyzBytes(rgb, 0); n.ToXyzBytes(rgb, 0);
Assert.Equal(rgb, new byte[] { 141, 90, 0 }); Assert.Equal(rgb, new byte[] { 141, 90, 0 });
@ -615,7 +615,7 @@ namespace ImageSharp.Tests.Colors
Assert.Equal(bgra, new byte[] { 192, 90, 141, 39 }); Assert.Equal(bgra, new byte[] { 192, 90, 141, 39 });
NormalizedShort4 r = new NormalizedShort4(); NormalizedShort4 r = new NormalizedShort4();
r.PackFromBytes(9, 115, 202, 127); r.PackFromRgba32(new Rgba32(9, 115, 202, 127));
r.ToXyzwBytes(rgba, 0); r.ToXyzwBytes(rgba, 0);
Assert.Equal(rgba, new byte[] { 9, 115, 202, 127 }); Assert.Equal(rgba, new byte[] { 9, 115, 202, 127 });
} }
@ -708,7 +708,7 @@ namespace ImageSharp.Tests.Colors
// Alpha component accuracy will be awful. // Alpha component accuracy will be awful.
Rgba1010102 r = new Rgba1010102(); Rgba1010102 r = new Rgba1010102();
r.PackFromBytes(25, 0, 128, 0); r.PackFromRgba32(new Rgba32(25, 0, 128, 0));
r.ToXyzwBytes(rgba, 0); r.ToXyzwBytes(rgba, 0);
Assert.Equal(rgba, new byte[] { 25, 0, 128, 0 }); Assert.Equal(rgba, new byte[] { 25, 0, 128, 0 });
} }
@ -801,7 +801,7 @@ namespace ImageSharp.Tests.Colors
Assert.Equal(bgra, new byte[] { 76, 38, 20, 115 }); Assert.Equal(bgra, new byte[] { 76, 38, 20, 115 });
Rgba64 r = new Rgba64(); Rgba64 r = new Rgba64();
r.PackFromBytes(20, 38, 76, 115); r.PackFromRgba32(new Rgba32(20, 38, 76, 115));
r.ToXyzwBytes(rgba, 0); r.ToXyzwBytes(rgba, 0);
Assert.Equal(rgba, new byte[] { 20, 38, 76, 115 }); Assert.Equal(rgba, new byte[] { 20, 38, 76, 115 });
} }
@ -856,7 +856,7 @@ namespace ImageSharp.Tests.Colors
Assert.Equal(bgra, new byte[] { 0, 127, 128, 255 }); Assert.Equal(bgra, new byte[] { 0, 127, 128, 255 });
Short2 r = new Short2(); Short2 r = new Short2();
r.PackFromBytes(20, 38, 0, 255); r.PackFromRgba32(new Rgba32(20, 38, 0, 255));
r.ToXyzwBytes(rgba, 0); r.ToXyzwBytes(rgba, 0);
Assert.Equal(rgba, new byte[] { 20, 38, 0, 255 }); Assert.Equal(rgba, new byte[] { 20, 38, 0, 255 });
} }
@ -913,7 +913,7 @@ namespace ImageSharp.Tests.Colors
Assert.Equal(bgra, new byte[] { 243, 177, 172, 128 }); Assert.Equal(bgra, new byte[] { 243, 177, 172, 128 });
Short4 r = new Short4(); Short4 r = new Short4();
r.PackFromBytes(20, 38, 0, 255); r.PackFromRgba32(new Rgba32(20, 38, 0, 255));
r.ToXyzwBytes(rgba, 0); r.ToXyzwBytes(rgba, 0);
Assert.Equal(rgba, new byte[] { 20, 38, 0, 255 }); Assert.Equal(rgba, new byte[] { 20, 38, 0, 255 });
} }

8
tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs

@ -156,7 +156,7 @@ namespace ImageSharp.Tests.PixelFormats
{ {
int i3 = i * 3; int i3 = i * 3;
expected[i].PackFromBytes(source[i3 + 0], source[i3 + 1], source[i3 + 2], 255); expected[i].PackFromRgba32(new Rgba32(source[i3 + 0], source[i3 + 1], source[i3 + 2], 255));
} }
TestOperation( TestOperation(
@ -197,7 +197,7 @@ namespace ImageSharp.Tests.PixelFormats
{ {
int i4 = i * 4; int i4 = i * 4;
expected[i].PackFromBytes(source[i4 + 0], source[i4 + 1], source[i4 + 2], source[i4 + 3]); expected[i].PackFromRgba32(new Rgba32(source[i4 + 0], source[i4 + 1], source[i4 + 2], source[i4 + 3]));
} }
TestOperation( TestOperation(
@ -238,7 +238,7 @@ namespace ImageSharp.Tests.PixelFormats
{ {
int i3 = i * 3; int i3 = i * 3;
expected[i].PackFromBytes(source[i3 + 2], source[i3 + 1], source[i3 + 0], 255); expected[i].PackFromRgba32(new Rgba32(source[i3 + 2], source[i3 + 1], source[i3 + 0], 255));
} }
TestOperation( TestOperation(
@ -279,7 +279,7 @@ namespace ImageSharp.Tests.PixelFormats
{ {
int i4 = i * 4; int i4 = i * 4;
expected[i].PackFromBytes(source[i4 + 2], source[i4 + 1], source[i4 + 0], source[i4 + 3]); expected[i].PackFromRgba32(new Rgba32(source[i4 + 2], source[i4 + 1], source[i4 + 0], source[i4 + 3]));
} }
TestOperation( TestOperation(

4
tests/ImageSharp.Tests/TestUtilities/ImageProviders/SolidProvider.cs

@ -53,11 +53,11 @@ namespace ImageSharp.Tests
{ {
Image<TPixel> image = base.GetImage(); Image<TPixel> image = base.GetImage();
TPixel color = default(TPixel); TPixel color = default(TPixel);
color.PackFromBytes(this.r, this.g, this.b, this.a); color.PackFromRgba32(new Rgba32(this.r, this.g, this.b, this.a));
return image.Fill(color); return image.Fill(color);
} }
public override void Serialize(IXunitSerializationInfo info) public override void Serialize(IXunitSerializationInfo info)
{ {
info.AddValue("red", this.r); info.AddValue("red", this.r);

Loading…
Cancel
Save