2022-06-26 11:06:35 +02:00
|
|
|
/*
|
|
|
|
+---------------------------------------+
|
|
|
|
| Effets speciaux sur les images |
|
2022-10-28 05:07:32 +02:00
|
|
|
| troisieme module |
|
2022-06-26 11:06:35 +02:00
|
|
|
+---------------------------------------+
|
|
|
|
Thierry Boudet <oulala@chez.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <math.h> /* yo ! */
|
|
|
|
|
2022-06-27 00:48:18 +02:00
|
|
|
#include "../tthimage.h"
|
2022-06-26 11:06:35 +02:00
|
|
|
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/*
|
|
|
|
* 11 Fev 2003: que vais-je mettre ici ?
|
|
|
|
* 5 avr 2007: je commence a en avoir une idee plus precise.
|
|
|
|
*/
|
2022-09-17 11:23:21 +02:00
|
|
|
int Image_effect_x_0(Image_Desc *src, Image_Desc *dst, int kr, int kg, int kb)
|
2022-06-26 11:06:35 +02:00
|
|
|
{
|
|
|
|
int foo, x, y, r, g, b;
|
|
|
|
int cr, cg, cb;
|
|
|
|
|
2022-08-22 17:53:30 +02:00
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, "*** Effect X_0: coeffs: %d %d %d\n", kr, kg, kb);
|
|
|
|
#endif
|
|
|
|
|
2022-09-17 11:23:21 +02:00
|
|
|
if ( (foo=Image_compare_desc(src, dst)) ) {
|
|
|
|
fprintf(stderr, "%s: images are differents %d\n", __func__, foo);
|
2022-06-26 11:06:35 +02:00
|
|
|
return foo;
|
|
|
|
}
|
|
|
|
|
2022-08-23 12:15:31 +02:00
|
|
|
cr = cg = cb = 0; /* raz des compteurs */
|
2022-06-26 11:06:35 +02:00
|
|
|
|
2022-08-23 12:15:31 +02:00
|
|
|
for (y=0; y<dst->height; y++) {
|
|
|
|
for (x=0; x<dst->width; x++) {
|
2022-09-17 11:23:21 +02:00
|
|
|
/* Image_getRGB(src, x, y, &r, &g, &b); */
|
|
|
|
r = src->Rpix[y][x];
|
|
|
|
g = src->Gpix[y][x];
|
|
|
|
b = src->Bpix[y][x];
|
2022-06-26 11:06:35 +02:00
|
|
|
if (r > kr) {
|
|
|
|
foo = g; g = b; b = foo;
|
|
|
|
cr ++;
|
|
|
|
}
|
|
|
|
if (g > kg) {
|
|
|
|
foo = r; r = b; b = foo;
|
|
|
|
cg ++;
|
|
|
|
}
|
|
|
|
if (b > kb) {
|
|
|
|
foo = g; g = r; r = foo;
|
|
|
|
cb ++;
|
|
|
|
}
|
2022-09-17 11:23:21 +02:00
|
|
|
/* Image_plotRGB(dst, x, y, r, g, b); */
|
|
|
|
dst->Rpix[y][x] = r;
|
|
|
|
dst->Gpix[y][x] = g;
|
|
|
|
dst->Bpix[y][x] = b;
|
2022-06-26 11:06:35 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-17 11:23:21 +02:00
|
|
|
/* fprintf(stderr, "* %s : counts: %d %d %d\n", __func__, cr, cg, cb); */
|
2022-06-26 11:06:35 +02:00
|
|
|
|
2022-08-23 12:15:31 +02:00
|
|
|
return FUNC_IS_BETA;
|
2022-06-26 11:06:35 +02:00
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/* 2 fevrier 2003: je fait du n'importe quoi, la... */
|
|
|
|
/*
|
|
|
|
* 3 avril 2007: je me rend compte que les parametres ne servent a rien.
|
|
|
|
*/
|
2022-10-28 05:07:32 +02:00
|
|
|
int Image_effect_x_1(Image_Desc *src, Image_Desc *dst)
|
2022-06-26 11:06:35 +02:00
|
|
|
{
|
|
|
|
int foo, x, y, r, g, b;
|
|
|
|
|
2022-09-17 11:23:21 +02:00
|
|
|
if ( (foo=Image_compare_desc(src, dst)) ) {
|
|
|
|
fprintf(stderr, "I%s: images are differents %d\n", __func__, foo);
|
2022-06-26 11:06:35 +02:00
|
|
|
return foo;
|
|
|
|
}
|
|
|
|
|
2022-09-17 11:23:21 +02:00
|
|
|
for (y=0; y<dst->height; y++) {
|
|
|
|
for (x=0; x<dst->width; x++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
r = src->Rpix[y][x];
|
|
|
|
g = src->Gpix[y][x];
|
|
|
|
b = src->Bpix[y][x];
|
|
|
|
|
2022-10-28 05:07:32 +02:00
|
|
|
/* 2 fevrier 2003: je fait du n'importe quoi, la... */
|
2022-06-26 11:06:35 +02:00
|
|
|
dst->Rpix[y][x] = g^b;
|
|
|
|
dst->Gpix[y][x] = r^b;
|
|
|
|
dst->Bpix[y][x] = r^g;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FUNC_IS_BETA;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/*
|
2022-10-28 05:07:32 +02:00
|
|
|
* 1er Fevrier 2003: encore une autre experimentation, qui va etre
|
|
|
|
* basee sur la trigonometrie.
|
2022-06-26 11:06:35 +02:00
|
|
|
*/
|
2022-10-28 05:07:32 +02:00
|
|
|
int Image_effect_x_2(Image_Desc *src, Image_Desc *dst, int kx, int ky, int kv)
|
2022-06-26 11:06:35 +02:00
|
|
|
{
|
|
|
|
int foo, x, y, r, g, b;
|
|
|
|
double dr, dg, db, ar, ag, ab;
|
|
|
|
|
2022-09-17 11:23:21 +02:00
|
|
|
if ( (foo=Image_compare_desc(src, dst)) ) {
|
|
|
|
fprintf(stderr, "%s: images are differents %d\n", __func__, foo);
|
2022-06-26 11:06:35 +02:00
|
|
|
return foo;
|
|
|
|
}
|
|
|
|
|
2022-08-23 12:15:31 +02:00
|
|
|
/* a vrai dire, je ne comprend pas ou caser kx, ky et kz */
|
|
|
|
|
|
|
|
for (y=0; y<dst->height; y++) {
|
|
|
|
for (x=0; x<dst->width; x++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
r = src->Rpix[y][x];
|
|
|
|
g = src->Gpix[y][x];
|
|
|
|
b = src->Bpix[y][x];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* je scale chacune des composantes entre 0.0 et 1.0
|
|
|
|
*/
|
|
|
|
dr = ( (double)r ) / 255.0;
|
|
|
|
dg = ( (double)g ) / 255.0;
|
|
|
|
db = ( (double)b ) / 255.0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* en fait c'est pas du tout ce que je pense faire,
|
|
|
|
* mais bon, faut tout essayer...
|
|
|
|
*/
|
|
|
|
ar = atan2(dg, db);
|
|
|
|
ag = atan2(dr, db);
|
|
|
|
ab = atan2(dr, dg);
|
|
|
|
|
|
|
|
/*
|
2022-10-28 05:07:32 +02:00
|
|
|
* et la il y a des soucis d'echelle :)
|
2022-06-26 11:06:35 +02:00
|
|
|
* 15 mars 2005: pourquoi 156 ? (XXX)
|
|
|
|
*/
|
|
|
|
r = (int)(ar * 156.0);
|
|
|
|
g = (int)(ag * 156.0);
|
|
|
|
b = (int)(ab * 156.0);
|
|
|
|
|
|
|
|
dst->Rpix[y][x] = r;
|
|
|
|
dst->Gpix[y][x] = g;
|
|
|
|
dst->Bpix[y][x] = b;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FUNC_IS_BETA;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/*
|
|
|
|
* 30 Jan 2003: hop, j'improvise pendant que les patates cuisent :)
|
|
|
|
* 4 Fev 2003: et je peaufine pendant que le poulet mijote :)
|
2022-10-28 05:07:32 +02:00
|
|
|
* 27 Oct 2003: je debugge pendant que le the infuse :)
|
2022-06-26 11:06:35 +02:00
|
|
|
* 16 Mai 2005: je commence a ecrire la documentation.
|
|
|
|
* 29 sept 2015: je devrais finir la doc d'ici 2 ans.
|
2022-10-28 05:07:32 +02:00
|
|
|
* 19 aout 2022: je comprend pas ce que c'est cense faire :)
|
2022-06-26 11:06:35 +02:00
|
|
|
*
|
|
|
|
*/
|
2022-10-28 05:07:32 +02:00
|
|
|
int Image_effect_x_3(Image_Desc *src, Image_Desc *dst, int kx, int ky, char *comp)
|
2022-06-26 11:06:35 +02:00
|
|
|
{
|
|
|
|
int foo, sx, sy;
|
|
|
|
int x, y, r, g, b;
|
|
|
|
int cx, cy, dx, dy;
|
|
|
|
|
2022-08-22 17:53:30 +02:00
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, "%s : kx %d ky %d comp '%s'\n", __func__, kx, ky, comp);
|
|
|
|
#endif
|
|
|
|
|
2022-10-28 05:07:32 +02:00
|
|
|
if ( (foo=Image_compare_desc(src, dst)) ) {
|
2022-06-26 11:06:35 +02:00
|
|
|
fprintf(stderr, "%s: images are differents %d\n", __func__, foo);
|
|
|
|
return foo;
|
|
|
|
}
|
|
|
|
|
2022-10-28 05:07:32 +02:00
|
|
|
if (strlen(comp) != 2) {
|
|
|
|
fprintf(stderr, "%s: bad comp parameter '%s'\n", __func__, comp);
|
2022-06-26 11:06:35 +02:00
|
|
|
fprintf(stderr, " must be a 2 chars string, from 'rgb'\n");
|
|
|
|
return INVALID_PARAM;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* conversion en minuscules des deux lettres de composantes
|
|
|
|
*/
|
|
|
|
cx = tolower(comp[0]); cy = tolower(comp[1]);
|
|
|
|
dx = dy = 0;
|
|
|
|
sx = sy = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ici il faudrait une validation des deux lettres, mais j'ai la
|
2022-10-28 05:07:32 +02:00
|
|
|
* flemme d'ecrire ce genre de chos maintenant.
|
|
|
|
* Je vais plutot aller boofer.
|
2022-06-26 11:06:35 +02:00
|
|
|
*/
|
|
|
|
|
2022-10-28 05:07:32 +02:00
|
|
|
for (y=0; y<dst->height; y++) {
|
|
|
|
for (x=0; x<dst->width; x++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
r = src->Rpix[y][x];
|
|
|
|
g = src->Gpix[y][x];
|
|
|
|
b = src->Bpix[y][x];
|
|
|
|
|
2022-10-28 05:07:32 +02:00
|
|
|
switch(cx) {
|
2022-06-26 11:06:35 +02:00
|
|
|
case 'r': dx = r; break;
|
|
|
|
case 'g': dx = g; break;
|
|
|
|
case 'b': dx = b; break;
|
|
|
|
}
|
2022-10-28 05:07:32 +02:00
|
|
|
switch(cy) {
|
2022-06-26 11:06:35 +02:00
|
|
|
case 'r': dy = r; break;
|
|
|
|
case 'g': dy = g; break;
|
|
|
|
case 'b': dy = b; break;
|
|
|
|
}
|
|
|
|
|
|
|
|
sx = x + ((kx * (dx-128)) / 100);
|
|
|
|
sy = y + ((ky * (dy-128)) / 100);
|
|
|
|
|
|
|
|
if ( sx >= 0 && sx < dst->width &&
|
2022-10-28 05:07:32 +02:00
|
|
|
sy >= 0 && sy < dst->height ) {
|
2022-06-26 11:06:35 +02:00
|
|
|
r = src->Rpix[sy][sx];
|
|
|
|
g = src->Gpix[sy][sx];
|
|
|
|
b = src->Bpix[sy][sx];
|
|
|
|
Image_plotRGB(dst, x, y, r, g, b);
|
|
|
|
}
|
2022-10-28 05:07:32 +02:00
|
|
|
else {
|
2022-06-26 11:06:35 +02:00
|
|
|
Image_plotRGB(dst, x, y, r, r, r);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Je suis vraiment confus, mais je n'y comprend RIEN :)
|
|
|
|
*/
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FUNC_IS_ALPHA;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
2022-08-23 12:15:31 +02:00
|
|
|
int Image_effect_x_4(Image_Desc *src, Image_Desc *dst, int flags)
|
2022-06-26 11:06:35 +02:00
|
|
|
{
|
|
|
|
int foo;
|
|
|
|
int x, y;
|
|
|
|
int r, g, b, r2, g2, b2;
|
|
|
|
|
|
|
|
#if DEBUG_LEVEL
|
|
|
|
fprintf(stderr, "*** effect x4 is not ready for prime time ***\n");
|
|
|
|
#endif
|
|
|
|
|
2022-08-23 12:15:31 +02:00
|
|
|
if ( (foo=Image_compare_desc(src, dst)) ) {
|
2022-09-17 11:23:21 +02:00
|
|
|
fprintf(stderr, "%s: images are differents %d\n", __func__, foo);
|
2022-06-26 11:06:35 +02:00
|
|
|
return foo;
|
|
|
|
}
|
|
|
|
|
2022-08-23 12:15:31 +02:00
|
|
|
for (y=0; y<src->height; y++) {
|
|
|
|
for (x=0; x<src->width; x++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
r = src->Rpix[y][x];
|
|
|
|
g = src->Gpix[y][x];
|
|
|
|
b = src->Bpix[y][x];
|
|
|
|
r2 = r; g2 = g; b2 = b;
|
|
|
|
|
|
|
|
if (flags & 1) {
|
|
|
|
if (r > g) b2 = (r + g) / 2;
|
|
|
|
if (b > g) r2 = (b + g) / 2;
|
|
|
|
if (r > b) g2 = (r + b) / 2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (r < g) b2 = (r + g) / 2;
|
|
|
|
if (b < g) r2 = (b + g) / 2;
|
|
|
|
if (r < b) g2 = (r + b) / 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
Image_plotRGB(dst, x, y, r2, g2, b2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FUNC_IS_BETA;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|
|
|
|
/* 22 avril 2007: je vais essayer d'inventer un nouveau truc, mais il
|
|
|
|
* faudrait que les gosses arretent de ma casser les oreilles avec leur
|
|
|
|
* machine a batailles. putain de gamecube... */
|
2022-08-23 12:15:31 +02:00
|
|
|
/* 23 aout 2022 : j'ai bien envie d'une SNES et d'un Trinitron */
|
2022-10-28 05:07:32 +02:00
|
|
|
int Image_effect_x_5(Image_Desc *src, Image_Desc *dst, int kx, int ky, int kz)
|
2022-06-26 11:06:35 +02:00
|
|
|
{
|
|
|
|
int foo, sx, sy;
|
|
|
|
int x, y, r, g, b;
|
|
|
|
int r2, g2, b2;
|
|
|
|
double dr, dg, db, dr2, dg2, db2;
|
|
|
|
|
|
|
|
fprintf(stderr, "*** effect x5 is not ready for prime time ***\n");
|
|
|
|
#if DEBUG_LEVEL
|
2022-08-23 12:15:31 +02:00
|
|
|
fprintf(stderr, ">>> %s ( %p %p %d %d %d )\n", __func__, src, dst,
|
2022-06-26 11:06:35 +02:00
|
|
|
kx, ky, kz);
|
|
|
|
#endif
|
|
|
|
|
2022-09-17 11:23:21 +02:00
|
|
|
if ( (foo=Image_compare_desc(src, dst)) ) {
|
2022-06-26 11:06:35 +02:00
|
|
|
fprintf(stderr, "Image effect x 5: images are differents %d\n", foo);
|
|
|
|
return foo;
|
|
|
|
}
|
|
|
|
|
2022-09-17 11:23:21 +02:00
|
|
|
for (y=0; y<src->height; y++) {
|
|
|
|
for (x=0; x<src->width; x++) {
|
2022-06-26 11:06:35 +02:00
|
|
|
r = src->Rpix[y][x];
|
|
|
|
g = src->Gpix[y][x];
|
|
|
|
b = src->Bpix[y][x];
|
|
|
|
dr = (double)r / 255.0;
|
|
|
|
dg = (double)g / 255.0;
|
|
|
|
db = (double)b / 255.0;
|
|
|
|
dr2 = pow(dg, db);
|
|
|
|
dg2 = pow(db, dr);
|
|
|
|
db2 = pow(dr, dg);
|
|
|
|
r2 = (int)(dr2 * 255.0);
|
|
|
|
g2 = (int)(dg2 * 255.0);
|
|
|
|
b2 = (int)(db2 * 255.0);
|
|
|
|
#if DEBUG_LEVEL
|
2022-09-17 11:23:21 +02:00
|
|
|
if (x==42 && y==42) {
|
2022-06-26 11:06:35 +02:00
|
|
|
printf("{{{ pixels %3d %3d %3d }}}\n", r, g, b);
|
|
|
|
printf("{{{ result %3d %3d %3d }}}\n", r2, g2, b2);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
Image_plotRGB(dst, x, y, r2, g2, b2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return FUNC_IS_ALPHA;
|
|
|
|
}
|
|
|
|
/*::------------------------------------------------------------------::*/
|