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; int taille;
n=(Table_conversion *)malloc(sizeof(Table_conversion)); n=(Table_conversion *)malloc(sizeof(Table_conversion));
if (n!=0) if (n!=NULL)
{ {
// On recopie les paramŠtres demands // On recopie les paramŠtres demands
n->nbb_r=nbb_r; 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 // On tente d'allouer la table
taille=(n->rng_r)*(n->rng_v)*(n->rng_b); taille=(n->rng_r)*(n->rng_v)*(n->rng_b);
n->table=(byte *)malloc(taille); n->table=(byte *)malloc(taille);
if (n->table!=0) if (n->table!=NULL)
// C'est bon! // C'est bon!
memset(n->table,0,taille); // Inutile, mais plus propre memset(n->table,0,taille); // Inutile, mais plus propre
else else
{ {
// Table impossible … allouer // Table impossible … allouer
free(n); free(n);
n=0; n=NULL;
} }
} }
@ -663,12 +663,16 @@ ClusterSet * CS_New(int nbmax,Table_occurence * to)
{ {
// On recopie les paramŠtres demands // On recopie les paramŠtres demands
n->nbmax=TO_Compter_couleurs(to); 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) if (n->nbmax>nbmax)
{
n->nbmax=nbmax; n->nbmax=nbmax;
}
// On tente d'allouer la table // On tente d'allouer la table
n->clusters=(Cluster *)malloc(nbmax*sizeof(Cluster)); n->clusters=(Cluster *)malloc(nbmax*sizeof(Cluster));
if (n->clusters!=0) if (n->clusters!=NULL)
// C'est bon! On initialise // C'est bon! On initialise
CS_Init(n,to); CS_Init(n,to);
else else
@ -761,8 +765,10 @@ void CS_Generer(ClusterSet * cs,Table_occurence * to)
Cluster_Analyser(&Nouveau1,to); Cluster_Analyser(&Nouveau1,to);
Cluster_Analyser(&Nouveau2,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); CS_Set(cs,&Nouveau1);
if(Nouveau2.occurences>0)
CS_Set(cs,&Nouveau2); CS_Set(cs,&Nouveau2);
} }
} }
@ -881,7 +887,7 @@ DegradeSet * DS_New(ClusterSet * cs)
DegradeSet * n; DegradeSet * n;
n=(DegradeSet *)malloc(sizeof(DegradeSet)); n=(DegradeSet *)malloc(sizeof(DegradeSet));
if (n!=0) if (n!=NULL)
{ {
// On recopie les paramŠtres demands // On recopie les paramŠtres demands
n->nbmax=cs->nbmax; n->nbmax=cs->nbmax;
@ -1113,9 +1119,13 @@ int Valeur_modifiee(int valeur,int modif)
{ {
valeur+=modif; valeur+=modif;
if (valeur<0) if (valeur<0)
{
valeur=0; valeur=0;
}
else if (valeur>255) else if (valeur>255)
{
valeur=255; valeur=255;
}
return valeur; return valeur;
} }
@ -1132,8 +1142,7 @@ void Convert_bitmap_24B_to_256_Floyd_Steinberg(Bitmap256 Dest,Bitmap24B Source,i
Bitmap256 D; Bitmap256 D;
int Pos_X,Pos_Y; int Pos_X,Pos_Y;
int Rouge,Vert,Bleu; int Rouge,Vert,Bleu;
int DRouge,DVert,DBleu; float ERouge,EVert,EBleu;
int ERouge,EVert,EBleu;
// On initialise les variables de parcours: // On initialise les variables de parcours:
Courant =Source; // Le pixel dont on s'occupe 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); *D=TC_Get(tc,Rouge,Vert,Bleu);
// Puis on calcule pour chaque composante l'erreur dûe à l'approximation // Puis on calcule pour chaque composante l'erreur dûe à l'approximation
Rouge=palette[*D].R - Rouge; Rouge-=palette[*D].R;
Vert =palette[*D].V - Vert; Vert -=palette[*D].V;
Bleu =palette[*D].B - Bleu; Bleu -=palette[*D].B;
// On initialise la quantité d'erreur diffusée
DRouge=Rouge;
DVert =Vert;
DBleu =Bleu;
// Et dans chaque pixel voisin on propage l'erreur // Et dans chaque pixel voisin on propage l'erreur
// A droite: // 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->V=Valeur_modifiee(C_plus1->V,EVert );
C_plus1->B=Valeur_modifiee(C_plus1->B,EBleu ); C_plus1->B=Valeur_modifiee(C_plus1->B,EBleu );
} }
DRouge-=ERouge;
DVert -=EVert;
DBleu -=EBleu;
// En bas à gauche: // En bas à gauche:
if (Pos_Y+1<hauteur) 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->V=Valeur_modifiee(S_moins1->V,EVert );
S_moins1->B=Valeur_modifiee(S_moins1->B,EBleu ); S_moins1->B=Valeur_modifiee(S_moins1->B,EBleu );
} }
DRouge-=ERouge;
DVert -=EVert;
DBleu -=EBleu;
// En bas: // En bas:
ERouge=(Rouge/4); ERouge=(Rouge*5/16.0);
EVert =(Vert /4); EVert =(Vert*5 /16.0);
EBleu =(Bleu /4); EBleu =(Bleu*5 /16.0);
Suivant->R=Valeur_modifiee(Suivant->R,ERouge); Suivant->R=Valeur_modifiee(Suivant->R,ERouge);
Suivant->V=Valeur_modifiee(Suivant->V,EVert ); Suivant->V=Valeur_modifiee(Suivant->V,EVert );
Suivant->B=Valeur_modifiee(Suivant->B,EBleu ); Suivant->B=Valeur_modifiee(Suivant->B,EBleu );
DRouge-=ERouge;
DVert -=EVert;
DBleu -=EBleu;
// En bas à droite: // En bas à droite:
if (Pos_X+1<largeur) if (Pos_X+1<largeur)
{ {
S_plus1->R=Valeur_modifiee(S_plus1->R,DRouge); ERouge=(Rouge/16.0);
S_plus1->V=Valeur_modifiee(S_plus1->V,DVert ); EVert =(Vert /16.0);
S_plus1->B=Valeur_modifiee(S_plus1->B,DBleu ); 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_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 *); 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 R;
byte V; byte V;

View File

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