Bibliothèque de traitements d'images en virgule flottante.
http://la.buvette.org/photos/cumul/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
385 lines
8.9 KiB
385 lines
8.9 KiB
/* |
|
* SPECIAL EFFECTS |
|
* |
|
* Du code bien cracra / tTh / Tetalab |
|
*/ |
|
#include <stdio.h> |
|
#include <string.h> |
|
#include <stdlib.h> |
|
#include <malloc.h> |
|
#include <math.h> |
|
|
|
#include "../floatimg.h" |
|
|
|
#include "fifo.h" |
|
#include "metriques.h" |
|
#include "sfx.h" |
|
|
|
/* -------------------------------------------------------------- */ |
|
/* here are global vars exported by the main module |
|
*/ |
|
extern int verbosity; |
|
|
|
/* -------------------------------------------------------------- */ |
|
/* |
|
* please, add some parameters ! |
|
*/ |
|
int incrustation_vignette(FloatImg *src, FloatImg *dst, int k) |
|
{ |
|
int x, y, x4, y4; |
|
float rgb[3]; |
|
|
|
#if DEBUG_LEVEL |
|
fprintf(stderr, ">>> %s ( %p %p %d )\n", __func__, src, dst, k); |
|
#endif |
|
|
|
x4 = dst->width / 4, y4 = dst->height / 4; |
|
|
|
for (y=0; y<y4; y++) { |
|
for (x=0; x<x4; x++) { |
|
fimg_get_rgb(src, x*4, y*4, rgb); |
|
fimg_put_rgb(dst, x+39, y+39, rgb); |
|
} |
|
} |
|
|
|
return -1; |
|
} |
|
/* -------------------------------------------------------------- */ |
|
/* nouveau du premier dimanche de 2020 'nextgen' */ |
|
static int pixel_trinitron(FloatImg *pimg, int pos[4], float *fvals) |
|
{ |
|
int x, y, pline, off; |
|
|
|
for (y=pos[1]; y<pos[1]+pos[3]; y++) { |
|
pline = y*pimg->width; |
|
for (x=pos[0]+2; x<pos[0]+pos[2]-2; x++) { |
|
off = pline + x; |
|
pimg->R[off] = fvals[0]; |
|
pimg->G[off] = fvals[1]; |
|
pimg->B[off] = fvals[2]; |
|
} |
|
} |
|
return 0; |
|
} |
|
int trinitron(FloatImg *pimg, int notused) |
|
{ |
|
int x, y, coo[4], foo; |
|
float vals[3]; |
|
|
|
#if DEBUG_LEVEL |
|
fprintf(stderr, ">>> %s ( %p %d )\n", __func__, pimg, notused); |
|
#endif |
|
|
|
#define STP 16 /* stepd for x & y axex */ |
|
coo[2] = coo[3] = STP; |
|
|
|
for (y=0; y<pimg->height; y+=STP) { |
|
coo[1] = y; |
|
for (x=0; x<pimg->width; x+=STP) { |
|
coo[0] = x; |
|
foo = stat_zone(pimg, coo, vals); |
|
if (foo) abort(); |
|
/* next step : plot the datas */ |
|
pixel_trinitron(pimg, coo, vals); |
|
} |
|
} |
|
#undef STP |
|
return 0; |
|
} |
|
/* -------------------------------------------------------------- */ |
|
/* nouveau du 27 decembre 2020, un soir de grand froid... */ |
|
int octotree_classif(FloatImg *pimg, float kdist, int notused) |
|
{ |
|
int foo; |
|
float mm[6], delta[3]; |
|
float r, g, b, kr, kg, kb, dp, trig; |
|
int idx, sz, n8, count; |
|
typedef struct { |
|
float x, y, z; |
|
} ptc_t; |
|
ptc_t ptc[8]; |
|
|
|
#if DEBUG_LEVEL |
|
fprintf(stderr, ">>> %s ( %p %f %d )\n", __func__, |
|
pimg, kdist, notused); |
|
#endif |
|
|
|
foo = fimg_get_minmax_rgb(pimg, mm); |
|
if (foo) { |
|
fprintf(stderr, "oups %d in get minmax\n", foo); |
|
return foo; |
|
} |
|
if (verbosity>1) fimg_print_minmax(mm, " input pic "); |
|
|
|
/* |
|
* compute the 8 center points |
|
*/ |
|
delta[0] = mm[1] - mm[0]; /* R */ |
|
delta[1] = mm[3] - mm[2]; /* G */ |
|
delta[2] = mm[5] - mm[4]; /* B */ |
|
// fprintf(stderr, "delta: %11.3f %11.3f %11.3f\n", |
|
// delta[0], delta[1], delta[2]); |
|
for (idx=0; idx<8; idx++) { |
|
kr = 0.25 * ((idx & 0x4) ? 1 : 3); |
|
kg = 0.25 * ((idx & 0x2) ? 1 : 3); |
|
kb = 0.25 * ((idx & 0x1) ? 1 : 3); |
|
// fprintf(stderr, "%6d %.2f %.2f %.2f\n", idx, kr, kg, kb); |
|
ptc[idx].x = (delta[0] * kr) + mm[0]; |
|
ptc[idx].y = (delta[1] * kg) + mm[2]; |
|
ptc[idx].z = (delta[2] * kb) + mm[4]; |
|
// fprintf(stderr, "%6d %.3f %.3f %.3f\n", idx, |
|
// ptc[idx].x, ptc[idx].y, ptc[idx].z); |
|
} |
|
|
|
sz = pimg->width * pimg->height; |
|
trig = kdist * ((mm[1] + mm[3] + mm[5])/6.0); |
|
// fprintf(stderr, "trig value %f\n", trig); |
|
|
|
count = 0; |
|
|
|
#define X(a,b) ( ((a)-(b)) * ((a)-(b)) ) |
|
for (idx=0; idx<sz; idx++) { |
|
|
|
r = pimg->R[idx]; g = pimg->G[idx]; b = pimg->B[idx]; |
|
for (n8=0; n8<8; n8++) { |
|
dp = sqrt(X(r,ptc[n8].x)+X(g,ptc[n8].y)+X(b,ptc[n8].z)); |
|
if (dp < trig) { |
|
pimg->R[idx] = ptc[n8].x; |
|
pimg->G[idx] = ptc[n8].y; |
|
pimg->B[idx] = ptc[n8].z; |
|
count++; |
|
break; |
|
} |
|
else { |
|
pimg->R[idx]=pimg->G[idx]=pimg->B[idx]=0.0; |
|
} |
|
} |
|
} |
|
|
|
if (verbosity > 1) { |
|
fprintf(stderr, "%s: %d/%d pixels, ratio %f\n", __func__, count, sz, |
|
(float)count/(float)sz); |
|
} |
|
|
|
return 0; |
|
} |
|
/* -------------------------------------------------------------- */ |
|
/* nouveau du 19 decembre 2020, pour le grand ecran de da Scritch */ |
|
|
|
int upside_down(FloatImg *pimg) |
|
{ |
|
float *rowpix; |
|
float *Ps, *Pd; |
|
int Os, Od; /* offset of lines */ |
|
int wsz; |
|
int ya, y2; |
|
|
|
if (verbosity>1) fprintf(stderr, "%s: image width is %d\n", |
|
__func__, pimg->width); |
|
|
|
rowpix = calloc(pimg->width, sizeof(float)); |
|
if (NULL==rowpix) { |
|
fprintf(stderr, "%s : memory full\n", __func__); |
|
exit(1); |
|
} |
|
|
|
wsz = pimg->width * sizeof(float); |
|
if (verbosity>1) fprintf(stderr, "%s: wsx = %d\n", __func__, wsz); |
|
|
|
for (ya=0; ya<pimg->height/2; ya++) { |
|
|
|
y2 = pimg->height - (ya+1); |
|
Os = (pimg->width * ya); |
|
Od = (pimg->width * y2); |
|
|
|
/* let's go, crash coredumping... */ |
|
Ps = pimg->R + Os; |
|
Pd = pimg->R + Od; |
|
memcpy(rowpix, Ps, wsz); |
|
memcpy(Ps, Pd, wsz); |
|
memcpy(Pd, rowpix, wsz); |
|
|
|
Ps = pimg->G + Os; |
|
Pd = pimg->G + Od; |
|
memcpy(rowpix, Ps, wsz); |
|
memcpy(Ps, Pd, wsz); |
|
memcpy(Pd, rowpix, wsz); |
|
|
|
Ps = pimg->B + Os; |
|
Pd = pimg->B + Od; |
|
memcpy(rowpix, Ps, wsz); |
|
memcpy(Ps, Pd, wsz); |
|
memcpy(Pd, rowpix, wsz); |
|
} |
|
|
|
free(rowpix); |
|
|
|
return 0; |
|
} |
|
/* -------------------------------------------------------------- */ |
|
/* nouveau du 9 decembre 2020, en ecoutant le Fermion raconter du |
|
superbe portnawak */ |
|
int bouger_les_pixels(FloatImg *pimg, int intensite) |
|
{ |
|
int x, y, nx, ny; |
|
float rgb[3]; |
|
|
|
#if DEBUG_LEVEL |
|
fprintf(stderr, ">>> %s ( %p %d )\n", __func__, pimg, intensite); |
|
#endif |
|
|
|
if (intensite < 1) { |
|
fprintf(stderr, "%s: %d bad intensity\n", __func__, intensite); |
|
return -1; |
|
} |
|
|
|
for (x=0; x<pimg->width; x++) { |
|
for (y=0; y<pimg->height; y++) { |
|
|
|
nx = x+(rand()%intensite)-(intensite/2); |
|
ny = y+(rand()%intensite)-(intensite/2); |
|
|
|
if ( nx<0 || ny<0 || nx>=pimg->width |
|
|| ny>=pimg->height ) |
|
continue; |
|
|
|
/* XXX optimize here ? */ |
|
fimg_get_rgb(pimg, nx, ny, rgb); |
|
fimg_put_rgb(pimg, x, y, rgb); |
|
|
|
} |
|
} |
|
|
|
return 0; |
|
} |
|
/* -------------------------------------------------------------- */ |
|
/* nouveau du 9 decembre 2020, en ecoutant les Cernettes */ |
|
int mirror_split(FloatImg *pimg, int kaboo) |
|
{ |
|
int line, x, xs, xd; |
|
|
|
#if DEBUG_LEVEL |
|
fprintf(stderr, ">>> %s ( %p %d )\n", __func__, pimg, kaboo); |
|
#endif |
|
|
|
for (line=0; line<pimg->height; line++) { |
|
for (x=0; x<pimg->width/2; x++) { |
|
xs = (pimg->width * line) + x; |
|
xd = (pimg->width * line) + (pimg->width -x); |
|
pimg->R[xd] = pimg->R[xs]; |
|
pimg->G[xd] = pimg->G[xs]; |
|
pimg->B[xd] = pimg->B[xs]; |
|
} |
|
} |
|
|
|
return 0; |
|
} |
|
/* -------------------------------------------------------------- */ |
|
/* nouveau du 20 novembre 2020, pour encoder une vidz du vernissage |
|
* du festival Sauvageonnes de Mixart-Myrys */ |
|
int des_bords_sombres_a(FloatImg *pimg, int offset) |
|
{ |
|
float coef; |
|
int xpos, xp2, lidx, y; |
|
|
|
#if DEBUG_LEVEL |
|
fprintf(stderr, ">>> %s ( %p %d )\n", __func__, pimg, offset); |
|
#endif |
|
|
|
if (offset<0 || offset>=pimg->width) { |
|
fprintf(stderr, "%s: offset %d is bad\n", __func__, offset); |
|
return -66; |
|
} |
|
|
|
for (y=0; y<pimg->height; y++) { |
|
lidx = y * pimg->width; /* start of the |
|
'y' line */ |
|
for (xpos=0; xpos<offset; xpos++) { |
|
coef = (float)xpos / (float)offset; |
|
pimg->R[xpos+lidx] *= coef; |
|
pimg->G[xpos+lidx] *= coef; |
|
pimg->B[xpos+lidx] *= coef; |
|
xp2 = pimg->width-xpos; |
|
pimg->R[xp2+lidx] *= coef; |
|
pimg->G[xp2+lidx] *= coef; |
|
pimg->B[xp2+lidx] *= coef; |
|
} |
|
} |
|
|
|
return 0; |
|
} |
|
/* -------------------------------------------------------------- */ |
|
/* nouveau Mon 10 May 2021 08:46:02 PM CEST |
|
* chez Eric 1KA */ |
|
int des_bords_sombres_b(FloatImg *pimg, int offset) |
|
{ |
|
|
|
#if DEBUG_LEVEL |
|
fprintf(stderr, ">>> %s ( %p %d )\n", __func__, pimg, offset); |
|
#endif |
|
|
|
if (offset<0 || offset>=pimg->width) { |
|
fprintf(stderr, "%s: offset %d is bad\n", __func__, offset); |
|
return -66; |
|
} |
|
|
|
return -1; |
|
} |
|
/* -------------------------------------------------------------- */ |
|
/* |
|
* int binarize(FloatImg *pimg, int notused) was now in |
|
* funcs/sfx2.c |
|
* same move for trinarize. |
|
*/ |
|
/* -------------------------------------------------------------- */ |
|
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; foo<todo; foo++) |
|
{ |
|
fval = (float)drand48() * mval; |
|
x = rand() % fimg->width; |
|
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; foo<todo; foo++) |
|
{ |
|
fval = (float)drand48() * mval; |
|
x = 1 + (rand() % (fimg->width-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; |
|
} |
|
/* -------------------------------------------------------------- */ |
|
|
|
|