Working palette reduction ! You can now load 24b pcx images !

git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@121 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
Adrien Destugues 2008-08-13 17:31:32 +00:00
parent b6986f2b56
commit 867ac703ca
4 changed files with 37 additions and 16 deletions

View File

@ -2293,7 +2293,7 @@ byte Bouton_Load_ou_Save(byte Load, byte Image)
short Bouton_clicke;
struct Fenetre_Bouton_scroller * Scroller_de_fichiers;
short Temp;
unsigned Bidon=0; // Sert à appeler _dos_setdrive
int Bidon=0; // Sert à appeler SDL_GetKeyState
word Drives_Debut_Y;
byte Charger_ou_sauver_l_image=0;
char Nom_drive[3]=" ";
@ -2458,8 +2458,7 @@ byte Bouton_Load_ou_Save(byte Load, byte Image)
do
{
puts("boutons.c 2454\n");
//Etat_Du_Clavier=SDL_GetKeyState(Bidon);
Etat_Du_Clavier=SDL_GetKeyState(&Bidon);
} while ((Etat_Du_Clavier[SDLK_y]==0) && (Etat_Du_Clavier[SDLK_n]==0) && (Etat_Du_Clavier[SDLK_ESCAPE]==0));
// On efface la demande de confirmation

View File

@ -615,12 +615,15 @@ long Freespace(byte Numero_de_lecteur)
return 0;
}
// Les images ILBM sont stockés en bitplanes donc on doit trifouiller les bits pour
// en faire du chunky
byte Couleur_ILBM_line(word Pos_X, word Vraie_taille_ligne)
{
// CL sera le rang auquel on extrait les bits de la couleur
byte cl = 7 - (Pos_X & 7);
int ax,bh,dx;
byte bl;
byte bl=0;
for(dx = HBPm1;dx>=0;dx--);
{
@ -699,7 +702,7 @@ void Tester_chrono(void)
if((SDL_GetTicks()/55)-Chrono_delay>Chrono_cmp) Etat_chrono=1;
}
// Effectue uyne inversion de la brosse selon une droite horizontale
// Effectue une inversion de la brosse selon une droite horizontale
void Flip_Y_LOWLEVEL(void)
{
// ESI pointe sur la partie haute de la brosse

View File

@ -1719,7 +1719,7 @@ void Load_LBM(void)
// Deluxe paint le fait... alors on le fait...
Back_color=Header.Transp_col;
// On commence par passer la palette en 256 comme a, si la nouvelle
// On commence par passer la palette en 256 comme ça, si la nouvelle
// palette a moins de 256 coul, la précédente ne souffrira pas d'un
// assombrissement préjudiciable.
if (Config.Clear_palette)

39
op_c.c
View File

@ -264,11 +264,6 @@ void TO_Compter_occurences(Table_occurence * t,Bitmap24B image,int taille)
Bitmap24B ptr;
int indice;
DEBUG("reduction",t->red_r);
DEBUG("decalage rouge",t->dec_r);
DEBUG("decalage vert",t->dec_v);
DEBUG("decalage bleu",t->dec_b);
for (indice=taille,ptr=image;indice>0;indice--,ptr++)
TO_Inc(t,ptr->R,ptr->V,ptr->B);
}
@ -666,18 +661,33 @@ void CS_Set(ClusterSet * cs,Cluster * c)
cs->nb++;
}
// Détermination de la meilleure palette en utilisant l'algo Median Cut :
// 1) On considère l'espace (R,V,B) comme 1 boîte
// 2) On cherche les extrêmes de la boîte en (R,V,B)
// 3) On trie les pixels de l'image selon l'axe le plus long parmi (R,V,B)
// 4) On coupe la boîte en deux au milieu, et on compacte pour que chaque bord corresponde bien à un pixel extreme
// 5) On recommence à couper selon le plus grand axe toutes boîtes confondues
// 6) On s'arrête quand on a le nombre de couleurs voulu
void CS_Generer(ClusterSet * cs,Table_occurence * to)
{
Cluster Courant;
Cluster Nouveau1;
Cluster Nouveau2;
// Tant qu'on a moins de 256 clusters
while (cs->nb<cs->nbmax)
{
// On récupère le plus grand cluster
CS_Get(cs,&Courant);
// On le coupe en deux
Cluster_Split(&Courant,&Nouveau1,&Nouveau2,Courant.plus_large,to);
// On compacte ces deux nouveaux (il peut y avoir un espace entre l'endroit de la coupure et les premiers pixels du cluster)
Cluster_Analyser(&Nouveau1,to);
Cluster_Analyser(&Nouveau2,to);
// On met ces deux nouveaux clusters dans le clusterSet
CS_Set(cs,&Nouveau1);
CS_Set(cs,&Nouveau2);
}
@ -771,9 +781,9 @@ void CS_Generer_TC_et_Palette(ClusterSet * cs,Table_occurence * to,Table_convers
palette[indice].V=cs->clusters[indice].v;
palette[indice].B=cs->clusters[indice].b;
for (r=cs->clusters[indice].Rmin;r</*=*/cs->clusters[indice].Rmax;r++)
for (v=cs->clusters[indice].Vmin;v</*=*/cs->clusters[indice].Vmax;v++)
for (b=cs->clusters[indice].Bmin;b</*=*/cs->clusters[indice].Bmax;b++)
for (r=cs->clusters[indice].Rmin;r<=cs->clusters[indice].Rmax;r++)
for (v=cs->clusters[indice].Vmin;v<=cs->clusters[indice].Vmax;v++)
for (b=cs->clusters[indice].Bmin;b<=cs->clusters[indice].Bmax;b++)
TC_Set(tc,r,v,b,indice);
}
}
@ -894,14 +904,14 @@ Table_conversion * Optimiser_palette(Bitmap24B image,int taille,struct Composant
// Création des éléments nécessaires au calcul de palette optimisée:
to=0; tc=0; cs=0; ds=0;
DEBUG("START OPTIMIZING",1);
to=TO_New(r,v,b);
if (to!=0)
{
tc=TC_New(r,v,b);
if (tc!=0)
{
// Première étape : on compte les pixels de chaque couleur pour pouvoir trier là dessus
TO_Compter_occurences(to,image,taille);
cs=CS_New(256,to);
@ -909,7 +919,10 @@ Table_conversion * Optimiser_palette(Bitmap24B image,int taille,struct Composant
{
// C'est bon, on a pu tout allouer
// On génère les clusters (avec l'algo du median cut)
CS_Generer(cs,to);
// On calcule la teinte de chaque pixel (Luminance et chrominance)
CS_Calculer_teintes(cs,to);
ds=DS_New(cs);
@ -919,8 +932,11 @@ Table_conversion * Optimiser_palette(Bitmap24B image,int taille,struct Composant
DS_Delete(ds);
}
// Enfin on trie les clusters (donc les couleurs de la palette) dans un ordre sympa : par couleur, et par luminosité pour chaque couleur
CS_Trier_par_luminance(cs);
CS_Trier_par_chrominance(cs);
// Enfin on génère la palette et la table de correspondance entre chaque couleur 24b et sa couleur palette associée.
CS_Generer_TC_et_Palette(cs,to,tc,palette);
CS_Delete(cs);
@ -1155,6 +1171,9 @@ static const byte precision_24b[]=
// Convertie avec le plus de précision possible une image 24b en 256c
// Renvoie s'il y a eu une erreur ou pas..
// Cette fonction utilise l'algorithme "median cut" (Optimiser_palette) pour trouver la palette, et diffuse les erreurs avec floyd-steinberg.
int Convert_bitmap_24B_to_256(Bitmap256 Dest,Bitmap24B Source,int largeur,int hauteur,struct Composantes * palette)
{
Table_conversion * table; // table de conversion