322 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			322 lines
		
	
	
		
			7.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/*
 | 
						|
 *		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"
 | 
						|
 | 
						|
#include  "fonctions.h"
 | 
						|
#include  "glitches.h"
 | 
						|
#include  "crapulator.h"
 | 
						|
#include  "metriques.h"
 | 
						|
#include  "filterstack.h"
 | 
						|
 | 
						|
int		verbosity;
 | 
						|
 | 
						|
/* -------------------------------------------------------------- */
 | 
						|
/*  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);
 | 
						|
}
 | 
						|
 | 
						|
int tentative_triage(glob_t *ptr_glob, IdxValue **ptr_idxval,
 | 
						|
		int method, double *p_average)
 | 
						|
{
 | 
						|
int		idx, foo, nombre;
 | 
						|
float		metrique;
 | 
						|
double		average;
 | 
						|
char		*filename;
 | 
						|
IdxValue	*idxvalues;
 | 
						|
 | 
						|
#if DEBUG_LEVEL
 | 
						|
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;
 | 
						|
average     = 0.0;
 | 
						|
 | 
						|
/* compute all the needed values */
 | 
						|
for (idx=0; idx<nombre; idx++) {
 | 
						|
	filename = ptr_glob->gl_pathv[idx];
 | 
						|
	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;
 | 
						|
		}
 | 
						|
	if (verbosity)
 | 
						|
		fprintf(stderr, "%5d   %s   %10.3f\r", 
 | 
						|
					idx, filename, metrique);
 | 
						|
	idxvalues[idx].idx = idx;
 | 
						|
	idxvalues[idx].value = metrique;
 | 
						|
	average += (double)metrique;
 | 
						|
	}
 | 
						|
 | 
						|
if (method) {
 | 
						|
	/* and now, we can massage all our datas */
 | 
						|
	// fprintf(stderr, "sorting %d ...\n", method);
 | 
						|
	qsort(idxvalues, nombre, sizeof(IdxValue), cmp_idxvalues);
 | 
						|
	}
 | 
						|
 | 
						|
if (verbosity > 1) {
 | 
						|
	for (idx=0; idx<nombre; idx++) {
 | 
						|
		printf("%5d   %9.3f  %5d\n", idx,
 | 
						|
				idxvalues[idx].value, idxvalues[idx].idx);
 | 
						|
		fflush(stdout);
 | 
						|
		}
 | 
						|
	}
 | 
						|
average /= (double)nombre;
 | 
						|
*p_average = average;
 | 
						|
 | 
						|
fprintf(stderr, "\naverage %f\n", average);
 | 
						|
 | 
						|
return 0;
 | 
						|
}
 | 
						|
 | 
						|
/* -------------------------------------------------------------- */
 | 
						|
/*
 | 
						|
 *		This is the mega working loop
 | 
						|
 */
 | 
						|
int interpolator(char *pattern, char *outdir, int Nsteps,
 | 
						|
				int infx, int outfx, int sort)
 | 
						|
{
 | 
						|
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;
 | 
						|
double		meanmetric;
 | 
						|
IdxValue	*idx_values;			/* gni? */
 | 
						|
 | 
						|
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);
 | 
						|
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;
 | 
						|
foo = tentative_triage(&globbuf, &idx_values, sort, &meanmetric);
 | 
						|
if (foo) {
 | 
						|
	fprintf(stderr, "sort of %p -> %d\n\n", idx_values, foo);
 | 
						|
	return foo;
 | 
						|
	}
 | 
						|
 | 
						|
foo = fimg_fileinfos(globbuf.gl_pathv[0], iarray);
 | 
						|
if (FIMG_TYPE_RGB != iarray[2]) {
 | 
						|
	fprintf(stderr, "can work only on RGB fimg picture, was %d\n",
 | 
						|
							iarray[2]);	
 | 
						|
	exit(1);	/* BLAM! */
 | 
						|
	}
 | 
						|
 | 
						|
#if 0
 | 
						|
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");
 | 
						|
#endif
 | 
						|
 | 
						|
w = iarray[0], h = iarray[1];
 | 
						|
fprintf(stderr, "first image size : %dx%d\n", w, h);
 | 
						|
 | 
						|
fimg_create(&A,   w, h, 3);	pFirst  = &A;
 | 
						|
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 */
 | 
						|
	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;
 | 
						|
 | 
						|
	/* here was the input filter */
 | 
						|
	foo = filterstack_run(0, &B, 0);
 | 
						|
	if (foo) {
 | 
						|
		fprintf(stderr, "%s: input fx fail %d\n", __func__, foo);
 | 
						|
		exit(1);
 | 
						|
		}
 | 
						|
 | 
						|
	for (step=0; step<Nsteps; step++) {
 | 
						|
		coef = (float)step / (float)Nsteps;
 | 
						|
		fimg_interpolate(pSecond, pFirst, &Out, coef);
 | 
						|
 | 
						|
		foo = filterstack_run(1, &Out, 0);
 | 
						|
		if (foo) {
 | 
						|
			fprintf(stderr, "run filt stack--> %d\n", foo);
 | 
						|
			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;
 | 
						|
	/* XXX THIS CODE DON'T WORK !!! */
 | 
						|
#endif
 | 
						|
 | 
						|
	}
 | 
						|
 | 
						|
fprintf(stderr, "\ngenerated %d png files\n", ipng);
 | 
						|
 | 
						|
return 0;
 | 
						|
}
 | 
						|
/* -------------------------------------------------------------- */
 | 
						|
void help(void)
 | 
						|
{
 | 
						|
puts("\tINTERPOLATOR");
 | 
						|
puts("usage:\n\tinterpolator [options] <inglob> <outdir> <nbsteep>");
 | 
						|
 | 
						|
/*	may be we can make options incoherent, like 
 | 
						|
 *	the options of 'fonderie' software ?
 | 
						|
 */
 | 
						|
puts("options:");
 | 
						|
puts("\t-S nn\t\tmysterious sort");
 | 
						|
puts("\t-E i:bla:k\tinput  filter chain");
 | 
						|
puts("\t-F name:j\toutput filter chain");
 | 
						|
puts("\t-L\t\tlist available filters");
 | 
						|
// OBSOLETE puts("\t-w nn\t\tinput effect");
 | 
						|
// OBSOLETE puts("\t-x nn\t\toutput effect");
 | 
						|
puts("\t-v\t\tincrease verbosity");
 | 
						|
 | 
						|
if (verbosity) {
 | 
						|
	list_crapulors("available filters");
 | 
						|
	}
 | 
						|
 | 
						|
exit(0);
 | 
						|
}
 | 
						|
/* -------------------------------------------------------------- */
 | 
						|
int main (int argc, char *argv[])
 | 
						|
{
 | 
						|
int		foo;
 | 
						|
int		nbrsteps = 9;
 | 
						|
int		opt;
 | 
						|
// 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);
 | 
						|
 | 
						|
#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
 | 
						|
 | 
						|
while ((opt = getopt(argc, argv, "E:F:hLS:vw:x:")) != -1) {
 | 
						|
	switch(opt) {
 | 
						|
		case 'E':	InFchain = optarg;	break;
 | 
						|
		case 'F':	OutFchain = optarg;	break;
 | 
						|
		case 'h':	help();			break;
 | 
						|
		case 'L':
 | 
						|
			list_crapulors("available filters");
 | 
						|
			exit(0);
 | 
						|
		case 'S':	sort = atoi(optarg);	break;
 | 
						|
		case 'v':	verbosity++;		break;
 | 
						|
// OBSOLETE 	case 'w':	inFx = atoi(optarg);	break;
 | 
						|
// OBSOLETE 	case 'x':	outFx = atoi(optarg);	break;
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
#if DEBUG_LEVEL
 | 
						|
fprintf(stderr, "%s: argc = %d, optind = %d\n", argv[0], argc, optind);
 | 
						|
#endif
 | 
						|
 | 
						|
if (3 != (argc-optind)) {
 | 
						|
	fprintf(stderr, "args: [options] <inglob> <outdir> <nbsteep>\n");
 | 
						|
	exit(1);
 | 
						|
	}
 | 
						|
 | 
						|
foo = parse_filter_chain(0, InFchain);
 | 
						|
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);
 | 
						|
	exit(1);
 | 
						|
	}
 | 
						|
 | 
						|
if (verbosity > 1) {
 | 
						|
	puts("=========================");
 | 
						|
	filterstack_list(0, __FILE__);
 | 
						|
	filterstack_list(1, __FILE__);
 | 
						|
	puts("=========================");
 | 
						|
	}
 | 
						|
 | 
						|
nbrsteps = atoi(argv[optind+2]);
 | 
						|
foo = interpolator(argv[optind], argv[optind+1], nbrsteps,
 | 
						|
					0, 0, sort);
 | 
						|
 | 
						|
fprintf(stderr, "interpolator give us a %d score\n", foo);
 | 
						|
 | 
						|
return 0;
 | 
						|
}
 | 
						|
/* -------------------------------------------------------------- */
 |