balgrim
Messages postés52Date d'inscriptionvendredi 26 avril 2002StatutMembreDernière intervention28 octobre 2003
-
6 août 2002 à 00:04
cs_grandvizir
Messages postés1106Date d'inscriptionsamedi 8 novembre 2003StatutMembreDernière intervention 3 septembre 2006
-
21 mai 2005 à 10:07
Cette discussion concerne un article du site. Pour la consulter dans son contexte d'origine, cliquez sur le lien ci-dessous.
cs_grandvizir
Messages postés1106Date d'inscriptionsamedi 8 novembre 2003StatutMembreDernière intervention 3 septembre 200622 21 mai 2005 à 10:07
Résumons le principe simplement:
Red => 255-Red;
Green => 255-Green;
Blue => 255-Blue;
Ca donne la couleur inverse...
balgrim
Messages postés52Date d'inscriptionvendredi 26 avril 2002StatutMembreDernière intervention28 octobre 2003 6 août 2002 à 00:04
ok je vais voir ça, et encore merci!
Balgrim.
balgrim
Messages postés52Date d'inscriptionvendredi 26 avril 2002StatutMembreDernière intervention28 octobre 2003 5 août 2002 à 23:35
heu encore,
j'ai vu que tu savais maitriser la fonction scanline.
cependant g pas tous compris a comment sa marche:
est-ce que par exemple:
a:=bmp.ScanLine[bmpSource.height-1]
renvoi tous les pixel d'une image??
en fait sa m'arrangerai :o)
Enfin bon bref...*ne nous eloignons pas de ma source ;)*
Voila,bye
Balgrim.
balgrim
Messages postés52Date d'inscriptionvendredi 26 avril 2002StatutMembreDernière intervention28 octobre 2003 5 août 2002 à 23:25
hé beh, je vois ke ma source n'est pas passé inaperçu :o).
C vrai que c pas top mais je debute en asm --> raisons de plus pour te remercier pour tous tes conseil.
Bon ya quelque truc ke je voudrait te demander sur ce que tu a ecrit:
-pour le type record, sa serai pas plus simple de faire
mov MonRGB.R,ecx; (a moi que sa marche po)
Il faut dire que la j'ai de coi optimisé mon code :)
bah encore merci, je vais rectifier tout de suite la version pascal :o) (j'avais pas utilisé)
cs_Nono40
Messages postés962Date d'inscriptionmercredi 3 avril 2002StatutMembreDernière intervention12 septembre 20062 5 août 2002 à 23:08
Allez pendant que j'y suis encore un petit commentaire pour continuer sur les Procédures en assembleur.
Si on veut faire une fonction plutôt qu'une procédure, il faut procéder comme suit :
function RGBFromLongASM(Couleur:TColor):TMonRGB;Pascal; //version asm
asm
xor ecx,ecx
mov eax,couleur
//rouge
mov cl,al
mov edx,@Result
mov TMonRGB([edx]).R,ecx
//vert
mov cl,ah
mov TMonRGB([edx]).G,ecx
//bleu
shr eax,16
mov cl,al
mov TMonRGB([edx]).B,ecx
end;
Comme le type du résultat ( TMonRGB ) n'est pas scalaire, il faut remplir les champs du TMonRGB à l'aide de l'adresse de Result : Mov EDX,@result. Ensuite c'est la même chose.
Attention : quand une fonction retourne un type scalaire ( comme CHAR,INTEGER au autre ), alors la valeur de retour est à passer dans le registre AL,AX ou EAX.
Nono.
cs_Nono40
Messages postés962Date d'inscriptionmercredi 3 avril 2002StatutMembreDernière intervention12 septembre 20062 5 août 2002 à 22:58
Ah, aussi pour répondre à ta demande avec un type composé RECORD :
Type TMonRGB = Record
R:Integer;
G:Integer;
B:Integer;
End;
Delphi autorise l'utilisation des type pour calculer les déclages dans les instructions assembleur : TMonRGB([EDX]).G permet à partir de l'adresse de base contenu dans EDX de calculer le déplacement supplémentaire avec .G. C'est mieux qye d'écrir [EDX+4] car on reste indépendant des directives d'alignement des variables.
La procédure en Pascal dans ce cas-ci ne change pas beaucoup :
procedure RGBFromLongPascal(Couleur:TColor;Var MonRGB:TMonRGB);
begin
MonRGB.B:=(Couleur And $00FF0000) Shr 16;
MonRGB.G:=(Couleur And $0000FF00) Shr 8;
MonRGB.R:=(Couleur And $000000FF);
end;
Nono.
cs_Nono40
Messages postés962Date d'inscriptionmercredi 3 avril 2002StatutMembreDernière intervention12 septembre 20062 5 août 2002 à 22:45
En fait l'utilisation de variables globales pour stocker le résultat de la fonction n'est pas une habitude à prendre. Il vaut mieux passer des paramètres par variables, c'est plus pratique à utiliser ensuite :
procedure RGBFromLongASM(Couleur:TColor;Var Rouge,Vert,Bleu:Integer);Pascal; //version asm
asm
xor ecx,ecx
mov eax,couleur
//rouge
mov cl,al
mov edx,rouge
mov Dword ptr[edx],ecx
//vert
mov cl,ah
mov edx,vert
mov Dword ptr[edx],ecx
//bleu
shr eax,16
mov cl,al
mov edx,bleu
mov Dword ptr[edx],ecx
end;
Note la directive de compilation PASCAL, elle permet de forcer Delphi à ne pas utliser les registres comme paramètres, c'est plus clair quand on programme en assembleur. Il n'est pas alors utile de connaitre les règles d'optimisation par registre.
Le code de la version Pascal de ta procédure est le même dans ce cas.
Nono.
cs_Nono40
Messages postés962Date d'inscriptionmercredi 3 avril 2002StatutMembreDernière intervention12 septembre 20062 5 août 2002 à 19:53
J'ai quelques remarques :
*** Méthode assembleur :
Ton prindipe d'extraction des couleurs est bien compliqué : n'oublie pas que AL est l'octet de poids faible de EAX AH l'octet de poids fort de AX, AX étant le mot de poids faible de EAX. Donc quand tu charges Couleur dans EAX tu trouves directement :
Le bleu dans le mot de poids fort de EAX
Le vert dans AH !!!
Le rouge dans AL !!!
Donc ta procédure peut ce réduire à :
procedure RGBFromLongASM(Couleur:TColor); //version asm
asm
push eax
mov eax,couleur
//rouge
mov rouge,al
//vert
mov vert,ah
//bleu
shr eax,16
mov bleu,al
pop eax
end;
*** Méthode Pascal :
Ton source ne compile pas ! Pour les division c'est le signe / et non le signe de plus tu travail sur des entiers donc il faut utiliser DIV plutôt que / car ça évite un temps de cycle cosidérable pour les conversion entiers/flotant.
Il vaudrait mieux travailler sur des masques, c'est plus rapide et plus clair :
procedure RGBFromLongPascal(Couleur:TColor); //d'apres le code de fabiin sur un forum vb :)
begin
Bleu:=(Couleur And $00FF0000) Shr 16;
Vert:=(Couleur And $0000FF00) Shr 8;
Rouge =(Couleur And $000000FF);
end;
21 mai 2005 à 10:07
Red => 255-Red;
Green => 255-Green;
Blue => 255-Blue;
Ca donne la couleur inverse...
6 août 2002 à 00:04
Balgrim.
5 août 2002 à 23:35
j'ai vu que tu savais maitriser la fonction scanline.
cependant g pas tous compris a comment sa marche:
est-ce que par exemple:
a:=bmp.ScanLine[bmpSource.height-1]
renvoi tous les pixel d'une image??
en fait sa m'arrangerai :o)
Enfin bon bref...*ne nous eloignons pas de ma source ;)*
Voila,bye
Balgrim.
5 août 2002 à 23:25
C vrai que c pas top mais je debute en asm --> raisons de plus pour te remercier pour tous tes conseil.
Bon ya quelque truc ke je voudrait te demander sur ce que tu a ecrit:
-pour le type record, sa serai pas plus simple de faire
mov MonRGB.R,ecx; (a moi que sa marche po)
Il faut dire que la j'ai de coi optimisé mon code :)
bah encore merci, je vais rectifier tout de suite la version pascal :o) (j'avais pas utilisé)
5 août 2002 à 23:08
Si on veut faire une fonction plutôt qu'une procédure, il faut procéder comme suit :
function RGBFromLongASM(Couleur:TColor):TMonRGB;Pascal; //version asm
asm
xor ecx,ecx
mov eax,couleur
//rouge
mov cl,al
mov edx,@Result
mov TMonRGB([edx]).R,ecx
//vert
mov cl,ah
mov TMonRGB([edx]).G,ecx
//bleu
shr eax,16
mov cl,al
mov TMonRGB([edx]).B,ecx
end;
Comme le type du résultat ( TMonRGB ) n'est pas scalaire, il faut remplir les champs du TMonRGB à l'aide de l'adresse de Result : Mov EDX,@result. Ensuite c'est la même chose.
Attention : quand une fonction retourne un type scalaire ( comme CHAR,INTEGER au autre ), alors la valeur de retour est à passer dans le registre AL,AX ou EAX.
Nono.
5 août 2002 à 22:58
Type TMonRGB = Record
R:Integer;
G:Integer;
B:Integer;
End;
procedure RGBFromLongASM(Couleur:TColor;Var MonRGB:TMonRGB);Pascal; //version asm
asm
xor ecx,ecx
mov eax,couleur
//rouge
mov cl,al
mov edx,MonRGB
mov TMonRGB([edx]).R,ecx
//vert
mov cl,ah
mov TMonRGB([edx]).G,ecx
//bleu
shr eax,16
mov cl,al
mov TMonRGB([edx]).B,ecx
end;
Delphi autorise l'utilisation des type pour calculer les déclages dans les instructions assembleur : TMonRGB([EDX]).G permet à partir de l'adresse de base contenu dans EDX de calculer le déplacement supplémentaire avec .G. C'est mieux qye d'écrir [EDX+4] car on reste indépendant des directives d'alignement des variables.
La procédure en Pascal dans ce cas-ci ne change pas beaucoup :
procedure RGBFromLongPascal(Couleur:TColor;Var MonRGB:TMonRGB);
begin
MonRGB.B:=(Couleur And $00FF0000) Shr 16;
MonRGB.G:=(Couleur And $0000FF00) Shr 8;
MonRGB.R:=(Couleur And $000000FF);
end;
Nono.
5 août 2002 à 22:45
procedure RGBFromLongASM(Couleur:TColor;Var Rouge,Vert,Bleu:Integer);Pascal; //version asm
asm
xor ecx,ecx
mov eax,couleur
//rouge
mov cl,al
mov edx,rouge
mov Dword ptr[edx],ecx
//vert
mov cl,ah
mov edx,vert
mov Dword ptr[edx],ecx
//bleu
shr eax,16
mov cl,al
mov edx,bleu
mov Dword ptr[edx],ecx
end;
Note la directive de compilation PASCAL, elle permet de forcer Delphi à ne pas utliser les registres comme paramètres, c'est plus clair quand on programme en assembleur. Il n'est pas alors utile de connaitre les règles d'optimisation par registre.
Le code de la version Pascal de ta procédure est le même dans ce cas.
Nono.
5 août 2002 à 19:53
*** Méthode assembleur :
Ton prindipe d'extraction des couleurs est bien compliqué : n'oublie pas que AL est l'octet de poids faible de EAX AH l'octet de poids fort de AX, AX étant le mot de poids faible de EAX. Donc quand tu charges Couleur dans EAX tu trouves directement :
Le bleu dans le mot de poids fort de EAX
Le vert dans AH !!!
Le rouge dans AL !!!
Donc ta procédure peut ce réduire à :
procedure RGBFromLongASM(Couleur:TColor); //version asm
asm
push eax
mov eax,couleur
//rouge
mov rouge,al
//vert
mov vert,ah
//bleu
shr eax,16
mov bleu,al
pop eax
end;
*** Méthode Pascal :
Ton source ne compile pas ! Pour les division c'est le signe / et non le signe de plus tu travail sur des entiers donc il faut utiliser DIV plutôt que / car ça évite un temps de cycle cosidérable pour les conversion entiers/flotant.
Il vaudrait mieux travailler sur des masques, c'est plus rapide et plus clair :
procedure RGBFromLongPascal(Couleur:TColor); //d'apres le code de fabiin sur un forum vb :)
begin
Bleu:=(Couleur And $00FF0000) Shr 16;
Vert:=(Couleur And $0000FF00) Shr 8;
Rouge =(Couleur And $000000FF);
end;
Nono.