Codage par plages (RLE)

Tape n'importe quel texte et observe-le se diviser en plages — les répétitions consécutives du même caractère fusionnent en une seule paire (symbole, nombre). Les longues plages réduisent les données ; les courtes plages les font grossir.

Chargement de la simulation interactive...

Leçon

La théorie — Codage par plages (RLE)

Le codage par plages remplace chaque plage maximale de symboles identiques par un seul couple (symbole, compte). Ce qui arrive dans l’affichage n’est pas le texte mais deux nombres : N caractères et R plages. Toutes les autres valeurs de la page sont le quotient de ces deux-là.

Ce que signifie chaque symbole

N
le nombre de caractères en entrée — la longueur de ce que vous avez tapé, rien de plus.
R
le nombre de plages, c’est-à-dire de blocs maximaux d’un même symbole répété. R augmente de un partout où deux voisins diffèrent : il compte des frontières, pas des caractères.
N/R, la longueur moyenne des plages. C’est la seule quantité qui décide du résultat.
ratio
N/2R, soit L̄/2. Au-dessus de 1, la sortie est plus petite que l’entrée.

D’où vient la formule

  1. Comptez des plages, pas des caractères. Dans 0010111100001111 les voisins diffèrent en cinq endroits : il y a donc six plages et la ligne affiche R=6.
  2. La taille codée vaut 2R, et rien d’autre. Ce dont les plages sont faites n’entre jamais dans le calcul — six plages coûtent douze unités, qu’il s’agisse de pixels, de lettres ou de chiffres.
  3. Divisez : ratio = N/2R = L̄/2. L’équilibre se situe donc à L̄ = 2, et il est exactement atteignable — tapez AABB et les barres affichent 4 octets à l’entrée, 4 à la sortie.
  4. Les deux sens ne sont pas symétriques. Vers le haut, aucune limite : une seule plage d’un million de caractères se code en un couple. Vers le bas, le plancher est à 0.50× et ne peut être franchi, car le pire que puisse faire une entrée est de donner à chaque caractère sa propre plage.

Comment lire ce que vous voyez

Les quatre exemples font exactement seize caractères, ce qui vaut la peine de les lire comme un ensemble. Ligne d’image a trois plages et donne 6 octets. Plages classiques en a quatre et donne 8. Masque binaire en a six et donne 12. Pire cas en a seize et donne 32. Même longueur en entrée, et il sort de 6 à 32 octets — un facteur cinq, réglé entièrement par R. Tapez ensuite hello world : onze caractères, dix plages, 20 octets. La prose ordinaire se loge au bas de cette plage, et c’est toute la raison pour laquelle le codage par plages est un composant de compresseur plutôt qu’un compresseur.

Suppose
Qu’un couple coûte exactement 2 unités, qu’un symbole et un compte ont la même largeur, et qu’un compte peut être de taille quelconque. Les codeurs réels donnent au compte une largeur fixe — un octet, donc 255 — et doivent scinder une plage plus longue en plusieurs couples, ce qui remonte légèrement l’équilibre au-dessus de 2. L’hypothèse de largeur égale échoue le plus nettement là où le codage par plages excelle : dans un fax en 1 bit, le symbole tient sur un bit, le compte non.
Ne tient plus quand
Le plancher à 0.50× n’est pas un défaut qu’on pourrait supprimer par ingénierie. Un codeur sans perte doit être réversible : des entrées distinctes doivent donner des sorties distinctes, et il y a moins de chaînes courtes que de chaînes longues vers lesquelles envoyer. Tout procédé qui raccourcit ne serait-ce qu’une entrée en rallonge donc une autre. C’est un fait de dénombrement, pas une propriété du codage par plages. PackBits, dans le troisième éclairage ci-dessus, ramène son pire cas à un octet de contrôle pour 128 — moins de 1% — et personne ne va plus loin, car le plancher peut être abaissé sans limite mais jamais atteint. Le codage par plages se contente de porter ce coût à l’extérieur, dans un affichage qu’on peut regarder bouger.

pourquoi le seuil de rentabilité est exactement 2 🖖

Chaque plage — quelle que soit sa longueur — coûte le même stockage : 2 unités, une pour le symbole, une pour le nombre. Une plage de longueur L ne vaut la peine d'être codée que lorsque cela coûte moins que d'écrire L caractères bruts — c'est-à-dire quand L est supérieur à 2. En moyenne sur toute l'entrée, cette condition devient L̄ = N/R supérieur à 2, où N est la longueur totale et R le nombre de plages — exactement la limite que vérifie la formule ci-dessus. C'est aussi pourquoi le RLE est un mauvais compresseur généraliste : le texte anglais, le code source et les données aléatoires ont rarement des plages plus longues que 2, c'est pourquoi le RLE est réservé aux données conçues exprès pour avoir de longues plages — les scans fax en 1 bit, les bitmaps creux et les images à palette avec des aplats de couleur. Les formats réels poussent l'idée plus loin : le PNG applique un filtre delta Paeth/Sub/Up sur chaque ligne de balayage avant la compression, transformant d'abord les dégradés doux en longues plages de différences proches de zéro — le RLE (via DEFLATE) fait le reste. Essaie l'exemple du pire cas ci-dessus : seize caractères distincts donnent seize plages de longueur 1, donc le codage nécessite 32 unités pour stocker 16 caractères — l'entrée double de taille.

la compression qu'on inventerait soi-même 🖖

Le codage par plages est la seule idée de compression qu'on pourrait réinventer tout seul : au lieu d'écrire WWWWWWW lettre par lettre, on dit simplement "7 W" — le même raccourci qu'on emploie en lisant "trois fois sept" dans un numéro de téléphone. Il parcourt les données en une seule passe de gauche à droite et ne retient rien au-delà de la plage qu'il compte, ce qui le rend rapide et facile à diffuser en flux. Et il est sans perte : à partir des paires (symbole, compte) on reconstruit l'original à l'identique, contrairement au JPEG ou au MP3, qui jettent le détail pour de bon.

le cousin du RLE qui ne peut pas gonfler 🖖

Le RLE naïf peut doubler des données incompressibles, mais la variante PackBits d'Apple — née dans le MacPaint des années 1980 et toujours un mode de compression standard du TIFF — est conçue pour ne presque jamais grossir. Chaque bloc commence par un octet de contrôle signé : une valeur non négative signifie "les octets suivants sont littéraux", une valeur négative "répète l'octet suivant". Les données uniques sont copiées telles quelles par blocs allant jusqu'à 128 octets, si bien que le pire cas n'ajoute qu'un octet de contrôle pour 128 — moins de 1 % de surcoût au lieu des 100 % que le RLE naïf peut atteindre.

Problème entièrement résolu

  1. Encodage par plages de AAAAAABBBCCDDDDD en quatre paires 5 étapes

    Le codage par plages transforme AAAAAABBBCCDDDDD en quatre paires. Calculez la compression, puis la condition exacte sous laquelle ce schéma rend un fichier plus grand.

    1. Le codage est le plus évident : remplacer chaque plage par le caractère et sa longueur. Seize caractères se réduisent ainsi à quatre paires.

    2. Deux nombres décrivent toute entrée de ce schéma — sa longueur et son nombre de plages — et leur rapport donne la longueur moyenne des plages. Ici, il vaut 4.

    3. Comptons maintenant rigoureusement. Chaque paire coûte deux symboles, un caractère et un décompte, la sortie est donc de 2R pour une entrée de N. Rien d'autre concernant les données n'importe.

    4. Le schéma est donc gagnant exactement lorsque 2R < N, ce qui équivaut à une longueur moyenne de plage supérieure à 2. Ici, 8 contre 16 — une réduction de moitié nette — et la ligne de verdict sur le panneau indique la même chose en un seul symbole.

    5. En dessous de ce seuil, il est perdant, et pour une longueur moyenne de plage de 1, il perd de manière maximale : chaque caractère devient une paire, doublant la taille du fichier.

    Réponse

    L'outil affiche N = 16 et R = 4, une longueur moyenne de plage de 4 et un gain de 2×. La condition essentielle à retenir est la suivante : le codage RLE compresse si et seulement si les plages mesurent en moyenne plus de deux, et c'est l'un des rares schémas de compression dont le point de rentabilité est un nombre unique vérifiable à l'œil nu. Saisissez ABCD dans la zone de texte et observez la taille doubler. Ce n'est pas un défaut — c'est la raison pour laquelle le RLE ne survit que là où les plages sont garanties par construction : lignes de balayage de fax, bitmaps creux, et zones unies d'un JPEG après quantification, jamais sur du texte général.

Parcours

La compression à la main

Mène à Huffman l'idée dans sa forme la plus simple : remplacer une suite de symboles identiques par le symbole et une quantité.

Références (3)

Exemples de problèmes

  • Plages classiques - "AAAAAABBBCCDDDDD" → (A,6)(B,3)(C,2)(D,5) — 16 caractères réduits à 8 paires
  • Pire cas - "ABCDEFGHIJKLMNOP" — tous les caractères sont uniques, chaque paire est plus longue que l'original
  • Masque bitmap - "0010111100001111" — ligne de pixels montrant pourquoi PNG préfiltre avant le RLE
  • Ligne de balayage d'image - "WWWWWWWBBBBBWWWW" — ligne d'image N&B simple, forte structure de suites répétées