FloatImg/Fonderie/interpolator.c

333 lines
7.7 KiB
C
Raw Normal View History

/*
* INTERPOLATOR 2070
*
* +---------------------------------------+
* ! Do not use that software in real life !
* +---------------------------------------+
*
* imported in FloatImg Mon Nov 9 19:08:57 CET 2020
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <glob.h>
#include "../floatimg.h"
2020-11-16 11:12:29 +01:00
#include "fonctions.h"
2020-11-10 03:58:18 +01:00
#include "glitches.h"
2020-11-10 00:50:25 +01:00
#include "crapulator.h"
#include "metriques.h"
2020-12-07 04:45:51 +01:00
#include "filterstack.h"
int verbosity;
2020-11-10 00:50:25 +01:00
int convert_to_gray; /* needed by fonctions.c */
/* -------------------------------------------------------------- */
/* on va essayer de trier l'ordre d'apparition des images
* selon une metrique approximative
*/
typedef struct {
int idx; /* in globbuf.gl_pathv[n] */
float value; /* from metric analyse */
} IdxValue;
static int cmp_idxvalues(const void *pa, const void *pb)
{
return ( ((IdxValue *)pa)->value > ((IdxValue *)pb)->value);
}
2020-12-15 17:49:12 +01:00
int tentative_triage(glob_t *ptr_glob, IdxValue **ptr_idxval,
int method, double *p_average)
{
int idx, foo, nombre;
float metrique;
2020-12-15 17:49:12 +01:00
double average;
char *filename;
IdxValue *idxvalues;
#if DEBUG_LEVEL
2020-11-15 11:47:37 +01:00
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, ptr_glob,
ptr_idxval, method);
#endif
nombre = ptr_glob->gl_pathc;
/* allocate the array for the sorting action */
idxvalues = calloc(nombre, sizeof(IdxValue));
if (NULL==idxvalues) {
fprintf(stderr, "MEMORY ERROR in %s\n", __func__);
exit(1);
}
fprintf(stderr, "IdxValues array at %p\n", idxvalues);
*ptr_idxval = idxvalues;
2020-12-15 17:49:12 +01:00
average = 0.0;
/* compute all the needed values */
for (idx=0; idx<nombre; idx++) {
filename = ptr_glob->gl_pathv[idx];
2020-12-07 22:02:08 +01:00
foo = get_float_metric_from_file(filename, &metrique, method);
if (foo) {
fprintf(stderr, "%s: err %d get metric of '%s'\n", __func__,
foo, filename);
return -1;
}
2020-12-07 04:45:51 +01:00
if (verbosity)
2020-12-18 10:18:09 +01:00
fprintf(stderr, "%5d %s %10.3f\r",
idx, filename, metrique);
idxvalues[idx].idx = idx;
idxvalues[idx].value = metrique;
2020-12-15 17:49:12 +01:00
average += (double)metrique;
}
2020-11-15 11:47:37 +01:00
if (method) {
/* and now, we can massage all our datas */
2020-12-07 22:02:08 +01:00
// fprintf(stderr, "sorting %d ...\n", method);
2020-11-15 11:47:37 +01:00
qsort(idxvalues, nombre, sizeof(IdxValue), cmp_idxvalues);
}
2020-12-03 13:05:44 +01:00
if (verbosity > 1) {
2020-11-16 11:12:29 +01:00
for (idx=0; idx<nombre; idx++) {
2020-12-07 10:11:54 +01:00
printf("%5d %9.3f %5d\n", idx,
2020-11-16 11:12:29 +01:00
idxvalues[idx].value, idxvalues[idx].idx);
fflush(stdout);
}
}
2020-12-15 17:49:12 +01:00
average /= (double)nombre;
*p_average = average;
fprintf(stderr, "\naverage %f\n", average);
return 0;
}
/* -------------------------------------------------------------- */
/*
* This is the mega working loop
*/
2020-11-15 11:47:37 +01:00
int interpolator(char *pattern, char *outdir, int Nsteps,
int infx, int outfx, int sort)
{
2020-11-10 03:58:18 +01:00
FloatImg A, B, Out, *pFirst, *pSecond;
glob_t globbuf;
int foo, idx, ipng, w, h, step;
int curpix;
int iarray[3];
char *cptr, line[200];
float coef, value;
2020-12-15 17:49:12 +01:00
double meanmetric;
IdxValue *idx_values;
2020-12-03 19:47:02 +01:00
fprintf(stderr, " interpolate from '%s' to '%s' with %d steps.\n",
pattern, outdir, Nsteps);
memset(&globbuf, 0, sizeof(glob_t));
foo = glob(pattern, 0, NULL, &globbuf);
2020-12-07 04:45:51 +01:00
fprintf(stderr, "globbing '%s' -> %d, %d files found\n",
pattern, foo, (int)globbuf.gl_pathc);
if (0 == globbuf.gl_pathc) {
fprintf(stderr, "%s : no file found, aborting\n", __func__);
return -1;
}
idx_values = NULL;
2020-12-15 17:49:12 +01:00
foo = tentative_triage(&globbuf, &idx_values, sort, &meanmetric);
2020-12-07 04:45:51 +01:00
if (foo) {
fprintf(stderr, "sort of %p -> %d\n\n", idx_values, foo);
return foo;
}
foo = fimg_fileinfos(globbuf.gl_pathv[0], iarray);
2020-11-10 14:00:22 +01:00
if (FIMG_TYPE_RGB != iarray[2]) {
fprintf(stderr, "can work only on RGB fimg picture, was %d\n",
iarray[2]);
2020-12-15 17:49:12 +01:00
exit(1); /* BLAM! */
2020-11-10 14:00:22 +01:00
}
2020-12-15 17:49:12 +01:00
if (infx) fprintf(stderr, "\tin fx #%d\n", infx);
else fprintf(stderr, "\tno in fx\n");
if (outfx) fprintf(stderr, "\tout fx #%d\n", outfx);
else fprintf(stderr, "\tno out fx\n");
w = iarray[0], h = iarray[1];
2020-11-10 14:00:22 +01:00
fprintf(stderr, "first image size : %dx%d\n", w, h);
fimg_create(&A, w, h, 3); pFirst = &A;
2020-12-07 22:02:08 +01:00
fimg_vdeg_a(&A, idx_values[0].value);
fimg_create(&B, w, h, 3); pSecond = &B;
fimg_create(&Out, w, h, 3);
ipng = 0;
for (idx=0; idx<globbuf.gl_pathc; idx++) {
curpix = idx_values[idx].idx;
cptr = globbuf.gl_pathv[curpix]; /* aliasing filename */
/* read the next file in B */
2020-12-07 04:45:51 +01:00
fprintf(stderr, "%5d / %5d %s\r", idx,
(int)globbuf.gl_pathc, cptr);
foo = fimg_load_from_dump(cptr, &B);
if (foo) {
fprintf(stderr, "load %s from dump -> %d\n", cptr, foo);
continue;
}
value = idx_values[idx].value;
2020-12-03 19:47:02 +01:00
/* here, insert the input filter */
2020-12-12 18:45:44 +01:00
if (infx) {
foo = crapulator(&B, infx, value);
}
else {
foo = filterstack_run(0, &B, 0);
}
2020-11-10 00:50:25 +01:00
if (foo) {
2020-11-20 22:25:30 +01:00
fprintf(stderr, "%s: input fx fail %d\n", __func__, foo);
2020-11-10 00:50:25 +01:00
exit(1);
}
for (step=0; step<Nsteps; step++) {
coef = (float)step / (float)Nsteps;
fimg_interpolate(pSecond, pFirst, &Out, coef);
2020-11-15 21:31:02 +01:00
/* here we can insert the OUTPUT filter */
2020-12-07 04:45:51 +01:00
// foo = crapulator(&Out, outfx, value);
//if (foo) {
// fprintf(stderr, "\n%s: out fx %d failure %d\n",
// __func__, outfx, foo);
// exit(1);
// }
2020-12-12 18:45:44 +01:00
foo = filterstack_run(1, &Out, 0);
2020-12-07 04:45:51 +01:00
if (foo) {
2020-12-12 18:45:44 +01:00
fprintf(stderr, "run filt stack--> %d\n", foo);
2020-12-07 04:45:51 +01:00
return foo;
}
sprintf(line, "%s/%05d.png", outdir, ipng);
foo = fimg_save_as_png(&Out, line, 0);
if (foo) {
fprintf(stderr, "err saving %s\n", line);
return -8;
}
ipng++;
}
#if 1
/* temporary hack : move datas */
fimg_copy_data(&B, &A);
#else
/* swap pointers to the two picz */
pTmp = pSecond;
pSecond = pFirst;
pFirst = pTmp;
2020-11-10 00:50:25 +01:00
/* XXX THIS CODE DON'T WORK !!! */
#endif
2020-12-07 04:45:51 +01:00
}
fprintf(stderr, "\ngenerated %d png files\n", ipng);
return 0;
}
/* -------------------------------------------------------------- */
2020-11-10 03:58:18 +01:00
void help(void)
{
2020-12-03 13:05:44 +01:00
puts("\tINTERPOLATOR");
puts("usage:\n\tinterpolator [options] <inglob> <outdir> <nbsteep>");
2020-11-10 03:58:18 +01:00
/* may be we can make options incoherent, like
* the options of 'fonderie' software ?
*/
2020-12-03 13:05:44 +01:00
puts("options:");
puts("\t-S nn\tmysterious sort");
2020-12-07 04:45:51 +01:00
puts("\t-F i:j\tfilter chain");
2020-12-30 14:42:44 +01:00
puts("\t-L\tlist available filters");
2020-12-03 13:05:44 +01:00
puts("\t-w nn\tinput effect");
puts("\t-x nn\toutput effect");
2020-12-07 04:45:51 +01:00
puts("\t-v\tincrease verbosity");
2020-11-10 03:58:18 +01:00
exit(0);
}
/* -------------------------------------------------------------- */
int main (int argc, char *argv[])
{
int foo;
int nbrsteps = 9;
2020-11-10 03:58:18 +01:00
int opt;
2020-11-15 11:47:37 +01:00
int inFx = 0;
int outFx = 0;
int sort = 0;
char *InFchain = "0";
char *OutFchain = "0";
fprintf(stderr, "*** %s : compiled by tTh, %s %s\n", __FILE__,
__DATE__, __TIME__);
fimg_print_version(2);
2020-12-15 17:49:12 +01:00
//#if DEBUG_LEVEL
/* this is for the debug off calling shellscript */
for (foo=0; foo<argc; foo++)
fprintf(stderr, "%5d %s\n", foo, argv[foo]);
//#endif
2020-12-30 14:42:44 +01:00
while ((opt = getopt(argc, argv, "E:F:hLS:vw:x:")) != -1) {
2020-11-10 03:58:18 +01:00
switch(opt) {
case 'E': InFchain = optarg; break;
case 'F': OutFchain = optarg; break;
2020-11-10 14:00:22 +01:00
case 'h': help(); break;
2020-12-30 14:42:44 +01:00
case 'L':
list_crapulors("available filters");
exit(0);
2020-11-15 11:47:37 +01:00
case 'S': sort = atoi(optarg); break;
2020-11-10 03:58:18 +01:00
case 'v': verbosity++; break;
2020-11-15 11:47:37 +01:00
case 'w': inFx = atoi(optarg); break;
case 'x': outFx = atoi(optarg); break;
2020-11-10 03:58:18 +01:00
}
}
2020-12-15 17:49:12 +01:00
//#if DEBUG_LEVEL
fprintf(stderr, "%s: argc = %d, optind = %d\n", argv[0], argc, optind);
//#endif
2020-11-10 03:58:18 +01:00
2020-11-15 11:47:37 +01:00
if (3 != (argc-optind)) {
fprintf(stderr, "args: [options] <inglob> <outdir> <nbsteep>\n");
exit(1);
}
foo = parse_filter_chain(0, InFchain);
2020-12-07 04:45:51 +01:00
if (foo) {
fprintf(stderr, "err %d parsing '%s'\n", foo, InFchain);
exit(1);
}
foo = parse_filter_chain(1, OutFchain);
if (foo) {
fprintf(stderr, "err %d parsing '%s'\n", foo, OutFchain);
2020-12-07 04:45:51 +01:00
exit(1);
}
2020-12-15 17:49:12 +01:00
if (verbosity > 1) {
2020-12-24 10:28:56 +01:00
puts("=========================");
2020-12-12 18:45:44 +01:00
filterstack_list(0, __FILE__);
filterstack_list(1, __FILE__);
2020-12-24 10:28:56 +01:00
puts("=========================");
2020-12-12 18:45:44 +01:00
}
2020-12-07 04:45:51 +01:00
2020-11-15 11:47:37 +01:00
nbrsteps = atoi(argv[optind+2]);
foo = interpolator(argv[optind], argv[optind+1], nbrsteps,
inFx, outFx, sort);
fprintf(stderr, "interpolator give us a %d score\n", foo);
return 0;
}
/* -------------------------------------------------------------- */