// On copy apply for type image!
  bool histogramRGBL::apply(const image& src,dvector& dest) const {

    if (src.empty()) {
      dest.clear();
      setStatusString("input channel empty");
      return false;
    }

    const parameters& param = getParameters();

    int theMin(0),theMax(255);

    const int lastIdx = param.cells-1;

    const float m = float(lastIdx)/(theMax-theMin);
    int y,r,g,b,l;
    int idx;
    int entries;

    vector<rgbPixel>::const_iterator it,eit;

    dest.resize(4*param.cells,0.0,false,true); // initialize with 0
    dvector theR(param.cells,0.0);
    dvector theG(param.cells,0.0);
    dvector theB(param.cells,0.0);
    dvector theL(param.cells,0.0);

    entries = 0;

    // if b too small, it's possible to calculate everything faster...

    // check if the ignore value
    if (param.considerAllData) {
      for (y=0;y<src.rows();++y) {
        const vector<rgbPixel>& vct = src.getRow(y);
        for (it=vct.begin(),eit=vct.end();it!=eit;++it) {
          r = (*it).getRed();
          g = (*it).getGreen();
          b = (*it).getBlue();
          l = (min(r,g,b)+max(r,g,b))/2;

          idx = static_cast<int>(r*m);
          theR.at(idx)++;
          idx = static_cast<int>(g*m);
          theG.at(idx)++;
          idx = static_cast<int>(b*m);
          theB.at(idx)++;
          idx = static_cast<int>(l*m);
          theL.at(idx)++;

          entries++;
        }
      }
    } else {
      for (y=0;y<src.rows();++y) {
        const vector<rgbPixel>& vct = src.getRow(y);
        for (it=vct.begin(),eit=vct.end();it!=eit;++it) {
          if ((*it) != param.ignoreValue) {
            r = (*it).getRed();
            g = (*it).getGreen();
            b = (*it).getBlue();
            l = (min(r,g,b)+max(r,g,b))/2;

            idx = static_cast<int>(r*m);
            theR.at(idx)++;
            idx = static_cast<int>(g*m);
            theG.at(idx)++;
            idx = static_cast<int>(b*m);
            theB.at(idx)++;
            idx = static_cast<int>(l*m);
            theL.at(idx)++;

            entries++;
          }
        }
      }
    }

    if (param.smooth) {
      convolution convolver;
      convolution::parameters cpar;
      cpar.boundaryType = lti::Mirror;
      cpar.setKernel(param.kernel);
      convolver.setParameters(cpar);

      matrix<double> tmp;
      tmp.useExternData(4,param.cells,&dest.at(0));

      convolver.apply(theR,tmp.getRow(0));
      convolver.apply(theG,tmp.getRow(1));
      convolver.apply(theB,tmp.getRow(2));
      convolver.apply(theL,tmp.getRow(3));

    } else {
      dest.fill(theR,0);
      dest.fill(theG,param.cells);
      dest.fill(theB,2*param.cells);
      dest.fill(theL,3*param.cells);
    }

    if (param.normalize) {
      if (entries > 0) {
        dest.divide(entries);
      }
    }

    return true;

  };