Some fixes to the floyd steinberg dithering. The error was added to the neughbour pixels, it is now substracted, the results are much better. However, the palette seems to lack saturated colors (in comparison to the one generated b ygimp, wich gives more dithering, but better overall subjective ressemblance to the 24bit image. Maybe having less dithering is fine for us, as we are in a pixelart painting program afterall...

git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@369 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
Adrien Destugues 2008-12-03 20:50:52 +00:00
parent 14accb544b
commit 7c658a6855
4 changed files with 37 additions and 39 deletions

BIN
gfx2.cfg

Binary file not shown.

60
op_c.c
View File

@ -178,7 +178,7 @@ Table_conversion * TC_New(int nbb_r,int nbb_v,int nbb_b)
int taille;
n=(Table_conversion *)malloc(sizeof(Table_conversion));
if (n!=0)
if (n!=NULL)
{
// On recopie les paramŠtres demands
n->nbb_r=nbb_r;
@ -199,14 +199,14 @@ Table_conversion * TC_New(int nbb_r,int nbb_v,int nbb_b)
// On tente d'allouer la table
taille=(n->rng_r)*(n->rng_v)*(n->rng_b);
n->table=(byte *)malloc(taille);
if (n->table!=0)
if (n->table!=NULL)
// C'est bon!
memset(n->table,0,taille); // Inutile, mais plus propre
else
{
// Table impossible … allouer
free(n);
n=0;
n=NULL;
}
}
@ -663,12 +663,16 @@ ClusterSet * CS_New(int nbmax,Table_occurence * to)
{
// On recopie les paramŠtres demands
n->nbmax=TO_Compter_couleurs(to);
// On vient de compter le nombre de couleurs existantes, s'il est plus grand que 256 on limite à 256 (nombre de couleurs voulu au final)
if (n->nbmax>nbmax)
{
n->nbmax=nbmax;
}
// On tente d'allouer la table
n->clusters=(Cluster *)malloc(nbmax*sizeof(Cluster));
if (n->clusters!=0)
if (n->clusters!=NULL)
// C'est bon! On initialise
CS_Init(n,to);
else
@ -761,8 +765,10 @@ void CS_Generer(ClusterSet * cs,Table_occurence * to)
Cluster_Analyser(&Nouveau1,to);
Cluster_Analyser(&Nouveau2,to);
// On met ces deux nouveaux clusters dans le clusterSet
// On met ces deux nouveaux clusters dans le clusterSet... sauf s'ils sont vides
if(Nouveau1.occurences>0)
CS_Set(cs,&Nouveau1);
if(Nouveau2.occurences>0)
CS_Set(cs,&Nouveau2);
}
}
@ -881,7 +887,7 @@ DegradeSet * DS_New(ClusterSet * cs)
DegradeSet * n;
n=(DegradeSet *)malloc(sizeof(DegradeSet));
if (n!=0)
if (n!=NULL)
{
// On recopie les paramŠtres demands
n->nbmax=cs->nbmax;
@ -1113,9 +1119,13 @@ int Valeur_modifiee(int valeur,int modif)
{
valeur+=modif;
if (valeur<0)
{
valeur=0;
}
else if (valeur>255)
{
valeur=255;
}
return valeur;
}
@ -1132,8 +1142,7 @@ void Convert_bitmap_24B_to_256_Floyd_Steinberg(Bitmap256 Dest,Bitmap24B Source,i
Bitmap256 D;
int Pos_X,Pos_Y;
int Rouge,Vert,Bleu;
int DRouge,DVert,DBleu;
int ERouge,EVert,EBleu;
float ERouge,EVert,EBleu;
// On initialise les variables de parcours:
Courant =Source; // Le pixel dont on s'occupe
@ -1157,14 +1166,9 @@ void Convert_bitmap_24B_to_256_Floyd_Steinberg(Bitmap256 Dest,Bitmap24B Source,i
*D=TC_Get(tc,Rouge,Vert,Bleu);
// Puis on calcule pour chaque composante l'erreur dûe à l'approximation
Rouge=palette[*D].R - Rouge;
Vert =palette[*D].V - Vert;
Bleu =palette[*D].B - Bleu;
// On initialise la quantité d'erreur diffusée
DRouge=Rouge;
DVert =Vert;
DBleu =Bleu;
Rouge-=palette[*D].R;
Vert -=palette[*D].V;
Bleu -=palette[*D].B;
// Et dans chaque pixel voisin on propage l'erreur
// A droite:
@ -1178,9 +1182,6 @@ void Convert_bitmap_24B_to_256_Floyd_Steinberg(Bitmap256 Dest,Bitmap24B Source,i
C_plus1->V=Valeur_modifiee(C_plus1->V,EVert );
C_plus1->B=Valeur_modifiee(C_plus1->B,EBleu );
}
DRouge-=ERouge;
DVert -=EVert;
DBleu -=EBleu;
// En bas à gauche:
if (Pos_Y+1<hauteur)
{
@ -1193,25 +1194,22 @@ void Convert_bitmap_24B_to_256_Floyd_Steinberg(Bitmap256 Dest,Bitmap24B Source,i
S_moins1->V=Valeur_modifiee(S_moins1->V,EVert );
S_moins1->B=Valeur_modifiee(S_moins1->B,EBleu );
}
DRouge-=ERouge;
DVert -=EVert;
DBleu -=EBleu;
// En bas:
ERouge=(Rouge/4);
EVert =(Vert /4);
EBleu =(Bleu /4);
ERouge=(Rouge*5/16.0);
EVert =(Vert*5 /16.0);
EBleu =(Bleu*5 /16.0);
Suivant->R=Valeur_modifiee(Suivant->R,ERouge);
Suivant->V=Valeur_modifiee(Suivant->V,EVert );
Suivant->B=Valeur_modifiee(Suivant->B,EBleu );
DRouge-=ERouge;
DVert -=EVert;
DBleu -=EBleu;
// En bas à droite:
if (Pos_X+1<largeur)
{
S_plus1->R=Valeur_modifiee(S_plus1->R,DRouge);
S_plus1->V=Valeur_modifiee(S_plus1->V,DVert );
S_plus1->B=Valeur_modifiee(S_plus1->B,DBleu );
ERouge=(Rouge/16.0);
EVert =(Vert /16.0);
EBleu =(Bleu /16.0);
S_plus1->R=Valeur_modifiee(S_plus1->R,ERouge);
S_plus1->V=Valeur_modifiee(S_plus1->V,EVert );
S_plus1->B=Valeur_modifiee(S_plus1->B,EBleu );
}
}

View File

@ -49,7 +49,7 @@ typedef void (* fonction_display_zoom) (word,word,word,byte *);
typedef void (* fonction_display_brush_Color_zoom) (word,word,word,word,word,word,byte,word,byte *);
typedef void (* fonction_display_brush_Mono_zoom) (word,word,word,word,word,word,byte,byte,word,byte *);
struct Composantes
struct __attribute__ ((__packed__)) Composantes
{
byte R;
byte V;

View File

@ -427,11 +427,11 @@ static const T_TABLEAIDE TableAideCredits[] =
AIDE_TEXTE("")
AIDE_BOLD(" BUGFINDERS") //
AIDE_TEXTE("") //
AIDE_TEXTE(" Ced El Topo fallenblood")
AIDE_TEXTE(" Frost Grimmy keito")
AIDE_TEXTE(" kusma Lord Graga mind")
AIDE_TEXTE(" MooZ richienyhus tempest")
AIDE_TEXTE(" titus^Rab tobe")
AIDE_TEXTE(" BDCIron Ced El Topo ")
AIDE_TEXTE(" fallenblood Frost Grimmy ")
AIDE_TEXTE(" keito kusma Lord Graga ")
AIDE_TEXTE(" mind MooZ richienyhus")
AIDE_TEXTE(" tempest titus^Rab tobe")
AIDE_TEXTE("")
AIDE_BOLD (" OUR HOMEPAGE") //
AIDE_TEXTE("") //