/*-----------------------------------------------------------------------
  
    File        : fade_images.cpp

    Description : Compute a linear fading between two images

    Author      : David Tschumperlé

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    ---------------------------------------------------------------------*/

#include "../CImg.h"
// The lines below are not necessary in your own code, it simply allows 
// the source compilation with compilers that do not respect the C++ standart.
#if ( defined(_MSC_VER) && _MSC_VER<=1200 ) || defined(__DMC__)
#define std
#endif

int main(int argc,char **argv) {

  // Read and check command line parameters
  cimg_usage("Compute a linear fading between two 2D images");
  const char *file_i1 = cimg_option("-i1","img/sh0r.pgm","Input Image 1");
  const char *file_i2 = cimg_option("-i2","img/milla.ppm","Input Image 2");
  const char *file_o  = cimg_option("-o",(char*)NULL,"Output Image");
  const double pmin   = cimg_option("-min",40.0,"Begin of the fade (in %)")/100.0;
  const double pmax   = cimg_option("-max",60.0,"End of the fade (in %)")/100.0;
  const double angle  = cimg_option("-angle",0.0,"Fade angle")*cimg_library::cimg::PI/180;
  const double ca=std::cos(angle), sa=std::sin(angle);
  if (!file_i1 || !file_i2) throw cimg_library::CImgArgumentException("You must specify two input images (type '%s -h')",argv[0]);
  
  // Init images
  cimg_library::CImg<unsigned char> img1(file_i1), img2(file_i2);
  if (img2.width!=img1.width || img2.height!=img1.height || img2.depth!=img1.depth || img2.dim!=img1.dim) {
    int 
      dx = cimg_library::cimg::max(img1.width,img2.width),
      dy = cimg_library::cimg::max(img1.height,img2.height),
      dz = cimg_library::cimg::max(img1.depth,img2.depth),
      dv = cimg_library::cimg::max(img1.dim,img2.dim);
    img1.resize(dx,dy,dz,dv);
    img2.resize(dx,dy,dz,dv);
  }
  cimg_library::CImg<unsigned char> dest(img1,false);
  
  // Compute the faded image
  double alpha;
  cimg_mapXYZV(dest,x,y,z,k) {
    const double X = ((double)x/img1.width-0.5)*ca + ((double)y/img1.height-0.5)*sa;
    if (X+0.5<pmin) alpha=0; else {
      if (X+0.5>pmax) alpha=1; else alpha=(X+0.5-pmin)/(pmax-pmin);
    }
    dest(x,y,z,k) = (unsigned char)((1-alpha)*img1(x,y,z,k) + alpha*img2(x,y,z,k));
  }
  
  // Save and exit
  if (!file_o) dest.display(); else dest.save(file_o);
  exit(0);
  return 0;
}
