/* -*- Mode: C++ -*-
 *
 * $Header: /home/gene/library/website/docsrc/exrtoppm/src/RCS/exrtoppm.cpp,v 395.1 2008/04/20 17:25:50 gene Exp $
 *
 * Copyright (c) 2005 Gene Michael Stover.  All rights reserved.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public
 * License along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301
 * USA
 */

#include "this.h"

using namespace Imf;
using namespace std;

/*
 */
enum { ACTION_HELP, ACTION_RUN };

/*
 * Stream to which we write PPM output.
 * Change it with the "-o" command line option.
 */
static FILE *S_ofp = stdout;

/*
 */
static void
S_Help ()
{
  printf ("\nCopyright (c) 2006 Gene Michael Stover.  All rights reserved.");
  printf ("\nCompiled %s at %s", __DATE__, __TIME__);
  printf ("\n");
  printf ("\nexrtoppm [-h] [-i input] [-o output]");
  printf ("\n");
  printf ("\nThe complete documentation is available on the world wide web");
  printf (" at");
  printf ("\n<http://cybertiggyr.com/gene/exrtoppm/>.");
}

/*
 */
static int
S_Run (char pathname[])
{
  int rc = 0;
  RgbaInputFile exr (pathname);
  int width, height, y, x;
  Rgba *pixel;
  PpmPixel ppm;

  fprintf (S_ofp, "P3\n");
  width = exr.dataWindow().max.x - exr.dataWindow().min.x + 1;
  height = exr.dataWindow().max.y - exr.dataWindow().min.y + 1;
  fprintf (S_ofp, "%d %d ", width, height);
  fprintf (S_ofp, "255");
  pixel = new Rgba[width];
  if (pixel != NULL) {
    exr.setFrameBuffer (pixel, 1, 0);
    for (y = exr.dataWindow().min.y; y <= exr.dataWindow().max.y; ++y) {
      exr.readPixels (y, y);
      for (x = exr.dataWindow().min.x; x <= exr.dataWindow().max.x; ++x) {
        PIXEL_ExrToPpm (&pixel[x], &ppm);
        fprintf (S_ofp, " %d %d %d", ppm.r, ppm.g, ppm.b);
      }
      fprintf (S_ofp, "\n");
    }
    delete pixel;
  } else {
    fprintf (stderr, "\n%s:%d:", __FILE__, __LINE__);
    fprintf (stderr, " new Rgba[%d] failed", 1 + exr.dataWindow().max.x);
    rc = 55;
  }
  return rc;
}

/*
 */
static int
S_Dispatch (int action, char pathname[])
{
  int rc = 0;

  switch (action) {
  case ACTION_HELP:
    S_Help ();
    break;
  case ACTION_RUN:
    rc = S_Run (pathname);
    break;
  default:
    fprintf (stderr, "\n%s:%d:", __FILE__, __LINE__);
    fprintf (stderr, " Action is %d.", action);
    fprintf (stderr, "  That's an unexpected value.");
    fprintf (stderr, "  This should never happen.");
    rc = 59;
  }
  return rc;
}

/*
 */
static int S_action = ACTION_RUN;
static char *S_exrname;

/*
 */
static int
S_Init ()
{
  int rc = 0;

  return rc;
}

extern "C" int getopt (int, char *[], char[]);
extern "C" char *optarg;
extern "C" int optind;

/*
 */
static int
S_CommandLine (int argc, char *argv[])
{
  int rc = 0, c;

  while (rc == 0 && (c = getopt (argc, argv, "hi:o:")) != EOF) {
    switch (c) {
    case 'h': S_action = ACTION_HELP; break;
    case 'i':
      S_exrname = optarg;
      break;
    case 'o':
      S_ofp = fopen (optarg, "w");
      if (S_ofp != NULL) {
        /* good */
      } else {
        perror ("fopen");
        fprintf (stderr, "%s:%d:", __FILE__, __LINE__);
        fprintf (stderr, " Can't open \"%s\" for output.", optarg);
        rc = 8;
      }
      break;
    case '?':
      fprintf (stderr, "\n%s:%d: getopt indicates an error.  Unknown option?",
              __FILE__, __LINE__);
      rc = 51;
      break;
    case ':':
      fprintf (stderr, "\n%s:%d:", __FILE__, __LINE__);
      fprintf (stderr, " getopt indicates an error.  Missing option");
      fprintf (stderr, " argument?");
      rc = 53;
      break;
    default:
      fprintf (stderr, "\n%s:%d:", __FILE__, __LINE__);
      fprintf (stderr, " getopt indicates an error?  It returned '%c'.", c);
      rc = 54;
    }
  }
  while (optind < argc) {
    fprintf (stderr, "\n%s:%d: Ignoring argv[%d] \"%s\"", __FILE__, __LINE__,
             optind, argv[optind]);
    ++optind;
  }
  return rc;
}

/*
 */
static void
S_Uninit ()
{
}

int
main (int argc, char *argv[])
{
  int rc = 0;

  if (S_Init () == 0) {
    if (S_CommandLine (argc, argv) == 0) {
      if (S_Dispatch (S_action, S_exrname) == 0) {
        /* good */
      } else {
        fprintf (stderr, "\n%s:%d: S_Dispatch failed", __FILE__, __LINE__);
        rc = 49;
      }
    } else {
      fprintf (stderr, "\n%s:%d: S_CommandLine failed", __FILE__, __LINE__);
      rc = -17;
    }
    S_Uninit ();
  } else {
    fprintf (stderr, "\n%s:%d: S_Init failed", __FILE__, __LINE__);
    rc = 74;
  }
  return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}

/* --- end of file --- */
