Browse Source

Use single cache base.

af/merge-core
James Jackson-South 8 years ago
parent
commit
350c4e7ed9
  1. 2
      src/ImageSharp/Formats/Gif/LzwEncoder.cs
  2. 1
      src/ImageSharp/Processing/Dithering/Processors/PaletteDitherProcessorBase.cs
  3. 28
      src/ImageSharp/Processing/Quantization/FrameQuantizers/FrameQuantizerBase{TPixel}.cs
  4. 34
      src/ImageSharp/Processing/Quantization/FrameQuantizers/OctreeFrameQuantizer{TPixel}.cs
  5. 9
      src/ImageSharp/Processing/Quantization/FrameQuantizers/PaletteFrameQuantizer{TPixel}.cs
  6. 8
      src/ImageSharp/Processing/Quantization/FrameQuantizers/WuFrameQuantizer{TPixel}.cs

2
src/ImageSharp/Formats/Gif/LzwEncoder.cs

@ -374,7 +374,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private int NextPixel(Span<byte> indexedPixels)
{
return indexedPixels[this.position++] & 0xff;
return indexedPixels[this.position++] & 0xFF;
}
/// <summary>

1
src/ImageSharp/Processing/Dithering/Processors/PaletteDitherProcessorBase.cs

@ -12,6 +12,7 @@ namespace SixLabors.ImageSharp.Processing.Dithering.Processors
/// <summary>
/// The base class for dither and diffusion processors that consume a palette.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
internal abstract class PaletteDitherProcessorBase<TPixel> : ImageProcessor<TPixel>
where TPixel : struct, IPixel<TPixel>
{

28
src/ImageSharp/Processing/Quantization/FrameQuantizers/FrameQuantizerBase{TPixel}.cs

@ -17,6 +17,11 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
public abstract class FrameQuantizerBase<TPixel> : IFrameQuantizer<TPixel>
where TPixel : struct, IPixel<TPixel>
{
/// <summary>
/// A lookup table for colors
/// </summary>
private readonly Dictionary<TPixel, byte> distanceCache = new Dictionary<TPixel, byte>();
/// <summary>
/// Flag used to indicate whether a single pass or two passes are needed for quantization.
/// </summary>
@ -119,21 +124,21 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
/// </summary>
/// <param name="pixel">The color.</param>
/// <param name="colorPalette">The color palette.</param>
/// <param name="cache">The cache to store the result in.</param>
/// <returns>The <see cref="byte"/></returns>
/// <returns>The <see cref="int"/></returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected byte GetClosestPixel(TPixel pixel, TPixel[] colorPalette, Dictionary<TPixel, byte> cache)
protected byte GetClosestPixel(TPixel pixel, TPixel[] colorPalette)
{
// Check if the color is in the lookup table
// if (cache.TryGetValue(pixel, out byte value))
// {
// return value;
// }
return this.GetClosestPixelSlow(pixel, colorPalette, cache);
if (this.distanceCache.TryGetValue(pixel, out byte value))
{
return value;
}
return this.GetClosestPixelSlow(pixel, colorPalette);
}
[MethodImpl(MethodImplOptions.NoInlining)]
private byte GetClosestPixelSlow(TPixel pixel, TPixel[] colorPalette, Dictionary<TPixel, byte> cache)
private byte GetClosestPixelSlow(TPixel pixel, TPixel[] colorPalette)
{
// Loop through the palette and find the nearest match.
int colorIndex = 0;
@ -159,8 +164,9 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
}
// Now I have the index, pop it into the cache for next time
// cache.Add(pixel, colorIndex);
return (byte)colorIndex;
byte result = (byte)colorIndex;
this.distanceCache.Add(pixel, result);
return result;
}
}
}

34
src/ImageSharp/Processing/Quantization/FrameQuantizers/OctreeFrameQuantizer{TPixel}.cs

@ -29,11 +29,6 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
/// </summary>
private readonly Octree octree;
/// <summary>
/// A lookup table for colors
/// </summary>
private Dictionary<TPixel, byte> colorMap = new Dictionary<TPixel, byte>();
/// <summary>
/// The reduced image palette
/// </summary>
@ -182,7 +177,7 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
{
// The colors have changed so we need to use Euclidean distance calculation to find the closest value.
// This palette can never be null here.
return this.GetClosestPixel(pixel, this.palette, this.colorMap);
return this.GetClosestPixel(pixel, this.palette);
}
pixel.ToRgba32(ref rgba);
@ -258,12 +253,23 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
/// <summary>
/// Gets or sets the number of leaves in the tree
/// </summary>
public int Leaves { get; set; }
public int Leaves
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
set;
}
/// <summary>
/// Gets the array of reducible nodes
/// </summary>
private OctreeNode[] ReducibleNodes { get; }
private OctreeNode[] ReducibleNodes
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get;
}
/// <summary>
/// Add a given color value to the Octree
@ -302,6 +308,7 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
/// <returns>
/// An <see cref="List{TPixel}"/> with the palletized colors
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TPixel[] Palletize(int colorCount)
{
while (this.Leaves > colorCount)
@ -327,6 +334,7 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
/// <returns>
/// The <see cref="int"/>.
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int GetPaletteIndex(ref TPixel pixel, ref Rgba32 rgba)
{
return this.root.GetPaletteIndex(ref pixel, 0, ref rgba);
@ -338,6 +346,7 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
/// <param name="node">
/// The node last quantized
/// </param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected void TrackPrevious(OctreeNode node)
{
this.previousNode = node;
@ -446,7 +455,11 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
/// <summary>
/// Gets the next reducible node
/// </summary>
public OctreeNode NextReducible { get; }
public OctreeNode NextReducible
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get;
}
/// <summary>
/// Add a color into the tree
@ -525,6 +538,7 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
/// </summary>
/// <param name="palette">The palette</param>
/// <param name="index">The current palette index</param>
[MethodImpl(MethodImplOptions.NoInlining)]
public void ConstructPalette(TPixel[] palette, ref int index)
{
if (this.leaf)
@ -557,6 +571,7 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
/// <returns>
/// The <see cref="int"/> representing the index of the pixel in the palette.
/// </returns>
[MethodImpl(MethodImplOptions.NoInlining)]
public int GetPaletteIndex(ref TPixel pixel, int level, ref Rgba32 rgba)
{
int index = this.paletteIndex;
@ -589,6 +604,7 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
/// </summary>
/// <param name="pixel">The pixel to add.</param>
/// <param name="rgba">The color to map to.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Increment(ref TPixel pixel, ref Rgba32 rgba)
{
pixel.ToRgba32(ref rgba);

9
src/ImageSharp/Processing/Quantization/FrameQuantizers/PaletteFrameQuantizer{TPixel}.cs

@ -2,7 +2,6 @@
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using SixLabors.ImageSharp.Advanced;
@ -18,11 +17,6 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
internal sealed class PaletteFrameQuantizer<TPixel> : FrameQuantizerBase<TPixel>
where TPixel : struct, IPixel<TPixel>
{
/// <summary>
/// A lookup table for colors
/// </summary>
private readonly Dictionary<TPixel, byte> colorMap = new Dictionary<TPixel, byte>();
/// <summary>
/// List of all colors in the palette.
/// </summary>
@ -36,6 +30,7 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
public PaletteFrameQuantizer(PaletteQuantizer quantizer, TPixel[] colors)
: base(quantizer, true)
{
Guard.MustBeLessThanOrEqualTo(256, colors.Length, "Maximum color count must be 256.");
this.colors = colors;
}
@ -99,6 +94,6 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
/// The quantized value
/// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private byte QuantizePixel(TPixel pixel) => this.GetClosestPixel(pixel, this.GetPalette(), this.colorMap);
private byte QuantizePixel(TPixel pixel) => this.GetClosestPixel(pixel, this.GetPalette());
}
}

8
src/ImageSharp/Processing/Quantization/FrameQuantizers/WuFrameQuantizer{TPixel}.cs

@ -68,11 +68,6 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
/// </summary>
private const int TableLength = IndexCount * IndexCount * IndexCount * IndexAlphaCount;
/// <summary>
/// A lookup table for colors
/// </summary>
private readonly Dictionary<TPixel, byte> colorMap = new Dictionary<TPixel, byte>();
/// <summary>
/// Moment of <c>P(c)</c>.
/// </summary>
@ -480,7 +475,6 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
using (IBuffer<long> volumeB = memoryAllocator.Allocate<long>(IndexCount * IndexAlphaCount))
using (IBuffer<long> volumeA = memoryAllocator.Allocate<long>(IndexCount * IndexAlphaCount))
using (IBuffer<float> volume2 = memoryAllocator.Allocate<float>(IndexCount * IndexAlphaCount))
using (IBuffer<long> area = memoryAllocator.Allocate<long>(IndexAlphaCount))
using (IBuffer<long> areaR = memoryAllocator.Allocate<long>(IndexAlphaCount))
using (IBuffer<long> areaG = memoryAllocator.Allocate<long>(IndexAlphaCount))
@ -855,7 +849,7 @@ namespace SixLabors.ImageSharp.Processing.Quantization.FrameQuantizers
{
// The colors have changed so we need to use Euclidean distance calculation to find the closest value.
// This palette can never be null here.
return this.GetClosestPixel(pixel, this.palette, this.colorMap);
return this.GetClosestPixel(pixel, this.palette);
}
// Expected order r->g->b->a

Loading…
Cancel
Save