libtthimage/Lib/combine.c

415 lines
9.1 KiB
C
Raw Normal View History

2022-06-26 11:06:35 +02:00
/*
combine.c others effects
========= --------------
made by Thierry Boudet, aka "Oulala", aka "Tonton Th".
2024-08-10 17:49:57 +02:00
ces fonctions combinent de diverses facons deux images
2022-06-26 11:06:35 +02:00
de memes dimensions. on pourra, par exemple, les utiliser
pour comparer deux traitements.
*/
#include <stdio.h>
#include <stdlib.h>
2023-10-11 22:36:16 +02:00
#include <math.h>
2022-06-26 11:06:35 +02:00
2022-06-27 00:48:18 +02:00
#include "../tthimage.h"
2022-06-26 11:06:35 +02:00
#ifndef min
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#endif
/*::------------------------------------------------------------------::*/
/*
2024-08-10 17:49:57 +02:00
* le parametre 'zak' n'est pas utilise et doit etre mis a 0
2022-06-26 11:06:35 +02:00
*/
2022-09-17 11:23:21 +02:00
int Image_combine_lines(Image_Desc *s1, Image_Desc *s2, Image_Desc *d,
2022-06-26 11:06:35 +02:00
int sy, int oy, int zak)
{
int foo, x, y, my, r, g, b;
2022-07-11 06:14:45 +02:00
if (sy == 0) {
2024-08-10 17:49:57 +02:00
fprintf(stderr, "%s: sy is 0 and zak is %d\n", __func__, zak);
2022-06-26 11:06:35 +02:00
return DIVISOR_IS_ZERO;
}
2022-07-11 06:14:45 +02:00
if ( (foo=Image_compare_desc(s1, s2)) ) {
2024-08-10 17:49:57 +02:00
fprintf(stderr, "%s: sources are differents (%d)\n", __func__, foo);
2022-06-26 11:06:35 +02:00
return foo;
}
#if DEBUG_LEVEL
fprintf(stderr, "Combine lines: %d %d\n", sy, oy);
#endif
2022-07-11 06:14:45 +02:00
for (y=0; y<s1->height; y++) {
2022-06-26 11:06:35 +02:00
my = (y+oy) / sy;
2022-07-11 06:14:45 +02:00
for (x=0; x<s1->width; x++) {
if ( my&1 ) {
2022-06-26 11:06:35 +02:00
r = (s1->Rpix[y])[x];
g = (s1->Gpix[y])[x];
b = (s1->Bpix[y])[x];
}
2022-07-11 06:14:45 +02:00
else {
2022-06-26 11:06:35 +02:00
r = (s2->Rpix[y])[x];
g = (s2->Gpix[y])[x];
b = (s2->Bpix[y])[x];
}
(d->Rpix[y])[x] = r;
(d->Gpix[y])[x] = g;
(d->Bpix[y])[x] = b;
}
}
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
/*
2024-08-10 17:49:57 +02:00
* le parametre 'zak' n'est pas utilise et doit etre mis a 0
2022-06-26 11:06:35 +02:00
*/
2022-09-17 11:23:21 +02:00
int Image_combine_columns(Image_Desc *s1, Image_Desc *s2, Image_Desc *d,
2022-06-26 11:06:35 +02:00
int sx, int ox, int zak)
{
int foo, x, y, mx, r, g, b;
2023-10-11 22:36:16 +02:00
if (zak) {
fprintf(stderr, "in %s, zak is not 0\n", __func__);
}
2022-07-11 06:14:45 +02:00
if (sx == 0) {
2022-06-26 11:06:35 +02:00
fprintf(stderr, "Combine Columns: sx is zer0\n");
return DIVISOR_IS_ZERO;
}
2022-07-11 06:14:45 +02:00
if ( (foo=Image_compare_desc(s1, s2)) ) {
2022-06-26 11:06:35 +02:00
fprintf(stderr, "Combine Lines: sources are differents (%d)\n", foo);
return foo;
}
#if DEBUG_LEVEL
fprintf(stderr, "Combine columns: %d %d\n", sx, ox);
#endif
2022-07-11 06:14:45 +02:00
for (y=0; y<s1->height; y++) {
for (x=0; x<s1->width; x++) {
2022-06-26 11:06:35 +02:00
mx = (x+ox) / sx;
2022-07-11 06:14:45 +02:00
if ( mx & 1 ) {
2022-06-26 11:06:35 +02:00
r = (s1->Rpix[y])[x];
g = (s1->Gpix[y])[x];
b = (s1->Bpix[y])[x];
}
2022-07-11 06:14:45 +02:00
else {
2022-06-26 11:06:35 +02:00
r = (s2->Rpix[y])[x];
g = (s2->Gpix[y])[x];
b = (s2->Bpix[y])[x];
}
(d->Rpix[y])[x] = r;
(d->Gpix[y])[x] = g;
(d->Bpix[y])[x] = b;
}
}
d->modified = 1;
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
/*
* 28 Jan 2001: pourquoi ne pas introduire un calcul automatique
* des coefficients ox & oy pour obtenir le centrage ?
*
* 'zak' parameter is not used, and must be 0.
*/
2022-09-17 11:23:21 +02:00
int Image_combine_checker(Image_Desc *s1, Image_Desc *s2, Image_Desc *d,
2022-06-26 11:06:35 +02:00
int sx, int sy, int ox, int oy, int zak)
{
int foo, r, g, b;
int x, y, mx, my;
#if DEBUG_LEVEL
fprintf(stderr, "Checker (%p, %p) -> %p [%d,%d] [%d,%d]\n",
s1, s2, d, sx, sy, ox, oy);
#endif
2022-07-11 06:14:45 +02:00
if (zak) {
fprintf(stderr, "%s: 'zak' = %d, must be 0.\n", __func__, zak);
2022-06-26 11:06:35 +02:00
}
2022-07-11 06:14:45 +02:00
if ( sx==0 || sy==0 ) {
2022-06-26 11:06:35 +02:00
fprintf(stderr, "Combine Checker: sx or sy is Zero\n");
return DIVISOR_IS_ZERO;
}
2022-07-11 06:14:45 +02:00
if ( (foo=Image_compare_desc(s1, s2)) ) {
2022-06-26 11:06:35 +02:00
fprintf(stderr, "Combine Checker: sources are differents (%d)\n", foo);
return foo;
}
2022-07-11 06:14:45 +02:00
for (y=0; y<s1->height; y++) {
2022-06-26 11:06:35 +02:00
my = (y+oy) / sy;
2022-07-11 06:14:45 +02:00
for (x=0; x<s1->width; x++) {
2022-06-26 11:06:35 +02:00
mx = (x+ox) / sx;
2022-07-11 06:14:45 +02:00
if ( (mx&1) != (my&1) ) {
2022-06-26 11:06:35 +02:00
r = (s1->Rpix[y])[x];
g = (s1->Gpix[y])[x];
b = (s1->Bpix[y])[x];
}
2022-07-11 06:14:45 +02:00
else {
2022-06-26 11:06:35 +02:00
r = (s2->Rpix[y])[x];
g = (s2->Gpix[y])[x];
b = (s2->Bpix[y])[x];
}
(d->Rpix[y])[x] = r;
(d->Gpix[y])[x] = g;
(d->Bpix[y])[x] = b;
}
}
return 0;
}
/*::------------------------------------------------------------------::*/
/*
* houba, celle-ci va me donner du mal, et on peut la
* considerer comme pas finie, c'est a dire, entre autre,
* que le prototype risque de changer.
*
* Toutes les suggestions sont les bienvenues, surtout si
* elles viennent de glandeur06 et son UltraSparc.
*
* Tiens, le parametre 'yo' ne sert a rien ?
*/
2022-09-17 11:23:21 +02:00
int Image_combine_cercle_flou(Image_Desc *s1, Image_Desc *s2, Image_Desc *d, int yo)
2022-06-26 11:06:35 +02:00
{
int foo;
int xcenter, ycenter;
int x, y, r1, v1, b1, r2, b2, v2;
float fx2, fy2, dmax, coef;
2022-07-11 06:14:45 +02:00
if ( (foo=Image_compare_desc(s1, s2)) ) {
2022-06-26 11:06:35 +02:00
fprintf(stderr, "Combine Cercle Flou: differents sources (%d)\n", foo);
return foo;
}
2022-07-11 06:14:45 +02:00
if ( (foo=Image_compare_desc(s1, d)) ) {
2022-06-26 11:06:35 +02:00
fprintf(stderr, "Combine Cercle Flou: source != dest (%d)\n", foo);
return foo;
}
xcenter = (s1->width) / 2;
ycenter = (s1->height) / 2;
dmax = (float)(xcenter*xcenter) + (float)(ycenter*ycenter);
dmax /= 1.732;
#if DEBUG_LEVEL
fprintf(stderr, "\tcentre: %d, %d\n", xcenter, ycenter);
fprintf(stderr, "\tdmax: %f\n", dmax);
fflush(stderr); /* vraiment necessaire ? */
#endif
2022-07-11 06:14:45 +02:00
for (y=0; y<s1->height; y++) {
2022-06-26 11:06:35 +02:00
fy2 = (float)((y-ycenter)*(y-ycenter));
2022-07-11 06:14:45 +02:00
for (x=0; x<s1->width; x++) {
2022-06-26 11:06:35 +02:00
fx2 = (float)((x-xcenter)*(x-xcenter));
r1 = (s1->Rpix[y])[x];
v1 = (s1->Gpix[y])[x];
b1 = (s1->Bpix[y])[x];
r2 = (s2->Rpix[y])[x];
v2 = (s2->Gpix[y])[x];
b2 = (s2->Bpix[y])[x];
coef = (fx2+fy2)/dmax;
2022-07-07 12:52:00 +02:00
if (1==yo) {
coef = cos(coef);
}
2022-06-26 11:06:35 +02:00
if (coef < 0.0) coef = 0.0;
if (coef > 1.0) coef = 1.0;
(d->Rpix[y])[x] = (int)(r1*(1.0-coef)+r2*coef);
(d->Gpix[y])[x] = (int)(v1*(1.0-coef)+v2*coef);
(d->Bpix[y])[x] = (int)(b1*(1.0-coef)+b2*coef);
}
2022-07-11 06:14:45 +02:00
#if DEBUG_LEVEL
2022-07-07 12:52:00 +02:00
fprintf(stderr, "x %4d y %4d c %f\n", x, y, coef);
2022-07-11 06:14:45 +02:00
#endif
2022-06-26 11:06:35 +02:00
}
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
/*
2024-08-10 17:49:57 +02:00
* le flag 'yo' decide quelle image sera en haut a droite.
* les parametres p1 & p2 ne sont pas utilises.
2022-06-26 11:06:35 +02:00
*/
2022-09-17 11:23:21 +02:00
int Image_combine_diagonale(Image_Desc *s1, Image_Desc *s2, Image_Desc *d,
2022-06-26 11:06:35 +02:00
int yo, int p1, int p2)
{
int foo;
int x, y, r, g, b;
int vertical, offset;
2023-10-11 22:36:16 +02:00
if ( p1 || p2 ) {
2024-08-10 17:49:57 +02:00
fprintf(stderr, "%s: bad p1 %d or bad p2 %d\n", __func__, p1, p2);
2023-10-11 22:36:16 +02:00
}
2022-07-11 06:14:45 +02:00
if ( (foo=Image_compare_desc(s1, s2)) ) {
2023-10-11 22:36:16 +02:00
fprintf(stderr, "%s: differents sources (%d)\n", __func__, foo);
2022-06-26 11:06:35 +02:00
return foo;
}
2022-07-11 06:14:45 +02:00
if (s1->height > s1->width) {
2022-06-26 11:06:35 +02:00
vertical = 1;
offset = (s1->height - s1->width) / 2;
}
2022-07-11 06:14:45 +02:00
else {
2022-06-26 11:06:35 +02:00
vertical = 0;
offset = (s1->width - s1->height) / 2;
}
2022-07-11 06:14:45 +02:00
for (y=0; y<s1->height; y++) {
for (x=0; x<s1->width; x++) {
if ( vertical ) {
2022-06-26 11:06:35 +02:00
if (x > (y-offset)) foo=1;
else foo=0;
}
2022-07-11 06:14:45 +02:00
else {
2022-06-26 11:06:35 +02:00
if ((x-offset) > y) foo=1;
else foo=0;
}
foo = yo ? !foo : foo; /* strange hack */
2022-07-11 06:14:45 +02:00
if (foo) {
2022-06-26 11:06:35 +02:00
r = (s1->Rpix[y])[x];
g = (s1->Gpix[y])[x];
b = (s1->Bpix[y])[x];
}
2022-07-11 06:14:45 +02:00
else {
2022-06-26 11:06:35 +02:00
r = (s2->Rpix[y])[x];
g = (s2->Gpix[y])[x];
b = (s2->Bpix[y])[x];
}
(d->Rpix[y])[x] = r;
(d->Gpix[y])[x] = g;
(d->Bpix[y])[x] = b;
}
}
/*
* 30 sept 2008 : est-ce que cette fonction a subi un bon fuzzing ?
2024-08-10 17:49:57 +02:00
* 9 aout 2024 : non, pas encore ;)
2022-06-26 11:06:35 +02:00
*/
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
/* 15 Nov 2000
we put in the destination image the min/max value
of the RGB componants.
*/
2022-09-17 11:23:21 +02:00
int Image_combine_minmax(Image_Desc *s1, Image_Desc *s2, Image_Desc *d, int flg)
2022-06-26 11:06:35 +02:00
{
int foo, x, y, r, g, b;
int r1, r2, g1, g2, b1, b2;
2022-07-11 06:14:45 +02:00
if ( (foo=Image_compare_desc(s1, s2)) ) {
2022-06-26 11:06:35 +02:00
fprintf(stderr, "Combine MinMax: differents sources (%d)\n", foo);
return foo;
}
2022-07-11 06:14:45 +02:00
for (y=0; y<s1->height; y++) {
for (x=0; x<s1->width; x++) {
2022-06-26 11:06:35 +02:00
r1 = (s1->Rpix[y])[x];
g1 = (s1->Gpix[y])[x];
b1 = (s1->Bpix[y])[x];
r2 = (s2->Rpix[y])[x];
g2 = (s2->Gpix[y])[x];
b2 = (s2->Bpix[y])[x];
2022-07-11 06:14:45 +02:00
if (flg) {
2022-06-26 11:06:35 +02:00
r = max(r1, r2);
g = max(g1, g2);
b = max(b1, b2);
}
else
{
r = min(r1, r2);
g = min(g1, g2);
b = min(b1, b2);
}
(d->Rpix[y])[x] = r;
(d->Gpix[y])[x] = g;
(d->Bpix[y])[x] = b;
}
}
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
/*
* fonction faite pour le finisseur de DBvsEE
*
2024-08-10 17:49:57 +02:00
* 6 oct 2001: une version qui permettrait de specifier les
2022-06-26 11:06:35 +02:00
* seuils en r,g et b serait assez pratique aussi.
*/
2022-09-17 11:23:21 +02:00
int Image_combine_if_not_black(Image_Desc *s1, Image_Desc *s2, Image_Desc *d)
2022-06-26 11:06:35 +02:00
{
int foo, x, y, r, g, b;
2022-07-11 06:14:45 +02:00
if ( (foo=Image_compare_desc(s1, s2)) ) {
2022-06-26 11:06:35 +02:00
fprintf(stderr, "Combine If Not Black: differents sources (%d)\n", foo);
return foo;
}
2022-07-11 06:14:45 +02:00
for (y=0; y<s1->height; y++) {
for (x=0; x<s1->width; x++) {
2022-06-26 11:06:35 +02:00
/* XXX Image_getRGB(s1, x, y, &r, &g, &b); */
r = (s1->Rpix[y])[x];
g = (s1->Gpix[y])[x];
b = (s1->Bpix[y])[x];
2022-07-11 06:14:45 +02:00
if ( r==0 && g==0 && b==0 ) {
2022-06-26 11:06:35 +02:00
/* XXX Image_getRGB(s2, x, y, &r, &g, &b); */
r = (s2->Rpix[y])[x];
g = (s2->Gpix[y])[x];
b = (s2->Bpix[y])[x];
}
/*Image_plotRGB(d, x, y, r, g, b);*/
(d->Rpix[y])[x] = r;
(d->Gpix[y])[x] = g;
(d->Bpix[y])[x] = b;
}
}
return FUNC_IS_BETA; /* XXX c'est pas du OLL_KORRECT ? */
}
/*::------------------------------------------------------------------::*/
/*
* gni ?
*/
2022-09-17 11:23:21 +02:00
int Image_poke_2zones(Image_Desc *src, Image_Desc *ia, Image_Desc *ib,
2022-06-26 11:06:35 +02:00
Image_Rect *za, Image_Rect *zb,
2022-09-17 11:23:21 +02:00
Image_Desc *dst)
2022-06-26 11:06:35 +02:00
{
int foo;
/* Image_Rect rect; */
2022-07-11 06:14:45 +02:00
if ( (foo=Image_compare_desc(src, dst)) ) {
2022-06-26 11:06:35 +02:00
fprintf(stderr, "Poke 2 Zone: src & dst: %d %s\n",
foo, Image_err2str(foo));
return foo;
}
Image_copy(src, dst);
fprintf(stderr, "Image Poke 2 Zones: ben, ya rien...\n");
return FUNC_NOT_FINISH;
}
/*::------------------------------------------------------------------::*/