diff --git a/.gitignore b/.gitignore index 8ba49abc..a95a764e 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ doc/*.idx doc/*.ilg doc/*.ind doc/co*.tex + funcs/t funcs/*.o funcs/*.png @@ -61,4 +62,6 @@ tools/fimgfx tools/*.png tools/*.tiff +Fonderie/*.o +Fonderie/fonderie diff --git a/Fonderie/Makefile b/Fonderie/Makefile new file mode 100644 index 00000000..155459ac --- /dev/null +++ b/Fonderie/Makefile @@ -0,0 +1,28 @@ + + +COPT = -g -no-pie -Wall -O3 -DDEBUG_LEVEL=0 -Werror=parentheses +LIBS = -lfloatimg -lpnglite -lm +OBJS = fonctions.o sfx.o crapulator.o +DEPS = fonctions.h crapulator.h + +fonderie: fonderie.c fonctions.h ${OBJS} Makefile + gcc ${COPT} $< ${OBJS} ${LIBS} -o $@ + +crapulator.o: crapulator.c ${DEPS} + gcc ${COPT} -c $< + +fonctions.o: fonctions.c fonctions.h Makefile + gcc ${COPT} -c $< + +sfx.o: sfx.c fonctions.h Makefile + gcc ${COPT} -c $< + +# --------------------------------------------------------- + +TOTAR = *.c *.h Makefile \ + *.sh + + + +# --------------------------------------------------------- + diff --git a/Fonderie/README.md b/Fonderie/README.md new file mode 100644 index 00000000..ca7e8c12 --- /dev/null +++ b/Fonderie/README.md @@ -0,0 +1,22 @@ +# Fonderie + +Avec toutes ces fonctions disponibles et `grabvidseq`, nous +savons faire des images **floues***. L'étape suivante, les plus +pervers d'entre vous le savent déja, est celle de la création +de **films flous**. + +## fonderie + +Le programme principal, utilisé à partir de la ligne de commande +avec une foule d'options aux mnémoniques abscons. + +Rassurez-vous, en général ils sont wrappables dans des scripts +shell. Il est même possible un jour qu'ils puissent lire des +paramètres dans `$(env)`. + + +## crapulator + +C'est dans ce module qu'est codé le moteur de filtrage, utilisé +aussi bien en entrée qu'en sortie. + diff --git a/Fonderie/crapulator.c b/Fonderie/crapulator.c new file mode 100644 index 00000000..dc5acfdb --- /dev/null +++ b/Fonderie/crapulator.c @@ -0,0 +1,122 @@ +/* + * crapulator.c + */ + +#include +#include + +#include + +#include "fonctions.h" +#include "crapulator.h" + +/* -------------------------------------------------------------- */ + +int crapulator(FloatImg *image, int idFx, float fval) +{ +int retval, foo; +FloatImg imgtmp; +static int count = 0; +int flag_debug = 0; +float value; + +#if DEBUG_LEVEL +fprintf(stderr, ">>> %s ( %p %d %f )\n", __func__, + image, idFx, fval); +#endif + +if (666==count) { + flag_debug = 1; + fprintf(stderr, "DEBUG PT 1 in %s:%d\n", __func__, __LINE__); + fimg_save_as_png(image, "source.png", 0); + } + +switch (idFx) { + case 0: /* DO NOTHING */ + retval = 0; break; + + case 1: + fimg_cos_01(image, image, + fimg_get_maxvalue(image)); + break; + case 2: + fimg_cos_010(image, image, + fimg_get_maxvalue(image)); + break; + case 3: + value = fimg_get_maxvalue(image); + fimg_mul_cste(image, -1.0); + fimg_add_cste(image, value); + foo = fimg_count_negativ(image); + if (foo) { + fimg_dump_to_file(image, "err.fimg", 0); + fprintf(stderr, "%s negativ %d\n", + __func__, foo); + return -78; + } + break; + case 4: + brotche_rand48_a(image, 0.20, + fimg_get_maxvalue(image)); + break; + case 5: + brotche_rand48_b(image, 0.10, + fimg_get_maxvalue(image)*0.8); + break; + case 6: + fimg_killcolors_a(image, 0.0); + break; + + case 7: + retval = fimg_colors_mixer_a(image, 2.0); + break; + + case 8: + fimg_clone(image, &imgtmp, 0); + fimg_clear(&imgtmp); + if (flag_debug) { + fprintf(stderr, "DEBUG A contour 2x2\n"); + fimg_save_as_png(image, "before.png", 0); + fimg_dump_to_file(image, "before.fimg", 0); + } + retval = fimg_contour_2x2(image, &imgtmp, 0); + if (retval) { + fprintf(stderr, "%s : err contour %d\n", + __func__, retval); + exit(1); + } + if (flag_debug) { + fprintf(stderr, "DEBUG B contour 2x2\n"); + // fimg_save_as_png(&imgtmp, "contour.png", 0); + fimg_dump_to_file(&imgtmp, "contour.fimg", 0); + } + fimg_copy_data(&imgtmp, image); + fimg_destroy(&imgtmp); + break; + + case 9: + retval = fimg_classif_trial(image, image, 0.37, 0); + if (retval) { + fprintf(stderr, "err %d in classif\n", retval); + exit(1); + } + break; + + default : + fprintf(stderr, "%s : effect #%d invalid\n", + __func__, idFx); + return -77; + } + +if (flag_debug) { + fprintf(stderr, "DEBUG PT 2 in %s:%d\n", __func__, __LINE__); + fimg_save_as_png(image, "after.png", 0); + } + +count++; flag_debug = 0; + +return retval; +} + +/* -------------------------------------------------------------- */ + diff --git a/Fonderie/crapulator.h b/Fonderie/crapulator.h new file mode 100644 index 00000000..58d15e99 --- /dev/null +++ b/Fonderie/crapulator.h @@ -0,0 +1,6 @@ +/* + * crapulator.h + */ + +int crapulator(FloatImg *image, int id_effect, float fparam); + diff --git a/Fonderie/fonctions.c b/Fonderie/fonctions.c new file mode 100644 index 00000000..5544e2ec --- /dev/null +++ b/Fonderie/fonctions.c @@ -0,0 +1,156 @@ +/* + * Fonctions de la Fonderie du Cumul + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * Du code bien cracra / tTh / Tetalab + */ +#include +#include +#include +#include + +#include + +#include "fonctions.h" +#include "crapulator.h" + +/* -------------------------------------------------------------- */ +/* global vars from main + */ +extern int verbosity; + +/* private vars of this module - it was very dirty + */ +static A_Fifo g_fifo; + +/* -------------------------------------------------------------- */ + +int faire_la_somme(A_Fifo *pfifo, FloatImg *destination, int step) +{ +int idx, foo; +FloatImg *pdest; + +if (NULL==destination) { + pdest = &(pfifo->total); } +else { + pdest = destination; } + +fimg_clear(pdest); +for (idx=0; idxnbslots; idx += step) { + foo = fimg_add_2(&(pfifo->slots[idx]), pdest); + if (foo) + { + fprintf(stderr, "%s: err %d on add_2\n", __func__, foo); + abort(); + } + } + +return 0; +} +/* -------------------------------------------------------------- */ +/* -------------------------------------------------------------- */ +/* + * this func save the fifo content as + * - float FIMG + * - 16 bits PNM + * - 8 bits PNG + */ +int export_fifo(char *fname, int postproc, int step) +{ +int foo, type; + +foo = faire_la_somme(&g_fifo, NULL, step); + +/* BEGIN GRUIK CODE */ +extern int convert_to_gray; +/* END OF THE KLUGE */ +if (convert_to_gray) { + fimg_to_gray(&g_fifo.total); + // fprintf(stderr, "%p gray-washed\n", &fifo.total); + } + +foo = crapulator(&g_fifo.total, postproc, 0.0); +if (foo) { + fprintf(stderr, "%s: ERR post process picture -> %d\n", + __func__, foo); + return foo; + } + +type = format_from_extension(fname); +switch (type) { + case FILE_TYPE_PNG: + foo = fimg_save_as_png(&g_fifo.total, fname, 0); + break; + case FILE_TYPE_PNM: + foo = fimg_save_as_pnm(&g_fifo.total, fname, 0); + break; + case FILE_TYPE_FIMG: + foo = fimg_dump_to_file(&g_fifo.total, fname, 0); + break; + default: + fprintf(stderr, "%s : type of '%s' unknow\n", + __func__, fname); + foo = 888; + break; + } + +if (foo) { + fprintf(stderr, "ERR EXPORT '%s' is %d\n", fname, foo); + exit(3); + } + +return 0; +} +/* -------------------------------------------------------------- */ +int insert_picture(FloatImg *src) +{ +FloatImg *dst; +int nbre; + +/* + * this is the where we can insert the 'input filter' + */ + +dst = &g_fifo.slots[g_fifo.next]; + +nbre = dst->width * dst->height * dst->type; +memcpy(dst->R, src->R, nbre*sizeof(float)); + +g_fifo.next++, g_fifo.next %= g_fifo.nbslots; +// maybe we can write : +// (++fifo.next) %= fifo.nbslots; + +if (verbosity > 2) fprintf(stderr, "%s : next slot %d\n", + __func__, g_fifo.next); + +return 0; +} +/* -------------------------------------------------------------- */ +int create_fifo(int nbslot, int w, int h, int t) +{ +int foo, idx; + +#if DEBUG_LEVEL +fprintf(stderr, ">>> %s ( %d %dx%d %d )\n", __func__, + nbslot, w, h, t); +#endif + +memset(&g_fifo, 0, sizeof(A_Fifo)); + +g_fifo.nbslots = nbslot; + +g_fifo.slots = calloc(nbslot, sizeof(FloatImg)); +if (NULL==g_fifo.slots) abort(); +for (idx=0; idx +#include +#include +#include +#include +#include + +#include "fonctions.h" +#include "crapulator.h" + +int verbosity; +int convert_to_gray; + +/* -------------------------------------------------------------- */ +int traite_une_image(FloatImg *image, int proc, int step) +{ +static int numero; +int foo; +char ligne[200]; + +/* here, we put the picz in the fifo machinery */ +foo = insert_picture(image); +if (foo) { + fprintf(stderr, "%s: err %d on insert\n", __func__, foo); + return foo; + } + +sprintf(ligne, "p8/%05d.png", numero); +/* ^^^ + XXX hardcoded value ? wtf ? + */ + +foo = export_fifo(ligne, proc, step); +if (foo) { + fprintf(stderr, "%s: err %d on export\n", __func__, foo); + return foo; + } +numero++; /* VERY IMPORTANT :) */ + +return 0; +} +/* -------------------------------------------------------------- */ +int insert_blank(FloatImg *image, int nbre, int pproc) +{ +int idx, foo; + +fimg_clear(image); + +for (idx=0; idx>> %s ( '%s' -> '%s' %d )\n", __func__, + pattern, outdir, szfifo); +#endif + +fprintf(stderr, "\tstep is %d\n", step); + +(void)fimg_timer_set(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"); + +foo = create_fifo(szfifo, 640, 480, FIMG_TYPE_RGB); +fprintf(stderr, "init fifo (%d slots) --> %d\n", szfifo, foo); + +fimg_create(&input, 640, 480, 3); + +/* XXX inject a few stange pics in the fifo */ +insert_blank(&input, BLANK, outfx); + +memset(&globbuf, 0, sizeof(glob_t)); +foo = glob(pattern, 0, NULL, &globbuf); +fprintf(stderr, "glob '%s' -> %d, %ld files found\n", pattern, foo, + globbuf.gl_pathc); + +for (idx=0; idx %d\n", idx, foo); + continue; + } + + /* ========================= */ + /* FSCKING INPUT FILTER HERE */ + foo = crapulator(&input, infx, 0.42); + if (foo) { + fprintf(stderr, "%s crapulator -> %d\n", __func__, foo); + exit(1); + } + + foo = traite_une_image(&input, outfx, step); + if (foo) { + fprintf(stderr, "traitement %s -> %d WTF?\n", cptr, foo); + break; + } + fprintf(stderr, "\t%5d\r", idx); + } + +fputs("\n", stderr); + +insert_blank(&input, BLANK, outfx); + +fin = fimg_timer_get(0); +if (idx) { + fprintf(stderr, "\nelapsed %.2f seconds, %.2f s/pic\n", fin, fin/idx); + } +else { + fprintf(stderr, "\nelapsed %.2f seconds\n", fin); + } + +return 8; +} +/* -------------------------------------------------------------- */ +void help(void) +{ +puts("\tFONDERIE\noptions:"); + +puts("\t-g\tconvert to gray"); +puts("\t-I\tinput glob pattern"); +puts("\t-O\toutput directory"); +puts("\t-T\tfifo size"); +puts("\t-v\tincrease verbosity"); +puts("\t-w\tinput effect"); +puts("\t-x\toutput effect"); + +exit(0); +} +/* -------------------------------------------------------------- */ +int main (int argc, char *argv[]) +{ +int foo, opt; +int fifosize = 10; +char *in_pattern = "capture/?????.fimg"; +char *out_dir = "p8"; +int in_effect = 0; +int out_effect = 0; +int steps = 1; + +fprintf(stderr, "*** %s :\n\tcompiled by tTh, %s %s\n\tpid %d\n", + argv[0], __DATE__, __TIME__, getpid()); +fimg_print_version(2); + +while ((opt = getopt(argc, argv, "ghI:O:s:T:vx:")) != -1) { + switch(opt) { + + case 'g': convert_to_gray = 1; + break; + case 'h': help(); + break; + case 'I': in_pattern = optarg; + break; + case 'O': out_dir = optarg; + break; + case 'T': fifosize = atoi(optarg); + break; + case 'v': verbosity++; + break; + case 'w': in_effect = atoi(optarg); + break; + case 'x': out_effect = atoi(optarg); + break; + case 's': steps = atoi(optarg); + break; + } + } + +foo = demarre_la_machine(in_pattern, out_dir, fifosize, in_effect, + out_effect, steps); +fprintf(stderr, "retour du big-run de la machine -> %d\n", foo); + +return 0; +} +/* -------------------------------------------------------------- */ diff --git a/Fonderie/sfx.c b/Fonderie/sfx.c new file mode 100644 index 00000000..e56841f5 --- /dev/null +++ b/Fonderie/sfx.c @@ -0,0 +1,76 @@ +/* + * SPECIAL EFFECTS + * + * Du code bien cracra / tTh / Tetalab + */ +#include +#include +#include +#include + +#include + +#include "fonctions.h" + +/* -------------------------------------------------------------- */ +/* global vars from main + */ +extern int verbosity; + +/* -------------------------------------------------------------- */ + +/* -------------------------------------------------------------- */ +int brotche_rand48_a(FloatImg *fimg, float ratio, float mval) +{ +int nbpix, todo, foo; +int x, y; +float fval; + +nbpix = fimg->width * fimg->height; +todo = (int)((float)nbpix * ratio); +if (verbosity > 1) { + fprintf(stderr, "%s: ratio %f nbpix %d todo %d\n", __func__, + ratio, nbpix, todo); + } + +for (foo=0; foowidth; + y = rand() % fimg->height; + fimg_plot_rgb(fimg, x, y, fval, fval, fval); + } + +return 0; +} +/* -------------------------------------------------------------- */ +int brotche_rand48_b(FloatImg *fimg, float ratio, float mval) +{ +int nbpix, todo, foo; +int x, y; +float fval; + +nbpix = fimg->width * fimg->height; +todo = (int)((float)nbpix * ratio); +if (verbosity > 1) { + fprintf(stderr, "%s: ratio %f nbpix %d todo %d\n", __func__, + ratio, nbpix, todo); + } + +for (foo=0; foowidth-2)); + y = rand() % fimg->height; + fimg_plot_rgb(fimg, x-1, y, fval, 0.0, 0.0); + fimg_plot_rgb(fimg, x , y, 0.0, 0.0, fval); + fimg_plot_rgb(fimg, x+1, y, 0.0, fval, 0.0); + } + +return 0; +} +/* -------------------------------------------------------------- */ + + + + diff --git a/README.md b/README.md index f8232f40..816880c4 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,8 @@ le canal IRC #tetalab sur le réseau de Par ailleurs, d'autres expérimentations sont [en cours](http://la.buvette.org/photos/cumul/fonderie/vidz.html#interpolator) sur le traitement et l'assemblage de ces images floues dans le but de faire -des films flous. Je sais aussi qu'un autre _diehard coder_ travaille sur la -parallélisation de certaines opérations. +des films flous. + +Un logiciel à base de [moyenne mobile](fonderie/) est en bonne voie. + *En avant vers l'infini, et au-delà...* - - diff --git a/floatimg.h b/floatimg.h index f3d402db..3f542a9f 100644 --- a/floatimg.h +++ b/floatimg.h @@ -3,7 +3,7 @@ * ugly code from tTh */ -#define FIMG_VERSION 109 +#define FIMG_VERSION 112 /* * in memory descriptor @@ -98,7 +98,7 @@ int fimg_lissage_2x2(FloatImg *img); int fimg_filter_3x3(FloatImg *s, FloatImg *d, FimgFilter3x3 *filtr); -int fimg_contour_2x2(FloatImg *psrc, FloatImg *pdst, int notused); +int fimg_contour_2x2(FloatImg *psrc, FloatImg *pdst, int reverse); /* 'sfx0' module */ int fimg_killcolors_a(FloatImg *fimg, float fval); @@ -109,6 +109,10 @@ int fimg_colors_mixer_a(FloatImg *fimg, float fval); /* #coronamaison */ int fimg_rotate_90(FloatImg *src, FloatImg *dst, int notused); + +/* universal exporter XXX */ +int fimg_export_picture(FloatImg *pic, char *fname, int flags); + /* PNM files module */ int fimg_save_as_pnm(FloatImg *head, char *fname, int flags); int fimg_load_from_pnm(char *fname, FloatImg *head, int notused); @@ -141,6 +145,8 @@ int fimg_desaturate(FloatImg *src, FloatImg *dst, int k); /* module funcs/geometry.c */ int fimg_halfsize_0(FloatImg *src, FloatImg *dst, int notused); +int fimg_displacement_0(FloatImg *psrc, FloatImg *pdst, int flags); + /* module funcs/rampes.c */ int fimg_hdeg_a(FloatImg *img, double dcoef); int fimg_vdeg_a(FloatImg *img, double dcoef); @@ -178,6 +184,8 @@ int fimg_save_as_png(FloatImg *src, char *outname, int flags); int fimg_test_pattern(FloatImg *fimg, int type, double dval); int fimg_draw_something(FloatImg *fimg); +/* file is 'funcs/utils.c' */ +void fimg_print_minmax(float minmax[6], char *titre); int parse_WxH(char *str, int *pw, int *ph); int parse_double(char *str, double *dptr); int format_from_extension(char *fname); diff --git a/funcs/Makefile b/funcs/Makefile index 971c09e3..4e398651 100644 --- a/funcs/Makefile +++ b/funcs/Makefile @@ -5,7 +5,8 @@ DEPS = ../floatimg.h Makefile OBJS = fimg-png.o fimg-tiff.o misc-plots.o filtrage.o utils.o \ fimg-libpnm.o rampes.o sfx0.o geometry.o rotate.o \ equalize.o fimg-fits.o saturation.o histogram.o \ - hsv.o classif.o contour2x2.o qsortrgb.o + hsv.o classif.o contour2x2.o qsortrgb.o exporter.o \ + displacement.o dithering.o #--------------------------------------------------------------- @@ -19,6 +20,9 @@ t: t.c $(DEPS) ../libfloatimg.a ../libfloatimg.a: $(OBJS) $(AR) r $@ $? +displacement.o: displacement.c + gcc $(COPT) -c $< + fimg-png.o: fimg-png.c $(DEPS) gcc $(COPT) -c $< @@ -52,6 +56,10 @@ histogram.o: histogram.c $(DEPS) equalize.o: equalize.c $(DEPS) gcc $(COPT) -c $< +dithering.o: dithering.c $(DEPS) + gcc $(COPT) -c $< + + sfx0.o: sfx0.c $(DEPS) gcc $(COPT) -c $< @@ -67,6 +75,9 @@ classif.o: classif.c $(DEPS) qsortrgb.o: qsortrgb.c $(DEPS) gcc $(COPT) -c $< +exporter.o: exporter.c $(DEPS) + gcc $(COPT) -c $< + hsv.o: hsv.c $(DEPS) gcc $(COPT) -c $< diff --git a/funcs/README.md b/funcs/README.md new file mode 100644 index 00000000..65b2f6eb --- /dev/null +++ b/funcs/README.md @@ -0,0 +1,20 @@ +# Fonctions + +Plein de fonctions qu'il serait bon de documenter :) + +## Contours + +Détecter des contours est une activité respectable. + +## Exporter + +Une méta-fonction qui va sauvegarder (dans la mesure de ses conséquences) +une image en fonction de l'extension du nom de fichier. + +## Sfx + +Effets spéciaux divers. + +## Dithering + +Work in progress... diff --git a/funcs/classif.c b/funcs/classif.c index eb6dc373..29860f33 100644 --- a/funcs/classif.c +++ b/funcs/classif.c @@ -9,7 +9,7 @@ #include "../floatimg.h" -int verbosity; +extern int verbosity; /* --------------------------------------------------------------------- */ /* nouveau 2 octobre 2020, juste avant sonoptic de la pluie craignos */ @@ -21,9 +21,19 @@ float range, dist, rgb[3], dr, dg, db; int x, y, on, off; #if DEBUG_LEVEL -fprintf(stderr, ">>> %s ( %p %p %f %d )\n", __func__, psrc, pdst, fval, notused); +fprintf(stderr, ">>> %s ( %p %p %f %d )\n", __func__, + psrc, pdst, fval, notused); #endif +if (FIMG_TYPE_RGB != psrc->type) { + fprintf(stderr, "%s: bad src type %d\n", __func__, psrc->type); + return -7; + } +if (fimg_images_not_compatible(psrc, pdst)) { + fprintf(stderr, "%s: bad dst type %d\n", __func__, pdst->type); + return -8; + } + /* calculer les amplitudes RGB de l'image source */ fimg_get_minmax_rgb(psrc, minmax); delta[0] = minmax[1] - minmax[0]; @@ -37,7 +47,7 @@ range = delta[0]; if (delta[1] 1) fprintf(stderr, "deltas : %f %f %f / %f\n", delta[0], delta[1], delta[2], range); @@ -45,7 +55,7 @@ if (verbosity ) fprintf(stderr, "deltas : %f %f %f / %f\n", baryc[0] = (minmax[1] + minmax[0]) / 2; baryc[1] = (minmax[3] + minmax[2]) / 2; baryc[2] = (minmax[5] + minmax[4]) / 2; -if (verbosity) fprintf(stderr, "barycs : %f %f %f\n", +if (verbosity > 1) fprintf(stderr, "barycs : %f %f %f\n", baryc[0], baryc[1], baryc[2]); on = off = 0; @@ -83,7 +93,7 @@ for (y=0; yheight; y++) { } } -fprintf(stderr, "on %d off %d\n", on, off); +if (verbosity > 1) fprintf(stderr, "on %d off %d\n", on, off); return 0; } diff --git a/funcs/contour2x2.c b/funcs/contour2x2.c index f33eea5e..87c42359 100644 --- a/funcs/contour2x2.c +++ b/funcs/contour2x2.c @@ -9,15 +9,16 @@ #include "../floatimg.h" -int verbosity; +extern int verbosity; /* --------------------------------------------------------------------- */ /* nouveau 4 octobre 2020, juste avant sonoptic de la pluie craignos */ -int fimg_contour_2x2(FloatImg *psrc, FloatImg *pdst, int notused) +int fimg_contour_2x2(FloatImg *psrc, FloatImg *pdst, int reverse) { float avg[4]; int foo, x, y, q; +float v1, v2; int tbl[] = /* deep magic inside */ { @@ -28,11 +29,27 @@ int tbl[] = /* deep magic inside */ }; #if DEBUG_LEVEL -fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, psrc, pdst, notused); +fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, psrc, pdst, reverse); #endif +if (FIMG_TYPE_RGB != psrc->type) { + fprintf(stderr, "%s: bad src type %d\n", __func__, psrc->type); + return -7; + } +if (fimg_images_not_compatible(psrc, pdst)) { + fprintf(stderr, "%s: bad dst type %d\n", __func__, pdst->type); + return -8; + } + +if (reverse) { + v1 = 0.0; v2 = 1.0; + } +else { + v1 = 1.0; v2 = 0.0; + } + foo = fimg_meanvalues(psrc, avg); -if (verbosity) { +if (verbosity > 1) { fprintf(stderr, "mean values : %f %f %f\n", avg[0], avg[1], avg[2]); } @@ -48,24 +65,27 @@ for (y=0; yheight-1; y++) { ( RP(x+1, y) << 2 ) | ( RP(x, y+1) << 1 ) | ( RP(x+1, y+1) ) ); - pdst->R[(y*psrc->width)+x] = tbl[q] ? 1.0 : 0.0 ; + pdst->R[(y*psrc->width)+x] = tbl[q] ? v1 : v2 ; q = ( ( GP(x, y) << 3 ) | ( GP(x+1, y) << 2 ) | ( GP(x, y+1) << 1 ) | ( GP(x+1, y+1) ) ); - pdst->G[(y*psrc->width)+x] = tbl[q] ? 1.0 : 0.0 ; + pdst->G[(y*psrc->width)+x] = tbl[q] ? v1 : v2 ; q = ( ( BP(x, y) << 3 ) | ( BP(x+1, y) << 2 ) | ( BP(x, y+1) << 1 ) | ( BP(x+1, y+1) ) ); - pdst->B[(y*psrc->width)+x] = tbl[q] ? 1.0 : 0.0 ; + pdst->B[(y*psrc->width)+x] = tbl[q] ? v1 : v2 ; } } +/* kill potential NaN values in last row or last column */ + fimg_killborders(pdst); + return 0; } /* --------------------------------------------------------------------- */ diff --git a/funcs/displacement.c b/funcs/displacement.c new file mode 100644 index 00000000..bb0cf491 --- /dev/null +++ b/funcs/displacement.c @@ -0,0 +1,89 @@ +/* + * displacement.c + */ + +#include +#include +#include +#include + +#include "../floatimg.h" + +extern int verbosity; + +/* --------------------------------------------------------------------- */ +/* --------------------------------------------------------------------- */ +/* nouveau 24 octobre 2020, pendant le masque-flamme coronavidique */ + +int fimg_displacement_0(FloatImg *psrc, FloatImg *pdst, int flags) +{ +int x, y, foo; +float minmax[6]; +float rgb[3]; +float dltr, dltg, dltb; /* delta des minmax */ +float dispx, dispy; + +int dstx, dsty; +int in, out; + +#if DEBUG_LEVEL +fprintf(stderr, ">>> %s ( %p %p 0x%04x )\n", __func__, psrc, pdst, flags); +#endif + +if (FIMG_TYPE_RGB != psrc->type) { + fprintf(stderr, "%s: bad src type %d\n", __func__, psrc->type); + return -7; + } +if (fimg_images_not_compatible(psrc, pdst)) { + fprintf(stderr, "%s: bad dst type %d\n", __func__, pdst->type); + return -8; + } + +foo = fimg_get_minmax_rgb(psrc, minmax); +if (verbosity) { + fimg_print_minmax(minmax, (char *)__func__); + } +dltr = minmax[1] - minmax[0]; +dltg = minmax[3] - minmax[2]; +dltb = minmax[5] - minmax[4]; + +in = out = 0; + +for (y=0; yheight; y++) { + + for (x=0; xwidth; x++) { + + fimg_get_rgb(psrc, x, y, rgb); + + dispx = (float)x + (rgb[1]/dltg * 20.0); + dispy = (float)y + (rgb[2]/dltb * 10.0); + dstx = (int)roundf(dispx - 10.0); + dsty = (int)roundf(dispy - 10.0); + + if ( (dstx < 0) || (dsty < 0) || + (dstx >= psrc->width) || + (dsty >= psrc->height) ) + { + /* OUT OF DESTINATION PICTURE */ + out++; + } + else { + if (flags & 1) { + /* going monochrome */ + rgb[1] = rgb[2] = rgb[0]; + } + fimg_put_rgb(pdst, dstx, dsty, rgb); + in++; + } + + } + + } + +if (verbosity) fprintf(stderr, "%s -> in %d out %d\n", __func__, in, out); + +return 0; +} +/* --------------------------------------------------------------------- */ + + diff --git a/funcs/dithering.c b/funcs/dithering.c new file mode 100644 index 00000000..14305487 --- /dev/null +++ b/funcs/dithering.c @@ -0,0 +1,31 @@ +/* + * FloatImg : some dithering experiments + */ + +#include +#include +#include +#include + +#include "../floatimg.h" + +extern int verbosity; + +/* --------------------------------------------------------------------- */ +int fimg_dither_0(FloatImg *psrc, FloatImg *pdst, int flags) +{ +int x, y; + +for (y=0; yheight; y++) { + + for (x=0; xwidth; x++) + { + + + } + } + +return -1; +} +/* --------------------------------------------------------------------- */ + diff --git a/funcs/exporter.c b/funcs/exporter.c new file mode 100644 index 00000000..ed6b698a --- /dev/null +++ b/funcs/exporter.c @@ -0,0 +1,75 @@ +/* + * exporter.c + */ + +#include +#include +#include + +#include "../floatimg.h" + +extern int verbosity; + +/* --------------------------------------------------------------------- */ +/* + * multi-magic 'save file' function. + */ +int fimg_export_picture(FloatImg *pic, char *fname, int flags) +{ +int filetype; +int foo; + +#if DEBUG_LEVEL +fprintf(stderr, ">>> %s ( %p '%s' 0x%X )\n", __func__, + pic, fname, flags); +#endif + +filetype = format_from_extension(fname); +if (verbosity) { + fprintf(stderr, "file %s : type %d\n", fname, filetype); + } + +switch(filetype) { + + case FILE_TYPE_FIMG: + foo = fimg_dump_to_file(pic, fname, 0); + break; + + case FILE_TYPE_PNM: + foo = fimg_save_as_pnm(pic, fname, 0); + break; + + case FILE_TYPE_PNG: + foo = fimg_save_as_png(pic, fname, 0); + break; + + case FILE_TYPE_TGA: + fprintf(stderr, "%s: FILE_TYPE_TGA not implemented\n", + __func__); + foo = -666; + break; + + case FILE_TYPE_TIFF: + foo = fimg_write_as_tiff(pic, fname, 0); + break; + + case FILE_TYPE_FITS: + foo = fimg_save_R_as_fits(pic, fname, 0); + break; + + default: + foo = -1789; + break; + + } + +if (foo) { + fprintf(stderr, "%s: exporting '%s' -> %d\n", __func__, + fname, foo); + /* que faire maintenant ? */ + } + +return foo; +} +/* --------------------------------------------------------------------- */ + diff --git a/funcs/filtrage.c b/funcs/filtrage.c index caec0c95..a1fbe59a 100644 --- a/funcs/filtrage.c +++ b/funcs/filtrage.c @@ -168,7 +168,8 @@ for (idx=0; idx>> %s ( %p %p %d )\n", __func__, psrc, pdst, notused); #endif +if (FIMG_TYPE_RGB != psrc->type) { + fprintf(stderr, "%s: bad src type %d\n", __func__, psrc->type); + return -7; + } +if (fimg_images_not_compatible(psrc, pdst)) { + fprintf(stderr, "%s: bad dst type %d\n", __func__, pdst->type); + return -8; + } + foo = fimg_copy_data(psrc, pdst); szimg = pdst->width * pdst->height; @@ -44,7 +53,7 @@ typedef struct { float r, g, b; } pix; -static compare_b(const void *p1, const void *p2) +static int compare_b(const void *p1, const void *p2) { pix *s1, *s2; s1 = (pix *)p1; @@ -62,6 +71,15 @@ float rgb[3]; fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, psrc, pdst, notused); #endif +if (FIMG_TYPE_RGB != psrc->type) { + fprintf(stderr, "%s: bad src type %d\n", __func__, psrc->type); + return -7; + } +if (fimg_images_not_compatible(psrc, pdst)) { + fprintf(stderr, "%s: bad dst type %d\n", __func__, pdst->type); + return -8; + } + szimg = pdst->width * pdst->height; fprintf(stderr, "%s : %d pixels\n", __func__, szimg); diff --git a/funcs/t.c b/funcs/t.c index d7d543b2..758ddd7b 100644 --- a/funcs/t.c +++ b/funcs/t.c @@ -14,12 +14,43 @@ int verbosity; float global_fvalue; +/* --------------------------------------------------------------------- */ +/* nouveau 24 octobre 2020, pendant le masque-flamme coronavidique */ + +int essai_displacement(char *infile, char *outfile) +{ +int foo; +FloatImg src, dst; + +fprintf(stderr, "%s : loading %s\n", __func__, infile); +foo = fimg_create_from_dump(infile, &src); +if (foo) { + fprintf(stderr, "%s: error loading '%s'\n", __func__, infile); + return foo; + } + +fimg_clone(&src, &dst, 1); + +foo = fimg_displacement_0(&src, &dst, 0); +if (foo) { + fprintf(stderr, "%s: err %d in disp map 0\n", __func__, foo); + return foo; + } + +foo = fimg_export_picture(&dst, outfile, 0); +if (foo) { + fprintf(stderr, "%s : err %d saving result\n", __func__, foo); + return foo; + } + +return 0; +} /* --------------------------------------------------------------------- */ /* * nouveau 7 octobre 2020 pendant sonoptic */ -int essai_qsort_rgb(char *infile) +int essai_qsort_rgb(char *infile, char *outfile) { FloatImg src, dst; int foo; @@ -45,12 +76,14 @@ if (foo) { return foo; } -foo = fimg_dump_to_file(&dst, "out.fimg", 0); +foo = fimg_export_picture(&dst, outfile, 0); if (foo) { fprintf(stderr, "%s : err %d saving result\n", __func__, foo); return foo; } +fimg_destroy(&src); fimg_destroy(&dst); + return 0; } @@ -58,7 +91,8 @@ return 0; /* * nouveau 5 octobre 2020 pendant sonoptic */ -int essai_contour_2x2(char *infile) + +int essai_contour_2x2(char *infile, char *outfile) { FloatImg src, dst; int foo; @@ -84,19 +118,21 @@ if (foo) { return foo; } -foo = fimg_save_as_pnm(&dst, "out.pnm", 0); +foo = fimg_export_picture(&dst, outfile, 0); if (foo) { fprintf(stderr, "%s : err %d saving result\n", __func__, foo); return foo; } +fimg_destroy(&src); fimg_destroy(&dst); + return 0; } /* --------------------------------------------------------------------- */ /* * nouveau 5 octobre 2020 pendant sonoptic */ -int essai_classif(char *infile) +int essai_classif(char *infile, char *outfile) { FloatImg src, dst; int foo; @@ -124,12 +160,14 @@ if (foo) { return foo; } -foo = fimg_save_as_pnm(&dst, "out.pnm", 0); +foo = fimg_export_picture(&dst, outfile, 0); if (foo) { fprintf(stderr, "%s : err %d saving result\n", __func__, foo); return foo; } +fimg_destroy(&src); fimg_destroy(&dst); + return 0; } /* --------------------------------------------------------------------- */ @@ -222,8 +260,8 @@ fimg_save_as_png(&src, "test.png", 0); foo = fimg_rotate_90(&src, &dst, 0); fprintf(stderr, "rotate 90 -> %d\n", foo); -foo = fimg_save_as_png(&dst, "rotated90.png", 0); -foo = fimg_save_as_pnm(&dst, "rotated90.pnm", 0); +foo = fimg_export_picture(&dst, "rotated90.png", 0); +foo = fimg_export_picture(&dst, "rotated90.pnm", 0); fimg_destroy(&src); @@ -456,6 +494,12 @@ printf("%-10s %d\n\n", fname, foo); foo = format_from_extension(fname="foo.png"); printf("%-10s %d\n\n", fname, foo); +foo = format_from_extension(fname="foo.tiff"); +printf("%-10s %d\n\n", fname, foo); + +foo = format_from_extension(fname="foo.fits"); +printf("%-10s %d\n\n", fname, foo); + foo = format_from_extension(fname="foo.xyzzy"); printf("%-10s %d\n\n", fname, foo); @@ -473,7 +517,7 @@ re = fimg_test_pattern(&fimg, 9, 1.0); if (re) { fprintf(stderr, "fimg_test_pattern -> %d\n", re); } -fimg_save_as_pnm(&fimg, "mire.pnm", 0); +fimg_export_picture(&fimg, "mire.pnm", 0); return -1; } @@ -519,7 +563,6 @@ return 0; } /* --------------------------------------------------------------------- */ - int fimg_essai_histo(FloatImg *src, char *outpic, int k); /* histogram.c */ int fimg_essai_hsv(char *fname); /* hsv.c */ @@ -551,7 +594,8 @@ return 0; } /* --------------------------------------------------------------------- */ enum nCmd { Equalize=1, Rotate, Sfx0, F3x3, MIRE, Wfits, Wpng, Wtiff, - Histo, Hsv, Classif, Ctr2x2, Qsortrgb }; + Histo, Hsv, Classif, Ctr2x2, Qsortrgb, + Displace }; typedef struct { char *name; int Cmd; @@ -571,6 +615,7 @@ Command commands[] = { { "classif", Classif }, { "ctr2x2", Ctr2x2 }, { "qsortrgb", Qsortrgb }, + { "displace", Displace }, { NULL, 0 } } ; @@ -592,7 +637,10 @@ void help(int k) { Command *pcmd; -fprintf(stderr, "usage:\n\t./t command filename\n"); +fprintf(stderr, "usage:\n\t./t [options] command filename\n"); + +fprintf(stderr, "options:\n"); +fprintf(stderr, "\t-o outfile\n"); fprintf(stderr, "commands:\n"); pcmd = commands; @@ -608,16 +656,20 @@ exit(0); int main(int argc, char *argv[]) { int foo, opt; -char *filename, *command; +char *filename, *command, *outfile; fprintf(stderr, "++++++++ test des fonctions pid=%d\n", getpid()); +fprintf(stderr, "++++++++ compiled "__DATE__" at " __TIME__ "\n"); -global_fvalue = 1.0; +global_fvalue = 1.0; +outfile = "out.pnm"; +command = "none"; -while ((opt = getopt(argc, argv, "hk:v")) != -1) { +while ((opt = getopt(argc, argv, "hk:o:p:v")) != -1) { switch(opt) { case 'h': help(0); break; case 'k': global_fvalue = atof(optarg); break; + case 'o': outfile = optarg; break; case 'v': verbosity++; break; } } @@ -670,13 +722,16 @@ switch(opt) { foo = fimg_essai_hsv(filename); break; case Classif: - foo = essai_classif(filename); + foo = essai_classif(filename, outfile); break; case Ctr2x2: - foo = essai_contour_2x2(filename); + foo = essai_contour_2x2(filename, outfile); break; case Qsortrgb: - foo = essai_qsort_rgb(filename); + foo = essai_qsort_rgb(filename, outfile); + break; + case Displace: + foo = essai_displacement(filename, outfile); break; default: fprintf(stderr, "%s : bad command\n", command); @@ -688,7 +743,7 @@ if (foo) { fprintf(stderr, "Essai ====> %d\n", foo); } -fprintf(stderr, "++++++++++++++ end of pid %d\n", getpid()); +fprintf(stderr, "+++++ end of %s pid %d\n", command, getpid()); return 0; } /* --------------------------------------------------------------------- */ diff --git a/funcs/utils.c b/funcs/utils.c index 32a9a1de..78aa0c1b 100644 --- a/funcs/utils.c +++ b/funcs/utils.c @@ -7,6 +7,16 @@ extern int verbosity; /* must be declared around main() */ +/* --------------------------------------------------------------------- */ +void fimg_print_minmax(float minmax[6], char *titre) +{ + +fprintf(stderr, "\t\tminmax %s\n", titre); +fprintf(stderr, "red\t\t%10f %10f\n", minmax[0], minmax[1]); +fprintf(stderr, "green\t\t%10f %10f\n", minmax[2], minmax[3]); +fprintf(stderr, "blue\t\t%10f %10f\n", minmax[4], minmax[5]); + +} /* --------------------------------------------------------------------- */ int parse_WxH(char *str, int *pw, int *ph) { diff --git a/funcs/vroum.sh b/funcs/vroum.sh index c0bb44ac..1fb25881 100755 --- a/funcs/vroum.sh +++ b/funcs/vroum.sh @@ -3,10 +3,17 @@ src=/dev/shm/foo.fimg out=out.fimg +<<<<<<< HEAD maxi=99 W="640" H="480" grabopt=" -s 640x480 -v -p 0 -n 150 -c cos01 -d /dev/video2 " +======= +maxi=249 +W="320" +H="240" +grabopt=" -s ${W}x${H}w -vv -p 0 -n 60 -c none " +>>>>>>> 423ab7f0eca3e74777b24f795fadf075c0066138 mkdir /tmp/V @@ -20,13 +27,15 @@ do grabvidseq -$grabopt -o $src fval=$(echo "$foo / $maxi" | bc -l) - ./t -k $fval qsortrgb $src - echo $foo ' = ' $fval + ./t -vv -k 0.333 -o $out classif $src + # fimgstats $out + + echo $foo ' => ' $fval dst=$(printf "/tmp/V/%03d.png" $foo) - - montage $src $out -geometry $G $dst + echo $dst + montage $src $out -tile 1x2 -geometry $G $dst done -convert -delay 20 /tmp/V/*.png foo.gif +convert -delay 10 /tmp/V/*.png foo.gif