public int GetPaletteIndex(ref TPixel pixel, int level) { int index = this.paletteIndex; if (!this.leaf) { int shift = 7 - level; Rgba32 rgba = default; pixel.ToRgba32(ref rgba); int pixelIndex = ((rgba.B & Mask[level]) >> (shift - 2)) | ((rgba.G & Mask[level]) >> (shift - 1)) | ((rgba.R & Mask[level]) >> shift); OctreeNode child = this.children[pixelIndex]; if (child != null) { index = child.GetPaletteIndex(ref pixel, level + 1); } else { throw new Exception($"Cannot retrieve a pixel at the given index {pixelIndex}."); } } return(index); }
/// <summary> /// Add a color into the tree /// </summary> /// <param name="pixel">The pixel color</param> /// <param name="colorBits">The number of significant color bits</param> /// <param name="level">The level in the tree</param> /// <param name="octree">The tree to which this node belongs</param> public void AddColor(ref TPixel pixel, int colorBits, int level, Octree octree) { // Update the color information if this is a leaf if (this.leaf) { this.Increment(ref pixel); // Setup the previous node octree.TrackPrevious(this); } else { // Go to the next level down in the tree int shift = 7 - level; Rgba32 rgba = default; pixel.ToRgba32(ref rgba); int index = ((rgba.B & Mask[level]) >> (shift - 2)) | ((rgba.G & Mask[level]) >> (shift - 1)) | ((rgba.R & Mask[level]) >> shift); OctreeNode child = this.children[index]; if (child is null) { // Create a new child node and store it in the array child = new OctreeNode(level + 1, colorBits, octree); this.children[index] = child; } // Add the color to the child node child.AddColor(ref pixel, colorBits, level + 1, octree); } }
public void Invoke(int y) { Rgba32 rgb = default; Span <TPixel> pixelRow = this.source.GetPixelRowSpan(y); for (int x = this.startX; x < this.endX; x++) { TPixel pixel = pixelRow[x]; pixel.ToRgba32(ref rgb); var x1 = Math.Max(x - this.startX - this.clusterSize + 1, 0); var x2 = Math.Min(x - this.startX + this.clusterSize + 1, this.bounds.Width - 1); var y1 = Math.Max(y - this.startY - this.clusterSize + 1, 0); var y2 = Math.Min(y - this.startY + this.clusterSize + 1, this.bounds.Height - 1); var count = (uint)((x2 - x1) * (y2 - y1)); var sum = (long)Math.Min(this.intImage[x2, y2] - this.intImage[x1, y2] - this.intImage[x2, y1] + this.intImage[x1, y1], long.MaxValue); if ((rgb.R + rgb.G + rgb.B) * count <= sum * this.thresholdLimit) { this.source[x, y] = this.lower; } else { this.source[x, y] = this.upper; } } }
/// <summary> /// Return the palette index for the passed color /// </summary> /// <param name="pixel">The pixel data.</param> /// <param name="level">The level.</param> /// <param name="rgba">The color to map to.</param> /// <returns> /// The <see cref="int"/> representing the index of the pixel in the palette. /// </returns> public int GetPaletteIndex(TPixel pixel, int level, ref Rgba32 rgba) { int index = this.paletteIndex; if (!this.leaf) { int shift = 7 - level; pixel.ToRgba32(ref rgba); int pixelIndex = ((rgba.B & Mask[level]) >> (shift - 2)) | ((rgba.G & Mask[level]) >> (shift - 1)) | ((rgba.R & Mask[level]) >> shift); if (this.children[pixelIndex] != null) { index = this.children[pixelIndex].GetPaletteIndex(pixel, level + 1, ref rgba); } else { throw new Exception($"Cannot retrive a pixel at the given index {pixelIndex}."); } } return(index); }
public void Increment(ref TPixel pixel, ref Rgba32 rgba) { pixel.ToRgba32(ref rgba); this.pixelCount++; this.red += rgba.R; this.green += rgba.G; this.blue += rgba.B; }