deflate — compression et décompression deflate¶
Ce module permet la compression et la décompression de données binaires avec l”algorithme DEFLATE (couramment utilisé dans la bibliothèque zlib et l’archiveur gzip). Ajouté dans MicroPython v1.21.
Disponibilité sur les cartes prises en charge par OpenMV :
Carte |
Décompression |
Compression |
|---|---|---|
OpenMV Cam N6 |
Oui |
Non |
OpenMV AE3 |
Oui |
Oui |
OpenMV Cam RT1062 |
Oui |
Oui |
OpenMV Cam Pure Thermal |
Oui |
Non |
OpenMV Cam M4 |
Oui |
Non |
OpenMV Cam M7 |
Oui |
Non |
OpenMV Cam H7 |
Oui |
Non |
OpenMV Cam H7 Plus |
Oui |
Non |
Arduino Giga |
Oui |
Non |
Arduino Portenta H7 |
Oui |
Non |
Arduino Nicla Vision |
Oui |
Non |
Arduino Nano 33 BLE Sense |
Oui |
Non |
Arduino Nano RP2040 Connect |
Oui |
Non |
Classes¶
- class deflate.DeflateIO(stream: Any, format: int = AUTO, wbits: int = 0, close: bool = False, /)¶
Cette classe peut être utilisée pour envelopper un stream, c’est-à-dire tout objet de type flux tel qu’un fichier, un socket ou un flux (y compris
io.BytesIO). Elle est elle-même un flux et implémente les méthodes standard read/readinto/write/close.Le stream doit être un flux bloquant. Les flux non bloquants ne sont actuellement pas pris en charge.
Le paramètre format peut prendre n’importe laquelle des constantes définies ci-dessous, et vaut par défaut
AUTOqui, pour la décompression, détecte automatiquement les flux gzip ou zlib, et pour la compression génère un flux brut.Le paramètre wbits définit le logarithme en base 2 de la taille de la fenêtre du dictionnaire DEFLATE. Par exemple, régler wbits à
10fixe la taille de la fenêtre à 1024 octets. Les valeurs valides vont de5à15inclus (correspondant à des tailles de fenêtre de 32 à 32k octets).Si wbits est réglé à
0(la valeur par défaut), alors pour la compression une taille de fenêtre de 256 octets sera utilisée (comme si wbits valait 8). Pour la décompression, cela dépend du format :RAWutilisera 256 octets (correspondant à wbits réglé à 8).ZLIB(ouAUTOavec zlib détecté) utilisera la valeur de l’en-tête zlib.GZIP(ouAUTOavec gzip détecté) utilisera 32 kilo-octets (correspondant à wbits réglé à 15).
Consultez les notes sur la taille de fenêtre ci-dessous pour plus d’informations sur la taille de fenêtre et les flux zlib et gzip.
Si close est réglé à
True, alors le flux sous-jacent sera fermé automatiquement lorsque le fluxdeflate.DeflateIOest fermé. C’est utile si vous souhaitez renvoyer un fluxdeflate.DeflateIOqui enveloppe un autre flux sans que l’appelant ait besoin de gérer le flux sous-jacent.Si la compression est activée, une instance
deflate.DeflateIOdonnée prend en charge à la fois la lecture et l’écriture. Par exemple, un flux bidirectionnel comme un socket peut être enveloppé, ce qui permet la compression/décompression dans les deux sens.
Constantes¶
Les quatre constantes format sélectionnent l’encadrement appliqué autour du flux de bits deflate brut.
- deflate.AUTO: int¶
Pour la décompression, détecte automatiquement le format d’entrée en inspectant les premiers octets du flux (zlib ou gzip). Pour la compression, génère un flux deflate brut sans en-tête ni fin de trame (équivalent à
RAW).
- deflate.RAW: int¶
Un flux deflate brut (pas d’en-tête, pas de fin de trame, pas de somme de contrôle). Comme le flux ne contient aucune métadonnée, le décompresseur ne peut pas retrouver la taille de fenêtre à partir des données ; wbits doit donc être réglé explicitement lors de la décompression — sinon la fenêtre par défaut de 256 octets risque d’être trop petite.
- deflate.ZLIB: int¶
Un flux deflate encapsulé en zlib tel que défini par RFC 1950 : un en-tête de 2 octets qui enregistre la taille de fenêtre, la charge utile deflate, et une somme de contrôle Adler-32 en fin de trame. Compact et auto-descriptif ; bien adapté à un usage embarqué.
- deflate.GZIP: int¶
Un flux deflate encapsulé en gzip tel que défini par RFC 1952 : un en-tête avec des métadonnées optionnelles de nom de fichier/horodatage, la charge utile deflate, et un CRC-32 en fin de trame suivi de la longueur non compressée. C’est le format produit par l’outil en ligne de commande
gzipet pargzip.GzipFile. L’en-tête n’enregistre pas la taille de fenêtre, le décompresseur doit donc supposer 32 Kio à moins que wbits ne soit défini.
Exemples¶
Un cas d’usage typique de deflate.DeflateIO consiste à lire ou écrire un fichier compressé depuis le stockage :
import deflate
# Writing a zlib-compressed stream (uses the default window size of 256 bytes).
with open("data.z", "wb") as f:
with deflate.DeflateIO(f, deflate.ZLIB) as d:
# Use d.write(...) etc
# Reading a zlib-compressed stream (auto-detect window size).
with open("data.z", "rb") as f:
with deflate.DeflateIO(f, deflate.ZLIB) as d:
# Use d.read(), d.readinto(), etc.
Comme deflate.DeflateIO est un flux, il peut être utilisé par exemple avec json.dump() et json.load() (et partout ailleurs où des flux peuvent être utilisés) :
import deflate, json
# Write a dictionary as JSON in gzip format, with a
# small (64 byte) window size.
config = { ... }
with open("config.gz", "wb") as f:
with deflate.DeflateIO(f, deflate.GZIP, 6) as f:
json.dump(config, f)
# Read back that dictionary.
with open("config.gz", "rb") as f:
with deflate.DeflateIO(f, deflate.GZIP, 6) as f:
config = json.load(f)
Si vos données source ne sont pas dans un format de flux, vous pouvez utiliser io.BytesIO pour les transformer en un flux utilisable avec deflate.DeflateIO :
import deflate, io
# Decompress a bytes/bytearray value.
compressed_data = get_data_z()
with deflate.DeflateIO(io.BytesIO(compressed_data), deflate.ZLIB) as d:
decompressed_data = d.read()
# Compress a bytes/bytearray value.
uncompressed_data = get_data()
stream = io.BytesIO()
with deflate.DeflateIO(stream, deflate.ZLIB) as d:
d.write(uncompressed_data)
compressed_data = stream.getvalue()
Taille de la fenêtre deflate¶
La taille de la fenêtre limite jusqu’où dans le flux le (dé)compresseur peut faire référence. Augmenter la taille de la fenêtre améliore la compression, mais nécessite plus de mémoire et rend le compresseur plus lent.
Si un flux d’entrée a été compressé avec une taille de fenêtre donnée, alors DeflateIO utilisant une taille de fenêtre plus petite échouera en cours de décompression avec OSError, mais seulement si une référence arrière renvoie effectivement plus loin que la taille de fenêtre du décompresseur. Cela signifie qu’il peut être possible de décompresser avec une taille de fenêtre plus petite. Par exemple, ce serait trivialement le cas si les données non compressées d’origine sont plus courtes que la taille de la fenêtre.
Décompression¶
Le format zlib comprend un en-tête qui spécifie la taille de fenêtre utilisée pour compresser les données. Cela indique la taille de fenêtre maximale requise pour décompresser ce flux. Si cette valeur d’en-tête est inférieure à la valeur wbits spécifiée (ou si wbits n’est pas défini), alors la valeur de l’en-tête sera utilisée.
Le format gzip n’inclut pas la taille de fenêtre dans l’en-tête, et suppose que tous les compresseurs gzip (par exemple l’utilitaire gzip, ou l’implémentation de gzip.GzipFile par CPython) utilisent la taille de fenêtre maximale de 32 Kio. Pour cette raison, si le paramètre wbits n’est pas défini, le décompresseur utilisera une taille de fenêtre de 32 Kio (correspondant à wbits réglé à 15). Cela signifie que pour pouvoir décompresser un flux gzip arbitraire, vous devez disposer d’au moins cette quantité de RAM. Si vous contrôlez les données source, envisagez plutôt d’utiliser le format zlib avec une taille de fenêtre plus petite.
Le format raw n’a pas d’en-tête et n’inclut donc aucune information sur la taille de fenêtre. Si wbits n’est pas défini, il prendra par défaut une taille de fenêtre de 256 octets, qui peut ne pas être suffisante pour un flux donné. Il est donc recommandé de toujours définir explicitement wbits lors de l’utilisation du format raw.
Compression¶
Pour la compression, MicroPython utilise par défaut une taille de fenêtre de 256 octets pour tous les formats. Cela offre un taux de compression raisonnable avec une utilisation mémoire minimale et un temps de compression rapide, et génère une sortie qui fonctionnera avec n’importe quel décompresseur.