/******************************************************************************

   This file is a part of the

             COMPLEX PSEUDO-RAW SAR IMAGE PROCESSING TOOLBOX

   Copyright (C) 2017 Rémy Abergel (Remy.Abergel AT parisdescartes.fr), Loïc
   Denis (Loic.Denis AT univ-st-etienne.fr), Saïd Ladjal (Said.Ladjal AT
   telecom-paristech.fr) and Florence Tupin (Florence.Tupin AT
   telecom-paristech.fr).

   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 3 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, see <http://www.gnu.org/licenses/>.

******************************************************************************/

/*
   Compilation (using gcc):
   ========================

   gcc -O3 tiffreadasc.c tiffwrite.c -ltiff -o tiffreadasc


   Ddescription:
   =============

   Read an image in ascii format (the user enter the gray level in ascii
   format).

*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define FREE_ALL() {				\
    if(NULL != u) free(u);			\
  }
#define ASSERT_ALLOC(cmd) if(NULL == (cmd)) { printf("Not enough memory\n"); FREE_ALL(); exit(EXIT_FAILURE); }

static void display_usage()
{
  printf("\nRead an image in ascii format (in row-major order)\n\n");
  printf("Usage: tiffreadasc [-t type] [-v] out width height\n\n");
  printf("   -t type   : (default = float) select output type\n");
  printf("   -v        : enable verbose mode\n");
  printf("   out       : output TIFF image (monopage)\n");
  printf("   witdh     : image width\n");
  printf("   height    : image height\n\n");
  printf("Note: possible saving pixel types (option -t) are:\n\n");
  printf("   'uint8' or 'int8' : unsigned or signed 8-bits integer)\n");
  printf("   'uint16' or 'int16' : unsigned or signed 16-bits integer)\n");
  printf("   'uint32' or 'int32' : unsigned or signed 32-bits integer)\n");
  printf("   'float' : 32 bits per pixel TIFF-float precision\n\n");
}


int main(int argc, char **argv)
{
  char *filename_out = NULL, *widthvalue = NULL, *heightvalue = NULL, *tvalue = NULL, vflag = 0;
  double *u;
  int i,adr,nx,ny,type;

  /******************************************/
  /*            arguments parser            */
  /******************************************/

  /* main parser */
  for(i=1;i<argc;i++) {
    if (strcmp(argv[i],"-v") == 0) vflag = 1;
    else if (strcmp(argv[i],"-t") == 0) {
      if(i==argc-1) { display_usage(); printf("Error: option -t requires an argument\n\n"); return EXIT_FAILURE; }
      else { tvalue = argv[i+1]; i++; }
    }
    else if (NULL == filename_out) filename_out = argv[i];
    else if (NULL == widthvalue) widthvalue = argv[i];
    else if (NULL == heightvalue) heightvalue = argv[i];
    else { display_usage(); printf("Error: could not retrieve properly input arguments.\n\n"); return EXIT_FAILURE; }
  }

  /* check consistency */
  if ((NULL == filename_out) || (NULL == widthvalue) || (NULL == heightvalue)) {
    display_usage();
    if (NULL == filename_out) printf("Error: output 'out' is missing\n\n");
    else if (NULL == widthvalue) printf("Error: input 'width' is missing\n\n");
    else printf("Error: input 'height' is missing\n\n");
    return EXIT_FAILURE;
  }
  if ((NULL == tvalue) || (strcmp(tvalue,"float")==0)) type = 0; // float (default)
  else if (strcmp(tvalue,"uint8")==0) type = 8; // unsigned 8-bits integer
  else if (strcmp(tvalue,"int8")==0) type = -8; // signed 8-bits integer
  else if (strcmp(tvalue,"uint16")==0) type = 16; // unsigned 16-bits integer
  else if (strcmp(tvalue,"int16")==0) type = -16; // signed 16-bits integer
  else if (strcmp(tvalue,"uint32")==0) type = 32; // unsigned 32-bits integer
  else if (strcmp(tvalue,"int32")==0) type = -32; // signed 32-bits integer
  else {
    printf("Error: unrecognized type value (option -f).Possible choices are\ntype=uint8,int8,uint16,int16,uint32,int32,float.\n");
    return EXIT_FAILURE;
  }
  if(sscanf(widthvalue,"%d",&nx) != 1) { display_usage(); printf("Error: could not retrieve properly input 'width'\n\n"); return EXIT_FAILURE; }
  if(sscanf(heightvalue,"%d",&ny) != 1) { display_usage(); printf("Error: could not retrieve properly input 'height'\n\n"); return EXIT_FAILURE; }

  /* memory allocation */
  ASSERT_ALLOC(u = (double*) malloc (nx*ny * sizeof(double)));

  /*** main loop  ***/
  for(adr=0;adr<nx*ny;adr++) {
    if(scanf("%lf",u+adr) != 1) {
      printf("\nError: some image graylevels are missing or could not be read properly.\n\n");
      return EXIT_FAILURE;
    }
  }

  /* write tiff image */
  if(EXIT_FAILURE == save_monopage_striped_tiff_from_double(filename_out,u,nx,ny,vflag,type)) {
    if(vflag) printf("Free memory and exit the program.\n\n");
    else printf("An error occured (try verbose mode using option -v to get more informations)\n");
    FREE_ALL();
    return EXIT_FAILURE;
  }

  /* free memory */
  FREE_ALL();

}
