From cdb06fdd48e016e14040ad83367cb46d991df70e Mon Sep 17 00:00:00 2001 From: dirk Date: Sun, 30 Oct 2016 11:50:28 +0100 Subject: [PATCH] Added optimized implementation of PixelAccessor for Color. --- src/ImageSharp/Colors/ColorPixelAccessor.cs | 98 +++++++++++++++++++++ src/ImageSharp/Image.cs | 6 ++ src/ImageSharp/Image/ImageBase.cs | 2 +- 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 src/ImageSharp/Colors/ColorPixelAccessor.cs diff --git a/src/ImageSharp/Colors/ColorPixelAccessor.cs b/src/ImageSharp/Colors/ColorPixelAccessor.cs new file mode 100644 index 000000000..e7ed0819c --- /dev/null +++ b/src/ImageSharp/Colors/ColorPixelAccessor.cs @@ -0,0 +1,98 @@ +// +// Copyright (c) James Jackson-South and contributors. +// Licensed under the Apache License, Version 2.0. +// + +namespace ImageSharp +{ + using System; + using System.Runtime.CompilerServices; + + public unsafe sealed class ColorPixelAccessor : PixelAccessor + { + public ColorPixelAccessor(ImageBase image) + : base(image) + { + } + + protected override void CopyFromBGR(PixelRow row, int targetY, int width) + { + byte* source = row.DataPointer; + byte* destination = this.GetRowPointer(targetY); + + for (int x = 0; x < width; x++) + { + Unsafe.Write(destination, (uint)(*(source + 2) << 24 | *(source + 1) << 16 | *source << 8 | 255)); + + source += 3; + destination += 4; + } + } + + protected override void CopyFromBGRA(PixelRow row, int targetY, int width) + { + byte* source = row.DataPointer; + byte* destination = this.GetRowPointer(targetY); + + for (int x = 0; x < width; x++) + { + Unsafe.Write(destination, (uint)(*(source + 2) << 24 | *(source + 1) << 16 | *source << 8 | *(source + 3))); + + source += 4; + destination += 4; + } + } + + protected override void CopyToBGR(PixelRow row, int sourceY, int width) + { + byte* source = this.GetRowPointer(sourceY); + byte* destination = row.DataPointer; + + for (int x = 0; x < width; x++) + { + if (BitConverter.IsLittleEndian) + { + *destination = *(source + 1); + *(destination + 1) = *(source + 2); + *(destination + 2) = *(source + 3); + } + else + { + *destination = *(source + 3); + *(destination + 1) = *(source + 2); + *(destination + 2) = *(source + 1); + } + + source += 4; + destination += 3; + } + } + + protected override void CopyToBGRA(PixelRow row, int sourceY, int width) + { + byte* source = this.GetRowPointer(sourceY); + byte* destination = row.DataPointer; + + for (int x = 0; x < width; x++) + { + if (BitConverter.IsLittleEndian) + { + *destination = *(source + 1); + *(destination + 1) = *(source + 2); + *(destination + 2) = *(source + 3); + *(destination + 3) = *source; + } + else + { + *destination = *source; + *(destination + 1) = *(source + 3); + *(destination + 2) = *(source + 2); + *(destination + 3) = *(source + 1); + } + + source += 4; + destination += 4; + } + } + } +} diff --git a/src/ImageSharp/Image.cs b/src/ImageSharp/Image.cs index ff139cfab..28eb3ff99 100644 --- a/src/ImageSharp/Image.cs +++ b/src/ImageSharp/Image.cs @@ -56,5 +56,11 @@ namespace ImageSharp : base(other) { } + + /// + public override PixelAccessor Lock() + { + return new ColorPixelAccessor(this); + } } } diff --git a/src/ImageSharp/Image/ImageBase.cs b/src/ImageSharp/Image/ImageBase.cs index 0bc527519..7e9ca2701 100644 --- a/src/ImageSharp/Image/ImageBase.cs +++ b/src/ImageSharp/Image/ImageBase.cs @@ -146,7 +146,7 @@ namespace ImageSharp } /// - public PixelAccessor Lock() + public virtual PixelAccessor Lock() { return new PixelAccessor(this); }