unccfi

Menu principal

Le programme unccfi est un outil en ligne de commande développé en C qui permet de décompresser les images disques .CFI produites par l'utilitaire FDCOPY.COM d'Amstrad.

Description

Il est placé sous licence GNU GPL v3.

L’utilitaire FDCOPY.COM d'Amstrad permet de compresser des images de disquettes en utilisant un algorithme de type RLE (Run-length encoding). La mise en œuvre est simple, nécessite peu de puissance de calcul et demeure très efficace sur des images disques.

Le format de ces fichiers est également simplifié à l'extrême. Il est décrit sur la page FDCOPY file format.

unccfi ne permet que la décompression de ces fichiers.

Téléchargement

Le code source de cet utilitaire est disponible en téléchargement. Le code est suffisamment simple pour pouvoir être compilé sur une grande majorité de compilateur C.

Télécharger unccfi-1.0.tar.xz Taille du fichier : 12,4 ko

Compilation

Pour décompresser l’archive :

shell
tar xzvf unccfi-1.0.tar.xz

Une fois décompressée l'archive présente le dossier suivant :

unccfi-1.0

Pour compiler unccfi , vous devez disposer du compilateur gcc, une installation minimale étant suffisante. Placez-vous dans le répertoire unccfi-1.0 et tapez la commande suivante :

shell
make unccfi

Si tout se passe bien, un exécutable unccfi est créé dans le répertoire.

Utilisation

Pour utiliser unccfi, il faut que l'exécutable soit dans un répertoire pointé par la variable d'environnement PATH ou préciser son chemin complet lors de l'appel.

L’utilitaire est basique. Il prend un fichier .CFI en entrée standard et le décompresse sur la sortie standard.

Il peut être utilisé de la façon suivante :

shell
cat FILE.CFI | unccfi > FILE.IMG

Il faut bien sûr remplacer FILE.CFI par la fichier à décompresser et FILE.IMG par le nom du fichier que l'on cherche à créer.

Code source

c
#include <stdio.h>

int main() {
	while(!feof(stdin)) {
		/* The CFI file is composed of tracks which starts with the track
		 * length 
		 */
		int tracklength = getchar() + 256 * getchar();

		while(tracklength > 0) {
			/* A track is composed of compressed or uncompressed blocks */
			int blocklength = getchar() + getchar() * 256;

			/* Checks whether the block is compressed or not */
			if(blocklength >= 0x8000) {
				int torepeat;

				/* The block is compressed, it occupies 3 bytes */
				tracklength -= 3;

				/* Calculate the number of repeats */
				blocklength -= 0x8000;

				/* Get the byte to repeat */
				torepeat = getchar();

				/* Output the character blocklength times */
				for(; blocklength > 0; blocklength--) putchar(torepeat);
			} else {
				/* The block is uncompressed */
				/* It occupies blocklength + 2 bytes */
				tracklength -= blocklength + 2;

				/* Directly stream blocklength bytes from stdin to stdout */
				for(; blocklength > 0; blocklength--) putchar(getchar());
			}
		}
	}

	/* Everything went well, maybe */
	return 0;
}