Bonsoir, je vous expose le problème. Je tente en ce moment de charger un fichier XPM dans mon bitmap.
Jusque là pas de problèmes avec des images contenant un petit nombre de couleurs. Au delà d'un seuil (je pense au dessus de 32000 items mais pas vraiment certain ) et la paf.
Note : Le fichier que je tente de charger à 83071 couleurs

Pour le stockage de la palette de couleurs j'utilise un stringlist maison ou je génère un "hash" :
Lisez les commentaires dans le code
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function ComputeSensitiveStringHash(const aString: string): integer;
var
 i:integer;
 s:string;
begin
 // trouvé sur le forum anglais de lazarus, si je me souviens
 // Fonctionne jusqu'à un nombre X de valeurs dans le tableau. Après il y a des "Duplicata"
 result:=0;
 for i:=1 to length(aString) do
  result:=result*$20844 xor ord(aString[i]);  
 
(* Cette méthode fonctionne très bien le seul soucis sa rapidité une vrai tortue 
 s:='';
 for i:=1 to length(aString) do
 begin
   s:=s+inttostr(ord(aString[i]));
 
 end;
 result:=strtoint(s); *)
end;
J'ai essayé avec un vieux code pour calculer avec un algo CRC32 mais idem, ainsi que d'autre formules mais ça foire si le nombre d'item à stocker est trop important.

Auriez vous une idée pour générer un code unique à chaque coup et performant en terme de rapidité ?
La difficulté c'est qu'a la fin je trie ma liste dans l'ordre croissant en utilisant le Hash comme paramètre

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
function CompareStringListItemHashText(item1, item2: TObject): Integer;
begin
  result:=TGLZStringListItem(item1).getHashText-TGLZStringListItem(item2).getHashText; // le nom est mal choisi, mais le type est bien Integer
end;
Pour mieux que vous compreniez pourquoi voici ma fonction de recherche :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
function TCustomHashStringList.Find(Const S:String; var index: integer): boolean;
var
   HashKey, Pivot, First, Last: Integer;
   found:Boolean;
begin
 if Count = 0 then exit;
 if not(FIsSorted) then Sort;
 Index:=Count;
 Found  := False;
 result:=false;
 First:=0;
 Last:=Count-1;
 
 // On génère le hash de S pour la comparaison
 if FCaseSensitive then HashKey:=ComputeSensitiveStringHash(S)
 else HashKey:=ComputeInSensitiveStringHash(S);
 
 // Quelques vérifications basiques
 // On vérifie avec le 1er item
 if HashKey = FDirectList^[0].getHashText then   //if S=GetItem(0).Text then
 begin
   index := 0;
   Result := True;
   Exit;
 end;
 // On vérifie avec le dernier item
 if HashKey = FDirectList^[Last].getHashText then     //if S=GetItem(Count-1).Text then
 begin
   index := Count-1;
   Result := true;
   Exit;
 end;
 // On borne par rapport à l'item du milieu de la liste
 // On choisi donc quelle partie  chercher dans la liste
 // On réduit ainsi déja par 2 le nombre d'items à parcourir lors de la recherche
 Pivot :=(Count div 2);
 if HashKey = FDirectList^[Pivot].getHashText then  //if S=GetItem(Pivot).Text then
 begin
   Index:=Pivot;
   Result:=true;
   Exit;
 end
 else if HashKey > FDirectList^[Pivot].getHashText then
 begin
   First:=Pivot;
 end
 else
 begin
   Last:=Pivot;
 end;
 Index:=Last;
 repeat
    // On borne par rapport au milieu de la tranche actuelle
    Pivot := ((First + Last) div 2);
    // On a trouvé on s'en va
    if HashKey =FDirectList^[Pivot].getHashText then
    begin
      Index:=Pivot;
      Result:=true;
      Exit;
    end
    else  // On marque les nouvelles bornes de recherche
    if HashKey > FDirectList^[Pivot].getHashText then
    begin
      First:=Pivot;
      Dec(Index);
    end
    else
    begin
      Last:=Pivot-1;
      Index:=Last; // On laisse comme ca pour pouvoir sortir de la boucle Index < 0. On a n'a pas trouvé l'élément
      if Last<0 then Last:=0; // si négatif provoque une erreur
 
    end;
    // On vérifie si notre position est valide
    if (Index>=First) and (Index<=Last) then Found:=(FDirectList^[Index].getHashText=HashKey);
 until (Index<First) or (Index<0) or found;
 if found then result:=true;
end;
Ca fait des semaines que je suis dessus et je patoge dans la semoule aucune méthodes rapide ne fonctionne

Merci