Compression et encodage de données
La compression de données est un domaine très vaste et très important en informatique. Il existe de nombreuses techniques de compression, qui sont utilisées dans de nombreux domaines : compression d'images, compression de vidéos, compression de fichiers, etc.
Dans ce cours nous allons découvrir des techniques de compression très répandue :
- Le codage par plages (ou run-length encoding)
- le codage de Huffman
Nous allons voir comment ils fonctionnent, et comment les implémenter en C++.
Compression de données
La compression de données est une technique qui permet de réduire la taille des données. Cela permet de stocker plus de données sur un support de stockage, ou de transmettre les données plus rapidement sur un réseau.
C'est un domaine crucial en informatique moderne. Sans la compression de données, il serait impossible de stocker des milliers de photos sur un téléphone portable, ou de regarder des vidéos en streaming sur Internet.
Il existe deux types de compression de données : la compression avec perte et la compression sans perte. La compression avec perte permet de réduire la taille des données, mais on ne garantit pas que les données décompressées seront identiques aux données d'origine. C'est le cas par exemple de la compression d'images au format JPEG où la perte de qualité est relativement maîtrisée pour cela soit le moins perceptible par l'œil humain. La compression sans perte permet de retrouver les données d'origine après les avoir décompressées. C'est le cas par exemple de la compression d'images au format PNG.
Le format JPEG est un format de compression avec perte.Le processus de compression JPEG est assez complexe et est composé de plusieurs étapes. Certaines de ces étapes sont des étapes de compression avec perte, et d'autres sont des étapes de compression sans perte (dont l'encodage RLE et l'encodage de Huffman que nous allons voir dans ce cours). C'est pour cela que l'on dit que le format JPEG est un format de compression avec perte.
Prérequis
Pour ce cours, il est nécessaire de connaître quelques notions de base sur la représentation des données en informatique. Voici un résumé des notions à connaître :
-
Un bit est la plus petite unité de stockage en informatique. Il ne peut prendre que deux valeurs : 0 ou 1. Un octet est un groupe de 8 bits. Il peut donc prendre 256 valeurs différentes (de 0 à 255).
-
Chaque donnée peut être représentée par une suite de bits. Par exemple, le nombre 42 peut être représenté en binaire par la suite de bits
101010. Avec un octet, on peut représenter au maximum 256 nombres différents. -
Un caractère est généralement codé sur un octet (cela peut dépendre de l'encodage utilisé). Cela signifie que l'on peut représenter 256 caractères différents. Cela inclut les lettres de l'alphabet, les chiffres, les caractères spéciaux, etc.
Encodage et représentation des données
Un encodage est une manière de représenter les données. Par exemple, on peut représenter le nombre 42 de la manière suivante : 101010. C'est un encodage binaire. On peut aussi représenter le nombre 42 de la manière suivante : 2A. C'est un encodage hexadécimal.
Encoder des données revient à associer à chaque donnée un code.
Dans la suite de ce cours nous allons nous intéresser à l'encodage binaire. C'est l'encodage utilisé par les ordinateurs et qui permet de représenter les données de manière la plus compacte possible. C'est aussi l'encodage utilisé par les algorithmes de compression.
Dans un fichier texte, chaque lettre est représentée par un caractère. Ce caractère est généralement encodé sur un octet. Cela signifie que l'on peut représenter au maximum 256 caractères différents. Cela inclut les lettres de l'alphabet, les chiffres, les caractères spéciaux, etc.
Mais cela dépend des données du problème. Cet encodage sur un octet est simplement une convention qui permet d'associer à chaque caractère un code unique et d'uniformiser la manière dont les caractères sont représentés (chaque caractère est représenté par un octet). C'est bien pratique et flexible pour communiquer des fichiers texte entre ordinateurs.
Compression
Mais généralement lorsqu'il s'agit de compresser des données, les données du problème sont plus simples. Par exemple on pourrait se limiter aux lettres de l'alphabet. Dans ce cas, avoir un octet pour représenter chaque lettre est une perte d'espace. En effet, on pourrait se contenter de 5 bits pour représenter les 26 lettres de l'alphabet. Cela permettrait de réduire la taille du texte de 37.5% !
Plus généralement, si on se limite à n possibilités de données et que l'on souhaite utiliser un encodage avec le même nombre de bits pour chaque donnée, il faut bits pour représenter chaque donnée.
Par exemple, si on se limite aux 26 lettres de l'alphabet, il faut