/// <summary>
		/// Add a color into the tree
		/// </summary>
		/// <param name="pixel">The 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 ( Color32* pixel , int colorBits , int level , Octree octree )
		{
			// Update the color information if this is a leaf
			if ( _leaf )
			{
				Increment ( pixel ) ;
				// Setup the previous node
				octree.TrackPrevious ( this ) ;
			}
			else
			{
				// Go to the next level down in the tree
				int	shift = 7 - level ;
				int index = ( ( pixel->Red & mask[level] ) >> ( shift - 2 ) ) |
					( ( pixel->Green & mask[level] ) >> ( shift - 1 ) ) |
					( ( pixel->Blue & mask[level] ) >> ( shift ) ) ;

				OctreeNode	child = _children[index] ;

				if ( null == child )
				{
					// Create a new child node & store in the array
					child = new OctreeNode ( level + 1 , colorBits , octree ) ; 
					_children[index] = child ;
				}

				// Add the color to the child node
				child.AddColor ( pixel , colorBits , level + 1 , octree ) ;
			}

		}
		// Aqui comienza el algoritmo propiamente dicho
		public void EvaluateSteps( BitmapData sourceData, Bitmap output, int width , int height , Rectangle bounds )
		{
			Octree octree = new Octree(MaxColorBits);

			FirstPass( sourceData , width , height, octree ) ;
			output.Palette = this.GetPalette ( output.Palette, octree ) ;
			SecondPass( sourceData , output , width , height , bounds, octree ) ;
		}
		/// <summary>
		/// Construct the node
		/// </summary>
		/// <param name="level">The level in the tree = 0 - 7</param>
		/// <param name="colorBits">The number of significant color bits in the image</param>
		/// <param name="octree">The tree to which this node belongs</param>
		public OctreeNode ( int level , int colorBits , Octree octree )
		{
			// Construct the new node
			_leaf = ( level == colorBits ) ;

			_red = _green = _blue = 0 ;
			_pixelCount = 0 ;

			// If a leaf, increment the leaf count
			if ( _leaf )
			{
				octree.Leaves++ ;
				_nextReducible = null ;
				_children = null ; 
			}
			else
			{
				// Otherwise add this to the reducible nodes
				_nextReducible = octree.ReducibleNodes[level] ;
				octree.ReducibleNodes[level] = this ;
				_children = new OctreeNode[8] ;
			}
		}
		private void SecondPass ( BitmapData sourceData , Bitmap output , int width , int height , Rectangle bounds, Octree octree )
		{
			BitmapData	outputData = null ;

			try
			{
				// Lock the output bitmap into memory
				outputData = output.LockBits ( bounds , ImageLockMode.WriteOnly , PixelFormat.Format8bppIndexed ) ;

				// Define the source data pointers. The source row is a byte to
				// keep addition of the stride value easier (as this is in bytes)
				byte*	pSourceRow = (byte*)sourceData.Scan0.ToPointer ( ) ;
				Int32*	pSourcePixel = (Int32*)pSourceRow ;
				Int32*	pPreviousPixel = pSourcePixel ;

				// Now define the destination data pointers
				byte*	pDestinationRow = (byte*) outputData.Scan0.ToPointer();
				byte*	pDestinationPixel = pDestinationRow ;

				// And convert the first pixel, so that I have values going into the loop
				byte	pixelValue = QuantizePixel ( (Color32*)pSourcePixel, octree ) ;

				// Assign the value of the first pixel
				*pDestinationPixel = pixelValue ;

				// Loop through each row
				for ( int row = 0 ; row < height ; row++ )
				{
					// Set the source pixel to the first pixel in this row
					pSourcePixel = (Int32*) pSourceRow ;

					// And set the destination pixel pointer to the first pixel in the row
					pDestinationPixel = pDestinationRow ;

					// Loop through each pixel on this scan line
					for ( int col = 0 ; col < width ; col++ , pSourcePixel++ , pDestinationPixel++ )
					{
						// Check if this is the same as the last pixel. If so use that value
						// rather than calculating it again. This is an inexpensive optimisation.
						if ( *pPreviousPixel != *pSourcePixel )
						{
							// Quantize the pixel
							pixelValue = QuantizePixel ( (Color32*)pSourcePixel, octree ) ;

							// And setup the previous pointer
							pPreviousPixel = pSourcePixel ;
						}

						// And set the pixel in the output
						*pDestinationPixel = pixelValue ;
					}

					// Add the stride to the source row
					pSourceRow += sourceData.Stride ;

					// And to the destination row
					pDestinationRow += outputData.Stride ;
				}
			}
			finally
			{
				// Ensure that I unlock the output bits
				output.UnlockBits ( outputData ) ;
			}
		}
		private void FirstPass ( BitmapData sourceData , int width , int height, Octree octree )
		{
			// Define the source data pointers. The source row is a byte to
			// keep addition of the stride value easier (as this is in bytes)
			byte*	pSourceRow = (byte*)sourceData.Scan0.ToPointer ( ) ;
			Int32*	pSourcePixel ;

			// Loop through each row
			for ( int row = 0 ; row < height ; row++ )
			{
				// Set the source pixel to the first pixel in this row
				pSourcePixel = (Int32*) pSourceRow ;

				// And loop through each column
				for ( int col = 0 ; col < width ; col++ , pSourcePixel++ )
					// Now I have the pixel, call the FirstPassQuantize function...
					octree.AddColor ( (Color32*)pSourcePixel ) ;

				// Add the stride to the source row
				pSourceRow += sourceData.Stride ;
			}
		}
		private byte QuantizePixel ( Color32* pixel, Octree octree  )
		{
			byte	paletteIndex = (byte)MaxColors ;	// The color at [_maxColors] is set to transparent

			// Get the palette index if this non-transparent
			if ( pixel->Alpha > 0 )
				paletteIndex = (byte)octree.GetPaletteIndex ( pixel ) ;

			return paletteIndex ;
		}
		private ColorPalette GetPalette ( ColorPalette original, Octree octree )
		{
			// First off convert the octree to _maxColors colors
			ArrayList	palette = octree.Palletize ( MaxColors - 1 ) ;

			// Then convert the palette based on those colors
			for ( int index = 0 ; index < palette.Count ; index++ )
				original.Entries[index] = (Color)palette[index] ;

			// Add the transparent color
			original.Entries[MaxColors] = Color.FromArgb ( 0 , 0 , 0 , 0 ) ;

			return original ;
		}