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 - Afficheur d'images IFF compressées
(Article écrit par Emmanuel Hocdet et extrait d'Amiga News Tech - mars 1992)
|
|
Partout ! Les réducteurs d'octets sont partout ! Que faire, face à une telle invasion ? Le mieux est
certainement d'apprendre à les connaître, en vous plongeant par exemple dans l'article qui suit.
Cet article fait suite à celui paru récemment dans Amiga Revue et qui traite de l'utilisation générale de
la compression. Nous allons donc étudier en détail avec les algorithmes élémentaires et donc faciles à
implémenter. Au programme, compression par topologie, par demi-octet, et suppression des répétitions.
Compression par topologie
Cette méthode consiste à différencier dans un tableau de bits, l'octet le plus courant d'un fichier (en général 0),
puis d'en éliminer toutes les occurrences. Par exemple, la séquence originale $12 $00 $80 $FF $00 $00 $A1 $00 sera
remplacée par la séquence compactée $12 $80 $FF $A1 suivie du tableau %10110010 (0 désigne le caractère compacté et
1 un caractère non compacté), d'où un gain de 3 octets sur 8.
Cet algorithme, quoique peu rentable, a l'avantage d'être simple et rapide. Il a d'ailleurs été utilisé au temps
des micro-dinosaures à faible capacité de traitement.
Compression par demi-octet
Cet algorithme fut élaboré sur des ordinateurs 8 bits. Il permet d'extraire la partie commune d'une série de N
octets (entre autres le demi-octet de poids fort). Celui-ci est alors stocké avec N (nombre codé sur 4 bits) dans
un octet, immédiatement suivi par les 4 bits de poids faible de chaque octet ainsi réduit.
Le petit schéma ci-joint mettra les choses au clair. Des résultats ne sont obtenus que pour les données à variation modérée.
Dans la pratique, cette méthode s'utilise couplée à d'autres algorithmes comme le RLE et est alors adaptée au type
de l'ordinateur : pour un 16/32 bits, la compression se fait par demi-mots.
Le run-lenght-encoding
Le RLE, plus connu sous le nom de suppression des répétitions, permet de remplacer chaque série d'octets identiques
par la longueur de celle-ci et l'octet à répéter. Cet algorithme est largement utilisé lors de la sauvegarde d'images
et notamment dans le format IFF. Pour ce type de données, il allie en plus de la vitesse de traitement, la performance.
Prenons une image de 320 pixels de large (40 octets) comportant des zones de même couleur. Deux lignes ne comportant
qu'une suite d'octets à zéro peuvent être compressées : les 80 octets de cette zone sont alors remplacés par un compteur
(généralement codé sur 8 bits) de valeur la longueur de la série, suivie de l'octet de remplissage (ici, l'on trouve
80 et 0). Par contre la suite 11 12 13 ne peut subir le même traitement. Le compresseur/décompresseur doit alors absolument
différencier les deux cas. Une solution simple est de coder le compteur, caractérisant le nombre d'octets compactés ou non,
sur 7 bits (valeur < 128) et de garder le bit de poids fort (signe de l'octet) comme identificateur : une valeur
négative (bit 7 à 1) indiquera une compression. Cette implémentation est utilisée dans le programme d'aujourd'hui.
Le programme
Le format IFF, développé par la société Electronics Arts à la demande de Commodore, peut supporter plusieurs
compressions du type RLE. Le programme qui suit traite uniquement de la méthode utilisée dans Deluxe Paint,
le ByteRun1, car la plus répandue. Il peut relire une image aux dimensions standard ou en suraffichage
dans n'importe quel mode géré par DPaint IV, même le mode HAM entrelacé. De plus, il centrera automatiquement
l'image à l'écran. Par contre, pour des raisons évidentes de simplification, l'image ne sera pas lue depuis
le disque, mais directement incluse (grâce à la directive INCBIN du Devpac) dans l'exécutable.
Si vous voulez réaliser un diaporama de vos numérisations ou de vos superbes réalisations 2D et 3D, n'hésiter
pas à reprendre ce programme type.
***** Afficheur d'images IFF compressées par Emmanuel Hocdet
***** Assemblé avec Genim2 V2.15
***** reconnaît tous les formats de Deluxe Paint IV
D_init=$8200
D_PriB=$400
D_Btpl=$100
D_Copp=$80
D_Blit=$40
D_Spts=$20
D_Disk=$10
Dcon = D_init!D_Btpl
incdir "include:"
Include "exec/exec_lib.i"
Include "exec/memory.i"
SECTION intro,code
Start
bsr SaveAll
move #$7fff,$dff09a * Vide INTENA et DMACON
move #$7fff,$dff096
bsr Main Quel est le programme ?
botton btst #6,$bfe001 on attend la délicate pression
bne botton sur le zoli bouton de la souris
move.l Adr_ecr(pc),a1
move.l Taille_ecr(pc),d0
beq.s rien
CALLEXEC FreeMem Désalouons en coueur la mémoir
rien
bsr RestoreAll
rts
*****
***** SaveAll & RestorAll
*****
SaveAll move.l 4.w,a6
jsr -132(a6)
lea IrqVBL(pc),a0
move.l $6c.w,(a0)
lea INTENA(pc),a0
move.w $dff01c,(a0)
or.w #$c000,(a0)
lea DMACON(pc),a0
move.w $dff002,(a0)
or.w #$8100,(a0)
rts
RestoreAll
move.w #$7fff,$dff09a
move.l IrqVBL(pc),$6c.w
move.w INTENA(pc),$dff09a
move.w #$7fff,$dff096
move.w DMACON(pc),$dff096
move.l 4.w,a6
lea GFXlib(pc),a1
moveq #0,d0
jsr -552(a6)
move.l d0,a0
move.l 38(a0),$dff080
clr.w $dff088
move.l d0,a1
jsr -414(a6)
jsr -138(a6)
moveq #0,d0
rts
INTENA: dc.w 0
DMACON: dc.w 0
GFXlib: dc.b "graphics.library",0
even
IrqVBL dc.l 0
*****
***** Main
*****
Main
lea $dff180,a3 Debut des couleurs dans a3
moveq #2,d3 espace entre deux données couleur
lea picture,a4 Image IFF
bsr DecrunchIFF A tout de suite
bmi FIN
lea $dff000,a6
clr.l $102(a6) * Decalage a 0
move Nb_Plans(pc),d0 * Mode de l'écran
ror.w #4,d0
move Mode_ecr(pc),d1
and #$8804,d1
or d1,d0
or #$200,d0 Mode couleur
move d0,$100(a6) * BPLCON0
move X_ecr(pc),d3 Préparation pour le calcul
moveq #17,d4 de la taille de la fenêtre
move #$fff8,d5
move d1,d0
and #$8000,d0
beq.s No_Hires
moveq #9,d4 ...pour le Hires
move #$fffc,d5
move d3,d0
lsr.w #1,d0
move d0,X_ecr
No_Hires
move Nb_Plans(pc),d0
move d3,Séparation ...entre deux plans de bits
clr.l LaceVal
and #$0004,d1
beq.s No_Lace
move d3,d1 ...pour le Lace
mulu d0,d1
move.l d1,LaceVal valeur de l'autre serie de plans de bits
add d0,d0
lea Y_ecr(pc),a0
move (a0),d1
lsr.w #1,d1
move d1,(a0)
; bclr #15,$02a(a6)
No_Lace
subq #1,d0
mulu d0,d3 * Modulo= Xoctet*(NbPlans-1)
move d3,$108(a6) * Modulo plans
move d3,$10a(a6)
move Y_ecr(pc),d0 DiwStrtYv=166-Hauteur_Ecran/2
lsr.w #1,d0
neg.w d0
add.w #166,d0
lsl.w #8,d0
move X_ecr(pc),d1 DiwStrtXv=289-Largeur_Ecran/2
lsl.w #2,d1 *8/2 = *4
neg.w d1
add.w #289,d1
or d1,d0
move Y_ecr(pc),d2 DiwStopYv=Hauteur_Ecran/2-90
lsr.w #1,d2
sub.w #90,d2
lsl.w #8,d2
move X_ecr(pc),d3 DiwStopXv=Largeur_Ecran/2+33
lsl.w #2,d3 *8/2 = *4
add.w #33,d3
or d3,d2
sub d4,d1 DdfStrt=(DiwStrtXv-17)/2
lsr #1,d1
and d5,d1
move X_ecr(pc),d3 DdfStop=DdfStrt+(Largeur_Ecran/16-1)*8
lsr #1,d3
subq #1,d3
lsl #3,d3
add d1,d3
move.w d0,$08e(a6) * Display Window Start
move.w d2,$090(a6) * Display Window Stop
move.w d1,$092(a6) * Display Data Fetch Start
move.w d3,$094(a6) * Display Data Fetch Stop
move #$c020,$09a(a6) * Interruptions (INTENA)
move #Dcon,$096(a6) * DMACON
move.l #IT,$6c Interruption lancée
FIN rts
*****
***** Interruption : Vertical Blank
*****
IT
movem.l d0-d2/a0,-(sp)
move.l Adr_ecr(pc),d1 Adresse de l'Image
move $dff004,d0 LOF sert pour le mode Lace
bmi.s Mi LOF=1 ? oui alors va à Mi
add.l LaceVal(pc),d1 non
Mi lea $dff0e0,a0 Adresse bitplan1
moveq #0,d2
move Séparation(pc),d2 d2=Largeur en octets entre 2 Btpls
move Nb_Plans(pc),d0
subq #1,d0
loop1 move.l d1,(a0)+ Mise en place de l'image
add.l d2,d1
dbf d0,loop1
move #$20,$dff09c demande d'interruption
movem.l (sp)+,d0-d2/a0
rte
*****
***** Décrunchage de l'image IFF
*****
DecrunchIFF
cmp.l #'FORM',(a4)
bne erreur
add.l #8,a4
cmp.l #'ILBM',(a4) Image Iff ?
bne erreur
add.l #8,a4
move.l (a4),d5 BMHD long
move.l 4(a4),X_ecr vals X et Y de l'ecran
move.b 12(a4),Nb_Plans+1 nombre de plans de bits
add.l d5,a4
add.l #8,a4
move.l a3,d6 adresse ou mettre les
beq.s noCMAP couleurs = 0 ?
move.l a4,a6 CMAP long
bsr IFFcols
noCMAP
move.L (a4)+,d5
add.l d5,a4
cherche cmp.l #'CAMG',(a4) modes de l'Amiga
bne.s recherche
move 10(a4),Mode_ecr
recherche cmp.l #'BODY',(a4) debut des données
lea 2(a4),a4
bne.s cherche
move.l 2(a4),d4
add.l #6,a4
move X_ecr(pc),d0 calcul de la taille de l'ecran
lsr #3,d0
move d0,X_ecr
mulu Y_ecr(pc),d0
mulu Nb_Plans(pc),d0
move.l d0,Taille_ecr
move.l #MEMF_CHIP|MEMF_CLEAR,d1
CALLEXEC AllocMem comme son nom l'indique
move.l d0,Adr_ecr
beq erreur
move.l d0,a5
Decrunch moveq #0,d5 * Décompactage
move.b (a4)+,d5
bmi.s crunch
sub.l d5,d4 < 128
recopy move.b (a4)+,(a5)+
dbf d5,recopy
bra.s test
crunch neg.b d5 > 128
move.b (a4)+,d6
rempli move.b d6,(a5)+
dbf d5,rempli
test subq.l #2,d4 code + 1er octet = 2
bhi.s Decrunch
moveq #0,d7
rts
IFFcols move.l (a6)+,d7
CMAP moveq #0,d6 * Décode les couleurs
move.b (a6),d6
lsl.w #4,d6 3 octets par couleurs (RGB)
move.b 2(a6),d6
lsr.b #4,d6
or.b 1(a6),d6
move d6,(a3)
add.l d3,a3
lea 3(a6),a6
subq.l #3,d7
bne.s CMAP
rts
erreur clr.l Taille_ecr
moveq #-1,d7
rts
LaceVal dc.l 0
Séparation dc.w 0
Mode_ecr dc.w 0
Nb_Plans dc.w 0
X_ecr dc.w 0
Y_ecr dc.w 0
Taille_ecr dc.l 0
Adr_ecr dc.l 0
*****
***** Image
*****
picture incbin "RLE_Image2.iff"
end
|
|