The cluster system for color reduction when loading a truecolor image now uses a linked list instead of a table. This fix a potential problem because there was an overlapping memcpy. It also avoids copying the big cluster table around and just moves pointer around. It should be faster but I did not really noticed any change on my computer :(. Maybe it's too fast...
The same can probably be done for the gradient sets. git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@927 416bcca6-2ee7-4201-b75f-2eb2f807beb1
This commit is contained in:
parent
3a7edb8323
commit
e877292ca2
2
Makefile
2
Makefile
@ -210,7 +210,7 @@ else
|
|||||||
|
|
||||||
# Compiles a regular linux exectutable for the native platform
|
# Compiles a regular linux exectutable for the native platform
|
||||||
BIN = grafx2
|
BIN = grafx2
|
||||||
COPT = -W -Wall -Wdeclaration-after-statement -O$(OPTIM) -std=c99 -c -g `sdl-config --cflags` $(TTFCOPT)
|
COPT = -W -Wall -Wdeclaration-after-statement -std=c99 -c -g `sdl-config --cflags` $(TTFCOPT)
|
||||||
LOPT = `sdl-config --libs` -lSDL_image $(TTFLOPT) -lpng
|
LOPT = `sdl-config --libs` -lSDL_image $(TTFLOPT) -lpng
|
||||||
# Use gcc for compiling. Use ncc to build a callgraph and analyze the code.
|
# Use gcc for compiling. Use ncc to build a callgraph and analyze the code.
|
||||||
CC = gcc
|
CC = gcc
|
||||||
|
|||||||
263
op_c.c
263
op_c.c
@ -657,37 +657,40 @@ void Cluster_compute_hue(T_Cluster * c,T_Occurrence_table * to)
|
|||||||
//////////////////////////// M‚thodes de gestion des ensembles de clusters //
|
//////////////////////////// M‚thodes de gestion des ensembles de clusters //
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/// Setup the first cluster before we start the operations
|
||||||
void CS_Init(T_Cluster_set * cs,T_Occurrence_table * to)
|
void CS_Init(T_Cluster_set * cs,T_Occurrence_table * to)
|
||||||
{
|
{
|
||||||
cs->clusters[0].Rmin=cs->clusters[0].rmin=0;
|
cs->clusters->Rmin = cs->clusters->rmin = 0;
|
||||||
cs->clusters[0].Gmin=cs->clusters[0].vmin=0;
|
cs->clusters->Gmin = cs->clusters->vmin = 0;
|
||||||
cs->clusters[0].Bmin=cs->clusters[0].bmin=0;
|
cs->clusters->Bmin = cs->clusters->bmin = 0;
|
||||||
cs->clusters[0].Rmax=cs->clusters[0].rmax=to->rng_r-1;
|
cs->clusters->Rmax = cs->clusters->rmax = to->rng_r-1;
|
||||||
cs->clusters[0].Vmax=cs->clusters[0].vmax=to->rng_g-1;
|
cs->clusters->Vmax = cs->clusters->vmax = to->rng_g-1;
|
||||||
cs->clusters[0].Bmax=cs->clusters[0].bmax=to->rng_b-1;
|
cs->clusters->Bmax = cs->clusters->bmax = to->rng_b-1;
|
||||||
Cluster_analyser(cs->clusters+0,to);
|
cs->clusters->next = NULL;
|
||||||
// Et hop : le 1er ensemble de couleurs est initialis‚
|
Cluster_analyser(cs->clusters,to);
|
||||||
cs->nb=1;
|
cs->nb=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Allocate a new cluster set
|
||||||
T_Cluster_set * CS_New(int nbmax,T_Occurrence_table * to)
|
T_Cluster_set * CS_New(int nbmax,T_Occurrence_table * to)
|
||||||
{
|
{
|
||||||
T_Cluster_set * n;
|
T_Cluster_set * n;
|
||||||
|
|
||||||
n=(T_Cluster_set *)malloc(sizeof(T_Cluster_set));
|
n=(T_Cluster_set *)malloc(sizeof(T_Cluster_set));
|
||||||
if (n!=0)
|
if (n != NULL)
|
||||||
{
|
{
|
||||||
// On recopie les paramŠtres demand‚s
|
// On recopie les paramŠtres demand‚s
|
||||||
n->nb_max=OT_count_colors(to);
|
n->nb_max=OT_count_colors(to);
|
||||||
|
|
||||||
// On vient de compter le nombre de couleurs existantes, s'il est plus grand que 256 on limit à 256 (nombre de couleurs voulu au final)
|
// 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->nb_max>nbmax)
|
if (n->nb_max>nbmax)
|
||||||
{
|
{
|
||||||
n->nb_max=nbmax;
|
n->nb_max=nbmax;
|
||||||
}
|
}
|
||||||
|
|
||||||
// On tente d'allouer la table
|
// On tente d'allouer le premier cluster
|
||||||
n->clusters=(T_Cluster *)malloc(nbmax*sizeof(T_Cluster));
|
n->clusters=(T_Cluster *)malloc(sizeof(T_Cluster));
|
||||||
if (n->clusters!=NULL)
|
if (n->clusters!=NULL)
|
||||||
// C'est bon! On initialise
|
// C'est bon! On initialise
|
||||||
CS_Init(n,to);
|
CS_Init(n,to);
|
||||||
@ -702,67 +705,73 @@ T_Cluster_set * CS_New(int nbmax,T_Occurrence_table * to)
|
|||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Free a cluster set
|
||||||
void CS_Delete(T_Cluster_set * cs)
|
void CS_Delete(T_Cluster_set * cs)
|
||||||
{
|
{
|
||||||
|
T_Cluster* nxt;
|
||||||
|
while(cs->clusters != NULL)
|
||||||
|
{
|
||||||
|
nxt = cs->clusters->next;
|
||||||
free(cs->clusters);
|
free(cs->clusters);
|
||||||
|
cs->clusters = nxt;
|
||||||
|
}
|
||||||
free(cs);
|
free(cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CS_Get(T_Cluster_set * cs,T_Cluster * c)
|
void CS_Get(T_Cluster_set * cs,T_Cluster * c)
|
||||||
{
|
{
|
||||||
int index;
|
T_Cluster* current = cs->clusters;
|
||||||
|
T_Cluster* prev = NULL;
|
||||||
|
|
||||||
// On cherche un cluster que l'on peut couper en deux, donc avec au moins deux valeurs
|
// Search a cluster with at least 2 distinct colors so we can split it
|
||||||
// différentes sur l'une des composantes
|
do
|
||||||
for (index=0;index<cs->nb;index++)
|
{
|
||||||
if ( (cs->clusters[index].rmin<cs->clusters[index].rmax) ||
|
if ( (current->rmin < current->rmax) ||
|
||||||
(cs->clusters[index].vmin<cs->clusters[index].vmax) ||
|
(current->vmin < current->vmax) ||
|
||||||
(cs->clusters[index].bmin<cs->clusters[index].bmax) )
|
(current->bmin < current->bmax) )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// On le recopie dans c
|
prev = current;
|
||||||
*c=cs->clusters[index];
|
|
||||||
|
|
||||||
// On décrémente le nombre et on décale tous les clusters suivants
|
} while((current = current -> next));
|
||||||
// Sachant qu'on va réinsérer juste après, il me semble que ça serait une bonne idée de gérer les clusters
|
|
||||||
// comme une liste chainée... on n'a aucun accès direct dedans, que des parcours ...
|
// copy it to c
|
||||||
|
*c = *current;
|
||||||
|
|
||||||
|
// remove it from the list
|
||||||
cs->nb--;
|
cs->nb--;
|
||||||
memcpy((cs->clusters+index),(cs->clusters+index+1),(cs->nb-index)*sizeof(T_Cluster));
|
|
||||||
|
if(prev)
|
||||||
|
prev->next = current->next;
|
||||||
|
else
|
||||||
|
cs->clusters = current->next;
|
||||||
|
free(current);
|
||||||
|
current = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CS_Set(T_Cluster_set * cs,T_Cluster * c)
|
void CS_Set(T_Cluster_set * cs,T_Cluster * c)
|
||||||
{
|
{
|
||||||
int index;
|
T_Cluster* current = cs->clusters;
|
||||||
// int decalage;
|
T_Cluster* prev = NULL;
|
||||||
|
|
||||||
// Le tableau des clusters est trié par nombre d'occurences. Donc on cherche la position du premier cluster
|
// Search the first cluster that is smaller than ours
|
||||||
// qui est plus grand que le notre
|
if(current != NULL) // don't search if the list is empty
|
||||||
for (index=0;index<cs->nb;index++)
|
do
|
||||||
if (cs->clusters[index].occurences<c->occurences)
|
|
||||||
/*
|
|
||||||
if (((OPTPAL_Cluster[index].rmax-OPTPAL_Cluster[index].rmin+1)*
|
|
||||||
(OPTPAL_Cluster[index].gmax-OPTPAL_Cluster[index].gmin+1)*
|
|
||||||
(OPTPAL_Cluster[index].bmax-OPTPAL_Cluster[index].bmin+1))
|
|
||||||
<
|
|
||||||
((Set->rmax-Set->rmin+1)*
|
|
||||||
(Set->gmax-Set->gmin+1)*
|
|
||||||
(Set->bmax-Set->bmin+1))
|
|
||||||
)
|
|
||||||
*/
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (index<cs->nb)
|
|
||||||
{
|
{
|
||||||
// On distingue ici une insertion plutot qu'un placement en fin de liste.
|
if (current->occurences < c->occurences)
|
||||||
// On doit donc décaler les ensembles suivants vers la fin pour se faire
|
break;
|
||||||
// une place dans la liste.
|
prev = current;
|
||||||
|
} while((current = current -> next));
|
||||||
|
|
||||||
//for (decalage=cs->nb;decalage>index;decalage--)
|
// Now insert our cluster just before the one we found
|
||||||
// memcpy((cs->clusters+decalage),(cs->clusters+decalage-1),sizeof(T_Cluster));
|
c -> next = current;
|
||||||
memmove(cs->clusters+index+1,cs->clusters+index,(cs->nb-index)*sizeof(T_Cluster));
|
|
||||||
}
|
current = malloc(sizeof(T_Cluster));
|
||||||
|
*current = *c ;
|
||||||
|
|
||||||
|
if(prev) prev -> next = current;
|
||||||
|
else cs->clusters = current;
|
||||||
|
|
||||||
cs->clusters[index]=*c;
|
|
||||||
cs -> nb++;
|
cs -> nb++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -802,96 +811,91 @@ void CS_Generate(T_Cluster_set * cs,T_Occurrence_table * to)
|
|||||||
|
|
||||||
void CS_Compute_colors(T_Cluster_set * cs,T_Occurrence_table * to)
|
void CS_Compute_colors(T_Cluster_set * cs,T_Occurrence_table * to)
|
||||||
{
|
{
|
||||||
int index;
|
|
||||||
T_Cluster * c;
|
T_Cluster * c;
|
||||||
|
|
||||||
for (index=0,c=cs->clusters;index<cs->nb;index++,c++)
|
for (c=cs->clusters;c!=NULL;c=c->next)
|
||||||
Cluster_compute_hue(c,to);
|
Cluster_compute_hue(c,to);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CS_Sort_by_chrominance(T_Cluster_set * cs)
|
void CS_Sort_by_chrominance(T_Cluster_set * cs)
|
||||||
{
|
{
|
||||||
int byte_used[256];
|
|
||||||
int decalages[256];
|
|
||||||
int index;
|
|
||||||
T_Cluster* nc;
|
T_Cluster* nc;
|
||||||
|
T_Cluster* prev = NULL;
|
||||||
|
T_Cluster* place;
|
||||||
|
T_Cluster* newlist = NULL;
|
||||||
|
|
||||||
nc=(T_Cluster *)malloc(cs->nb_max*sizeof(T_Cluster));
|
while((nc = cs->clusters))
|
||||||
|
|
||||||
// Initialisation de la table d'occurence de chaque octet
|
|
||||||
for (index=0;index<256;index++)
|
|
||||||
byte_used[index]=0;
|
|
||||||
|
|
||||||
// Comptage du nombre d'occurences de chaque octet
|
|
||||||
for (index=0;index<cs->nb;index++)
|
|
||||||
byte_used[cs->clusters[index].h]++;
|
|
||||||
|
|
||||||
// Calcul de la table des d‚calages
|
|
||||||
decalages[0]=0;
|
|
||||||
for (index=1;index<256;index++)
|
|
||||||
decalages[index]=decalages[index-1]+byte_used[index-1];
|
|
||||||
|
|
||||||
// Copie r‚ordonn‚e dans la nouvelle liste
|
|
||||||
for (index=0;index<cs->nb;index++)
|
|
||||||
{
|
{
|
||||||
nc[decalages[cs->clusters[index].h]]=cs->clusters[index];
|
// Remove the first cluster from the original list
|
||||||
decalages[cs->clusters[index].h]++;
|
nc = cs->clusters;
|
||||||
|
cs->clusters = cs->clusters->next;
|
||||||
|
|
||||||
|
// Find his position in the new list
|
||||||
|
for(place = newlist;place != NULL; place = place->next)
|
||||||
|
{
|
||||||
|
if(place->h > nc->h) break;
|
||||||
|
prev = place;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remplacement de la liste d‚sordonn‚e par celle tri‚e
|
// Chain it there
|
||||||
free(cs->clusters);
|
nc->next = place;
|
||||||
cs->clusters=nc;
|
if(prev) prev->next = nc;
|
||||||
|
else newlist = nc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put the new list bavk in place
|
||||||
|
cs->clusters = newlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CS_Sort_by_luminance(T_Cluster_set * cs)
|
void CS_Sort_by_luminance(T_Cluster_set * cs)
|
||||||
{
|
{
|
||||||
int byte_used[256];
|
|
||||||
int decalages[256];
|
|
||||||
int index;
|
|
||||||
T_Cluster* nc;
|
T_Cluster* nc;
|
||||||
|
T_Cluster* prev = NULL;
|
||||||
|
T_Cluster* place;
|
||||||
|
T_Cluster* newlist = NULL;
|
||||||
|
|
||||||
nc=(T_Cluster *)malloc(cs->nb_max*sizeof(T_Cluster));
|
while((nc = cs->clusters))
|
||||||
|
|
||||||
// Initialisation de la table d'occurence de chaque octet
|
|
||||||
for (index=0;index<256;index++)
|
|
||||||
byte_used[index]=0;
|
|
||||||
|
|
||||||
// Comptage du nombre d'occurences de chaque octet
|
|
||||||
for (index=0;index<cs->nb;index++)
|
|
||||||
byte_used[cs->clusters[index].l]++;
|
|
||||||
|
|
||||||
// Calcul de la table des d‚calages
|
|
||||||
decalages[0]=0;
|
|
||||||
for (index=1;index<256;index++)
|
|
||||||
decalages[index]=decalages[index-1]+byte_used[index-1];
|
|
||||||
|
|
||||||
// Copie r‚ordonn‚e dans la nouvelle liste
|
|
||||||
for (index=0;index<cs->nb;index++)
|
|
||||||
{
|
{
|
||||||
nc[decalages[cs->clusters[index].l]]=cs->clusters[index];
|
// Remove the first cluster from the original list
|
||||||
decalages[cs->clusters[index].l]++;
|
nc = cs->clusters;
|
||||||
|
cs->clusters = cs->clusters->next;
|
||||||
|
|
||||||
|
// Find his position in the new list
|
||||||
|
for(place = newlist;place != NULL; place = place->next)
|
||||||
|
{
|
||||||
|
if(place->l > nc->l) break;
|
||||||
|
prev = place;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remplacement de la liste d‚sordonn‚e par celle tri‚e
|
// Chain it there
|
||||||
free(cs->clusters);
|
nc->next = place;
|
||||||
cs->clusters=nc;
|
if(prev) prev->next = nc;
|
||||||
|
else newlist = nc;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put the new list bavk in place
|
||||||
|
cs->clusters = newlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CS_Generate_color_table_and_palette(T_Cluster_set * cs,T_Conversion_table * tc,T_Components * palette)
|
void CS_Generate_color_table_and_palette(T_Cluster_set * cs,T_Conversion_table * tc,T_Components * palette)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
int r,g,b;
|
int r,g,b;
|
||||||
|
T_Cluster* current = cs->clusters;
|
||||||
|
|
||||||
for (index=0;index<cs->nb;index++)
|
for (index=0;index<cs->nb;index++)
|
||||||
{
|
{
|
||||||
palette[index].R=cs->clusters[index].r;
|
palette[index].R=current->r;
|
||||||
palette[index].G=cs->clusters[index].g;
|
palette[index].G=current->g;
|
||||||
palette[index].B=cs->clusters[index].b;
|
palette[index].B=current->b;
|
||||||
|
|
||||||
for (r=cs->clusters[index].Rmin;r<=cs->clusters[index].Rmax;r++)
|
for (r=current->Rmin; r<=current->Rmax; r++)
|
||||||
for (g=cs->clusters[index].Gmin;g<=cs->clusters[index].Vmax;g++)
|
for (g=current->Gmin;g<=current->Vmax;g++)
|
||||||
for (b=cs->clusters[index].Bmin;b<=cs->clusters[index].Bmax;b++)
|
for (b=current->Bmin;b<=current->Bmax;b++)
|
||||||
CT_set(tc,r,g,b,index);
|
CT_set(tc,r,g,b,index);
|
||||||
|
current = current->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -902,9 +906,9 @@ void CS_Generate_color_table_and_palette(T_Cluster_set * cs,T_Conversion_table *
|
|||||||
void GS_Init(T_Gradient_set * ds,T_Cluster_set * cs)
|
void GS_Init(T_Gradient_set * ds,T_Cluster_set * cs)
|
||||||
{
|
{
|
||||||
ds->gradients[0].nb_colors=1;
|
ds->gradients[0].nb_colors=1;
|
||||||
ds->gradients[0].min=cs->clusters[0].h;
|
ds->gradients[0].min=cs->clusters->h;
|
||||||
ds->gradients[0].max=cs->clusters[0].h;
|
ds->gradients[0].max=cs->clusters->h;
|
||||||
ds->gradients[0].hue=cs->clusters[0].h;
|
ds->gradients[0].hue=cs->clusters->h;
|
||||||
// Et hop : le 1er ensemble de d‚grad‚s est initialis‚
|
// Et hop : le 1er ensemble de d‚grad‚s est initialis‚
|
||||||
ds->nb=1;
|
ds->nb=1;
|
||||||
}
|
}
|
||||||
@ -943,20 +947,21 @@ void GS_Delete(T_Gradient_set * ds)
|
|||||||
|
|
||||||
void GS_Generate(T_Gradient_set * ds,T_Cluster_set * cs)
|
void GS_Generate(T_Gradient_set * ds,T_Cluster_set * cs)
|
||||||
{
|
{
|
||||||
int ic,id; // Les indexs de parcours des ensembles
|
int id; // Les indexs de parcours des ensembles
|
||||||
int best_gradient; // Meilleur d‚grad‚
|
int best_gradient; // Meilleur d‚grad‚
|
||||||
int best_diff; // Meilleure diff‚rence de chrominance
|
int best_diff; // Meilleure diff‚rence de chrominance
|
||||||
int diff; // difference de chrominance courante
|
int diff; // difference de chrominance courante
|
||||||
|
T_Cluster * current = cs->clusters;
|
||||||
|
|
||||||
// Pour chacun des clusters … traiter
|
// Pour chacun des clusters … traiter
|
||||||
for (ic=0;ic<cs->nb;ic++)
|
do
|
||||||
{
|
{
|
||||||
// On recherche le d‚grad‚ le plus proche de la chrominance du cluster
|
// On recherche le d‚grad‚ le plus proche de la chrominance du cluster
|
||||||
best_gradient=-1;
|
best_gradient=-1;
|
||||||
best_diff=99999999;
|
best_diff=99999999;
|
||||||
for (id=0;id<ds->nb;id++)
|
for (id=0;id<ds->nb;id++)
|
||||||
{
|
{
|
||||||
diff=abs(cs->clusters[ic].h - ds->gradients[id].hue);
|
diff=abs(current->h - ds->gradients[id].hue);
|
||||||
if ((best_diff>diff) && (diff<16))
|
if ((best_diff>diff) && (diff<16))
|
||||||
{
|
{
|
||||||
best_gradient=id;
|
best_gradient=id;
|
||||||
@ -968,13 +973,13 @@ void GS_Generate(T_Gradient_set * ds,T_Cluster_set * cs)
|
|||||||
if (best_gradient!=-1)
|
if (best_gradient!=-1)
|
||||||
{
|
{
|
||||||
// On met … jour le d‚grad‚
|
// On met … jour le d‚grad‚
|
||||||
if (cs->clusters[ic].h < ds->gradients[best_gradient].min)
|
if (current->h < ds->gradients[best_gradient].min)
|
||||||
ds->gradients[best_gradient].min=cs->clusters[ic].h;
|
ds->gradients[best_gradient].min=current->h;
|
||||||
if (cs->clusters[ic].h > ds->gradients[best_gradient].max)
|
if (current->h > ds->gradients[best_gradient].max)
|
||||||
ds->gradients[best_gradient].max=cs->clusters[ic].h;
|
ds->gradients[best_gradient].max=current->h;
|
||||||
ds->gradients[best_gradient].hue=((ds->gradients[best_gradient].hue*
|
ds->gradients[best_gradient].hue=((ds->gradients[best_gradient].hue*
|
||||||
ds->gradients[best_gradient].nb_colors)
|
ds->gradients[best_gradient].nb_colors)
|
||||||
+cs->clusters[ic].h)
|
+current->h)
|
||||||
/(ds->gradients[best_gradient].nb_colors+1);
|
/(ds->gradients[best_gradient].nb_colors+1);
|
||||||
ds->gradients[best_gradient].nb_colors++;
|
ds->gradients[best_gradient].nb_colors++;
|
||||||
}
|
}
|
||||||
@ -983,17 +988,19 @@ void GS_Generate(T_Gradient_set * ds,T_Cluster_set * cs)
|
|||||||
// On cr‚e un nouveau d‚grad‚
|
// On cr‚e un nouveau d‚grad‚
|
||||||
best_gradient=ds->nb;
|
best_gradient=ds->nb;
|
||||||
ds->gradients[best_gradient].nb_colors=1;
|
ds->gradients[best_gradient].nb_colors=1;
|
||||||
ds->gradients[best_gradient].min=cs->clusters[ic].h;
|
ds->gradients[best_gradient].min=current->h;
|
||||||
ds->gradients[best_gradient].max=cs->clusters[ic].h;
|
ds->gradients[best_gradient].max=current->h;
|
||||||
ds->gradients[best_gradient].hue=cs->clusters[ic].h;
|
ds->gradients[best_gradient].hue=current->h;
|
||||||
ds->nb++;
|
ds->nb++;
|
||||||
}
|
}
|
||||||
cs->clusters[ic].h=best_gradient;
|
current->h=best_gradient;
|
||||||
}
|
} while((current = current->next));
|
||||||
|
|
||||||
// On redistribue les valeurs dans les clusters
|
// On redistribue les valeurs dans les clusters
|
||||||
for (ic=0;ic<cs->nb;ic++)
|
current = cs -> clusters;
|
||||||
cs->clusters[ic].h=ds->gradients[cs->clusters[ic].h].hue;
|
do
|
||||||
|
current->h=ds->gradients[current->h].hue;
|
||||||
|
while((current = current ->next));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
4
op_c.h
4
op_c.h
@ -88,7 +88,7 @@ typedef struct
|
|||||||
|
|
||||||
///////////////////////////////////////// Définition d'un ensemble de couleur
|
///////////////////////////////////////// Définition d'un ensemble de couleur
|
||||||
|
|
||||||
typedef struct
|
typedef struct S_Cluster
|
||||||
{
|
{
|
||||||
int occurences; // Nb total d'occurences des couleurs de l'ensemble
|
int occurences; // Nb total d'occurences des couleurs de l'ensemble
|
||||||
|
|
||||||
@ -106,6 +106,8 @@ typedef struct
|
|||||||
byte r,g,b; // color synthétisant l'ensemble
|
byte r,g,b; // color synthétisant l'ensemble
|
||||||
byte h; // Chrominance
|
byte h; // Chrominance
|
||||||
byte l; // Luminosité
|
byte l; // Luminosité
|
||||||
|
|
||||||
|
struct S_Cluster* next;
|
||||||
} T_Cluster;
|
} T_Cluster;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
9
setup.c
9
setup.c
@ -57,7 +57,8 @@ int Create_ConfigDirectory(char * config_dir)
|
|||||||
// Determine which directory contains the executable.
|
// Determine which directory contains the executable.
|
||||||
// IN: Main's argv[0], some platforms need it, some don't.
|
// IN: Main's argv[0], some platforms need it, some don't.
|
||||||
// OUT: Write into program_dir. Trailing / or \ is kept.
|
// OUT: Write into program_dir. Trailing / or \ is kept.
|
||||||
// Note : in fact this is only used to check for the datafiles and fonts in this same directory.
|
// Note : in fact this is only used to check for the datafiles and fonts in
|
||||||
|
// this same directory.
|
||||||
void Set_program_directory(ARG_UNUSED const char * argv0,char * program_dir)
|
void Set_program_directory(ARG_UNUSED const char * argv0,char * program_dir)
|
||||||
{
|
{
|
||||||
#undef ARG_UNUSED
|
#undef ARG_UNUSED
|
||||||
@ -76,9 +77,9 @@ void Set_program_directory(ARG_UNUSED const char * argv0,char * program_dir)
|
|||||||
|
|
||||||
// Others: The part of argv[0] before the executable name.
|
// Others: The part of argv[0] before the executable name.
|
||||||
// Keep the last \ or /.
|
// Keep the last \ or /.
|
||||||
// Note that on Unix, once installed, the executable is called from a shell script
|
// Note that on Unix, once installed, the executable is called from a shell
|
||||||
// sitting in /usr/local/bin/, this allows argv[0] to contain the full path.
|
// script sitting in /usr/local/bin/, this allows argv[0] to contain the full
|
||||||
// On Windows, Mingw32 already provides the full path in all cases.
|
// path. On Windows, Mingw32 already provides the full path in all cases.
|
||||||
#else
|
#else
|
||||||
Extract_path(program_dir, argv0);
|
Extract_path(program_dir, argv0);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user