diff --git a/src/ImageProcessorCore/Colors/ColorConstants.cs b/src/ImageProcessorCore/Colors/ColorConstants.cs
new file mode 100644
index 000000000..ed9718423
--- /dev/null
+++ b/src/ImageProcessorCore/Colors/ColorConstants.cs
@@ -0,0 +1,179 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageProcessorCore
+{
+ using System;
+ using System.Collections.Generic;
+
+ ///
+ /// Provides useful color definitions.
+ ///
+ public static class ColorConstants
+ {
+ ///
+ /// Provides a lazy, one time method of returning the colors.
+ ///
+ private static readonly Lazy SafeColors = new Lazy(GetWebSafeColors);
+
+ ///
+ /// Gets a collection of named, web safe, colors as defined in the CSS Color Module Level 4.
+ ///
+ public static Color[] WebSafeColors => SafeColors.Value;
+
+ ///
+ /// Returns an array of web safe colors.
+ ///
+ ///
+ private static Color[] GetWebSafeColors()
+ {
+ return new List
+ {
+ Color.AliceBlue,
+ Color.AntiqueWhite,
+ Color.Aqua,
+ Color.Aquamarine,
+ Color.Azure,
+ Color.Beige,
+ Color.Bisque,
+ Color.Black,
+ Color.BlanchedAlmond,
+ Color.Blue,
+ Color.BlueViolet,
+ Color.Brown,
+ Color.BurlyWood,
+ Color.CadetBlue,
+ Color.Chartreuse,
+ Color.Chocolate,
+ Color.Coral,
+ Color.CornflowerBlue,
+ Color.Cornsilk,
+ Color.Crimson,
+ Color.Cyan,
+ Color.DarkBlue,
+ Color.DarkCyan,
+ Color.DarkGoldenrod,
+ Color.DarkGray,
+ Color.DarkGreen,
+ Color.DarkKhaki,
+ Color.DarkMagenta,
+ Color.DarkOliveGreen,
+ Color.DarkOrange,
+ Color.DarkOrchid,
+ Color.DarkRed,
+ Color.DarkSalmon,
+ Color.DarkSeaGreen,
+ Color.DarkSlateBlue,
+ Color.DarkSlateGray,
+ Color.DarkTurquoise,
+ Color.DarkViolet,
+ Color.DeepPink,
+ Color.DeepSkyBlue,
+ Color.DimGray,
+ Color.DodgerBlue,
+ Color.Firebrick,
+ Color.FloralWhite,
+ Color.ForestGreen,
+ Color.Fuchsia,
+ Color.Gainsboro,
+ Color.GhostWhite,
+ Color.Gold,
+ Color.Goldenrod,
+ Color.Gray,
+ Color.Green,
+ Color.GreenYellow,
+ Color.Honeydew,
+ Color.HotPink,
+ Color.IndianRed,
+ Color.Indigo,
+ Color.Ivory,
+ Color.Khaki,
+ Color.Lavender,
+ Color.LavenderBlush,
+ Color.LawnGreen,
+ Color.LemonChiffon,
+ Color.LightBlue,
+ Color.LightCoral,
+ Color.LightCyan,
+ Color.LightGoldenrodYellow,
+ Color.LightGray,
+ Color.LightGreen,
+ Color.LightPink,
+ Color.LightSalmon,
+ Color.LightSeaGreen,
+ Color.LightSkyBlue,
+ Color.LightSlateGray,
+ Color.LightSteelBlue,
+ Color.LightYellow,
+ Color.Lime,
+ Color.LimeGreen,
+ Color.Linen,
+ Color.Magenta,
+ Color.Maroon,
+ Color.MediumAquamarine,
+ Color.MediumBlue,
+ Color.MediumOrchid,
+ Color.MediumPurple,
+ Color.MediumSeaGreen,
+ Color.MediumSlateBlue,
+ Color.MediumSpringGreen,
+ Color.MediumTurquoise,
+ Color.MediumVioletRed,
+ Color.MidnightBlue,
+ Color.MintCream,
+ Color.MistyRose,
+ Color.Moccasin,
+ Color.NavajoWhite,
+ Color.Navy,
+ Color.OldLace,
+ Color.Olive,
+ Color.OliveDrab,
+ Color.Orange,
+ Color.OrangeRed,
+ Color.Orchid,
+ Color.PaleGoldenrod,
+ Color.PaleGreen,
+ Color.PaleTurquoise,
+ Color.PaleVioletRed,
+ Color.PapayaWhip,
+ Color.PeachPuff,
+ Color.Peru,
+ Color.Pink,
+ Color.Plum,
+ Color.PowderBlue,
+ Color.Purple,
+ Color.RebeccaPurple,
+ Color.Red,
+ Color.RosyBrown,
+ Color.RoyalBlue,
+ Color.SaddleBrown,
+ Color.Salmon,
+ Color.SandyBrown,
+ Color.SeaGreen,
+ Color.SeaShell,
+ Color.Sienna,
+ Color.Silver,
+ Color.SkyBlue,
+ Color.SlateBlue,
+ Color.SlateGray,
+ Color.Snow,
+ Color.SpringGreen,
+ Color.SteelBlue,
+ Color.Tan,
+ Color.Teal,
+ Color.Thistle,
+ Color.Tomato,
+ Color.Transparent,
+ Color.Turquoise,
+ Color.Violet,
+ Color.Wheat,
+ Color.White,
+ Color.WhiteSmoke,
+ Color.Yellow,
+ Color.YellowGreen
+ }.ToArray();
+ }
+ }
+}
diff --git a/src/ImageProcessorCore/Formats/Bmp/BmpEncoder.cs b/src/ImageProcessorCore/Formats/Bmp/BmpEncoder.cs
index f5f80e689..1080daf0e 100644
--- a/src/ImageProcessorCore/Formats/Bmp/BmpEncoder.cs
+++ b/src/ImageProcessorCore/Formats/Bmp/BmpEncoder.cs
@@ -101,7 +101,6 @@ namespace ImageProcessorCore.Formats
amount = 4 - amount;
}
- // TODO: Make this parallel.
for (int y = image.Height - 1; y >= 0; y--)
{
for (int x = 0; x < image.Width; x++)
diff --git a/src/ImageProcessorCore/Formats/Gif/GifEncoder.cs b/src/ImageProcessorCore/Formats/Gif/GifEncoder.cs
index 995cab207..877931772 100644
--- a/src/ImageProcessorCore/Formats/Gif/GifEncoder.cs
+++ b/src/ImageProcessorCore/Formats/Gif/GifEncoder.cs
@@ -26,7 +26,7 @@ namespace ImageProcessorCore.Formats
///
/// The quantizer for reducing the color count.
///
- public IQuantizer Quantizer { get; set; } = new WuQuantizer();
+ public IQuantizer Quantizer { get; set; } = new OctreeQuantizer();
///
public string Extension => "gif";
@@ -130,12 +130,12 @@ namespace ImageProcessorCore.Formats
/// The
private QuantizedImage WriteColorTable(ImageBase image, Stream stream, int quality, int bitDepth)
{
- // Quantize the image returning a pallete.
+ // Quantize the image returning a palette.
QuantizedImage quantizedImage = this.Quantizer.Quantize(image, quality.Clamp(1, 255));
- // Grab the pallete and write it to the stream.
- Bgra32[] pallete = quantizedImage.Palette;
- int pixelCount = pallete.Length;
+ // Grab the palette and write it to the stream.
+ Bgra32[] palette = quantizedImage.Palette;
+ int pixelCount = palette.Length;
// Get max colors for bit depth.
int colorTableLength = (int)Math.Pow(2, bitDepth) * 3;
@@ -145,7 +145,7 @@ namespace ImageProcessorCore.Formats
i =>
{
int offset = i * 3;
- Bgra32 color = pallete[i];
+ Bgra32 color = palette[i];
colorTable[offset] = color.R;
colorTable[offset + 1] = color.G;
diff --git a/src/ImageProcessorCore/ImageExtensions.cs b/src/ImageProcessorCore/ImageExtensions.cs
index 50665b747..6a6d0e3f0 100644
--- a/src/ImageProcessorCore/ImageExtensions.cs
+++ b/src/ImageProcessorCore/ImageExtensions.cs
@@ -40,7 +40,7 @@ namespace ImageProcessorCore
/// The stream to save the image to.
/// The quality to save the image to. Between 1 and 100.
/// Thrown if the stream is null.
- public static void SaveAsJpeg(this ImageBase source, Stream stream, int quality = 80) => new JpegEncoder { Quality = quality }.Encode(source, stream);
+ public static void SaveAsJpeg(this ImageBase source, Stream stream, int quality = 75) => new JpegEncoder { Quality = quality }.Encode(source, stream);
///
/// Saves the image to the given stream with the gif format.
diff --git a/src/ImageProcessorCore/Quantizers/Octree/Quantizer.cs b/src/ImageProcessorCore/Quantizers/Octree/Quantizer.cs
index 2a330f782..5ee54d762 100644
--- a/src/ImageProcessorCore/Quantizers/Octree/Quantizer.cs
+++ b/src/ImageProcessorCore/Quantizers/Octree/Quantizer.cs
@@ -58,7 +58,7 @@ namespace ImageProcessorCore.Quantizers
byte[] quantizedPixels = new byte[width * height];
- // Get the pallete
+ // Get the palette
List palette = this.GetPalette();
this.SecondPass(image, quantizedPixels, width, height);
diff --git a/src/ImageProcessorCore/Quantizers/Palette/PaletteQuantizer.cs b/src/ImageProcessorCore/Quantizers/Palette/PaletteQuantizer.cs
new file mode 100644
index 000000000..74f192834
--- /dev/null
+++ b/src/ImageProcessorCore/Quantizers/Palette/PaletteQuantizer.cs
@@ -0,0 +1,126 @@
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageProcessorCore.Quantizers
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+
+ ///
+ /// Encapsulates methods to create a quantized image based upon the given palette.
+ ///
+ ///
+ public class PaletteQuantizer : Quantizer
+ {
+ ///
+ /// A lookup table for colors
+ ///
+ private readonly Dictionary colorMap = new Dictionary();
+
+ ///
+ /// List of all colors in the palette
+ ///
+ private Bgra32[] colors;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The color palette. If none is given this will default to the web safe colors defined
+ /// in the CSS Color Module Level 4.
+ ///
+ public PaletteQuantizer(Color[] palette = null)
+ : base(true)
+ {
+ this.colors = palette == null
+ ? ColorConstants.WebSafeColors.Select(c => (Bgra32)c).ToArray()
+ : palette.Select(c => (Bgra32)c).ToArray();
+ }
+
+ ///
+ public override QuantizedImage Quantize(ImageBase image, int maxColors)
+ {
+ Array.Resize(ref this.colors, maxColors.Clamp(1, 256));
+ return base.Quantize(image, maxColors);
+ }
+
+ ///
+ protected override byte QuantizePixel(Bgra32 pixel)
+ {
+ byte colorIndex = 0;
+ int colorHash = pixel.Bgra;
+
+ // Check if the color is in the lookup table
+ if (this.colorMap.ContainsKey(colorHash))
+ {
+ colorIndex = this.colorMap[colorHash];
+ }
+ else
+ {
+ // Not found - loop through the palette and find the nearest match.
+ // Firstly check the alpha value - if 0, lookup the transparent color
+ if (pixel.A == 0)
+ {
+ // Transparent. Lookup the first color with an alpha value of 0
+ for (int index = 0; index < this.colors.Length; index++)
+ {
+ if (this.colors[index].A == 0)
+ {
+ colorIndex = (byte)index;
+ this.TransparentIndex = colorIndex;
+ break;
+ }
+ }
+ }
+ else
+ {
+ // Not transparent...
+ int leastDistance = int.MaxValue;
+ int red = pixel.R;
+ int green = pixel.G;
+ int blue = pixel.B;
+
+ // Loop through the entire palette, looking for the closest color match
+ for (int index = 0; index < this.colors.Length; index++)
+ {
+ Bgra32 paletteColor = this.colors[index];
+
+ int redDistance = paletteColor.R - red;
+ int greenDistance = paletteColor.G - green;
+ int blueDistance = paletteColor.B - blue;
+
+ int distance = (redDistance * redDistance) +
+ (greenDistance * greenDistance) +
+ (blueDistance * blueDistance);
+
+ if (distance < leastDistance)
+ {
+ colorIndex = (byte)index;
+ leastDistance = distance;
+
+ // And if it's an exact match, exit the loop
+ if (distance == 0)
+ {
+ break;
+ }
+ }
+ }
+ }
+
+ // Now I have the color, pop it into the cache for next time
+ this.colorMap.Add(colorHash, colorIndex);
+ }
+
+ return colorIndex;
+ }
+
+ ///
+ protected override List GetPalette()
+ {
+ return this.colors.ToList();
+ }
+ }
+}
diff --git a/src/ImageProcessorCore/Quantizers/Wu/WuQuantizer.cs b/src/ImageProcessorCore/Quantizers/Wu/WuQuantizer.cs
index aa2a88048..660e5e5af 100644
--- a/src/ImageProcessorCore/Quantizers/Wu/WuQuantizer.cs
+++ b/src/ImageProcessorCore/Quantizers/Wu/WuQuantizer.cs
@@ -136,7 +136,7 @@ namespace ImageProcessorCore.Quantizers
/// The blue value.
/// The alpha value.
/// The index.
- private static int GetPalleteIndex(int r, int g, int b, int a)
+ private static int GetPaletteIndex(int r, int g, int b, int a)
{
return (r << ((IndexBits * 2) + IndexAlphaBits))
+ (r << (IndexBits + IndexAlphaBits + 1))
@@ -156,22 +156,22 @@ namespace ImageProcessorCore.Quantizers
/// The result.
private static double Volume(Box cube, long[] moment)
{
- return moment[GetPalleteIndex(cube.R1, cube.G1, cube.B1, cube.A1)]
- - moment[GetPalleteIndex(cube.R1, cube.G1, cube.B1, cube.A0)]
- - moment[GetPalleteIndex(cube.R1, cube.G1, cube.B0, cube.A1)]
- + moment[GetPalleteIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
- - moment[GetPalleteIndex(cube.R1, cube.G0, cube.B1, cube.A1)]
- + moment[GetPalleteIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
- + moment[GetPalleteIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
- - moment[GetPalleteIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
- - moment[GetPalleteIndex(cube.R0, cube.G1, cube.B1, cube.A1)]
- + moment[GetPalleteIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
- + moment[GetPalleteIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
- - moment[GetPalleteIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
- + moment[GetPalleteIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
- - moment[GetPalleteIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
- - moment[GetPalleteIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
- + moment[GetPalleteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
+ return moment[GetPaletteIndex(cube.R1, cube.G1, cube.B1, cube.A1)]
+ - moment[GetPaletteIndex(cube.R1, cube.G1, cube.B1, cube.A0)]
+ - moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A1)]
+ + moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
+ - moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A1)]
+ + moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
+ + moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
+ - moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
+ - moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A1)]
+ + moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
+ + moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
+ - moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
+ + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
+ - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
+ - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
+ + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
}
///
@@ -187,47 +187,47 @@ namespace ImageProcessorCore.Quantizers
{
// Red
case 0:
- return -moment[GetPalleteIndex(cube.R0, cube.G1, cube.B1, cube.A1)]
- + moment[GetPalleteIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
- + moment[GetPalleteIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
- - moment[GetPalleteIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
- + moment[GetPalleteIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
- - moment[GetPalleteIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
- - moment[GetPalleteIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
- + moment[GetPalleteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
+ return -moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A1)]
+ + moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
+ + moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
+ - moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
+ + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
+ - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
+ - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
+ + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
// Green
case 1:
- return -moment[GetPalleteIndex(cube.R1, cube.G0, cube.B1, cube.A1)]
- + moment[GetPalleteIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
- + moment[GetPalleteIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
- - moment[GetPalleteIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
- + moment[GetPalleteIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
- - moment[GetPalleteIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
- - moment[GetPalleteIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
- + moment[GetPalleteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
+ return -moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A1)]
+ + moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
+ + moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
+ - moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
+ + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
+ - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
+ - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
+ + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
// Blue
case 2:
- return -moment[GetPalleteIndex(cube.R1, cube.G1, cube.B0, cube.A1)]
- + moment[GetPalleteIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
- + moment[GetPalleteIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
- - moment[GetPalleteIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
- + moment[GetPalleteIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
- - moment[GetPalleteIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
- - moment[GetPalleteIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
- + moment[GetPalleteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
+ return -moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A1)]
+ + moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
+ + moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
+ - moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
+ + moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
+ - moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
+ - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
+ + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
// Alpha
case 3:
- return -moment[GetPalleteIndex(cube.R1, cube.G1, cube.B1, cube.A0)]
- + moment[GetPalleteIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
- + moment[GetPalleteIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
- - moment[GetPalleteIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
- + moment[GetPalleteIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
- - moment[GetPalleteIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
- - moment[GetPalleteIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
- + moment[GetPalleteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
+ return -moment[GetPaletteIndex(cube.R1, cube.G1, cube.B1, cube.A0)]
+ + moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
+ + moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
+ - moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
+ + moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
+ - moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
+ - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
+ + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
default:
throw new ArgumentOutOfRangeException(nameof(direction));
@@ -248,47 +248,47 @@ namespace ImageProcessorCore.Quantizers
{
// Red
case 0:
- return moment[GetPalleteIndex(position, cube.G1, cube.B1, cube.A1)]
- - moment[GetPalleteIndex(position, cube.G1, cube.B1, cube.A0)]
- - moment[GetPalleteIndex(position, cube.G1, cube.B0, cube.A1)]
- + moment[GetPalleteIndex(position, cube.G1, cube.B0, cube.A0)]
- - moment[GetPalleteIndex(position, cube.G0, cube.B1, cube.A1)]
- + moment[GetPalleteIndex(position, cube.G0, cube.B1, cube.A0)]
- + moment[GetPalleteIndex(position, cube.G0, cube.B0, cube.A1)]
- - moment[GetPalleteIndex(position, cube.G0, cube.B0, cube.A0)];
+ return moment[GetPaletteIndex(position, cube.G1, cube.B1, cube.A1)]
+ - moment[GetPaletteIndex(position, cube.G1, cube.B1, cube.A0)]
+ - moment[GetPaletteIndex(position, cube.G1, cube.B0, cube.A1)]
+ + moment[GetPaletteIndex(position, cube.G1, cube.B0, cube.A0)]
+ - moment[GetPaletteIndex(position, cube.G0, cube.B1, cube.A1)]
+ + moment[GetPaletteIndex(position, cube.G0, cube.B1, cube.A0)]
+ + moment[GetPaletteIndex(position, cube.G0, cube.B0, cube.A1)]
+ - moment[GetPaletteIndex(position, cube.G0, cube.B0, cube.A0)];
// Green
case 1:
- return moment[GetPalleteIndex(cube.R1, position, cube.B1, cube.A1)]
- - moment[GetPalleteIndex(cube.R1, position, cube.B1, cube.A0)]
- - moment[GetPalleteIndex(cube.R1, position, cube.B0, cube.A1)]
- + moment[GetPalleteIndex(cube.R1, position, cube.B0, cube.A0)]
- - moment[GetPalleteIndex(cube.R0, position, cube.B1, cube.A1)]
- + moment[GetPalleteIndex(cube.R0, position, cube.B1, cube.A0)]
- + moment[GetPalleteIndex(cube.R0, position, cube.B0, cube.A1)]
- - moment[GetPalleteIndex(cube.R0, position, cube.B0, cube.A0)];
+ return moment[GetPaletteIndex(cube.R1, position, cube.B1, cube.A1)]
+ - moment[GetPaletteIndex(cube.R1, position, cube.B1, cube.A0)]
+ - moment[GetPaletteIndex(cube.R1, position, cube.B0, cube.A1)]
+ + moment[GetPaletteIndex(cube.R1, position, cube.B0, cube.A0)]
+ - moment[GetPaletteIndex(cube.R0, position, cube.B1, cube.A1)]
+ + moment[GetPaletteIndex(cube.R0, position, cube.B1, cube.A0)]
+ + moment[GetPaletteIndex(cube.R0, position, cube.B0, cube.A1)]
+ - moment[GetPaletteIndex(cube.R0, position, cube.B0, cube.A0)];
// Blue
case 2:
- return moment[GetPalleteIndex(cube.R1, cube.G1, position, cube.A1)]
- - moment[GetPalleteIndex(cube.R1, cube.G1, position, cube.A0)]
- - moment[GetPalleteIndex(cube.R1, cube.G0, position, cube.A1)]
- + moment[GetPalleteIndex(cube.R1, cube.G0, position, cube.A0)]
- - moment[GetPalleteIndex(cube.R0, cube.G1, position, cube.A1)]
- + moment[GetPalleteIndex(cube.R0, cube.G1, position, cube.A0)]
- + moment[GetPalleteIndex(cube.R0, cube.G0, position, cube.A1)]
- - moment[GetPalleteIndex(cube.R0, cube.G0, position, cube.A0)];
+ return moment[GetPaletteIndex(cube.R1, cube.G1, position, cube.A1)]
+ - moment[GetPaletteIndex(cube.R1, cube.G1, position, cube.A0)]
+ - moment[GetPaletteIndex(cube.R1, cube.G0, position, cube.A1)]
+ + moment[GetPaletteIndex(cube.R1, cube.G0, position, cube.A0)]
+ - moment[GetPaletteIndex(cube.R0, cube.G1, position, cube.A1)]
+ + moment[GetPaletteIndex(cube.R0, cube.G1, position, cube.A0)]
+ + moment[GetPaletteIndex(cube.R0, cube.G0, position, cube.A1)]
+ - moment[GetPaletteIndex(cube.R0, cube.G0, position, cube.A0)];
// Alpha
case 3:
- return moment[GetPalleteIndex(cube.R1, cube.G1, cube.B1, position)]
- - moment[GetPalleteIndex(cube.R1, cube.G1, cube.B0, position)]
- - moment[GetPalleteIndex(cube.R1, cube.G0, cube.B1, position)]
- + moment[GetPalleteIndex(cube.R1, cube.G0, cube.B0, position)]
- - moment[GetPalleteIndex(cube.R0, cube.G1, cube.B1, position)]
- + moment[GetPalleteIndex(cube.R0, cube.G1, cube.B0, position)]
- + moment[GetPalleteIndex(cube.R0, cube.G0, cube.B1, position)]
- - moment[GetPalleteIndex(cube.R0, cube.G0, cube.B0, position)];
+ return moment[GetPaletteIndex(cube.R1, cube.G1, cube.B1, position)]
+ - moment[GetPaletteIndex(cube.R1, cube.G1, cube.B0, position)]
+ - moment[GetPaletteIndex(cube.R1, cube.G0, cube.B1, position)]
+ + moment[GetPaletteIndex(cube.R1, cube.G0, cube.B0, position)]
+ - moment[GetPaletteIndex(cube.R0, cube.G1, cube.B1, position)]
+ + moment[GetPaletteIndex(cube.R0, cube.G1, cube.B0, position)]
+ + moment[GetPaletteIndex(cube.R0, cube.G0, cube.B1, position)]
+ - moment[GetPaletteIndex(cube.R0, cube.G0, cube.B0, position)];
default:
throw new ArgumentOutOfRangeException(nameof(direction));
@@ -332,7 +332,7 @@ namespace ImageProcessorCore.Quantizers
int inb = b >> (8 - IndexBits);
int ina = a >> (8 - IndexAlphaBits);
- int ind = GetPalleteIndex(inr + 1, ing + 1, inb + 1, ina + 1);
+ int ind = GetPaletteIndex(inr + 1, ing + 1, inb + 1, ina + 1);
this.vwt[ind]++;
this.vmr[ind] += r;
@@ -393,7 +393,7 @@ namespace ImageProcessorCore.Quantizers
for (int a = 1; a < IndexAlphaCount; a++)
{
- int ind1 = GetPalleteIndex(r, g, b, a);
+ int ind1 = GetPaletteIndex(r, g, b, a);
line += this.vwt[ind1];
lineR += this.vmr[ind1];
@@ -418,7 +418,7 @@ namespace ImageProcessorCore.Quantizers
volumeA[inv] += areaA[a];
volume2[inv] += area2[a];
- int ind2 = ind1 - GetPalleteIndex(1, 0, 0, 0);
+ int ind2 = ind1 - GetPaletteIndex(1, 0, 0, 0);
this.vwt[ind1] = this.vwt[ind2] + volume[inv];
this.vmr[ind1] = this.vmr[ind2] + volumeR[inv];
@@ -445,22 +445,22 @@ namespace ImageProcessorCore.Quantizers
double da = Volume(cube, this.vma);
double xx =
- this.m2[GetPalleteIndex(cube.R1, cube.G1, cube.B1, cube.A1)]
- - this.m2[GetPalleteIndex(cube.R1, cube.G1, cube.B1, cube.A0)]
- - this.m2[GetPalleteIndex(cube.R1, cube.G1, cube.B0, cube.A1)]
- + this.m2[GetPalleteIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
- - this.m2[GetPalleteIndex(cube.R1, cube.G0, cube.B1, cube.A1)]
- + this.m2[GetPalleteIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
- + this.m2[GetPalleteIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
- - this.m2[GetPalleteIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
- - this.m2[GetPalleteIndex(cube.R0, cube.G1, cube.B1, cube.A1)]
- + this.m2[GetPalleteIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
- + this.m2[GetPalleteIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
- - this.m2[GetPalleteIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
- + this.m2[GetPalleteIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
- - this.m2[GetPalleteIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
- - this.m2[GetPalleteIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
- + this.m2[GetPalleteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
+ this.m2[GetPaletteIndex(cube.R1, cube.G1, cube.B1, cube.A1)]
+ - this.m2[GetPaletteIndex(cube.R1, cube.G1, cube.B1, cube.A0)]
+ - this.m2[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A1)]
+ + this.m2[GetPaletteIndex(cube.R1, cube.G1, cube.B0, cube.A0)]
+ - this.m2[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A1)]
+ + this.m2[GetPaletteIndex(cube.R1, cube.G0, cube.B1, cube.A0)]
+ + this.m2[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A1)]
+ - this.m2[GetPaletteIndex(cube.R1, cube.G0, cube.B0, cube.A0)]
+ - this.m2[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A1)]
+ + this.m2[GetPaletteIndex(cube.R0, cube.G1, cube.B1, cube.A0)]
+ + this.m2[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A1)]
+ - this.m2[GetPaletteIndex(cube.R0, cube.G1, cube.B0, cube.A0)]
+ + this.m2[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A1)]
+ - this.m2[GetPaletteIndex(cube.R0, cube.G0, cube.B1, cube.A0)]
+ - this.m2[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A1)]
+ + this.m2[GetPaletteIndex(cube.R0, cube.G0, cube.B0, cube.A0)];
return xx - (((dr * dr) + (dg * dg) + (db * db) + (da * da)) / Volume(cube, this.vwt));
}
@@ -643,7 +643,7 @@ namespace ImageProcessorCore.Quantizers
{
for (int a = cube.A0 + 1; a <= cube.A1; a++)
{
- this.tag[GetPalleteIndex(r, g, b, a)] = label;
+ this.tag[GetPaletteIndex(r, g, b, a)] = label;
}
}
}
@@ -758,7 +758,7 @@ namespace ImageProcessorCore.Quantizers
int g = color.G >> (8 - IndexBits);
int b = color.B >> (8 - IndexBits);
- int ind = GetPalleteIndex(r + 1, g + 1, b + 1, a + 1);
+ int ind = GetPaletteIndex(r + 1, g + 1, b + 1, a + 1);
pixels[i++] = this.tag[ind];
}
}