libtthimage/Lib/effects.c

346 lines
8.5 KiB
C

/*
+---------------------------------------+
| Effets speciaux sur les images |
+---------------------------------------+
Thierry Boudet <oulala@chez.com>
-----------------------------------------
vous pouvez aussi aller regarder le module 'combine.c'
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "../tthimage.h"
/*::------------------------------------------------------------------::*/
/*
* cette func a un defaut: le deplacement est randomatiquement
* lineaire, c'est a dire que la probabilite est constante dans
* toute l'intensite.
*/
int
Image_water( Image_Desc *source, Image_Desc *but, int intensite )
{
int x, y, nx, ny, r, g, b, foo;
#if DEBUG_LEVEL
int retry;
#endif
if ( (foo=Image_compare_desc(source, but)) ) {
fprintf(stderr, "%s : images are differents %d\n", __func__, foo);
return foo;
}
if (intensite < 1) {
fprintf(stderr, "%s : bad intensity %d\n", __func__, intensite);
intensite = 1;
}
if (source == but) {
fprintf(stderr, "%s : Source & Target are the same image, bad effect expected...\n", __func__ );
}
#if DEBUG_LEVEL
retry = 0;
#endif
for (x=0; x<source->width; x++) {
for (y=0; y<source->height; y++) {
foo = -1;
do {
nx = x+(rand()%intensite)-(intensite/2);
ny = y+(rand()%intensite)-(intensite/2);
foo++;
} while ( ! ( (nx >= 0) && (ny >=0) &&
(nx < source->width) &&
(ny < source->height) )
);
#if DEBUG_LEVEL
retry += foo;
#endif
r = (source->Rpix[ny])[nx];
g = (source->Gpix[ny])[nx];
b = (source->Bpix[ny])[nx];
(but->Rpix[y])[x] = r;
(but->Gpix[y])[x] = g;
(but->Bpix[y])[x] = b;
}
}
#if DEBUG_LEVEL
if (retry > 0)
fprintf(stderr, "image water: %d retries\n", retry);
else
fprintf(stderr, "image water: NO retry !\n");
#endif
but->modified = 1;
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
/*
* cette fonction peut etre utilisee avec la meme image
* en source et en destination.
*/
int
Image_noise(Image_Desc *source, Image_Desc *but, int intensite)
{
int x, y, r, g, b, foo;
if ( (foo=Image_compare_desc(source, but)) ) {
fprintf(stderr, "%s : images are differents %d\n", __func__, foo);
return foo;
}
if (intensite < 1) {
fprintf(stderr, "%s : bad intensity %d\n", __func__, intensite);
intensite = 1;
}
for (x=0; x<source->width; x++) {
for (y=0; y<source->height; y++) {
r = Image_clamp_pixel((source->Rpix[y])[x]
+ (rand()%intensite) - (intensite/2));
g = Image_clamp_pixel((source->Gpix[y])[x]
+ (rand()%intensite) - (intensite/2));
b = Image_clamp_pixel((source->Bpix[y])[x]
+ (rand()%intensite) - (intensite/2));
(but->Rpix[y])[x] = r;
(but->Gpix[y])[x] = g;
(but->Bpix[y])[x] = b;
}
}
but->modified = 1;
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
/* 19 Aout 1999
j'ai rapidement besoin de cette fonction alors je code
a la rache :-[ (on appelle aussi c,a le codage 123momo)
*/
int Image_mirror(Image_Desc *src, Image_Desc *dst, int reserved)
{
register int x;
uint8_t *buffer;
int foo, largeur, y;
if (reserved != 0)
fprintf(stderr, "%s: reserved must be zero !\n", __func__);
if ( (foo=Image_compare_desc(src, dst)) ) {
fprintf(stderr, "%s: images are differents %d\n", __func__, foo);
return foo;
}
largeur = src->width;
if ((buffer = (uint8_t *)malloc(largeur)) == NULL) {
fprintf(stderr, "%s: no memory for buffer\n", __func__);
return BUFFER_NO_MEM;
}
for (y=0; y<src->height; y++) {
if (src->Rpix != NULL) {
for (x=0; x<largeur; x++)
buffer[x] = (src->Rpix[y])[x];
for (x=0; x<largeur; x++)
(dst->Rpix[y])[x] = buffer[largeur-x-1];
}
if (src->Gpix != NULL) {
for (x=0; x<largeur; x++)
buffer[x] = (src->Gpix[y])[x];
for (x=0; x<largeur; x++)
(dst->Gpix[y])[x] = buffer[largeur-x-1];
}
if (src->Bpix != NULL) {
for (x=0; x<largeur; x++)
buffer[x] = (src->Bpix[y])[x];
for (x=0; x<largeur; x++)
(dst->Bpix[y])[x] = buffer[largeur-x-1];
}
if (src->Apix != NULL) {
for (x=0; x<largeur; x++)
buffer[x] = (src->Apix[y])[x];
for (x=0; x<largeur; x++)
(dst->Apix[y])[x] = buffer[largeur-x-1];
}
}
free(buffer);
dst->modified = 1;
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
/* new 4 Janvier 2000 */
int
Image_upside_down(Image_Desc *src, Image_Desc *dst, int reserved)
{
int foo, y;
if ( (foo=Image_compare_desc(src, dst)) ) {
fprintf(stderr, "%s: images are differents %d\n", __func__, foo);
return foo;
}
if (0 != reserved) {
fprintf(stderr, "%s gni ?\n", __func__);
}
for (y=0; y<src->height; y++) {
memcpy(dst->Rpix[y], src->Rpix[src->height-(y+1)], src->width);
memcpy(dst->Gpix[y], src->Gpix[src->height-(y+1)], src->width);
memcpy(dst->Bpix[y], src->Bpix[src->height-(y+1)], src->width);
if (src->Apix != NULL)
memcpy(dst->Apix[y], src->Apix[src->height-(y+1)], src->width);
}
dst->modified = 1;
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
/*
* je soupc,onne un bug la dedans... XXX
*/
int
Image_scratch ( Image_Desc *source, Image_Desc * but, long nombre )
{
int xs, ys, xd, yd;
#if DEBUG_LEVEL
fprintf(stderr, "Scratching %ld times %p to %p\n", nombre, source, but);
#endif
Image_copy(source, but);
while (nombre--) {
xs = rand() % source->width;
ys = rand() % source->height;
xd = rand() % source->width;
yd = rand() % source->height;
Image_pixel_copy(source, xs, ys, but, xd, yd);
}
but->modified = 1;
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
/* 7 Sep 1999 */
int
Image_swap_lines( Image_Desc *src, Image_Desc * dst )
{
int foo, line;
if (src == dst) {
fprintf(stderr, "%s: SRC & DST must be different\n", __func__);
return IMG_OVERWRITE;
}
if ( (foo=Image_compare_desc(src, dst)) ) {
fprintf(stderr, "%s: images have differents sizes. %d\n",
__func__, foo);
return foo;
}
for (line=0; line<(src->height-1); line+=2) {
memcpy(dst->Rpix[line+1], src->Rpix[line], src->width);
memcpy(dst->Rpix[line], src->Rpix[line+1], src->width);
memcpy(dst->Gpix[line+1], src->Gpix[line], src->width);
memcpy(dst->Gpix[line], src->Gpix[line+1], src->width);
memcpy(dst->Bpix[line+1], src->Bpix[line], src->width);
memcpy(dst->Bpix[line], src->Bpix[line+1], src->width);
}
dst->modified = 1;
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
/* 7 Sep 1999 */
int
Image_swap_cols( Image_Desc *src, Image_Desc * dst )
{
int foo, line, col, tmp, wmax;
if (src == dst) {
fprintf(stderr, "%s: SRC & DST must be different\n", __func__);
return IMG_OVERWRITE;
}
if ( (foo=Image_compare_desc(src, dst)) ) {
fprintf(stderr, "%s: images are differents %d\n", __func__, foo);
return foo;
}
if (src->width & 1)
wmax = src->width - 1;
else
wmax = src->width;
fprintf(stderr, "swap cols %d %d\n", src->width, wmax);
for (line=0; line<src->height; line++) {
for (col=0; col<wmax; col+=2) {
tmp = src->Rpix[line][col];
dst->Rpix[line][col] = src->Rpix[line][col+1];
dst->Rpix[line][col+1] = tmp;
tmp = src->Gpix[line][col];
dst->Gpix[line][col] = src->Gpix[line][col+1];
dst->Gpix[line][col+1] = tmp;
tmp = src->Bpix[line][col];
dst->Bpix[line][col] = src->Bpix[line][col+1];
dst->Bpix[line][col+1] = tmp;
}
}
dst->modified = 1;
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/
/* 7 Sep 1999 */
int
Image_swap_nibbles( Image_Desc *src, Image_Desc * dst )
{
int foo;
int x, y;
if ( (foo=Image_compare_desc(src, dst)) ) {
fprintf(stderr, "%s: images are differents %d\n", __func__, foo);
return foo;
}
for (x=0; x<src->width; x++) {
for (y=0; y<src->height; y++) {
dst->Rpix[y][x] = ((src->Rpix[y][x] & 0xf0) >> 4) |
((src->Rpix[y][x] & 0x0f) << 4);
#if DEBUG_LEVEL > 1
printf ("%02x %02x\n", src->Rpix[y][x], dst->Rpix[y][x]);
#endif
dst->Gpix[y][x] = ((src->Gpix[y][x] & 0xf0) >> 4) |
((src->Gpix[y][x] & 0x0f) << 4);
dst->Bpix[y][x] = ((src->Bpix[y][x] & 0xf0) >> 4) |
((src->Bpix[y][x] & 0x0f) << 4);
}
}
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/