374 lines
8.6 KiB
C
374 lines
8.6 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, "Image_Mirror: reserved must be zero !\n");
|
|
|
|
if ( (foo=Image_compare_desc(src, dst)) )
|
|
{
|
|
fprintf(stderr, "Image_Mirror: images are differents %d\n", foo);
|
|
return foo;
|
|
}
|
|
largeur = src->width;
|
|
|
|
if ((buffer = (uint8_t *)malloc(largeur)) == NULL)
|
|
{
|
|
fprintf(stderr, "Image_Mirror: no memory for buffer");
|
|
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, "Image_UpsideDown: images are differents %d\n", 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, "Image swap lines: SRC & DST must be different\n");
|
|
return IMG_OVERWRITE;
|
|
}
|
|
|
|
if ( (foo=Image_compare_desc(src, dst)) )
|
|
{
|
|
fprintf(stderr, "Image swap lines: images have differents sizes. %d\n",
|
|
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, "Image_SwapCols: SRC & DST must be different\n");
|
|
return IMG_OVERWRITE;
|
|
}
|
|
|
|
if ( (foo=Image_compare_desc(src, dst)) )
|
|
{
|
|
fprintf(stderr, "Image_SwapCols: images are differents %d\n", 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;
|
|
}
|
|
/*::------------------------------------------------------------------::*/
|