ossimRefPtr<ossimImageData> ossimHistogramEqualization::runEqualizationAlgorithm(T, ossimRefPtr<ossimImageData> tile)
{
   
   if(!theAccumulationHistogram ||
      !getHistogram())
   {
      return tile;
   }

   // for now we will always pull from res 0 information
   ossimRefPtr<ossimMultiBandHistogram> histo = getHistogram()->getMultiBandHistogram(0);

   if(histo.valid())
   {
      ossim_uint32 maxBands = ( (histo->getNumberOfBands() >
                                 tile->getNumberOfBands())?
                                tile->getNumberOfBands():
                                histo->getNumberOfBands());
      
      long offsetUpperBound = tile->getHeight()*tile->getWidth();

      for(ossim_uint32 band = 0; band < maxBands; ++band)
      {
         ossimRefPtr<ossimHistogram> bandHisto = histo->getHistogram(band);
         T* buf = static_cast<T*>(tile->getBuf(band));
         double *histoLut = band<theForwardLut.size()?theForwardLut[band]:NULL;
         ossim_uint32 actualBand = theBandList[band];
         if(bandHisto.valid())
         {
            if(buf&&histoLut&&(actualBand <  histo->getNumberOfBands()))
            {
               if(theInverseFlag)
               {
                  histoLut = theInverseLut[actualBand];
               }
               if(histoLut)
               {
                  if(tile->getDataObjectStatus() == OSSIM_FULL)
                  {
                     T minPix = (T)tile->getMinPix(actualBand);
                     T maxPix = (T)tile->getMaxPix(actualBand);
                     for(long offset = 0; offset < offsetUpperBound; ++offset)
                     {
                        ossim_int32 idx = bandHisto->GetIndex(buf[offset]);
                           
                        if(idx>=0)
                        {
                           T value = (T)(histoLut[idx]);

                           //---
                           // Assign clamping to min max.
                           // 
                           // ESH 03/2009 -- Clamping to within min-max fixed
                           //--- 
                           buf[offset] = value < minPix ? minPix :
                              (value > maxPix ? maxPix : value);
                        }
                     }
                  }
                  else
                  {
                     T minPix  = (T)tile->getMinPix(actualBand);
                     T maxPix  = (T)tile->getMaxPix(actualBand);
                     T nullPix = (T)tile->getNullPix(actualBand);
                     for(long offset = 0; offset < offsetUpperBound; ++offset)
                     {
                        ossim_int32 idx = bandHisto->GetIndex(buf[offset]);
                        
                        if((buf[offset]!=nullPix)&&(idx>=0))
                        {
                           T value = (T)(histoLut[idx]);

                           //---
                           // Assign clamping to min max.
                           // 
                           // ESH 03/2009 -- Clamping to within min-max fixed
                           //--- 
                           buf[offset] = value < minPix ? minPix :
                              (value > maxPix ? maxPix : value);
                        }
                        else
                        {
                           buf[offset] = nullPix;
                        }
                     }
                  }
               }
            }
         }
      }
      
      tile->validate();
   }
   
   return tile;
}
//**************************************************************************************************
template <class T> void ossimScaleFilter::runVerticalFilterTemplate(
   T /* dummy */,
   const ossimRefPtr<ossimImageData>& input,
   ossimRefPtr<ossimImageData>& output)
{
   ossimIrect viewRect  = output->getImageRectangle();
   ossimIrect imageRect = input->getImageRectangle();
   ossim_int32 vw = viewRect.width();
   ossim_int32 vh = viewRect.height();
   ossim_int32 iw = imageRect.width();
   ossimIpt origin(viewRect.ul());
   ossimIpt imageOrigin(imageRect.ul());
   ossimIpt inputUl = m_InputRect.ul();
   ossimIpt inputLr = m_InputRect.lr();
   double scale = 0.0;
   double support = 0.0;
   ossim_int32 x = 0;
   ossim_int32 y = 0;
   ossim_int32 start = 0;
   ossim_int32 stop  = 0;
   ossim_int32 kernelIdx = 0;
   const ossimFilter* filter = getVerticalFilter();
   ossim_float64 center = 0.0;
   ossim_int32 bandIdx = 0;
   ossim_int32 numberOfBands = m_Tile->getNumberOfBands();
   
   scale = m_BlurFactor*ossim::max(1.0/m_ScaleFactor.y, 1.0);
   
   support=scale*filter->getSupport();
   if (support <= 0.5)
   {
      support = .5 + FLT_EPSILON;
      scale = 1.0;
   }
   scale=1.0/scale;

   for(bandIdx = 0; bandIdx < numberOfBands; ++bandIdx)
   {
      T* imageBuf = (T*)input->getBuf(bandIdx);
      T* viewBuf  = (T*)output->getBuf(bandIdx);
      T np        = (T)input->getNullPix(bandIdx);
      T outNp     = (T)output->getNullPix(bandIdx);
      T outMinPix = (T)output->getMinPix(bandIdx);
      T outMaxPix = (T)output->getMaxPix(bandIdx);
     
      for(y = 0; y < vh; ++y)
      {
         center=(double) ((y + origin.y+0.5)/m_ScaleFactor.y);
         start=ossim::max((ossim_int32)ossim::round<int>(center-support), (ossim_int32)inputUl.y);
         stop=ossim::min((ossim_int32)ossim::round<int>(center+support), (ossim_int32)inputLr.y);
         ossim_int32 delta = stop-start;
         if (delta <= 0)
         {
            break;
         }
         vector<double> kernel(delta);
         double density = 0.0;
         for(kernelIdx = 0; kernelIdx < delta; ++kernelIdx)
         {
            kernel[kernelIdx] = filter->filter(scale*(start + kernelIdx - center + .5),
                                               filter->getSupport());
            density += kernel[kernelIdx];
         }
         if ((density != 0.0) && (density != 1.0))
         {
            /*
              Normalize.
            */
            density=1.0/density;
            for (kernelIdx=0; kernelIdx < delta; kernelIdx++)
               kernel[kernelIdx]*=density;
         }

         ossim_int32 offset       = ((start  - imageOrigin.y)*iw);
         ossim_int32 offsetCenter = ((((ossim_int32)center) - imageOrigin.y)*iw);
        
         for(x = 0; x < vw; ++x)
         {
            T* yptr         = imageBuf + offset       + x;
            T* yCenterptr   = imageBuf + offsetCenter + x;
            double result = 0.0;
            density = 0.0;

            if((*yCenterptr) == np)
            {
               *viewBuf = outNp;
            }
            else
            {
               for(kernelIdx = 0; kernelIdx < delta; ++kernelIdx)
               {
                  if((*yptr != np)&&
                     (kernel[kernelIdx] != 0.0))
                  {
                     result  += ((*yptr)*kernel[kernelIdx]);
                     density += kernel[kernelIdx];
                  }
                  yptr += iw;
               }
               if(density != 0.0)
               {
                  result /= density;
                 
                  if(result < outMinPix) result = outMinPix;
                  if(result > outMaxPix) result = outMaxPix;
                 
                  *viewBuf = (T)result;
               }
               else
               {
                  *viewBuf = outNp;
               }
            }
            ++viewBuf;
         }
      }
   }
}