/*
 * Calculate L^q distance on two colour images
 *
 * $Date$
 * $Revision$
 *
 */

#include <WTools.hh>

#include <cmath>
#include <iomanip>

#if !(defined __WATCOMC__ && __WATCOMC__ < 1230)
using namespace std;
#endif

#define ROWS 128
#define COLS 128
#define KEPT 40

int
main (int argc, char *argv[])
{
  if (argc != 3)
    {
      std::cerr << "Usage: ppmlq <file1> <file2>" << std::endl;
      return 1;
    }
  std::cout << "pgmcompare version " << WAVE_VERSION << " (c) 2001-2009 by Herbert"
#ifdef PFI
	    << " (pfi support enabled)"
#endif
	    << std::endl;

  ColorImage img1, img2;
  try
    {
      img1.read (argv[1]);
    }
  catch (const std::exception &e)
    {
      std::cerr << "Could not open first image for reading: " << argv[1]
		<< ", " << e.what () << std::endl;
      return 1;
    }
  try
    {
      img2.read (argv[2]);
    }
  catch (const std::exception &e)
    {
      std::cerr << "Could not open second image for reading: " << argv[2]
		<< ", " << e.what () << std::endl;
      return 2;
    }
  if (img1.colors () != img2.colors ())
    {
      std::cerr << "Error, inconsisten number of colours: " << img1.colors ()
		<< " vs. " << img2.colors () << std::endl;
      return 1;
    }
  if (img1.colors () != 3 && img1.colors () != 1)
    {
      std::cerr << "Error, invalid number of colours: " << img1.colors ()
		<< " must be 1 or 3." << std::endl;
      return 1;
    }
  ColorImage *scaled1 = img1.fitInto (ROWS, COLS, ef_outerBorder);
  ColorImage *scaled2 = img2.fitInto (ROWS, COLS, ef_outerBorder);
  if (scaled1->colors () == 3)
    {
      scaled1->colormodel (cm_yuv);
      scaled2->colormodel (cm_yuv);
    }
  double detailScore = 0;
  double averageScore = 0;
  for (int i = 0; i < scaled1->colors (); ++i)
    {
      Image *c1 = ImageComparison::truncateForLq (scaled1->channel (i),
						  KEPT, Haar);
      Image *c2 = ImageComparison::truncateForLq (scaled2->channel (i),
						  KEPT, Haar);
      averageScore += ImageComparison::calcLqAverageScore (*c1, *c2, i);
      detailScore += ImageComparison::calcLqDetailScore (*c1, *c2, i);
      DELETE (c1);
      DELETE (c2);
    }
  DELETE (scaled1);
  DELETE (scaled2);
  std::cout.setf (std::ios::fixed, std::ios::floatfield);
  std::cout <<  "L^q: "
	    << std::setprecision (5) << std::setw (11)
	    << detailScore + averageScore  << ", avg: "
	    << std::setprecision (5) << std::setw (11)
	    << averageScore << ", detail: "
	    << std::setprecision (5) << std::setw (11)
	    << detailScore
	    << endl;
  return 0;
}

