//
// This file is part of MorphoGraphX - http://www.MorphoGraphX.org
// Copyright (C) 2012-2021 Richard S. Smith and collaborators.
//
// If you use MorphoGraphX in your work, please cite:
//   http://dx.doi.org/10.7554/eLife.05864
//
// MorphoGraphX is free software, and is licensed under under the terms of the 
// GNU General (GPL) Public License version 2.0, http://www.gnu.org/licenses.
// 
#include "StackGammaFilter.hpp"
#include "Progress.hpp"
#include <omp.h>

namespace mgx 
{
  bool StackGammaFilter::run(const Store* input, Store* output, float gamma)
  {
    // Check gamma
    if(gamma <= 0)
      throw(QString("Gamma must be positive"));
  
    // Start the progress bar
    const Stack* stack = output->stack();
    progressStart(QString("Running Gamma Filter on stack %1").arg(stack->userId()), 0);
  
    // Get the stack dimensions
    Point3u imgSize = stack->size();
  
    // Get the input and output images, note they may be the same
    const HVecUS& src = input->data();
    HVecUS& dst = output->data();
  
    #pragma omp parallel for
    for(size_t z = 0; z < imgSize.z(); ++z)
      for(size_t y = 0; y < imgSize.y(); ++y)
        for(size_t x = 0; x < imgSize.x(); ++x) {
          float pix = src[stack->offset(x, y, z)];
          pix = pow(pix / 65535.0, gamma) * 65535;
          dst[stack->offset(x, y, z)] = ushort(pix);
        }
    // Tell MorphoGraphX to update the stack
    output->changed();
    // Copy the meta data for the stack in case store is different
    output->copyMetaData(input);
  
    // Print message in status bar
    SETSTATUS(QString("Processed Gamma Filter on stack %1").arg(stack->userId()));
  
    return true;
  }
  REGISTER_PROCESS(StackGammaFilter);
}
