Suivez-nous sur X

|
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z,
ALL
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
0,
A,
B,
C,
D,
E,
F,
G,
H,
I,
J,
K,
L,
M,
N,
O,
P,
Q,
R,
S,
T,
U,
V,
W,
X,
Y,
Z
|
|
A propos d'Obligement
|
|
David Brunet
|
|
|
|
Programmation : Assembleur - Visionneur d'images IFF
(Article écrit par Max et extrait d'Amiga News Tech - juillet 1990)
|
|
Voilà qui devrait faire plaisir à un certain strasbourgeois amateur de 3D : la création d'un visionneur/décompateur d'images au
format IFF, toutes résolutions - sauf Overscan, faut pas exagérer. Étant donné que je ne dispose pas du magazine
pour moi tout seul (soupir), je supposerai que vous connaissez déjà les éléments principaux du format IFF pour entrer
directement dans le vif du sujet. Dans le cas contraire, reportez-vous à la littérature adéquate, style
cet article, "La Bible De l'Amiga" ou "Amiga ROM Kernel Reference Manual : Includes and Autodocs"
pour les anglicistes.
Le programme présenté ici ne permet pas l'affichage de plusieurs images chaînées dans un seul fichier. De même,
il ne prend en compte que les blocs de données (chunks) les plus importants, à savoir : FORM (quand même !), CAMG (spécifique à l'Amiga),
CMAP (palette), BHMD (bitmap header) et BODY (les données graphiques elles-mêmes). Il accepte aussi bien les fichiers
compressés (selon l'algorythme en vigueur, baptisé "ByteRun1") que les fichiers étendus (résultats de l'IFF-Converter
de Deluxe Paint). Toutes les explications nécessaires sont incluses sous forme de commentaires dans le listing, aussi
n'en sera-t-il pas dit plus ici. Attention, c'est parti.
; ShowIFFs
; Par Max - Mai 1990
; Version Devpac II uniquement
; (pour Seka, allez au diable)
;incdir "Devpac2:Include
* FUNCDEF macro definition for 'exec/exec_lib.i'
FUNCDEF MACRO *function
_LVO\1 EQU FUNC_CNT
FUNC_CNT SET FUNC_CNT-6
ENDM
FUNC_CNT SET 5*-6
; changer le chemin ci-dessous avec le votre. (includes assembler)
; si vous avez une erreur sur les fichiers *_lib.i telecharger ceux-ci et copier-les
; sur vos includes http://aminet.net/package/dev/asm/incupd
; utilisation nom du programme suivi du fichier iff a afficher, alt gauche pour sortir.
INCDIR "C:\Users\kamel\Desktop\vbcc\NDK_3.1\Includes_Libs\include_i\"
INCLUDE "exec/exec.i"
INCLUDE "exec/exec_lib.i"
INCLUDE "exec/memory.i"
INCLUDE "intuition/intuition_lib.i"
INCLUDE "intuition/intuition.i"
INCLUDE "graphics/graphics_lib.i"
INCLUDE "graphics/view.i"
INCLUDE "graphics/gfx.i"
INCLUDE "libraries/dos_lib.i"
INCLUDE "libraries/dos.i"
; Definition de la structure BMHD facon Include
rsreset
BMHD rs.b 0
bmhd_w: rs.w 1
bmhd_h: rs.w 1
bmhd_x: rs.w 1
bmhd_y: rs.w 1
bmhd_nPlanes: rs.b 1
bmhd_masking: rs.b 1
bmhd_compression: rs.b 1
bmhd_pad1: rs.b 1
bmhd_transparentColor: rs.w 1
bmhd_xAspect: rs.b 1
bmhd_yAspect: rs.b 1
bmhd_pageWidth: rs.w 1
bmhd_pageHeight: rs.w 1
bmhd_SIZEOF: rs.w 0
; Definition des bits inutiles du CAMG
;en vue du masquage pour ViewModes
CAMGMASK EQU ((~(V_SPRITES|GENLOCK_VIDEO))&$FFFF)
;ExecBase EQU 4
; Petite macro pour nous simplifier la vie CALL
CALL MACRO
jsr _LVO\1(a6)
ENDM
; C'est parti mon kiki !; **************************************
Start:
move.l $4.w,a6
move.b #0,-1(a0,d0.w)
subq #1,d0
beq NoArg
move.l a0,FileName
; Ouverture de l'intuition library
lea IntName(pc),a1
moveq #0,d0
CALL OpenLibrary
move.l d0,IntBase
beq.s Nolnt
; Ouverture de la graphics.library
; Ouverture de la graphics.library
lea GfxName(pc),a1
moveq #0,d0
CALL OpenLibrary
move.l d0,GfxBase
beq.s NoGfx
; Ouverture de la dos.library
lea DosName(pc),a1
moveq #0,d0
CALL OpenLibrary
move.l d0,DosBase
beq.s NoDos
; Charge l'image IFF
bsr.s LoadPic
tst.l d7
; Erreur de chargement ?
beq.s NoPic
; Et l'affiche
bsr DisplayIFF
; Libere la memoire du fichier
move.l $4.w,a6
move.l Picture(pc),a1
move.l FileSize(pc),d0
CALL FreeMem
; Ferme la dos.library
NoPic: move.l DosBase(pc),a1
CALL CloseLibrary
; Ferme la graphics.library
NoDos: move.l GfxBase(pc),a1
CALL CloseLibrary
NoGfx: move.l IntBase(pc),a1
CALL CloseLibrary
Nolnt:
NoArg: rts
; *************************************
; * Routine de chargement du fichier *
; * IFF en memoire. *
; * en sortie, d7 sert de drapeau: *
; * d7=0 -> une erreur est survenue *
; * d7<>0 -> tout s'est bien passe *
; *************************************
LoadPic:
moveq #0,d7 ;d7=0 -> erreur sinon Ok
; Réserve 260 octets de CHIP-RAM pour Examine()
move.l #fib_SIZEOF,d0
move.l #MEMF_PUBLIC|MEMF_CLEAR,d1
CALL AllocMem
tst.l d0
beq NoMem
move.l d0,a5
; Obtient un Lock sur le fichier !
move.l DosBase(pc),a6
move.l FileName(pc),d1
moveq #ACCESS_READ,d2
CALL Lock
move.l d0,filelock_an
beq.s NoLock
; Fichier inexistant
; Examine() le fichier
move.l d0,d1
move.l a5,d2
CALL Examine
; Est-ce un repertoire ?
tst.l fib_DirEntryType(a5)
bpl.s IsDir
; Oui!
move.l fib_Size(a5),FileSize
; Sinon, sauve sa taille
; Reserve de la memoire pour charger le fichier
move.l $4.w,a6
move.l FileSize(pc),d0
moveq #MEMF_PUBLIC,d1
CALL AllocMem
move.l d0,Picture
beq.s NoMem2
; Ouvre le fichier
move.l DosBase(pc),a6
move.l FileName(pc),d1
move.l #MODE_OLDFILE,d2
CALL Open
move.l d0,d6
beq OpenErr
; Erreur d'ouverture
; Charge le fichier en memoire
move.l d0,d1
move.l Picture(pc),d2
move.l FileSize(pc),d3
CALL Read
; Ferme le fichier
move.l d6,d1
CALL Close
moveq #-1,d7
;d7<>0 -> Tout s'est bien passe
IsDir:
NoMem2:
OpenErr:; Libere le Lock du fichier
move.l filelock_an,d1
CALL UnLock
; Libere la memoire d'Examine()
NoLock: move.l $4.w,a6
move.l a5,a1
move.l #fib_SIZEOF,d0
CALL FreeMem
NoMem: rts
;************************************************
;* Routine d'atfichage de l'image IFF *
;* Gere les modes compacte et etendu *
;************************************************
;* Algorythme de compactage : *
;* tester l'octet de controle n; si n egale: *
;* 0...127 : copier n+1 octets de donnees *
;* -1...-127 : repeter -n+1 fois l'octet suivant*
;* -128: ne rien faire (ah bon ?} *
;************************************************
DisplayIFF:
move.l Picture(pc),a5
;a5=image FF
lea ScreenDefs(pc),a4
;a4=structure NewSereen
cmpi.l #'FORM',(a5)+
; Verifie si c'est un fichier IFF
bne IFFErr
;Non!
move.l (a5)+,d0
add.l a5,d0
; Sauve sa taille
move.l d0,FormEnd
cmpi.l #'ILBM',(a5)+
; Verifie si c'est un fichier ILBM
bne IFFErr
;Non!
; Boucle principale
Do: move.l (a5)+,d7
;d7=ChunkName
move.l (a5)+,d6
;d6=ChunkSize ,
cBMHD:
cmpi.l #'BMHD',d7
bne.s cCMAP
; Chunk BMHD (Bitmap Header)
move.w bmhd_w(a5),ns_Width(a4)
; Largeur
move.w bmhd_h(a5),ns_Height(a4)
; Hauteur
move.b bmhd_nPlanes(a5),ns_Depth+1(a4)
; Profondeur
tst.b bmhd_compression(a5)
; Fichier compresse ?
sne Compress
; Oui -> positionne le drapeau
bra Loop
; Prochain chunk
cCMAP: cmpi.l #'CMAP',d7
bne.s cCAMG
; Chunk CMAP (Color Map)
move.w d6,d7
ext.l d7
divu #3,d7
;d7 = nombre de couleurs
cmpi.w #32,d7
; Plus de 32 couleurs ?
ble.s CoulOk
moveq #32,d7
; Oui -> 32 couleurs max (c'est moi !)
CoulOk: move.w d7,NbCoul
; Sauve le nombre de couleurs
lea Palette(pc),a2
moveq #0,d5
subq #1,d7
CoLoop: move.b (a5)+,d5
; Composante Rouge
lsl.w #4,d5
or.b (a5)+,d5
; Composante Vert
lsl.w #4,d5
or.b (a5)+,d5
; Composante Bleu
lsr.w #4,d5
move.w d5,(a2)+
; Sauve le RVB dans la palette
dbra d7,CoLoop
; Prochaine couleur
moveq #0,d6
bra Loop
; Prochain chunk
cCAMG: cmp.l #'CAMG',d7
bne.s cBODY
; Chunk CAMG (Commodore Amiga)
move.l (a5),d0
andi.l #CAMGMASK,d0
; Masque les bits indesirables
move.w d0,ns_ViewModes(a4)
; Mode d'ecran dans Ia structure
bra Loop
; NewScreen (HAM, EHB, etc.)
cBODY:
cmp.l #'BODY',d7
bne Loop
; Chunk BODY (donnees graphiques) STOP :
move.l IntBase(pc),a6
; Ouvre l'ecran
lea ScreenDefs(pc),a0
move.w #CUSTOMSCREEN|SCREENQUIET,ns_Type(a0)
CALL OpenScreen
move.l d0,ScrHandle
beq IFFErr
; Si erreur, on arrete tout
; Charge la palette de couleurs
move.l GfxBase(pc),a6
move.l d0,a0
;:a0 = ScreenHandle
lea sc_ViewPort(a0),a0
lea Palette(pc),a1
move.w NbCoul(pc),d0
; Nombre de couleurs
ext.l d0
CALL LoadRGB4
; C'est parti !
; Le vrai boulot commence ici
move.w ns_Width(a4),d5
; Largeur en pixels
lsr.w #3,d5
;/8 = largeur en octets
moveq #0,d0
;Compteurlignes
Lignes: move.l ScrHandle(pc),a3
lea sc_BitMap+bm_Planes(a3),a3
move.w ns_Depth(a4),d1
; Compteur bitplanes
subq.w #1,d1
;-1 pour dbra
Planes: move.l (a3)+,a0
;a0 = bitplane en cours
move.w d0,d2
mulu d5,d2
lea (a0,d2.l),a0
; pointe la bonne ligne
moveq #0,d2
tst.b Compress
; image compressee ?
beq Normal
;non
; Au cas ou l'image est compressee
Comp: moveq #0,d3
move.b (a5)+,d3
; octet de controle dans d3
bmi.s Crunch
; negatif -> decompresser
ext.w d3
add.w d3,d2
addq.w #1,d2
CompL:
move.b (a5)+,(a0)+
; sinon copier n octets
dbra d3,CompL
bra.s NextByte
; au suivant !
Crunch: cmpi.b #$80,d3
; n=>128 ($80) ?
beq.s NextByte
; oui -> rien a faire
neg.b d3
;sinon n=-n
ext.w d3
add.w d3,d2
addq.w #1,d2
move.b (a5)+,d4
; prendre octet de donnee
CrunchL:
move.b d4,(a0)+
; et le repeter n+1 fois
dbra d3,CrunchL
; (+1 car dbra)
NextByte:
cmp.w d5,d2
; fin de ligne atteinte ?
blt.s Comp
; pas encore
bra.s NextL
; si oui passe au plan suivant
; Cas d'une image "etendue" (IFF-Converter)
Normal: move.w d5,d4
; largeur en octets
subq.w #1,d4
;-1 pour dbra
NLoop:
move.b (a5)+,(a0)+
; copier les donnees
dbra d4,NLoop
; une ligne complete
; Une ligne est atfichee,
; on passe au plan suivant
NextL: dbra d1,Planes
; Quand tous les plans de la ligne sont traites
; on passe a la ligne suivante
addq.w #1,d0
; compteur de lignes incremente
cmp.w ns_Height(a4),d0
; la hauteur est atieinte ?
blt.s Lignes
; Non, on continue
moveq #0,d6
;si oui on a fini; On arrive ici quand un chunk a ete traite
; (ou ignore pour ceux qui ne sont pas geres)
Loop: adda.l d6,a5
; Saute le chunk
; quon vient de traiter
move.l a5,d6
; Verifie qu'a5 est pair
andi.b #1,d6
beq.s Pair
addq.l #1,a5
; Si impair, on l'incremente
Pair: cmpa.l FormEnd(pc),a5
; Fin de la FORM?
blt Do
; Pas encore
; Attend ALT-Gauche
Wait: cmp.b #$37,$bfec01
bne.s Wait
; Ferme l'ecran
move.l IntBase(pc),a6
move.l ScrHandle(pc),a0
CALL CloseScreen
; Retour a l'envoyeur
IFFErr: rts
; Variables diverses
FormEnd:
dc.l 0
; Taille de la FORM
Compress: dc.b 0,0
NbCoul: dc.w 0
; Nombre de couleurs
Palette: ds.w 32
; Palette de 32 couleurs
IntBase: dc.l 0
GfxBase: dc.l 0
DosBase: dc.l 0
ScrHandle: dc.l 0
FileName: dc.l 0
filelock_an: dc.l 0
filehandle_an: dc.l 0
FileSize: dc.l 0
Picture: dc.l 0
IntName:
dc.b "intuition.library",0
even
GfxName:
dc.b "graphics.library",0
even
DosName:
dc.b "dos.library",0
even
; Structure NewScreen
ScreenDefs: ds.b ns_SIZEOF
END
|
Le fichier compilé se trouve ici.
Voilà, on se retrouve dans environ 30 jours avec deux routines de tri (l'une pour des nombres, l'autre pour des chaînes)
demandées par M. Sorant, gentil lecteur de... Vensuillet ? Vermuillet ? Vesrouillet (d'après notre vénéré directeur
de publication, il s'agit de Vernouillet en Eure-et-Loire. La prochaine fois, écrivez mieux, tout de même...).
|