Yves Rizoud 5fd1e42ea0 Copyright notices in source files
git-svn-id: svn://pulkomandy.tk/GrafX2/trunk@217 416bcca6-2ee7-4201-b75f-2eb2f807beb1
2008-10-08 19:40:47 +00:00

1518 lines
32 KiB
NASM
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

; Grafx2 - The Ultimate 256-color bitmap paint program
;
; Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
;
; Grafx2 is free software; you can redistribute it and/or
; modify it under the terms of the GNU General Public License
; as published by the Free Software Foundation; version 2
; of the License.
;
; Grafx2 is distributed in the hope that it will be useful,
; but WITHOUT ANY WARRANTY; without even the implied warranty of
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
; GNU General Public License for more details.
;
; You should have received a copy of the GNU General Public License
; along with Grafx2; if not, see <http://www.gnu.org/licenses/> or
; write to the Free Software Foundation, Inc.,
; 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
.386P
.MODEL FLAT
_DATA Segment dword public 'data'
Assume cs:_TEXT, ds:_DATA
; ---- Variables exportes ----
; ---- Dclaration des variables ----
; Variables … utilisation gnrale
VarA dd 0
VarB dd 0
VarC dd 0
VarD dd 0
VarE dd 0
VarF dd 0
; Variables pour le dithering Flloyd-Steinberg
DSFRouge dd 0
DSFVert dd 0
DSFBleu dd 0
DSFRougeAD dd 0
DSFVertAD dd 0
DSFBleuAD dd 0
_DATA ENDS
_TEXT Segment dword public 'code'
Assume cs:_TEXT, ds:_DATA
; ---- Fonctions exportes ----
; -- Fonctions de dithering Flloyd-Steinberg --
public OPASM_DitherFS_6123
public OPASM_DitherFS_623
public OPASM_DitherFS_12
public OPASM_DitherFS_6
public OPASM_DitherFS
public OPASM_DitherFS_2
public OPASM_Compter_occurences
public OPASM_Analyser_cluster
public OPASM_Split_cluster_Rouge
public OPASM_Split_cluster_Vert
public OPASM_Split_cluster_Bleu
OPASM_DitherFS_6123 proc near
push ebp
mov ebp,esp
arg Destination:dword,Source:dword,Largeur:dword,Palette:dword,TableC:dword,ReducR:byte,ReducV:byte,ReducB:byte,NbbV:byte,NbbB:byte
push ebx
push esi
push edi
; On place dans ESI l'adresse de la source
mov esi,Source
; On place dans EDI l'adresse de la destination
mov edi,Destination
; On place dans VarA la largeur … traiter
mov eax,Largeur
mov VarA,eax
; Pour chacun des pixels sur la largeur:
DFS6123_Pour_chaque_pixel:
; On regarde la meilleure couleur d'aprŠs la table de conversion 24b->8b
mov edx,[esi] ; EDX = XBVR
xor eax,eax ; EAX = 0000
xor ebx,ebx ; EBX = 0000
mov al,dl ; EAX = 000R
mov bl,dh ; EBX = 000V
shr edx,16 ; EDX = 00XB
mov DSFRouge,eax
xor dh,dh ; EDX = 000B
mov DSFVert ,ebx
mov DSFBleu ,edx
mov cl,ReducR
shr eax,cl ; EAX = 000r
mov cl,ReducV
shr ebx,cl ; EBX = 000v
mov cl,ReducB
shr edx,cl ; EDX = 000b
mov cl,NbbV
shl eax,cl ; EAX = 00r0
or eax,ebx ; EAX = 00rv
mov cl,NbbB
shl eax,cl ; EAX = 0rv0
mov ebx,TableC ; EBX = Table conversion
or edx,eax ; EDX = 0rvb
xor eax,eax
mov al,[ebx+edx] ; EAX = Table[R,V,B]
; On le place dans la destination
mov [edi],al
; On regarde la couleur de la palette
mov ebx,Palette
add ebx,eax
shl eax,1
add ebx,eax ; EBX = &Palette[Table[R,V,B]].R
xor eax,eax
xor ecx,ecx
xor edx,edx
mov al,[ebx+0] ; EAX = 000R
mov cl,[ebx+1] ; ECX = 000V
mov dl,[ebx+2] ; EDX = 000B
; On calcule l'erreur
sub eax,DSFRouge
sub ecx,DSFVert
sub edx,DSFBleu
neg eax
neg ecx
neg edx
mov DSFRouge,eax
mov DSFVert ,ecx
mov DSFBleu ,edx
; On initialise la quantit d'erreur … diffuser
mov DSFRougeAD,eax
mov DSFVertAD ,ecx
mov DSFBleuAD ,edx
; On diffuse l'erreur sur le pixel de droite (6)
mov eax,DSFRouge
mov ebx,DSFVert
mov ecx,DSFBleu
; "Multiplication signe par 7"
sal eax,3
sal ebx,3
sal ecx,3
sub eax,DSFRouge
sub ebx,DSFVert
sub ecx,DSFBleu
; Division signe par 16
sar eax,4
sar ebx,4
sar ecx,4
; Mise … jour de la quantit … diffuser
sub DSFRougeAD,eax
sub DSFVertAD ,ebx
sub DSFBleuAD ,ecx
; Diffusion de l'erreur dans la source
add esi,3
add al,[esi+0]
adc ah,0
jz DSF6123_6R_Pas_de_debordement
sar ax,16
not ax
DSF6123_6R_Pas_de_debordement:
add bl,[esi+1]
adc bh,0
jz DSF6123_6V_Pas_de_debordement
sar bx,16
not bx
DSF6123_6V_Pas_de_debordement:
add cl,[esi+2]
adc ch,0
jz DSF6123_6B_Pas_de_debordement
sar cx,16
not cx
DSF6123_6B_Pas_de_debordement:
mov [esi+0],al
mov [esi+1],bl
mov [esi+2],cl
; On diffuse l'erreur sur le pixel en bas … gauche (1)
mov eax,DSFRouge
mov ebx,DSFVert
mov ecx,DSFBleu
; "Multiplication signe par 3"
sal eax,1
sal ebx,1
sal ecx,1
add eax,DSFRouge
add ebx,DSFVert
add ecx,DSFBleu
; Division signe par 16
sar eax,4
sar ebx,4
sar ecx,4
; Mise … jour de la quantit … diffuser
sub DSFRougeAD,eax
sub DSFVertAD ,ebx
sub DSFBleuAD ,ecx
; Diffusion de l'erreur dans la source
mov edx,Largeur
shl edx,1
add edx,Largeur
add esi,edx
add al,[esi+0]
adc ah,0
jz DSF6123_1R_Pas_de_debordement
sar ax,16
not ax
DSF6123_1R_Pas_de_debordement:
add bl,[esi+1]
adc bh,0
jz DSF6123_1V_Pas_de_debordement
sar bx,16
not bx
DSF6123_1V_Pas_de_debordement:
add cl,[esi+2]
adc ch,0
jz DSF6123_1B_Pas_de_debordement
sar cx,16
not cx
DSF6123_1B_Pas_de_debordement:
mov [esi+0],al
mov [esi+1],bl
mov [esi+2],cl
; On diffuse l'erreur sur le pixel en bas (2)
mov eax,DSFRouge
mov ebx,DSFVert
mov ecx,DSFBleu
; Division signe par 4
sar eax,2
sar ebx,2
sar ecx,2
; Mise … jour de la quantit … diffuser
sub DSFRougeAD,eax
sub DSFVertAD ,ebx
sub DSFBleuAD ,ecx
; Diffusion de l'erreur dans la source
add esi,3
add al,[esi+0]
adc ah,0
jz DSF6123_2R_Pas_de_debordement
sar ax,16
not ax
DSF6123_2R_Pas_de_debordement:
add bl,[esi+1]
adc bh,0
jz DSF6123_2V_Pas_de_debordement
sar bx,16
not bx
DSF6123_2V_Pas_de_debordement:
add cl,[esi+2]
adc ch,0
jz DSF6123_2B_Pas_de_debordement
sar cx,16
not cx
DSF6123_2B_Pas_de_debordement:
mov [esi+0],al
mov [esi+1],bl
mov [esi+2],cl
; On diffuse l'erreur sur le pixel en bas … droite (3)
mov eax,DSFRougeAD
mov ebx,DSFVertAD
mov ecx,DSFBleuAD
; Diffusion de l'erreur dans la source
add esi,3
add al,[esi+0]
adc ah,0
jz DSF6123_3R_Pas_de_debordement
sar ax,16
not ax
DSF6123_3R_Pas_de_debordement:
add bl,[esi+1]
adc bh,0
jz DSF6123_3V_Pas_de_debordement
sar bx,16
not bx
DSF6123_3V_Pas_de_debordement:
add cl,[esi+2]
adc ch,0
jz DSF6123_3B_Pas_de_debordement
sar cx,16
not cx
DSF6123_3B_Pas_de_debordement:
mov [esi+0],al
mov [esi+1],bl
mov [esi+2],cl
; On passe au pixel suivant
sub esi,edx
sub esi,6
inc edi
dec VarA
jnz DFS6123_Pour_chaque_pixel
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
OPASM_DitherFS_6123 endp
OPASM_DitherFS_623 proc near
push ebp
mov ebp,esp
arg Destination:dword,Source:dword,Largeur:dword,Palette:dword,TableC:dword,ReducR:byte,ReducV:byte,ReducB:byte,NbbV:byte,NbbB:byte
push ebx
push esi
push edi
; On place dans ESI l'adresse de la source
mov esi,Source
; On place dans EDI l'adresse de la destination
mov edi,Destination
; On regarde la meilleure couleur d'aprŠs la table de conversion 24b->8b
mov edx,[esi] ; EDX = XBVR
xor eax,eax ; EAX = 0000
xor ebx,ebx ; EBX = 0000
mov al,dl ; EAX = 000R
mov bl,dh ; EBX = 000V
shr edx,16 ; EDX = 00XB
mov DSFRouge,eax
xor dh,dh ; EDX = 000B
mov DSFVert ,ebx
mov DSFBleu ,edx
mov cl,ReducR
shr eax,cl ; EAX = 000r
mov cl,ReducV
shr ebx,cl ; EBX = 000v
mov cl,ReducB
shr edx,cl ; EDX = 000b
mov cl,NbbV
shl eax,cl ; EAX = 00r0
or eax,ebx ; EAX = 00rv
mov cl,NbbB
shl eax,cl ; EAX = 0rv0
mov ebx,TableC ; EBX = Table conversion
or edx,eax ; EDX = 0rvb
xor eax,eax
mov al,[ebx+edx] ; EAX = Table[R,V,B]
; On le place dans la destination
mov [edi],al
; On regarde la couleur de la palette
mov ebx,Palette
add ebx,eax
shl eax,1
add ebx,eax ; EBX = &Palette[Table[R,V,B]].R
xor eax,eax
xor ecx,ecx
xor edx,edx
mov al,[ebx+0] ; EAX = 000R
mov cl,[ebx+1] ; ECX = 000V
mov dl,[ebx+2] ; EDX = 000B
; On calcule l'erreur
sub eax,DSFRouge
sub ecx,DSFVert
sub edx,DSFBleu
neg eax
neg ecx
neg edx
mov DSFRouge,eax
mov DSFVert ,ecx
mov DSFBleu ,edx
; On initialise la quantit d'erreur … diffuser
mov DSFRougeAD,eax
mov DSFVertAD ,ecx
mov DSFBleuAD ,edx
; On diffuse l'erreur sur le pixel de droite (6)
mov eax,DSFRouge
mov ebx,DSFVert
mov ecx,DSFBleu
; "Multiplication signe par 7"
sal eax,3
sal ebx,3
sal ecx,3
sub eax,DSFRouge
sub ebx,DSFVert
sub ecx,DSFBleu
; Division signe par 16
sar eax,4
sar ebx,4
sar ecx,4
; Mise … jour de la quantit … diffuser
sub DSFRougeAD,eax
sub DSFVertAD ,ebx
sub DSFBleuAD ,ecx
; Diffusion de l'erreur dans la source
add esi,3
add al,[esi+0]
adc ah,0
jz DSF623_6R_Pas_de_debordement
sar ax,16
not ax
DSF623_6R_Pas_de_debordement:
add bl,[esi+1]
adc bh,0
jz DSF623_6V_Pas_de_debordement
sar bx,16
not bx
DSF623_6V_Pas_de_debordement:
add cl,[esi+2]
adc ch,0
jz DSF623_6B_Pas_de_debordement
sar cx,16
not cx
DSF623_6B_Pas_de_debordement:
mov [esi+0],al
mov [esi+1],bl
mov [esi+2],cl
; On diffuse l'erreur sur le pixel en bas … gauche (1)
mov eax,DSFRouge
mov ebx,DSFVert
mov ecx,DSFBleu
; "Multiplication signe par 3"
sal eax,1
sal ebx,1
sal ecx,1
add eax,DSFRouge
add ebx,DSFVert
add ecx,DSFBleu
; Division signe par 16
sar eax,4
sar ebx,4
sar ecx,4
; Mise … jour de la quantit … diffuser
sub DSFRougeAD,eax
sub DSFVertAD ,ebx
sub DSFBleuAD ,ecx
; Diffusion de l'erreur dans la source
mov edx,Largeur
shl edx,1
add edx,Largeur
add esi,edx
; On diffuse l'erreur sur le pixel en bas (2)
mov eax,DSFRouge
mov ebx,DSFVert
mov ecx,DSFBleu
; Division signe par 4
sar eax,2
sar ebx,2
sar ecx,2
; Mise … jour de la quantit … diffuser
sub DSFRougeAD,eax
sub DSFVertAD ,ebx
sub DSFBleuAD ,ecx
; Diffusion de l'erreur dans la source
add esi,3
add al,[esi+0]
adc ah,0
jz DSF623_2R_Pas_de_debordement
sar ax,16
not ax
DSF623_2R_Pas_de_debordement:
add bl,[esi+1]
adc bh,0
jz DSF623_2V_Pas_de_debordement
sar bx,16
not bx
DSF623_2V_Pas_de_debordement:
add cl,[esi+2]
adc ch,0
jz DSF623_2B_Pas_de_debordement
sar cx,16
not cx
DSF623_2B_Pas_de_debordement:
mov [esi+0],al
mov [esi+1],bl
mov [esi+2],cl
; On diffuse l'erreur sur le pixel en bas … droite (3)
mov eax,DSFRougeAD
mov ebx,DSFVertAD
mov ecx,DSFBleuAD
; Diffusion de l'erreur dans la source
add esi,3
add al,[esi+0]
adc ah,0
jz DSF623_3R_Pas_de_debordement
sar ax,16
not ax
DSF623_3R_Pas_de_debordement:
add bl,[esi+1]
adc bh,0
jz DSF623_3V_Pas_de_debordement
sar bx,16
not bx
DSF623_3V_Pas_de_debordement:
add cl,[esi+2]
adc ch,0
jz DSF623_3B_Pas_de_debordement
sar cx,16
not cx
DSF623_3B_Pas_de_debordement:
mov [esi+0],al
mov [esi+1],bl
mov [esi+2],cl
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
OPASM_DitherFS_623 endp
OPASM_DitherFS_12 proc near
push ebp
mov ebp,esp
arg Destination:dword,Source:dword,Largeur:dword,Palette:dword,TableC:dword,ReducR:byte,ReducV:byte,ReducB:byte,NbbV:byte,NbbB:byte
push ebx
push esi
push edi
; On place dans ESI l'adresse de la source
mov esi,Source
; On place dans EDI l'adresse de la destination
mov edi,Destination
; On regarde la meilleure couleur d'aprŠs la table de conversion 24b->8b
mov edx,[esi] ; EDX = XBVR
xor eax,eax ; EAX = 0000
xor ebx,ebx ; EBX = 0000
mov al,dl ; EAX = 000R
mov bl,dh ; EBX = 000V
shr edx,16 ; EDX = 00XB
mov DSFRouge,eax
xor dh,dh ; EDX = 000B
mov DSFVert ,ebx
mov DSFBleu ,edx
mov cl,ReducR
shr eax,cl ; EAX = 000r
mov cl,ReducV
shr ebx,cl ; EBX = 000v
mov cl,ReducB
shr edx,cl ; EDX = 000b
mov cl,NbbV
shl eax,cl ; EAX = 00r0
or eax,ebx ; EAX = 00rv
mov cl,NbbB
shl eax,cl ; EAX = 0rv0
mov ebx,TableC ; EBX = Table conversion
or edx,eax ; EDX = 0rvb
xor eax,eax
mov al,[ebx+edx] ; EAX = Table[R,V,B]
; On le place dans la destination
mov [edi],al
; On regarde la couleur de la palette
mov ebx,Palette
add ebx,eax
shl eax,1
add ebx,eax ; EBX = &Palette[Table[R,V,B]].R
xor eax,eax
xor ecx,ecx
xor edx,edx
mov al,[ebx+0] ; EAX = 000R
mov cl,[ebx+1] ; ECX = 000V
mov dl,[ebx+2] ; EDX = 000B
; On calcule l'erreur
sub eax,DSFRouge
sub ecx,DSFVert
sub edx,DSFBleu
neg eax
neg ecx
neg edx
mov DSFRouge,eax
mov DSFVert ,ecx
mov DSFBleu ,edx
; On diffuse l'erreur sur le pixel en bas … gauche (1)
mov eax,DSFRouge
mov ebx,DSFVert
mov ecx,DSFBleu
; "Multiplication signe par 3"
sal eax,1
sal ebx,1
sal ecx,1
add eax,DSFRouge
add ebx,DSFVert
add ecx,DSFBleu
; Division signe par 16
sar eax,4
sar ebx,4
sar ecx,4
; Diffusion de l'erreur dans la source
mov edx,Largeur
add esi,3
shl edx,1
add edx,Largeur
add esi,edx
add al,[esi+0]
adc ah,0
jz DSF12_1R_Pas_de_debordement
sar ax,16
not ax
DSF12_1R_Pas_de_debordement:
add bl,[esi+1]
adc bh,0
jz DSF12_1V_Pas_de_debordement
sar bx,16
not bx
DSF12_1V_Pas_de_debordement:
add cl,[esi+2]
adc ch,0
jz DSF12_1B_Pas_de_debordement
sar cx,16
not cx
DSF12_1B_Pas_de_debordement:
mov [esi+0],al
mov [esi+1],bl
mov [esi+2],cl
; On diffuse l'erreur sur le pixel en bas (2)
mov eax,DSFRouge
mov ebx,DSFVert
mov ecx,DSFBleu
; Division signe par 4
sar eax,2
sar ebx,2
sar ecx,2
; Diffusion de l'erreur dans la source
add esi,3
add al,[esi+0]
adc ah,0
jz DSF12_2R_Pas_de_debordement
sar ax,16
not ax
DSF12_2R_Pas_de_debordement:
add bl,[esi+1]
adc bh,0
jz DSF12_2V_Pas_de_debordement
sar bx,16
not bx
DSF12_2V_Pas_de_debordement:
add cl,[esi+2]
adc ch,0
jz DSF12_2B_Pas_de_debordement
sar cx,16
not cx
DSF12_2B_Pas_de_debordement:
mov [esi+0],al
mov [esi+1],bl
mov [esi+2],cl
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
OPASM_DitherFS_12 endp
OPASM_DitherFS_6 proc near
push ebp
mov ebp,esp
arg Destination:dword,Source:dword,Largeur:dword,Palette:dword,TableC:dword,ReducR:byte,ReducV:byte,ReducB:byte,NbbV:byte,NbbB:byte
push ebx
push esi
push edi
; On place dans ESI l'adresse de la source
mov esi,Source
; On place dans EDI l'adresse de la destination
mov edi,Destination
; On place dans VarA la largeur … traiter
mov eax,Largeur
mov VarA,eax
; Pour chacun des pixels sur la largeur:
DFS6_Pour_chaque_pixel:
; On regarde la meilleure couleur d'aprŠs la table de conversion 24b->8b
mov edx,[esi] ; EDX = XBVR
xor eax,eax ; EAX = 0000
xor ebx,ebx ; EBX = 0000
mov al,dl ; EAX = 000R
mov bl,dh ; EBX = 000V
shr edx,16 ; EDX = 00XB
mov DSFRouge,eax
xor dh,dh ; EDX = 000B
mov DSFVert ,ebx
mov DSFBleu ,edx
mov cl,ReducR
shr eax,cl ; EAX = 000r
mov cl,ReducV
shr ebx,cl ; EBX = 000v
mov cl,ReducB
shr edx,cl ; EDX = 000b
mov cl,NbbV
shl eax,cl ; EAX = 00r0
or eax,ebx ; EAX = 00rv
mov cl,NbbB
shl eax,cl ; EAX = 0rv0
mov ebx,TableC ; EBX = Table conversion
or edx,eax ; EDX = 0rvb
xor eax,eax
mov al,[ebx+edx] ; EAX = Table[R,V,B]
; On le place dans la destination
mov [edi],al
; On regarde la couleur de la palette
mov ebx,Palette
add ebx,eax
shl eax,1
add ebx,eax ; EBX = &Palette[Table[R,V,B]].R
xor eax,eax
xor ecx,ecx
xor edx,edx
mov al,[ebx+0] ; EAX = 000R
mov cl,[ebx+1] ; ECX = 000V
mov dl,[ebx+2] ; EDX = 000B
; On calcule l'erreur
sub eax,DSFRouge
sub ecx,DSFVert
sub edx,DSFBleu
neg eax
neg ecx
neg edx
mov DSFRouge,eax
mov DSFVert ,ecx
mov DSFBleu ,edx
; On diffuse l'erreur sur le pixel de droite (6)
mov eax,DSFRouge
mov ebx,DSFVert
mov ecx,DSFBleu
; "Multiplication signe par 7"
sal eax,3
sal ebx,3
sal ecx,3
sub eax,DSFRouge
sub ebx,DSFVert
sub ecx,DSFBleu
; Division signe par 16
sar eax,4
sar ebx,4
sar ecx,4
; Diffusion de l'erreur dans la source
add esi,3
add al,[esi+0]
adc ah,0
jz DSF6_6R_Pas_de_debordement
sar ax,16
not ax
DSF6_6R_Pas_de_debordement:
add bl,[esi+1]
adc bh,0
jz DSF6_6V_Pas_de_debordement
sar bx,16
not bx
DSF6_6V_Pas_de_debordement:
add cl,[esi+2]
adc ch,0
jz DSF6_6B_Pas_de_debordement
sar cx,16
not cx
DSF6_6B_Pas_de_debordement:
mov [esi+0],al
mov [esi+1],bl
mov [esi+2],cl
; On passe au pixel suivant
inc edi
dec VarA
jnz DFS6_Pour_chaque_pixel
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
OPASM_DitherFS_6 endp
OPASM_DitherFS proc near
push ebp
mov ebp,esp
arg Destination:dword,Source:dword,TableC:dword,ReducR:byte,ReducV:byte,ReducB:byte,NbbV:byte,NbbB:byte
push ebx
push esi
push edi
; On place dans ESI l'adresse de la source
mov esi,Source
; On place dans EDI l'adresse de la destination
mov edi,Destination
; On regarde la meilleure couleur d'aprŠs la table de conversion 24b->8b
mov edx,[esi] ; EDX = XBVR
xor eax,eax ; EAX = 0000
xor ebx,ebx ; EBX = 0000
mov al,dl ; EAX = 000R
mov bl,dh ; EBX = 000V
shr edx,16 ; EDX = 00XB
mov DSFRouge,eax
xor dh,dh ; EDX = 000B
mov DSFVert ,ebx
mov DSFBleu ,edx
mov cl,ReducR
shr eax,cl ; EAX = 000r
mov cl,ReducV
shr ebx,cl ; EBX = 000v
mov cl,ReducB
shr edx,cl ; EDX = 000b
mov cl,NbbV
shl eax,cl ; EAX = 00r0
or eax,ebx ; EAX = 00rv
mov cl,NbbB
shl eax,cl ; EAX = 0rv0
mov ebx,TableC ; EBX = Table conversion
or edx,eax ; EDX = 0rvb
xor eax,eax
mov al,[ebx+edx] ; EAX = Table[R,V,B]
; On le place dans la destination
mov [edi],al
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
OPASM_DitherFS endp
OPASM_DitherFS_2 proc near
push ebp
mov ebp,esp
arg Destination:dword,Source:dword,Hauteur:dword,Palette:dword,TableC:dword,ReducR:byte,ReducV:byte,ReducB:byte,NbbV:byte,NbbB:byte
push ebx
push esi
push edi
; On place dans ESI l'adresse de la source
mov esi,Source
; On place dans EDI l'adresse de la destination
mov edi,Destination
; On place dans VarA la hauteur … traiter
mov eax,Hauteur
mov VarA,eax
; Pour chacun des pixels sur la largeur:
DFS2_Pour_chaque_pixel:
; On regarde la meilleure couleur d'aprŠs la table de conversion 24b->8b
mov edx,[esi] ; EDX = XBVR
xor eax,eax ; EAX = 0000
xor ebx,ebx ; EBX = 0000
mov al,dl ; EAX = 000R
mov bl,dh ; EBX = 000V
shr edx,16 ; EDX = 00XB
mov DSFRouge,eax
xor dh,dh ; EDX = 000B
mov DSFVert ,ebx
mov DSFBleu ,edx
mov cl,ReducR
shr eax,cl ; EAX = 000r
mov cl,ReducV
shr ebx,cl ; EBX = 000v
mov cl,ReducB
shr edx,cl ; EDX = 000b
mov cl,NbbV
shl eax,cl ; EAX = 00r0
or eax,ebx ; EAX = 00rv
mov cl,NbbB
shl eax,cl ; EAX = 0rv0
mov ebx,TableC ; EBX = Table conversion
or edx,eax ; EDX = 0rvb
xor eax,eax
mov al,[ebx+edx] ; EAX = Table[R,V,B]
; On le place dans la destination
mov [edi],al
; On regarde la couleur de la palette
mov ebx,Palette
add ebx,eax
shl eax,1
add ebx,eax ; EBX = &Palette[Table[R,V,B]].R
xor eax,eax
xor ecx,ecx
xor edx,edx
mov al,[ebx+0] ; EAX = 000R
mov cl,[ebx+1] ; ECX = 000V
mov dl,[ebx+2] ; EDX = 000B
; On calcule l'erreur
sub eax,DSFRouge
sub ecx,DSFVert
sub edx,DSFBleu
neg eax
neg ecx
neg edx
mov DSFRouge,eax
mov DSFVert ,ecx
mov DSFBleu ,edx
; On diffuse l'erreur sur le pixel en bas (2)
mov eax,DSFRouge
mov ebx,DSFVert
mov ecx,DSFBleu
; Division signe par 4
sar eax,2
sar ebx,2
sar ecx,2
; Diffusion de l'erreur dans la source
add esi,3
add al,[esi+0]
adc ah,0
jz DSF2_2R_Pas_de_debordement
sar ax,16
not ax
DSF2_2R_Pas_de_debordement:
add bl,[esi+1]
adc bh,0
jz DSF2_2V_Pas_de_debordement
sar bx,16
not bx
DSF2_2V_Pas_de_debordement:
add cl,[esi+2]
adc ch,0
jz DSF2_2B_Pas_de_debordement
sar cx,16
not cx
DSF2_2B_Pas_de_debordement:
mov [esi+0],al
mov [esi+1],bl
mov [esi+2],cl
; On passe au pixel suivant
inc edi
dec VarA
jnz DFS2_Pour_chaque_pixel
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
OPASM_DitherFS_2 endp
OPASM_Compter_occurences proc near
push ebp
mov ebp,esp
arg destination:dword,source:dword,taille:dword,reducR:byte,reducV:byte,reducB:byte,nbbV:byte,nbbB:byte
push ebx
push esi
push edi
; On place dans ESI l'adresse de la source
mov esi,source
; On place dans EDI l'adresse de la destination
mov edi,destination
; On place dans VarA le nb de pixels … traiter
mov eax,taille
mov VarA,eax
; Pour chacun des pixels:
CO_Pour_chaque_pixel:
; On regarde la couleur
xor eax,eax ; EAX = 0000
xor ebx,ebx ; EBX = 0000
xor edx,edx ; EDX = 0000
mov al,[esi] ; EAX = 000R
mov dx,[esi+1] ; EDX = 00BV
mov cl,reducR
xchg bl,dh ; EBX = 000B EDX = 000V
shr eax,cl ; EAX = 000r
mov cl,reducV
shr edx,cl ; EDX = 000v
mov cl,reducB
shr ebx,cl ; EBX = 000b
mov cl,nbbV
shl eax,cl ; EAX = 00r0
or eax,edx ; EAX = 00rv
mov cl,nbbB
shl eax,cl ; EAX = 0rv0
or eax,ebx ; EAX = 0rvb
shl eax,2 ; EAX = 0rvb * 4
inc dword ptr[edi+eax]
; On passe au pixel suivant
add esi,3
dec VarA
jnz CO_Pour_chaque_pixel
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
OPASM_Compter_occurences endp
OPASM_Analyser_cluster proc near
push ebp
mov ebp,esp
arg tableO:dword,rmin:dword,vmin:dword,bmin:dword,rmax:dword,vmax:dword,bmax:dword,rdec:dword,vdec:dword,bdec:dword,rinc:dword,vinc:dword,binc:dword,nbocc:dword
push ebx
push esi
push edi
; On place dans ESI l'adresse de base de la table d'occurence
mov esi,tableO
; On place dans DSF????? la valeur minimale des teintes
mov eax,[rmin]
mov ebx,[vmin]
mov ecx,[bmin]
mov eax,[eax]
mov ebx,[ebx]
mov ecx,[ecx]
mov DSFRouge,eax
mov DSFVert ,ebx
mov DSFBleu ,ecx
; On place dans VarDEF la valeur maximale courante des teintes
mov VarD,eax
mov VarE,ebx
mov VarF,ecx
; On place dans DSF?????AD la valeur maximale des teintes
mov eax,[rmax]
mov ebx,[vmax]
mov ecx,[bmax]
mov eax,[eax]
mov ebx,[ebx]
mov ecx,[ecx]
mov DSFRougeAD,eax
mov DSFVertAD ,ebx
mov DSFBleuAD ,ecx
; On place dans VarABC la valeur minimale courante des teintes
mov VarA,eax
mov VarB,ebx
mov VarC,ecx
; On place dans EDI le nombre d'occurences
xor edi,edi
; Pour chaque Rouge
mov ebx,DSFRouge
AC_Pour_chaque_rouge:
; Pour chaque Vert
mov ecx,DSFVert
AC_Pour_chaque_vert:
; Pour chaque Bleu
mov edx,DSFBleu
AC_Pour_chaque_bleu:
; On regarde le nombre d'occurences (=>EAX)
mov eax,ebx
or eax,ecx
or eax,edx
shl eax,2
mov eax,[esi+eax]
; S'il y a des occurences
or eax,eax
jz AC_Pas_d_occurences
; On incrmente le compteur
add edi,eax
; On met … jour les bornes
cmp ebx,VarA ; r ? rmin
jae AC_r_sup_rmin
mov VarA,ebx
AC_r_sup_rmin:
cmp ebx,VarD ; r ? rmax
jbe AC_r_inf_rmax
mov VarD,ebx
AC_r_inf_rmax:
cmp ecx,VarB ; v ? vmin
jae AC_v_sup_vmin
mov VarB,ecx
AC_v_sup_vmin:
cmp ecx,VarE ; v ? vmax
jbe AC_v_inf_vmax
mov VarE,ecx
AC_v_inf_vmax:
cmp edx,VarC ; b ? bmin
jae AC_b_sup_bmin
mov VarC,edx
AC_b_sup_bmin:
cmp edx,VarF ; b ? bmax
jbe AC_b_inf_bmax
mov VarF,edx
AC_b_inf_bmax:
AC_Pas_d_occurences:
; On passe au bleu suivant
add edx,binc
cmp edx,DSFBleuAD
jbe AC_Pour_chaque_bleu
; On passe au vert suivant
add ecx,vinc
cmp ecx,DSFVertAD
jbe AC_Pour_chaque_vert
; On passe au rouge suivant
add ebx,rinc
cmp ebx,DSFRougeAD
jbe AC_Pour_chaque_rouge
; On retourne les rsultats
; Nb d'occurences
mov eax,nbocc
mov [eax],edi
; Rmin & Rmax
mov eax,VarA
mov ebx,VarD
mov ecx,rdec
mov edx,rmin
mov edi,rmax
shr eax,cl
shr ebx,cl
mov [edx],eax
mov [edi],ebx
; Vmin & Vmax
mov eax,VarB
mov ebx,VarE
mov ecx,vdec
mov edx,vmin
mov edi,vmax
shr eax,cl
shr ebx,cl
mov [edx],eax
mov [edi],ebx
; Bmin & Bmax
mov eax,VarC
mov ebx,VarF
mov ecx,bdec
mov edx,bmin
mov edi,bmax
shr eax,cl
shr ebx,cl
mov [edx],eax
mov [edi],ebx
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
OPASM_Analyser_cluster endp
OPASM_Split_cluster_Rouge proc near
push ebp
mov ebp,esp
arg tableO:dword,rmin:dword,vmin:dword,bmin:dword,rmax:dword,vmax:dword,bmax:dword,rinc:dword,vinc:dword,binc:dword,limite:dword,rdec:dword,rouge:dword
push ebx
push esi
push edi
; On place dans ESI l'adresse de base de la table d'occurence
mov esi,tableO
; On place dans EDI le nombre d'occurences
xor edi,edi
; Pour chaque Rouge
mov ebx,rmin
SCR_Pour_chaque_rouge:
; Pour chaque Vert
mov ecx,vmin
SCR_Pour_chaque_vert:
; Pour chaque Bleu
mov edx,bmin
SCR_Pour_chaque_bleu:
; On regarde le nombre d'occurences (=>EAX)
mov eax,ebx
or eax,ecx
or eax,edx
shl eax,2
mov eax,[esi+eax]
; On le rajoute … EDI
add edi,eax
cmp edi,limite
jae SCR_Fin_recherche
; On passe au bleu suivant
add edx,binc
cmp edx,bmax
jbe SCR_Pour_chaque_bleu
; On passe au vert suivant
add ecx,vinc
cmp ecx,vmax
jbe SCR_Pour_chaque_vert
; On passe au rouge suivant
add ebx,rinc
cmp ebx,rmax
jbe SCR_Pour_chaque_rouge
SCR_Fin_recherche:
; On retourne le rsultat
mov ecx,rdec
shr ebx,cl
mov eax,rouge
mov [eax],ebx
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
OPASM_Split_cluster_Rouge endp
OPASM_Split_cluster_Vert proc near
push ebp
mov ebp,esp
arg tableO:dword,rmin:dword,vmin:dword,bmin:dword,rmax:dword,vmax:dword,bmax:dword,rinc:dword,vinc:dword,binc:dword,limite:dword,vdec:dword,vert:dword
push ebx
push esi
push edi
; On place dans ESI l'adresse de base de la table d'occurence
mov esi,tableO
; On place dans EDI le nombre d'occurences
xor edi,edi
; Pour chaque Vert
mov ebx,vmin
SCV_Pour_chaque_vert:
; Pour chaque Rouge
mov ecx,rmin
SCV_Pour_chaque_rouge:
; Pour chaque Bleu
mov edx,bmin
SCV_Pour_chaque_bleu:
; On regarde le nombre d'occurences (=>EAX)
mov eax,ebx
or eax,ecx
or eax,edx
shl eax,2
mov eax,[esi+eax]
; On le rajoute … EDI
add edi,eax
cmp edi,limite
jae SCV_Fin_recherche
; On passe au bleu suivant
add edx,binc
cmp edx,bmax
jbe SCV_Pour_chaque_bleu
; On passe au rouge suivant
add ecx,rinc
cmp ecx,rmax
jbe SCV_Pour_chaque_rouge
; On passe au vert suivant
add ebx,vinc
cmp ebx,vmax
jbe SCV_Pour_chaque_vert
SCV_Fin_recherche:
; On retourne le rsultat
mov ecx,vdec
shr ebx,cl
mov eax,vert
mov [eax],ebx
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
OPASM_Split_cluster_Vert endp
OPASM_Split_cluster_Bleu proc near
push ebp
mov ebp,esp
arg tableO:dword,rmin:dword,vmin:dword,bmin:dword,rmax:dword,vmax:dword,bmax:dword,rinc:dword,vinc:dword,binc:dword,limite:dword,bdec:dword,bleu:dword
push ebx
push esi
push edi
; On place dans ESI l'adresse de base de la table d'occurence
mov esi,tableO
; On place dans EDI le nombre d'occurences
xor edi,edi
; Pour chaque Bleu
mov ebx,bmin
SCB_Pour_chaque_bleu:
; Pour chaque Rouge
mov ecx,rmin
SCB_Pour_chaque_rouge:
; Pour chaque Vert
mov edx,vmin
SCB_Pour_chaque_vert:
; On regarde le nombre d'occurences (=>EAX)
mov eax,ebx
or eax,ecx
or eax,edx
shl eax,2
mov eax,[esi+eax]
; On le rajoute … EDI
add edi,eax
cmp edi,limite
jae SCB_Fin_recherche
; On passe au vert suivant
add edx,vinc
cmp edx,vmax
jbe SCB_Pour_chaque_vert
; On passe au rouge suivant
add ecx,rinc
cmp ecx,rmax
jbe SCB_Pour_chaque_rouge
; On passe au bleu suivant
add ebx,binc
cmp ebx,bmax
jbe SCB_Pour_chaque_bleu
SCB_Fin_recherche:
; On retourne le rsultat
mov ecx,bdec
shr ebx,cl
mov eax,bleu
mov [eax],ebx
pop edi
pop esi
pop ebx
mov esp,ebp
pop ebp
ret
OPASM_Split_cluster_Bleu endp
_TEXT ENDS
END