157 lines
3.5 KiB
C
157 lines
3.5 KiB
C
/*
|
|
* MOVEPIXELS
|
|
*
|
|
* This is experimental, do not use in production !
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
|
|
#include <floatimg.h>
|
|
|
|
int verbosity;
|
|
|
|
/* ------------------------------------------------------------------- */
|
|
int displace(FloatImg *psrc, FloatImg *pshift, FloatImg *pdst, float k)
|
|
{
|
|
int xd, yd, xs, ys;
|
|
float rgb[3], disp[3], maxv;
|
|
float minmax[6];
|
|
int foo, inside, outside;
|
|
float dltr, dltg, dltb; /* delta des minmax */
|
|
|
|
#if DEBUG_LEVEL
|
|
fprintf(stderr, ">>> %s ( %p %p %p %g )\n", __func__,
|
|
psrc, pshift, pdst, k);
|
|
#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, pshift)) {
|
|
fprintf(stderr, "%s: bad shift image %d\n", __func__, pshift->type);
|
|
return -8;
|
|
}
|
|
if (fimg_images_not_compatible(psrc, pdst)) {
|
|
fprintf(stderr, "%s: bad dst image %d\n", __func__, pdst->type);
|
|
return -8;
|
|
}
|
|
|
|
foo = fimg_get_minmax_rgb(pshift, minmax);
|
|
if (verbosity) {
|
|
fimg_print_minmax(minmax, (char *)__func__);
|
|
}
|
|
dltr = minmax[1] - minmax[0];
|
|
dltg = minmax[3] - minmax[2];
|
|
dltb = minmax[5] - minmax[4];
|
|
if (verbosity) fprintf(stderr, "delta shift %f %f %f\n", dltr, dltg, dltb);
|
|
|
|
maxv = fimg_get_maxvalue(psrc);
|
|
inside = outside = 0;
|
|
|
|
/* hardcoded parameters. this is very dirty :) */
|
|
|
|
#define MULT (140.0)
|
|
#define OFFS (70.0)
|
|
|
|
/* loop over all the pixels of the DESTINATION picture */
|
|
for (yd=0; yd<pdst->height; yd++) {
|
|
|
|
for (xd=0; xd<pdst->width; xd++) {
|
|
|
|
fimg_get_rgb(pshift, xd, yd, disp);
|
|
|
|
xs = xd + ((disp[0]/dltr*MULT) - OFFS);
|
|
ys = yd + ((disp[2]/dltb*MULT) - OFFS);
|
|
|
|
if ( xs<0 || xs>psrc->width ||
|
|
ys<0 || ys>psrc->height ) {
|
|
rgb[0] = rgb[1] = rgb[2] = 0.0;
|
|
outside++;
|
|
}
|
|
else {
|
|
fimg_get_rgb(psrc, xs, ys, rgb);
|
|
inside++;
|
|
}
|
|
|
|
fimg_put_rgb(pdst, xd, yd, rgb);
|
|
}
|
|
|
|
}
|
|
|
|
// fprintf(stderr, "%s: inside %d outside %d\n", __func__, inside, outside);
|
|
|
|
return 0;
|
|
}
|
|
/* ------------------------------------------------------------------- */
|
|
/*
|
|
* High level operateur, taking care of opening/closing
|
|
* files and doing memory management
|
|
*/
|
|
int move_the_pixels(char *infile, char *statfile, char *outfile, int k)
|
|
{
|
|
int foo;
|
|
FloatImg src, shift, dst;
|
|
|
|
#if DEBUG_LEVEL
|
|
fprintf(stderr, ">>> %s ( %s %s 0x%04x )\n", __func__,
|
|
infile, outfile, k);
|
|
#endif
|
|
|
|
/* 'infile' contains the shifting values */
|
|
foo = fimg_create_from_dump(infile, &shift);
|
|
if (foo) {
|
|
fprintf(stderr, "%s: error loading '%s'\n", __func__, infile);
|
|
return foo;
|
|
}
|
|
|
|
fimg_clone(&shift, &dst, 0);
|
|
|
|
foo = fimg_create_from_dump(statfile, &src);
|
|
if (foo) {
|
|
fprintf(stderr, "%s: error loading 'cumul.fimg'\n", __func__);
|
|
return foo;
|
|
}
|
|
|
|
foo = displace(&src, &shift, &dst, 42.42);
|
|
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;
|
|
}
|
|
/* ------------------------------------------------------------------- */
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int foo;
|
|
char *srcfile, *dstfile;
|
|
|
|
if (3 != argc) {
|
|
fprintf(stderr, "usage:\n\t%s src.fimg dst.fimg\n", argv[0]);
|
|
exit(1);
|
|
}
|
|
|
|
srcfile = argv[1];
|
|
dstfile = argv[2];
|
|
verbosity = 0;
|
|
|
|
/* XXX the static picture file MUST be selectable by the yuser ! */
|
|
foo = move_the_pixels(srcfile, "reference.fimg", dstfile, 3);
|
|
|
|
fprintf(stderr, "move pixels %s -> %s = %d\n", srcfile, dstfile, foo);
|
|
|
|
return 0;
|
|
}
|
|
/* ------------------------------------------------------------------- */
|