public override int[][] TransformImage(Hashtable source)
 {
     if(source == null)
         return null;
     else
     {
         int[][] input = (int[][])source["image"];
         int mask = (int)source["mask"];
         double count = (double)(255.0 / (mask * mask)); //square mask
     ColorHistogram h = new ColorHistogram(mask, mask);
         int width = input.Length;
         int height = input[0].Length;
     Func<Histogram, int, byte> fn = (hi,current) => (byte)(count * (double)hi[0, current + 1]);
     Func<int,int,IEnumerable<int>> grabNeighborhood = (px, py) => input.GrabNeighborhood(px, py, width, height, mask);
         for(int x = 0; x < width; x++)
         {
             int[] iX = input[x];
       Func<int,IEnumerable<int>> gX = (py) => grabNeighborhood(x,py);
             //close over these values
             for(int y = 0; y < height; y++)
             {
     Color c = Color.FromArgb(iX[y]);
     h.Repurpose(gX(y));
     iX[y] = Color.FromArgb(255, fn(h.Red, (int)c.R),
                                 fn(h.Green, (int)c.G),
                                 fn(h.Blue, (int)c.B)).ToArgb();
             }
         }
         return input;
     }
 }
 public override int[][] TransformImage(Hashtable source)
 {
     if(source == null)
         return null;
     else
     {
         int[][] input = (int[][])source["image"];
         //the histogram object automatically creates a pixel intensity
         //distribution upon creation. It also computes the global equalized
         //intensity based upon it's frequency in the given image.
         ColorHistogram ch = new ColorHistogram(input);
         for(int x = 0; x < input.Length; x++)
         {
             int[] line = input[x];
             for(int y = 0; y < input[y].Length; y++)
             {
                 //we just replace the previous pixels with the new ones
                 Color c = Color.FromArgb(line[y]);
                 line[y] = Color.FromArgb(255,ch.Red.GlobalEqualizedIntensity[c.R],
                         ch.Green.GlobalEqualizedIntensity[c.G],
                         ch.Blue.GlobalEqualizedIntensity[c.B]).ToArgb();
             }
         }
         return input;
     }
 }
 public override int[][] TransformImage(Hashtable source)
 {
     int[][] aImage = (int[][])source["image"];
     int[][] oImage = (int[][])source["otherImage"];
     int aWidth = aImage.Length;
     int aHeight = aImage[0].Length;
     int[][] cImage = new int[aWidth][];
     ColorHistogram cloneHisto = new ColorHistogram(aImage);
     ColorHistogram refHisto = new ColorHistogram(oImage);
     for(int i = 0; i < 256; i++)
     {
         glRed[i] = (byte)Math.Round(Compute(i, refHisto.Red));
         glGreen[i] = (byte)Math.Round(Compute(i, refHisto.Green));
         glBlue[i] = (byte)Math.Round(Compute(i, refHisto.Blue));
     }
     byte[] resultRed = GenerateConversion(glRed,
             refHisto.Red.GlobalEqualizedIntensity,
             cloneHisto.Red.GlobalEqualizedIntensity);
     byte[] resultBlue = GenerateConversion(glBlue,
             refHisto.Blue.GlobalEqualizedIntensity,
             cloneHisto.Blue.GlobalEqualizedIntensity);
     byte[] resultGreen = GenerateConversion(glGreen,
             refHisto.Green.GlobalEqualizedIntensity,
             cloneHisto.Green.GlobalEqualizedIntensity);
     //then apply result to the given image
     //TODO: See if we need to make a copy image.
     //Is it safe to just overwrite the original image memory?
     for(int i = 0; i < aWidth; i++)
     {
         int[] aSlice = aImage[i];
         int[] q = new int[aHeight];
         for(int j = 0; j < aHeight; j++)
         {
             Color c = Color.FromArgb(aSlice[j]);
             q[j] = Color.FromArgb(255,
                     resultRed[c.R],
                     resultGreen[c.G],
                     resultBlue[c.B]).ToArgb();
         }
         cImage[i] = q;
     }
     return cImage;
 }