/*
* process_command.c
*
* Copyright (C) 2019, Tristan Dagobert, CMLA, École Normale Supérieure Paris-Saclay.
*
* This software is a computer program.
* It is a part of a code which estimates, given a satellite time series
* the visibility of each image. Given a gray level time series, it provides a
* Boolean times series indicating the visibility (mainly the opaque clouds,
* haze and shadow).
*
*
* This software is governed by the CeCILL-C license under French law and
* abiding by the rules of distribution of free software. You can use,
* modify and/ or redistribute the software under the terms of the CeCILL-C
* license as circulated by CEA, CNRS and INRIA at the following URL
* "http://www.cecill.info".
*
* As a counterpart to the access to the source code and rights to copy,
* modify and redistribute granted by the license, users are provided only
* with a limited warranty and the software's author, the holder of the
* economic rights, and the successive licensors have only limited
* liability.
*
* In this respect, the user's attention is drawn to the risks associated
* with loading, using, modifying and/or developing or reproducing the
* software by the user in light of its specific status of free software,
* that may mean that it is complicated to manipulate, and that also
* therefore means that it is reserved for developers and experienced
* professionals having in-depth computer knowledge. Users are therefore
* encouraged to load and test the software's suitability as regards their
* requirements in conditions enabling the security of their systems and/or
* data to be ensured and, more generally, to use and operate it in the
* same conditions as regards security.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "iio.h"
#include "stratus.h"
#include "utilities.h"
#include "process_command.h"
/*============================================================================*/
char * VERSION = "1.0";
/* This global variable indicates if we compute only statistics for the last
* image of the input sequence */
const char *TAB_FEATURES[9] = {"prefixe", "output_all", "SIFT"};
/*============================================================================*/
static void
print_version(char ** argv)
{
printf ("%s %s\n", argv[0], VERSION);
return;
}
/*============================================================================*/
static void
print_usage(char ** argv)
{
printf ("Usage :\n");
printf ("\n");
printf ("%s --help | --version | [--opt-alpha ALPHA] "
"[--opt-theta THETA] --im-pfx-map IM(1)… IM(n) "
"--im-sift S(1)… S(n)\n",
argv[0]);
return;
}
/*============================================================================*/
static void
print_help(char ** argv)
{
print_usage(argv);
printf(
"MANDATORY\n"
" --im-pfx-map IM(1)… IM(n)\n"
" The output file names.\n"
" \n"
" --im-sift S(1)… S(n)\n"
" An input time series. It should represents a gray level time\n"
" series. This series will be used to compute the opaque cloud time\n"
" series.\n"
" \n"
"OPTIONS\n"
" --alpha ALPHA\n"
" SIFT distance threshold. Default value is set to 0.2, takes values\n"
" in [0, +1].\n"
" \n"
" --opt-theta THETA\n"
" Threshold, in pixels, used to remove the surface outliers. Default\n"
" value is set to 300. It takes values in [0, +oo].\n"
" \n"
" --version\n"
" display the program version\n"
" \n"
" --help\n"
" display the help\n"
);
return;
}
/*============================================================================*/
void
set_default_values(options_t *opt)
{
opt->alpha = 0.2;
opt->theta = 300;
return;
}
/*============================================================================*/
void
initialize_criteria_t(criteria_t *c)
{
c->nb_criteria = 0;
c->nb_ims = 0;
c->nrow = 0;
c->ncol = 0;
c->c = NULL;
return;
}
/*============================================================================*/
void
delete_criteria_t(criteria_t *ca)
{
criterion_t * head, * cn;
head = ca->c;
cn = head;
/* the list of maps is shared by all features, so it suffices to free it once. */
free_series_f(cn->maps, ca->nb_ims, NULL);
while(cn != NULL)
{
head = head-> next;
if (cn->ims != NULL) free_series_f(cn->ims, cn->nb_ims, NULL);
free(cn->filenames);
free(cn);
cn = head;
}
return;
}
/*============================================================================*/
void
delete_mappes(mappes_t m, int nb_ims)
{
int n;
for (n = 0; n < nb_ims; n++) if (m.sift != NULL) free(m.sift[n]);
if (m.sift != NULL) free(m.sift);
return;
}
/*============================================================================*/
void display_options_values(options_t opt)
{
printf("Threshold α distance SIFT.....: %5.2f\n", opt.alpha);
printf("Threshold surface θ (in pix)..: %5.2f\n", opt.theta);
return;
}
/*============================================================================*/
void
load_criteria_image_series(criteria_t *criteria)
{
int i, nrow, ncol;
int nb_ims = criteria->nb_ims;
criterion_t *c = criteria->c;
while(c != NULL)
{
if (c->type == PREFIXE)
{
c = c->next;
continue;
}
c->ims = malloc(nb_ims * sizeof(float*));
for (i = 0; i < nb_ims; i++)
{
c->ims[i] = iio_read_image_float(c->filenames[i], &ncol, &nrow);
printf("Reading %s\n", c->filenames[i]);
if (criteria->nrow == 0 && criteria->ncol == 0)
{
criteria->nrow = nrow;
criteria->ncol = ncol;
}
else
{
if (criteria->nrow != nrow || criteria->ncol != ncol)
{
printf("[FATAL] load_criteria_image_series() : Images have different sizes. Stop run.\n");
exit(EXIT_FAILURE);
}
}
}
c = c->next;
}
c = criteria->c;
while(c != NULL)
{
c->nb_ims = criteria->nb_ims;
c->nrow = criteria->nrow;
c->ncol = criteria->ncol;
c = c->next;
}
return;
}
/*============================================================================*/
void
display_files_series(criteria_t criteria)
{
int i;
criterion_t *c = criteria.c;
while(c != NULL)
{
if (c->type != PREFIXE)
{
printf("List of images pointer for %s :\n", TAB_FEATURES[c->type]);
for (i = 0; i < c->nb_ims; i++)
{
printf ("c->ims[%d]=%p\n", i, c->ims[i]);
}
}
c = c->next;
}
return;
}
/*============================================================================*/
criterion_t *
load_criterion_t(int criterion, char ** argv, int *position_motifs, int i, int j)
{
int k, l;
criterion_t *feature;
feature = malloc(sizeof(criterion_t));
if (feature == NULL)
{
printf("[FATAL] load_criterion_t() Allocation failed\n");
exit(EXIT_FAILURE);
}
feature->type = criterion;
feature->nb_ims = position_motifs[j + 1] - position_motifs[j] - 1;
feature->filenames = malloc (feature->nb_ims * sizeof (char *));
for (l = 0, k = i + 1; k < position_motifs[j + 1]; k++, l++)
{
feature->filenames[l] = argv[k];
}
feature->ims = NULL;
feature->maps = NULL;
feature->next = NULL;
return(feature);
}
/*============================================================================*/
int
process_command_line (int argc, char **argv, criteria_t *head, options_t *opt)
{
int i, j;
set_default_values(opt);
initialize_criteria_t(head);
int nb_params = 100;
int position_motifs[nb_params];
if (argc == 1)
{
print_usage(argv);
return(1);
}
for (i = 0; i < nb_params; i++)
position_motifs[i] = argc;
for (i = 0, j = 0; i < argc; i++)
{
if (strstr (argv[i], "--im") != NULL || strstr (argv[i], "--opt") != NULL)
{
position_motifs[j] = i;
j++;
}
if (strcmp (argv[i], "-h") == 0 || strcmp (argv[i], "--help") == 0)
{
print_help(argv);
return(1);
}
if (strcmp (argv[i], "-v") == 0 || strcmp (argv[i], "--version") == 0)
{
print_version(argv);
return(1);
}
}
if (j == 0)
{
printf("[FATAL] Incorrect parameters.\n");
return(1);
}
criterion_t * feature;
/* command line processing */
position_motifs[nb_params - 1] = argc;
for (i = 0, j = 0; i < argc; i++)
{
if (!strcmp ("--opt-alpha", argv[i]))
{
opt->alpha = atof (argv[i + 1]);
j++;
}
if (!strcmp ("--opt-theta", argv[i]))
{
opt->theta = atof (argv[i + 1]);
j++;
}
/* file name series options */
/* F := head->c
* head->c := neo
* neo->next := F
*/
else if (!strcmp ("--im-pfx-map", argv[i]))
{
feature = head->c;
head->c = load_criterion_t(PREFIXE, argv, position_motifs, i, j);
head->c->next = feature;
j++;
}
else if (!strcmp ("--im-sift", argv[i]))
{
feature = head->c;
head->c = load_criterion_t(SIFT, argv, position_motifs, i, j);
head->c->next = feature;
head->nb_criteria++;
j++;
}
}
/* coherence tests */
int nb_ims;
feature = head->c;
nb_ims = head->c->nb_ims;
while(feature != NULL)
{
if (feature->nb_ims != nb_ims)
{
printf("[FATAL] Incorrect number of files : %d / %d for %d. Stop run.\n",
feature->nb_ims, nb_ims, feature->type);
return(1);
}
feature = feature->next;
}
head->nb_ims = head->c->nb_ims;
if (head->nb_ims == 0)
{
printf ("[FATAL] No images\n");
return(1);
}
return 0;
}
/*============================================================================*/