From eb2a3bd15578035b28415aee444c8da7ccfd9aa0 Mon Sep 17 00:00:00 2001 From: Anton Firszov Date: Sun, 4 Jun 2017 04:22:50 +0200 Subject: [PATCH] almost done --- src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs | 29 ++++-- src/ImageSharp/Formats/Gif/GifDecoderCore.cs | 6 +- .../Components/Decoder/YCbCrToRgbTables.cs | 2 +- .../Formats/Jpeg/JpegDecoderCore.cs | 70 ++++++------- src/ImageSharp/Formats/Png/PngDecoderCore.cs | 71 +++++++------ src/ImageSharp/ImageSharp.csproj | 11 +++ src/ImageSharp/PixelFormats/Alpha8.cs | 4 +- src/ImageSharp/PixelFormats/Argb32.cs | 4 +- src/ImageSharp/PixelFormats/Bgr24.cs | 8 +- src/ImageSharp/PixelFormats/Bgr565.cs | 4 +- src/ImageSharp/PixelFormats/Bgra32.cs | 9 +- src/ImageSharp/PixelFormats/Bgra4444.cs | 4 +- src/ImageSharp/PixelFormats/Bgra5551.cs | 4 +- src/ImageSharp/PixelFormats/Byte4.cs | 4 +- .../PixelFormats/ColorBuilder{TPixel}.cs | 14 +-- src/ImageSharp/PixelFormats/HalfSingle.cs | 4 +- src/ImageSharp/PixelFormats/HalfVector2.cs | 4 +- src/ImageSharp/PixelFormats/HalfVector4.cs | 4 +- src/ImageSharp/PixelFormats/IPixel.cs | 9 +- .../PixelFormats/NormalizedByte2.cs | 4 +- .../PixelFormats/NormalizedByte4.cs | 4 +- .../PixelFormats/NormalizedShort2.cs | 4 +- .../PixelFormats/NormalizedShort4.cs | 4 +- .../PixelFormats/PixelConversionExtensions.cs | 2 +- .../PixelFormats/PixelOperations{TPixel}.cs | 99 ++++++++++--------- src/ImageSharp/PixelFormats/Rg32.cs | 4 +- src/ImageSharp/PixelFormats/Rgb24.cs | 20 +++- src/ImageSharp/PixelFormats/Rgba1010102.cs | 4 +- src/ImageSharp/PixelFormats/Rgba32.cs | 55 ++++++++++- src/ImageSharp/PixelFormats/Rgba64.cs | 4 +- src/ImageSharp/PixelFormats/RgbaVector.cs | 4 +- src/ImageSharp/PixelFormats/Short2.cs | 4 +- src/ImageSharp/PixelFormats/Short4.cs | 4 +- .../Quantizers/OctreeQuantizer{TPixel}.cs | 2 +- .../Quantizers/PaletteQuantizer{TPixel}.cs | 14 +-- src/Shared/stylecop.json | 8 +- .../Color/Bulk/PackFromXyzw.cs | 2 +- .../ImageSharp.Sandbox46.csproj | 2 +- tests/ImageSharp.Sandbox46/Program.cs | 1 + .../Formats/Jpg/YCbCrImageTests.cs | 4 +- .../ImageSharp.Tests/ImageSharp.Tests.csproj | 2 +- .../PixelFormats/PackedPixelTests.cs | 20 ++-- .../PixelFormats/PixelOperationsTests.cs | 8 +- .../ImageProviders/SolidProvider.cs | 4 +- 44 files changed, 322 insertions(+), 226 deletions(-) diff --git a/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpDecoderCore.cs index dd91aa11d..23eaa502c 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,20 @@ 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); + // TODO: Could use PixelOperations here! + this.currentStream.Read(row, 0, row.Length); int offset = 0; + + Span pixelRow = pixels.GetRowSpan(y); + for (int x = 0; x < arrayWidth; x++) { int colOffset = x * ppb; @@ -260,8 +268,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 +295,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 +305,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..7092d2dd0 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 = Rgb24.AsRgb24(colorTable, 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..12c7bb803 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; } @@ -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 = Rgb24.AsRgb24(palette, 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 = Rgb24.AsRgb24(palette, 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 = Rgb24.AsRgb24(this.palette, 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 = Rgb24.AsRgb24(this.palette, 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/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj index 6194be1bf..68a1571a3 100644 --- a/src/ImageSharp/ImageSharp.csproj +++ b/src/ImageSharp/ImageSharp.csproj @@ -53,6 +53,17 @@ TextTemplatingFileGenerator + Block8x8F.Generated.cs + + + + + + True + True + Block8x8F.Generated.tt + + \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Alpha8.cs b/src/ImageSharp/PixelFormats/Alpha8.cs index 6a78f15db..59934fdc6 100644 --- a/src/ImageSharp/PixelFormats/Alpha8.cs +++ b/src/ImageSharp/PixelFormats/Alpha8.cs @@ -80,9 +80,9 @@ 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; } /// diff --git a/src/ImageSharp/PixelFormats/Argb32.cs b/src/ImageSharp/PixelFormats/Argb32.cs index 56c33df33..f389723dc 100644 --- a/src/ImageSharp/PixelFormats/Argb32.cs +++ b/src/ImageSharp/PixelFormats/Argb32.cs @@ -248,9 +248,9 @@ 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); } /// diff --git a/src/ImageSharp/PixelFormats/Bgr24.cs b/src/ImageSharp/PixelFormats/Bgr24.cs index 7430e37ab..a3b3a907d 100644 --- a/src/ImageSharp/PixelFormats/Bgr24.cs +++ b/src/ImageSharp/PixelFormats/Bgr24.cs @@ -71,7 +71,7 @@ } /// - public void PackFromBytes(byte x, byte y, byte z, byte w) + public void PackFromRgba32(Rgba32 source) { throw new NotImplementedException(); } @@ -95,9 +95,13 @@ } /// + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void ToRgba32(ref Rgba32 dest) { - throw new NotImplementedException(); + dest.R = this.R; + dest.G = this.G; + dest.B = this.B; + dest.A = 255; } /// diff --git a/src/ImageSharp/PixelFormats/Bgr565.cs b/src/ImageSharp/PixelFormats/Bgr565.cs index 4f6b6aa20..af22b14a0 100644 --- a/src/ImageSharp/PixelFormats/Bgr565.cs +++ b/src/ImageSharp/PixelFormats/Bgr565.cs @@ -103,9 +103,9 @@ 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()); } /// diff --git a/src/ImageSharp/PixelFormats/Bgra32.cs b/src/ImageSharp/PixelFormats/Bgra32.cs index 3ad6bd336..e07e4c0e3 100644 --- a/src/ImageSharp/PixelFormats/Bgra32.cs +++ b/src/ImageSharp/PixelFormats/Bgra32.cs @@ -128,7 +128,7 @@ } /// - public void PackFromBytes(byte x, byte y, byte z, byte w) + public void PackFromRgba32(Rgba32 source) { throw new NotImplementedException(); } @@ -156,5 +156,12 @@ { throw new NotImplementedException(); } + + /// + /// 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 2c60aa900..d10ea58c7 100644 --- a/src/ImageSharp/PixelFormats/Bgra4444.cs +++ b/src/ImageSharp/PixelFormats/Bgra4444.cs @@ -94,9 +94,9 @@ 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()); } /// diff --git a/src/ImageSharp/PixelFormats/Bgra5551.cs b/src/ImageSharp/PixelFormats/Bgra5551.cs index 9812059a2..198f91108 100644 --- a/src/ImageSharp/PixelFormats/Bgra5551.cs +++ b/src/ImageSharp/PixelFormats/Bgra5551.cs @@ -94,9 +94,9 @@ 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()); } /// diff --git a/src/ImageSharp/PixelFormats/Byte4.cs b/src/ImageSharp/PixelFormats/Byte4.cs index a5fcfe8bf..14053ba12 100644 --- a/src/ImageSharp/PixelFormats/Byte4.cs +++ b/src/ImageSharp/PixelFormats/Byte4.cs @@ -95,9 +95,9 @@ 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()); } /// 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/HalfSingle.cs b/src/ImageSharp/PixelFormats/HalfSingle.cs index 441ee5417..1b564c87c 100644 --- a/src/ImageSharp/PixelFormats/HalfSingle.cs +++ b/src/ImageSharp/PixelFormats/HalfSingle.cs @@ -104,9 +104,9 @@ 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()); } /// diff --git a/src/ImageSharp/PixelFormats/HalfVector2.cs b/src/ImageSharp/PixelFormats/HalfVector2.cs index 373b4f970..237e25981 100644 --- a/src/ImageSharp/PixelFormats/HalfVector2.cs +++ b/src/ImageSharp/PixelFormats/HalfVector2.cs @@ -118,9 +118,9 @@ 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()); } /// diff --git a/src/ImageSharp/PixelFormats/HalfVector4.cs b/src/ImageSharp/PixelFormats/HalfVector4.cs index cd079146e..062287dbe 100644 --- a/src/ImageSharp/PixelFormats/HalfVector4.cs +++ b/src/ImageSharp/PixelFormats/HalfVector4.cs @@ -111,9 +111,9 @@ 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()); } /// diff --git a/src/ImageSharp/PixelFormats/IPixel.cs b/src/ImageSharp/PixelFormats/IPixel.cs index cc261e2eb..9090e1210 100644 --- a/src/ImageSharp/PixelFormats/IPixel.cs +++ b/src/ImageSharp/PixelFormats/IPixel.cs @@ -42,13 +42,10 @@ 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); /// /// Converts the pixel to format. diff --git a/src/ImageSharp/PixelFormats/NormalizedByte2.cs b/src/ImageSharp/PixelFormats/NormalizedByte2.cs index 44641710b..387cb6f41 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte2.cs @@ -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; diff --git a/src/ImageSharp/PixelFormats/NormalizedByte4.cs b/src/ImageSharp/PixelFormats/NormalizedByte4.cs index 86f00ed84..90657c3ac 100644 --- a/src/ImageSharp/PixelFormats/NormalizedByte4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedByte4.cs @@ -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; diff --git a/src/ImageSharp/PixelFormats/NormalizedShort2.cs b/src/ImageSharp/PixelFormats/NormalizedShort2.cs index fb11c16af..a0615563f 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort2.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort2.cs @@ -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; diff --git a/src/ImageSharp/PixelFormats/NormalizedShort4.cs b/src/ImageSharp/PixelFormats/NormalizedShort4.cs index 0da68b65e..f35fb6368 100644 --- a/src/ImageSharp/PixelFormats/NormalizedShort4.cs +++ b/src/ImageSharp/PixelFormats/NormalizedShort4.cs @@ -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; diff --git a/src/ImageSharp/PixelFormats/PixelConversionExtensions.cs b/src/ImageSharp/PixelFormats/PixelConversionExtensions.cs index c75719dc6..98a2083a1 100644 --- a/src/ImageSharp/PixelFormats/PixelConversionExtensions.cs +++ b/src/ImageSharp/PixelFormats/PixelConversionExtensions.cs @@ -21,7 +21,7 @@ public static void ToXyzBytes(this TPixel pixel, Span bytes, int startIndex) where TPixel : struct, IPixel { - ref Rgb24 dest = ref Unsafe.As(ref bytes[startIndex]); + ref Rgb24 dest = ref Rgb24.AsRgb24(bytes, startIndex); pixel.ToRgb24(ref dest); } diff --git a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs index 918662144..39c1c0524 100644 --- a/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs +++ b/src/ImageSharp/PixelFormats/PixelOperations{TPixel}.cs @@ -67,28 +67,31 @@ namespace ImageSharp.PixelFormats } /// - /// Bulk version of that converts data in . + /// Bulk version of that converts data in . /// /// 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)); + this.PackFromRgb24(sourceBytes.NonPortableCast(), destColors, count); + } - ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference(); - ref TPixel destRef = ref destColors.DangerousGetPinnableReference(); + internal virtual void PackFromRgb24(Span source, Span destPixels, int count) + { + 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++) { - 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); + rgba.Rgb = Unsafe.Add(ref sourceRef, i); + dp.PackFromRgba32(rgba); } } @@ -113,28 +116,31 @@ namespace ImageSharp.PixelFormats } /// - /// Bulk version of that converts data in . + /// Bulk version of that converts data in . /// /// The to the source bytes. /// The to the destination colors. /// The number of pixels to convert. internal virtual void PackFromXyzwBytes(Span sourceBytes, Span destColors, int count) { - Guard.MustBeSizedAtLeast(sourceBytes, count * 4, nameof(sourceBytes)); - Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors)); + this.PackFromRgba32(sourceBytes.NonPortableCast(), destColors, count); + } - ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference(); - ref TPixel destRef = ref destColors.DangerousGetPinnableReference(); + internal virtual void PackFromRgba32(Span source, Span destPixels, int count) + { + 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++) { - int i4 = i * 4; ref TPixel dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBytes( - Unsafe.Add(ref sourceRef, i4), - Unsafe.Add(ref sourceRef, i4 + 1), - Unsafe.Add(ref sourceRef, i4 + 2), - Unsafe.Add(ref sourceRef, i4 + 3)); + rgba = Unsafe.Add(ref sourceRef, i); + dp.PackFromRgba32(rgba); } } @@ -159,28 +165,31 @@ namespace ImageSharp.PixelFormats } /// - /// Bulk version of that converts data in . + /// Bulk version of that converts data in . /// /// The to the source bytes. /// The to the destination colors. /// The number of pixels to convert. internal virtual void PackFromZyxBytes(Span sourceBytes, Span destColors, int count) { - Guard.MustBeSizedAtLeast(sourceBytes, count * 3, nameof(sourceBytes)); - Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors)); + this.PackFromBgr24(sourceBytes.NonPortableCast(), destColors, count); + } - ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference(); - ref TPixel destRef = ref destColors.DangerousGetPinnableReference(); + internal virtual void PackFromBgr24(Span source, Span destPixels, int count) + { + 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++) { - int i3 = i * 3; ref TPixel dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBytes( - Unsafe.Add(ref sourceRef, i3 + 2), - Unsafe.Add(ref sourceRef, i3 + 1), - Unsafe.Add(ref sourceRef, i3), - 255); + rgba.Bgr = Unsafe.Add(ref sourceRef, i); + dp.PackFromRgba32(rgba); } } @@ -205,28 +214,30 @@ namespace ImageSharp.PixelFormats } /// - /// Bulk version of that converts data in . + /// Bulk version of that converts data in . /// /// The to the source bytes. /// The to the destination colors. /// The number of pixels to convert. internal virtual void PackFromZyxwBytes(Span sourceBytes, Span destColors, int count) { - Guard.MustBeSizedAtLeast(sourceBytes, count * 4, nameof(sourceBytes)); - Guard.MustBeSizedAtLeast(destColors, count, nameof(destColors)); + this.PackFromBgra32(sourceBytes.NonPortableCast(), destColors, count); + } - ref byte sourceRef = ref sourceBytes.DangerousGetPinnableReference(); - ref TPixel destRef = ref destColors.DangerousGetPinnableReference(); + internal virtual void PackFromBgra32(Span source, Span destPixels, int count) + { + 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++) { - int i4 = i * 4; ref TPixel dp = ref Unsafe.Add(ref destRef, i); - dp.PackFromBytes( - Unsafe.Add(ref sourceRef, i4 + 2), - Unsafe.Add(ref sourceRef, i4 + 1), - Unsafe.Add(ref sourceRef, i4), - Unsafe.Add(ref sourceRef, i4 + 3)); + rgba = Unsafe.Add(ref sourceRef, i).ToRgba32(); + dp.PackFromRgba32(rgba); } } diff --git a/src/ImageSharp/PixelFormats/Rg32.cs b/src/ImageSharp/PixelFormats/Rg32.cs index 86b516ede..0575689a7 100644 --- a/src/ImageSharp/PixelFormats/Rg32.cs +++ b/src/ImageSharp/PixelFormats/Rg32.cs @@ -107,9 +107,9 @@ 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()); } /// diff --git a/src/ImageSharp/PixelFormats/Rgb24.cs b/src/ImageSharp/PixelFormats/Rgb24.cs index 196c02d7c..1c91635dc 100644 --- a/src/ImageSharp/PixelFormats/Rgb24.cs +++ b/src/ImageSharp/PixelFormats/Rgb24.cs @@ -71,7 +71,7 @@ namespace ImageSharp.PixelFormats } /// - public void PackFromBytes(byte x, byte y, byte z, byte w) + public void PackFromRgba32(Rgba32 source) { throw new NotImplementedException(); } @@ -111,5 +111,23 @@ namespace ImageSharp.PixelFormats { throw new NotImplementedException(); } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ref Rgb24 AsRgb24(byte[] bytes, int offset) + { + return ref Unsafe.As(ref bytes[offset]); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static ref Rgb24 AsRgb24(ref byte baseRef, int offset) + { + return ref Unsafe.As(ref Unsafe.Add(ref baseRef, offset)); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static ref Rgb24 AsRgb24(Span bytes, int offset) + { + return ref Unsafe.As(ref bytes[offset]); + } } } \ No newline at end of file diff --git a/src/ImageSharp/PixelFormats/Rgba1010102.cs b/src/ImageSharp/PixelFormats/Rgba1010102.cs index 935f69795..e682aa477 100644 --- a/src/ImageSharp/PixelFormats/Rgba1010102.cs +++ b/src/ImageSharp/PixelFormats/Rgba1010102.cs @@ -101,9 +101,9 @@ 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()); } /// diff --git a/src/ImageSharp/PixelFormats/Rgba32.cs b/src/ImageSharp/PixelFormats/Rgba32.cs index 840018792..240a1a296 100644 --- a/src/ImageSharp/PixelFormats/Rgba32.cs +++ b/src/ImageSharp/PixelFormats/Rgba32.cs @@ -178,6 +178,44 @@ namespace ImageSharp } } + /// + /// Gets or sets the RGB components of this struct as + /// + public Rgb24 Rgb + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + return Unsafe.As(ref this); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + set + { + Unsafe.As(ref this) = value; + } + } + + /// + /// Gets or sets the RGB components of this struct as reverting the component order. + /// + 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; + } + } + /// public uint PackedValue { @@ -237,12 +275,9 @@ namespace ImageSharp /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void PackFromBytes(byte x, byte y, byte z, byte w) + public void PackFromRgba32(Rgba32 source) { - this.R = x; - this.G = y; - this.B = z; - this.A = w; + this = source; } /// @@ -337,6 +372,16 @@ namespace ImageSharp } } + /// + /// Gets the representation without normalizing to [0, 1] + /// + /// A of values in [0, 255] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal Vector4 ToUnscaledVector4() + { + return new Vector4(this.R, this.G, this.B, this.A); + } + /// /// Packs the four floats into a . /// diff --git a/src/ImageSharp/PixelFormats/Rgba64.cs b/src/ImageSharp/PixelFormats/Rgba64.cs index 92a839ddf..bdcf13763 100644 --- a/src/ImageSharp/PixelFormats/Rgba64.cs +++ b/src/ImageSharp/PixelFormats/Rgba64.cs @@ -100,9 +100,9 @@ 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()); } /// diff --git a/src/ImageSharp/PixelFormats/RgbaVector.cs b/src/ImageSharp/PixelFormats/RgbaVector.cs index f3498705d..c6eed1122 100644 --- a/src/ImageSharp/PixelFormats/RgbaVector.cs +++ b/src/ImageSharp/PixelFormats/RgbaVector.cs @@ -215,9 +215,9 @@ namespace ImageSharp.PixelFormats /// [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(); } /// diff --git a/src/ImageSharp/PixelFormats/Short2.cs b/src/ImageSharp/PixelFormats/Short2.cs index d369a6aae..0b3f4be93 100644 --- a/src/ImageSharp/PixelFormats/Short2.cs +++ b/src/ImageSharp/PixelFormats/Short2.cs @@ -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) { - Vector2 vector = new Vector2(x, y) / 255; + Vector2 vector = new Vector2(source.R, source.G) / 255; vector *= 65534; vector -= new Vector2(32767); this.PackedValue = Pack(vector.X, vector.Y); diff --git a/src/ImageSharp/PixelFormats/Short4.cs b/src/ImageSharp/PixelFormats/Short4.cs index 9f7a5d887..958300929 100644 --- a/src/ImageSharp/PixelFormats/Short4.cs +++ b/src/ImageSharp/PixelFormats/Short4.cs @@ -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) / 255; + Vector4 vector = source.ToVector4(); vector *= 65534; vector -= new Vector4(32767); this.PackedValue = Pack(vector.X, vector.Y, vector.Z, vector.W); diff --git a/src/ImageSharp/Quantizers/OctreeQuantizer{TPixel}.cs b/src/ImageSharp/Quantizers/OctreeQuantizer{TPixel}.cs index e19df4cfa..8ebea8533 100644 --- a/src/ImageSharp/Quantizers/OctreeQuantizer{TPixel}.cs +++ b/src/ImageSharp/Quantizers/OctreeQuantizer{TPixel}.cs @@ -499,7 +499,7 @@ namespace ImageSharp.Quantizers // And set the color of the palette entry var pixel = default(TPixel); - pixel.PackFromBytes(r, g, b, 255); + pixel.PackFromRgba32(new Rgba32(r, g, b, 255)); palette[index] = pixel; // Consume the next palette index diff --git a/src/ImageSharp/Quantizers/PaletteQuantizer{TPixel}.cs b/src/ImageSharp/Quantizers/PaletteQuantizer{TPixel}.cs index cf3ff94ee..e9d2841a1 100644 --- a/src/ImageSharp/Quantizers/PaletteQuantizer{TPixel}.cs +++ b/src/ImageSharp/Quantizers/PaletteQuantizer{TPixel}.cs @@ -18,11 +18,6 @@ namespace ImageSharp.Quantizers public sealed class PaletteQuantizer : Quantizer where TPixel : struct, IPixel { - /// - /// The pixel buffer, used to reduce allocations. - /// - private readonly byte[] pixelBuffer = new byte[4]; - /// /// A lookup table for colors /// @@ -48,14 +43,9 @@ namespace ImageSharp.Quantizers Rgba32[] constants = ColorConstants.WebSafeColors; TPixel[] safe = new TPixel[constants.Length + 1]; - for (int i = 0; i < constants.Length; i++) - { - 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; - } + Span constantsBytes = constants.AsSpan().NonPortableCast(); + PixelOperations.Instance.PackFromXyzwBytes(constantsBytes, safe, constants.Length); this.colors = safe; } else diff --git a/src/Shared/stylecop.json b/src/Shared/stylecop.json index df8f120a5..5a95b6c49 100644 --- a/src/Shared/stylecop.json +++ b/src/Shared/stylecop.json @@ -3,7 +3,13 @@ "settings": { "documentationRules": { "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 } } } \ No newline at end of file diff --git a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs index 501ae7949..807df50e8 100644 --- a/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs +++ b/tests/ImageSharp.Benchmarks/Color/Bulk/PackFromXyzw.cs @@ -40,7 +40,7 @@ namespace ImageSharp.Benchmarks.Color.Bulk { int i4 = i * 4; 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; } } diff --git a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj index 53cdffaea..ae17f3698 100644 --- a/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj +++ b/tests/ImageSharp.Sandbox46/ImageSharp.Sandbox46.csproj @@ -17,8 +17,8 @@ - + diff --git a/tests/ImageSharp.Sandbox46/Program.cs b/tests/ImageSharp.Sandbox46/Program.cs index b882de0cc..6f93df16e 100644 --- a/tests/ImageSharp.Sandbox46/Program.cs +++ b/tests/ImageSharp.Sandbox46/Program.cs @@ -10,6 +10,7 @@ namespace ImageSharp.Sandbox46 using ImageSharp.Tests; using ImageSharp.Tests.Colors; + using ImageSharp.Tests.PixelFormats; using ImageSharp.Tests.Processing.Transforms; using Xunit.Abstractions; diff --git a/tests/ImageSharp.Tests/Formats/Jpg/YCbCrImageTests.cs b/tests/ImageSharp.Tests/Formats/Jpg/YCbCrImageTests.cs index ba55665ca..f207dc1d1 100644 --- a/tests/ImageSharp.Tests/Formats/Jpg/YCbCrImageTests.cs +++ b/tests/ImageSharp.Tests/Formats/Jpg/YCbCrImageTests.cs @@ -31,7 +31,7 @@ namespace ImageSharp.Tests [InlineData(YCbCrImage.YCbCrSubsampleRatio.YCbCrSubsampleRatio422, 2, 1)] [InlineData(YCbCrImage.YCbCrSubsampleRatio.YCbCrSubsampleRatio440, 1, 2)] [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; @@ -49,7 +49,7 @@ namespace ImageSharp.Tests [InlineData(YCbCrImage.YCbCrSubsampleRatio.YCbCrSubsampleRatio422, 2)] [InlineData(YCbCrImage.YCbCrSubsampleRatio.YCbCrSubsampleRatio440, 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; diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj index afde531b4..9f3beb9e8 100644 --- a/tests/ImageSharp.Tests/ImageSharp.Tests.csproj +++ b/tests/ImageSharp.Tests/ImageSharp.Tests.csproj @@ -11,8 +11,8 @@ - + diff --git a/tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs b/tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs index 5ec7c21bb..dad426c40 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PackedPixelTests.cs @@ -302,7 +302,7 @@ namespace ImageSharp.Tests.Colors Assert.Equal(bgra, new byte[] { 0, 0, 128, 0 }); Byte4 r = new Byte4(); - r.PackFromBytes(20, 38, 0, 255); + r.PackFromRgba32(new Rgba32(20, 38, 0, 255)); r.ToXyzwBytes(rgba, 0); Assert.Equal(rgba, new byte[] { 20, 38, 0, 255 }); } @@ -448,7 +448,7 @@ namespace ImageSharp.Tests.Colors float y = -0.3f; Assert.Equal(0xda0d, new NormalizedByte2(x, y).PackedValue); NormalizedByte2 n = new NormalizedByte2(); - n.PackFromBytes(141, 90, 0, 0); + n.PackFromRgba32(new Rgba32(141, 90, 0, 0)); Assert.Equal(0xda0d, n.PackedValue); byte[] rgb = new byte[3]; @@ -491,7 +491,7 @@ namespace ImageSharp.Tests.Colors float w = -0.7f; Assert.Equal(0xA740DA0D, new NormalizedByte4(x, y, z, w).PackedValue); 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((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 NormalizedByte4 r = new NormalizedByte4(); - r.PackFromBytes(9, 115, 202, 127); + r.PackFromRgba32(new Rgba32(9, 115, 202, 127)); r.ToXyzwBytes(rgba, 0); Assert.Equal(rgba, new byte[] { 9, 115, 202, 127 }); @@ -554,7 +554,7 @@ namespace ImageSharp.Tests.Colors byte[] bgra = new byte[4]; NormalizedShort2 n = new NormalizedShort2(); - n.PackFromBytes(141, 90, 0, 0); + n.PackFromRgba32(new Rgba32(141, 90, 0, 0)); n.ToXyzBytes(rgb, 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 }); NormalizedShort4 r = new NormalizedShort4(); - r.PackFromBytes(9, 115, 202, 127); + r.PackFromRgba32(new Rgba32(9, 115, 202, 127)); r.ToXyzwBytes(rgba, 0); Assert.Equal(rgba, new byte[] { 9, 115, 202, 127 }); } @@ -708,7 +708,7 @@ namespace ImageSharp.Tests.Colors // Alpha component accuracy will be awful. Rgba1010102 r = new Rgba1010102(); - r.PackFromBytes(25, 0, 128, 0); + r.PackFromRgba32(new Rgba32(25, 0, 128, 0)); r.ToXyzwBytes(rgba, 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 }); Rgba64 r = new Rgba64(); - r.PackFromBytes(20, 38, 76, 115); + r.PackFromRgba32(new Rgba32(20, 38, 76, 115)); r.ToXyzwBytes(rgba, 0); 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 }); Short2 r = new Short2(); - r.PackFromBytes(20, 38, 0, 255); + r.PackFromRgba32(new Rgba32(20, 38, 0, 255)); r.ToXyzwBytes(rgba, 0); 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 }); Short4 r = new Short4(); - r.PackFromBytes(20, 38, 0, 255); + r.PackFromRgba32(new Rgba32(20, 38, 0, 255)); r.ToXyzwBytes(rgba, 0); Assert.Equal(rgba, new byte[] { 20, 38, 0, 255 }); } diff --git a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs index f387178e5..fa7d9d247 100644 --- a/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs +++ b/tests/ImageSharp.Tests/PixelFormats/PixelOperationsTests.cs @@ -156,7 +156,7 @@ namespace ImageSharp.Tests.PixelFormats { 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( @@ -197,7 +197,7 @@ namespace ImageSharp.Tests.PixelFormats { 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( @@ -238,7 +238,7 @@ namespace ImageSharp.Tests.PixelFormats { 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( @@ -279,7 +279,7 @@ namespace ImageSharp.Tests.PixelFormats { 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( diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/SolidProvider.cs b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/SolidProvider.cs index 65d55da55..0caded420 100644 --- a/tests/ImageSharp.Tests/TestUtilities/ImageProviders/SolidProvider.cs +++ b/tests/ImageSharp.Tests/TestUtilities/ImageProviders/SolidProvider.cs @@ -53,11 +53,11 @@ namespace ImageSharp.Tests { Image image = base.GetImage(); 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); } - + public override void Serialize(IXunitSerializationInfo info) { info.AddValue("red", this.r);