From ee8987857d4bfffeedd5b903730ef6dfd1a7fcb1 Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Fri, 15 Jul 2016 20:05:27 +1000 Subject: [PATCH] Now Color Former-commit-id: df0c84ebe32444c8e2bf964f839af8fd6b80d196 Former-commit-id: af528ad7c73c8c20f1f1fb5f0e4864bc00dfc4ee Former-commit-id: e62c836d6621e86a03386c83867d4dbcb668dc5e --- src/ImageProcessorCore/Bootstrapper.cs | 2 +- .../Formats/Bmp/BmpDecoderCore.cs | 27 ++++++----- .../Formats/Bmp/BmpEncoderCore.cs | 36 ++++++++------- src/ImageProcessorCore/Image.cs | 4 +- .../PackedVector/{Bgra32.cs => Color.cs} | 45 ++++++++++--------- .../PackedVector/IPackedVector.cs | 1 + ...PixelAccessor.cs => ColorPixelAccessor.cs} | 20 ++++----- .../Image/GetSetPixel.cs | 12 ++--- 8 files changed, 78 insertions(+), 69 deletions(-) rename src/ImageProcessorCore/PackedVector/{Bgra32.cs => Color.cs} (80%) rename src/ImageProcessorCore/PixelAccessor/{Bgra32PixelAccessor.cs => ColorPixelAccessor.cs} (87%) diff --git a/src/ImageProcessorCore/Bootstrapper.cs b/src/ImageProcessorCore/Bootstrapper.cs index a611119921..39e97e1100 100644 --- a/src/ImageProcessorCore/Bootstrapper.cs +++ b/src/ImageProcessorCore/Bootstrapper.cs @@ -44,7 +44,7 @@ namespace ImageProcessorCore this.pixelAccessors = new Dictionary> { - { typeof(Bgra32), i=> new Bgra32PixelAccessor(i) } + { typeof(Color), i=> new ColorPixelAccessor(i) } }; } diff --git a/src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs b/src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs index ee52c4ebfc..c964dec48a 100644 --- a/src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs @@ -49,7 +49,8 @@ namespace ImageProcessorCore.Formats /// Decodes the image from the specified this._stream and sets /// the data to image. /// - /// The type of pixels contained within the image. + /// The pixel format. + /// The packed format. long, float. /// The image, where the data should be set to. /// Cannot be null (Nothing in Visual Basic). /// The this._stream, where the image should be @@ -187,7 +188,8 @@ namespace ImageProcessorCore.Formats /// /// Reads the color palette from the stream. /// - /// The type of pixels contained within the image. + /// The pixel format. + /// The packed format. long, float. /// The image data to assign the palette to. /// The containing the colors. /// The width of the bitmap. @@ -238,9 +240,9 @@ namespace ImageProcessorCore.Formats int colorIndex = ((data[offset] >> (8 - bits - (shift * bits))) & mask) * 4; int arrayOffset = (row * width) + (colOffset + shift); - // Stored in b-> g-> r-> a order. + // Stored in b-> g-> r order. T packed = default(T); - packed.PackBytes(colors[colorIndex], colors[colorIndex + 1], colors[colorIndex + 2], 255); + packed.PackBytes(colors[colorIndex + 2], colors[colorIndex + 1], colors[colorIndex], 255); imageData[arrayOffset] = packed; } } @@ -250,7 +252,8 @@ namespace ImageProcessorCore.Formats /// /// Reads the 16 bit color palette from the stream /// - /// The type of pixels contained within the image. + /// The pixel format. + /// The packed format. long, float. /// The image data to assign the palette to. /// The width of the bitmap. /// The height of the bitmap. @@ -288,9 +291,9 @@ namespace ImageProcessorCore.Formats int arrayOffset = ((row * width) + x); - // Stored in b-> g-> r-> a order. + // Stored in b-> g-> r order. T packed = default(T); - packed.PackBytes(b, g, r, 255); + packed.PackBytes(r, g, b, 255); imageData[arrayOffset] = packed; } }); @@ -299,7 +302,8 @@ namespace ImageProcessorCore.Formats /// /// Reads the 24 bit color palette from the stream /// - /// The type of pixels contained within the image. + /// The pixel format. + /// The packed format. long, float. /// The image data to assign the palette to. /// The width of the bitmap. /// The height of the bitmap. @@ -329,7 +333,7 @@ namespace ImageProcessorCore.Formats // We divide by 255 as we will store the colors in our floating point format. // Stored in b-> g-> r-> a order. T packed = default(T); - packed.PackBytes(data[offset], data[offset + 1], data[offset + 2], 255); + packed.PackBytes(data[offset + 2], data[offset + 1], data[offset], 255); imageData[arrayOffset] = packed; } }); @@ -338,7 +342,8 @@ namespace ImageProcessorCore.Formats /// /// Reads the 32 bit color palette from the stream /// - /// The type of pixels contained within the image. + /// The pixel format. + /// The packed format. long, float. /// The image data to assign the palette to. /// The width of the bitmap. /// The height of the bitmap. @@ -367,7 +372,7 @@ namespace ImageProcessorCore.Formats // Stored in b-> g-> r-> a order. T packed = default(T); - packed.PackBytes(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]); + packed.PackBytes(data[offset + 2], data[offset + 1], data[offset], data[offset + 3]); imageData[arrayOffset] = packed; } }); diff --git a/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs b/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs index cc26ea700c..497afc70c4 100644 --- a/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs +++ b/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs @@ -13,7 +13,6 @@ namespace ImageProcessorCore.Formats /// /// Image encoder for writing an image to a stream as a Windows bitmap. /// - /// The encoder can currently only write 24-bit rgb images to streams. internal sealed class BmpEncoderCore { /// @@ -22,13 +21,14 @@ namespace ImageProcessorCore.Formats private BmpBitsPerPixel bmpBitsPerPixel; /// - /// Encodes the image to the specified stream from the . + /// Encodes the image to the specified stream from the . /// - /// The type of pixels contained within the image. - /// The to encode from. + /// The pixel format. + /// The packed format. long, float. + /// The to encode from. /// The to encode the image data to. /// The - public void Encode(ImageBase image, Stream stream, BmpBitsPerPixel bitsPerPixel) + public void Encode(ImageBase image, Stream stream, BmpBitsPerPixel bitsPerPixel) where T : IPackedVector, new() where TP : struct { @@ -121,14 +121,14 @@ namespace ImageProcessorCore.Formats /// /// Writes the pixel data to the binary stream. /// - /// The type of pixels contained within the image. - /// + /// The pixel format. + /// The packed format. long, float./// /// The containing the stream to write to. /// /// - /// The containing pixel data. + /// The containing pixel data. /// - private void WriteImage(EndianBinaryWriter writer, ImageBase image) + private void WriteImage(EndianBinaryWriter writer, ImageBase image) where T : IPackedVector, new() where TP : struct { @@ -139,7 +139,7 @@ namespace ImageProcessorCore.Formats amount = 4 - amount; } - using (IPixelAccessor pixels = image.Lock()) + using (IPixelAccessor pixels = image.Lock()) { switch (this.bmpBitsPerPixel) { @@ -157,11 +157,12 @@ namespace ImageProcessorCore.Formats /// /// Writes the 32bit color palette to the stream. /// - /// The type of pixels contained within the image. + /// The pixel format. + /// The packed format. long, float. /// The containing the stream to write to. /// The containing pixel data. /// The amount to pad each row by. - private void Write32bit(EndianBinaryWriter writer, IPixelAccessor pixels, int amount) + private void Write32bit(EndianBinaryWriter writer, IPixelAccessor pixels, int amount) where T : IPackedVector, new() where TP : struct { @@ -171,7 +172,7 @@ namespace ImageProcessorCore.Formats { // Convert back to b-> g-> r-> a order. byte[] bytes = pixels[x, y].ToBytes(); - writer.Write(bytes); + writer.Write(new[] { bytes[2], bytes[1], bytes[0], bytes[3] }); } // Pad @@ -185,10 +186,11 @@ namespace ImageProcessorCore.Formats /// /// Writes the 24bit color palette to the stream. /// - /// The containing the stream to write to. + /// The pixel format. + /// The packed format. long, float./// The containing the stream to write to. /// The containing pixel data. /// The amount to pad each row by. - private void Write24bit(EndianBinaryWriter writer, IPixelAccessor pixels, int amount) + private void Write24bit(EndianBinaryWriter writer, IPixelAccessor pixels, int amount) where T : IPackedVector, new() where TP : struct { @@ -196,9 +198,9 @@ namespace ImageProcessorCore.Formats { for (int x = 0; x < pixels.Width; x++) { - // Convert back to b-> g-> r-> a order. + // Convert back to b-> g-> r order. byte[] bytes = pixels[x, y].ToBytes(); - writer.Write(new[] { bytes[0], bytes[1], bytes[2] }); + writer.Write(new[] { bytes[2], bytes[1], bytes[0] }); } // Pad diff --git a/src/ImageProcessorCore/Image.cs b/src/ImageProcessorCore/Image.cs index 22c171f17b..e57129d29e 100644 --- a/src/ImageProcessorCore/Image.cs +++ b/src/ImageProcessorCore/Image.cs @@ -9,9 +9,9 @@ namespace ImageProcessorCore using System.IO; /// - /// Represents an image. Each pixel is a made up four 8-bit components blue, green, red, and alpha. + /// Represents an image. Each pixel is a made up four 8-bit components red, green, blue, and alpha. /// - public class Image : Image + public class Image : Image { /// /// Initializes a new instance of the class diff --git a/src/ImageProcessorCore/PackedVector/Bgra32.cs b/src/ImageProcessorCore/PackedVector/Color.cs similarity index 80% rename from src/ImageProcessorCore/PackedVector/Bgra32.cs rename to src/ImageProcessorCore/PackedVector/Color.cs index 73ff87d9fe..5f1ace7b0c 100644 --- a/src/ImageProcessorCore/PackedVector/Bgra32.cs +++ b/src/ImageProcessorCore/PackedVector/Color.cs @@ -1,7 +1,8 @@ -// +// // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // + namespace ImageProcessorCore { using System; @@ -13,13 +14,13 @@ namespace ImageProcessorCore /// Packed vector type containing four 8-bit unsigned normalized values ranging from 0 to 255. /// [StructLayout(LayoutKind.Explicit)] - public struct Bgra32 : IPackedVector, IEquatable + public struct Color : IPackedVector, IEquatable { /// /// Gets or sets the blue component. /// [FieldOffset(0)] - public byte B; + public byte R; /// /// Gets or sets the green component. @@ -31,7 +32,7 @@ namespace ImageProcessorCore /// Gets or sets the red component. /// [FieldOffset(2)] - public byte R; + public byte B; /// /// Gets or sets the alpha component. @@ -46,13 +47,13 @@ namespace ImageProcessorCore private readonly uint packedValue; /// - /// Initializes a new instance of the struct. + /// Initializes a new instance of the struct. /// /// The blue component. /// The green component. /// The red component. /// The alpha component. - public Bgra32(float b, float g, float r, float a) + public Color(float b, float g, float r, float a) : this() { Vector4 clamped = Vector4.Clamp(new Vector4(b, g, r, a), Vector4.Zero, Vector4.One) * 255f; @@ -63,13 +64,13 @@ namespace ImageProcessorCore } /// - /// Initializes a new instance of the struct. + /// Initializes a new instance of the struct. /// /// The blue component. /// The green component. /// The red component. /// The alpha component. - public Bgra32(byte b, byte g, byte r, byte a) + public Color(byte b, byte g, byte r, byte a) : this() { this.B = b; @@ -79,12 +80,12 @@ namespace ImageProcessorCore } /// - /// Initializes a new instance of the struct. + /// Initializes a new instance of the struct. /// /// /// The vector containing the components for the packed vector. /// - public Bgra32(Vector4 vector) + public Color(Vector4 vector) : this() { Vector4 clamped = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * 255f; @@ -95,31 +96,31 @@ namespace ImageProcessorCore } /// - /// Compares two objects for equality. + /// Compares two objects for equality. /// /// - /// The on the left side of the operand. + /// The on the left side of the operand. /// /// - /// The on the right side of the operand. + /// The on the right side of the operand. /// /// /// True if the current left is equal to the parameter; otherwise, false. /// - public static bool operator ==(Bgra32 left, Bgra32 right) + public static bool operator ==(Color left, Color right) { return left.packedValue == right.packedValue; } /// - /// Compares two objects for equality. + /// Compares two objects for equality. /// - /// The on the left side of the operand. - /// The on the right side of the operand. + /// The on the left side of the operand. + /// The on the right side of the operand. /// /// True if the current left is equal to the parameter; otherwise, false. /// - public static bool operator !=(Bgra32 left, Bgra32 right) + public static bool operator !=(Color left, Color right) { return left.packedValue != right.packedValue; } @@ -164,11 +165,11 @@ namespace ImageProcessorCore /// public override bool Equals(object obj) { - return (obj is Bgra32) && this.Equals((Bgra32)obj); + return (obj is Color) && this.Equals((Color)obj); } /// - public bool Equals(Bgra32 other) + public bool Equals(Color other) { return this.packedValue == other.packedValue; } @@ -192,13 +193,13 @@ namespace ImageProcessorCore /// Returns the hash code for this instance. /// /// - /// The instance of to return the hash code for. + /// The instance of to return the hash code for. /// /// /// A 32-bit signed integer that is the hash code for this instance. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - private int GetHashCode(Bgra32 packed) + private int GetHashCode(Color packed) { return packed.packedValue.GetHashCode(); } diff --git a/src/ImageProcessorCore/PackedVector/IPackedVector.cs b/src/ImageProcessorCore/PackedVector/IPackedVector.cs index a32870b2e0..99cd70d748 100644 --- a/src/ImageProcessorCore/PackedVector/IPackedVector.cs +++ b/src/ImageProcessorCore/PackedVector/IPackedVector.cs @@ -55,6 +55,7 @@ namespace ImageProcessorCore /// /// Expands the packed representation into a . /// The bytes are typically expanded in least to greatest significance order. + /// Red -> Green -> Blue -> Alpha /// /// The . byte[] ToBytes(); diff --git a/src/ImageProcessorCore/PixelAccessor/Bgra32PixelAccessor.cs b/src/ImageProcessorCore/PixelAccessor/ColorPixelAccessor.cs similarity index 87% rename from src/ImageProcessorCore/PixelAccessor/Bgra32PixelAccessor.cs rename to src/ImageProcessorCore/PixelAccessor/ColorPixelAccessor.cs index c48090d7b2..6d0812a2a4 100644 --- a/src/ImageProcessorCore/PixelAccessor/Bgra32PixelAccessor.cs +++ b/src/ImageProcessorCore/PixelAccessor/ColorPixelAccessor.cs @@ -12,15 +12,15 @@ namespace ImageProcessorCore /// Provides per-pixel access to an images pixels. /// /// - /// The image data is always stored in format, where the blue, green, red, and + /// The image data is always stored in format, where the red, green, blue, and /// alpha values are 8 bit unsigned bytes. /// - public sealed unsafe class Bgra32PixelAccessor : IPixelAccessor + public sealed unsafe class ColorPixelAccessor : IPixelAccessor { /// /// The position of the first pixel in the bitmap. /// - private Bgra32* pixelsBase; + private Color* pixelsBase; /// /// Provides a way to access the pixels from unmanaged memory. @@ -41,12 +41,12 @@ namespace ImageProcessorCore private bool isDisposed; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The image to provide pixel access for. /// - public Bgra32PixelAccessor(IImageBase image) + public ColorPixelAccessor(IImageBase image) { Guard.NotNull(image, nameof(image)); Guard.MustBeGreaterThan(image.Width, 0, "image width"); @@ -55,14 +55,14 @@ namespace ImageProcessorCore this.Width = image.Width; this.Height = image.Height; - this.pixelsHandle = GCHandle.Alloc(((ImageBase)image).Pixels, GCHandleType.Pinned); - this.pixelsBase = (Bgra32*)this.pixelsHandle.AddrOfPinnedObject().ToPointer(); + this.pixelsHandle = GCHandle.Alloc(((ImageBase)image).Pixels, GCHandleType.Pinned); + this.pixelsBase = (Color*)this.pixelsHandle.AddrOfPinnedObject().ToPointer(); } /// - /// Finalizes an instance of the class. + /// Finalizes an instance of the class. /// - ~Bgra32PixelAccessor() + ~ColorPixelAccessor() { this.Dispose(); } @@ -89,7 +89,7 @@ namespace ImageProcessorCore /// than zero and smaller than the width of the pixel. /// /// The at the specified position. - public Bgra32 this[int x, int y] + public Color this[int x, int y] { get { diff --git a/tests/ImageProcessorCore.Benchmarks/Image/GetSetPixel.cs b/tests/ImageProcessorCore.Benchmarks/Image/GetSetPixel.cs index 238a5ccad4..0af79c78ed 100644 --- a/tests/ImageProcessorCore.Benchmarks/Image/GetSetPixel.cs +++ b/tests/ImageProcessorCore.Benchmarks/Image/GetSetPixel.cs @@ -4,8 +4,8 @@ using BenchmarkDotNet.Attributes; - //using CoreColor = ImageProcessorCore.Color; - //using CoreImage = ImageProcessorCore.Image; + using CoreColor = ImageProcessorCore.Color; + using CoreImage = ImageProcessorCore.Image; using SystemColor = System.Drawing.Color; public class GetSetPixel @@ -21,12 +21,12 @@ } [Benchmark(Description = "ImageProcessorCore GetSet Pixel")] - public Bgra32 ResizeCore() + public CoreColor ResizeCore() { - Image image = new Image(400, 400); - using (IPixelAccessor imagePixels = image.Lock()) + CoreImage image = new CoreImage(400, 400); + using (IPixelAccessor imagePixels = image.Lock()) { - imagePixels[200, 200] = new Bgra32(1, 1, 1, 1); + imagePixels[200, 200] = new CoreColor(255, 255, 255, 255); return imagePixels[200, 200]; } }