300 lines
6.3 KiB
C
300 lines
6.3 KiB
C
/*
|
||
dither.c 31 Aout 1999
|
||
-------- ------------
|
||
*/
|
||
|
||
#include <stdio.h>
|
||
#include <stdlib.h>
|
||
#include "../tthimage.h"
|
||
|
||
/*::------------------------------------------------------------------::*/
|
||
/*
|
||
en entree, on doit avoir une image RGB, sinon, "segfault"
|
||
le parametre 'uh' represente l'intensite de la couleur 'on'
|
||
*/
|
||
int
|
||
Image_dither_Bayer_0(Image_Desc *s, Image_Desc *d, int uh)
|
||
{
|
||
int dx, dy, x, y, r, g, b;
|
||
|
||
/* directement copie de la page 389 de "Bitmapped graphics" de
|
||
Steve Rimmer. */
|
||
|
||
static char pattern[8][8] =
|
||
{
|
||
{ 0, 32, 8, 40, 2, 34, 10, 42 },
|
||
{ 48, 16, 56, 24, 50, 18, 58, 26 },
|
||
{ 12, 44, 4, 36, 14, 46, 6, 38 },
|
||
{ 60, 28, 52, 20, 62, 30, 54, 22 },
|
||
{ 3, 35, 11, 43, 1, 33, 9, 41 },
|
||
{ 51, 19, 59, 27, 49, 17, 57, 25 },
|
||
{ 15, 47, 7, 39, 13, 45, 5, 37 },
|
||
{ 63, 31, 55, 23, 61, 29, 53, 21 }
|
||
};
|
||
|
||
dx = s->width; dy = s->height;
|
||
|
||
for (y=0; y<dy; y++)
|
||
{
|
||
for (x=0; x<dx; x++)
|
||
{
|
||
r = s->Rpix[y][x];
|
||
if ((r>>2) > pattern[x&7][y&7]) d->Rpix[y][x] = uh;
|
||
else d->Rpix[y][x] = 0;
|
||
g = s->Gpix[y][x];
|
||
if ((g>>2) > pattern[x&7][y&7]) d->Gpix[y][x] = uh;
|
||
else d->Gpix[y][x] = 0;
|
||
b = s->Bpix[y][x];
|
||
if ((b>>2) > pattern[x&7][y&7]) d->Bpix[y][x] = uh;
|
||
else d->Bpix[y][x] = 0;
|
||
}
|
||
}
|
||
|
||
return OLL_KORRECT;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|
||
/*
|
||
* 19 Juin 2000: dithering on a 2x2 matrice.
|
||
* 15 Nov 2001: 'uh' parameter is _now_ working ;-}
|
||
*/
|
||
int
|
||
Image_dither_crude(Image_Desc *s, Image_Desc *d, int uh)
|
||
{
|
||
int x, y, r, g, b;
|
||
int som;
|
||
|
||
Image_clear(d, 0, 0, 0);
|
||
|
||
for (x=0; x<(s->width-1); x+=2)
|
||
{
|
||
for (y=0; y<(s->height-1); y+=2)
|
||
{
|
||
r = g = b = 0;
|
||
r += Image_R_pixel(s, x, y);
|
||
r += Image_R_pixel(s, x+1, y);
|
||
r += Image_R_pixel(s, x, y+1);
|
||
r += Image_R_pixel(s, x+1, y+1);
|
||
|
||
g += Image_G_pixel(s, x, y);
|
||
g += Image_G_pixel(s, x+1, y);
|
||
g += Image_G_pixel(s, x, y+1);
|
||
g += Image_G_pixel(s, x+1, y+1);
|
||
|
||
b += Image_B_pixel(s, x, y);
|
||
b += Image_B_pixel(s, x+1, y);
|
||
b += Image_B_pixel(s, x, y+1);
|
||
b += Image_B_pixel(s, x+1, y+1);
|
||
|
||
if (r < 512) Image_plotRGB(d, x, y, 0, 0, 0);
|
||
else Image_plotRGB(d, x, y, uh, 0, 0);
|
||
|
||
if (g < 512) Image_plotRGB(d, x+1, y, 0, 0, 0);
|
||
else Image_plotRGB(d, x+1, y, 0, uh, 0);
|
||
|
||
if (b < 512) Image_plotRGB(d, x, y+1, 0, 0, 0);
|
||
else Image_plotRGB(d, x, y+1, 0, 0, uh);
|
||
|
||
som = r + g + b;
|
||
|
||
if (som < 2048)
|
||
{
|
||
Image_plotRGB(d, x+1, y+1, 0, 0, 0);
|
||
}
|
||
else
|
||
{
|
||
Image_plotRGB(d, x+1, y+1, uh, uh, uh);
|
||
}
|
||
}
|
||
}
|
||
|
||
return OLL_KORRECT;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|
||
/*
|
||
* <09>a ne marche pas tr<74>s fort, ce truc...
|
||
*/
|
||
int
|
||
Image_dither_2x2(Image_Desc *s, Image_Desc *d, int uh)
|
||
{
|
||
int x, y, xm, ym;
|
||
int r, g, b, v;
|
||
|
||
x = s->width; xm = (x&1) ? (x-1) : x;
|
||
y = s->height; ym = (y&1) ? (y-1) : y;
|
||
|
||
Image_clear(d, 0, 0, 0);
|
||
|
||
#if DEBUG_LEVEL
|
||
fprintf(stderr, "dither 2x2: %d %d %d %d\n", x, xm, y, ym);
|
||
#endif
|
||
|
||
for (x=0; x<xm; x+=2)
|
||
{
|
||
for (y=0; y<ym; y+=2)
|
||
{
|
||
/*
|
||
* bon sang, mais que faire ici ?
|
||
*/
|
||
r = s->Rpix[y][x];
|
||
if (r > 127) Image_plotRGB(d, x, y, uh, 0, 0);
|
||
else Image_plotRGB(d, x, y, 0, 0, 0);
|
||
|
||
g = s->Gpix[y][x];
|
||
if (g > 127) Image_plotRGB(d, x+1, y, 0, uh, 0);
|
||
else Image_plotRGB(d, x+1, y, 0, 0, 0);
|
||
|
||
b = s->Bpix[y][x];
|
||
if (b > 127) Image_plotRGB(d, x, y+1, 0, 0, uh);
|
||
else Image_plotRGB(d, x, y+1, 0, 0, 0);
|
||
|
||
v = 0xf0 & ((r+g+b)/3);
|
||
Image_plotRGB(d, x+1, y+1, v, v, v);
|
||
}
|
||
}
|
||
|
||
return FUNC_IS_ALPHA;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|
||
int
|
||
Image_dither_seuil_random(Image_Desc *s, Image_Desc *d, int uh)
|
||
{
|
||
int x, y, r, g, b;
|
||
int foo;
|
||
|
||
if ( (foo=Image_compare_desc(s, d)) )
|
||
{
|
||
fprintf(stderr, "dither seuil random: images are differents %d\n", foo);
|
||
return foo;
|
||
}
|
||
|
||
Image_clear(d, 0, 0, 0);
|
||
|
||
for (y=0; y<s->height; y++)
|
||
{
|
||
for (x=0; x<s->width; x++)
|
||
{
|
||
if (s->Rpix[y][x] < rand() % 256) r = 0;
|
||
else r = uh;
|
||
|
||
if (Image_G_pixel(s, x, y) < rand() % 256) g = 0;
|
||
else g = uh;
|
||
|
||
if (Image_B_pixel(s, x, y) < rand() % 256) b = 0;
|
||
else b = uh;
|
||
|
||
(d->Rpix[y])[x] = r;
|
||
(d->Gpix[y])[x] = g;
|
||
(d->Bpix[y])[x] = b;
|
||
}
|
||
}
|
||
return OLL_KORRECT;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|
||
/*
|
||
* algo tire de Interactive Computer Graphics p. 135
|
||
*
|
||
* subtle bug: uh _must_ be 255 ?
|
||
*/
|
||
int
|
||
Image_dither_simple_error(Image_Desc *s, Image_Desc *d, int uh)
|
||
{
|
||
int x, y, xa, xb, inc, errR, errG, errB;
|
||
int r, g, b, dr, dg, db;
|
||
int foo;
|
||
|
||
if ( (foo=Image_compare_desc(s, d)) )
|
||
{
|
||
fprintf(stderr, "dither simple error: images are differents %d\n", foo);
|
||
return foo;
|
||
}
|
||
|
||
Image_clear(d, 0, 0, 0);
|
||
errR = errG = errB = 0;
|
||
|
||
for (y=0; y<s->height; y++)
|
||
{
|
||
if (y & 1)
|
||
{
|
||
xa = 0; xb = s->width - 1; inc = 1;
|
||
}
|
||
else
|
||
{
|
||
xa = s->width - 1; xb = 0; inc = -1;
|
||
}
|
||
|
||
for (x=xa; x!=xb; x+=inc)
|
||
{
|
||
r = (s->Rpix[y])[x];
|
||
if ( (r + errR) > 127 ) dr = uh;
|
||
else dr = 0;
|
||
errR = (r + errR) - dr;
|
||
|
||
g = (s->Gpix[y])[x];
|
||
if ( (g + errG) > 127 ) dg = uh;
|
||
else dg = 0;
|
||
errG = (g + errG) - dg;
|
||
|
||
b = (s->Bpix[y])[x];
|
||
if ( (b + errB) > 127 ) db = uh;
|
||
else db = 0;
|
||
errB = (b + errB) - db;
|
||
|
||
(d->Rpix[y])[x] = dr;
|
||
(d->Gpix[y])[x] = dg;
|
||
(d->Bpix[y])[x] = db;
|
||
}
|
||
}
|
||
|
||
return OLL_KORRECT;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|
||
/*
|
||
* parameters 'sa' and 'sb' must be carefully tuned.
|
||
* 29 Jan 2002: may be I can buid a func for automagically
|
||
* computing of right values ?
|
||
*/
|
||
int
|
||
Image_dither_double_seuil(Image_Desc *s, Image_Desc *d, int sa, int sb, int uh)
|
||
{
|
||
int x, y, r, g, b, foo;
|
||
|
||
if ( (foo=Image_compare_desc(s, d)) )
|
||
{
|
||
fprintf(stderr, "dither double seuil: images are differents %d\n", foo);
|
||
return foo;
|
||
}
|
||
|
||
if ( sa >= sb )
|
||
{
|
||
fprintf(stderr, "dither double seuil: lo %d > hi %d !\n", sa, sb);
|
||
}
|
||
|
||
for (y=0; y<s->height; y++)
|
||
{
|
||
for (x=0; x<s->width; x++)
|
||
{
|
||
r = (s->Rpix[y])[x];
|
||
if (r < sa) r = 0;
|
||
else if (r > sb) r = uh;
|
||
else r = (x&1 && y&1) ? 0 : uh;
|
||
|
||
g = (s->Gpix[y])[x];
|
||
if (g < sa) g = 0;
|
||
else if (g > sb) g = uh;
|
||
else g = (!(x&1) && y&1) ? 0 : uh;
|
||
|
||
b = (s->Bpix[y])[x];
|
||
if (b < sa) b = 0;
|
||
else if (b > sb) b = uh;
|
||
else b = (x&1 && !(y&1)) ? 0 : uh;
|
||
|
||
(d->Rpix[y])[x] = r;
|
||
(d->Gpix[y])[x] = g;
|
||
(d->Bpix[y])[x] = b;
|
||
}
|
||
}
|
||
|
||
return OLL_KORRECT;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|