Obligement - L'Amiga au maximum

Samedi 31 mai 2025 - 17:08  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

Actualité (récente)
Actualité (archive)
Comparatifs
Dossiers
Entrevues
Matériel (tests)
Matériel (bidouilles)
Points de vue
En pratique
Programmation
Reportages
Quizz
Tests de jeux
Tests de logiciels
Tests de compilations
Trucs et astuces
Articles divers

Articles in English


Réseaux sociaux

Suivez-nous sur X




Liste des jeux Amiga

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


Trucs et astuces

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


Glossaire

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


Galeries

Menu des galeries

BD d'Amiga Spécial
Caricatures Dudai
Caricatures Jet d'ail
Diagrammes de Jay Miner
Images insolites
Fin de jeux (de A à E)
Fin de Jeux (de F à O)
Fin de jeux (de P à Z)
Galerie de Mike Dafunk
Logos d'Obligement
Pubs pour matériels
Systèmes d'exploitation
Trombinoscope Alchimie 7
Vidéos


Téléchargement

Documents
Jeux
Logiciels
Magazines
Divers


Liens

Associations
Jeux
Logiciels
Matériel
Magazines et médias
Pages personnelles
Réparateurs
Revendeurs
Scène démo
Sites de téléchargement
Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


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.

compression

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


[Retour en haut] / [Retour aux articles]