deflate — deflate-compressie en -decompressie¶
Deze module maakt compressie en decompressie van binaire data mogelijk met het DEFLATE-algoritme (veelgebruikt in de zlib-bibliotheek en de gzip-archiver). Toegevoegd in MicroPython v1.21.
Beschikbaarheid op door OpenMV ondersteunde boards:
Board |
Decompressie |
Compressie |
|---|---|---|
OpenMV Cam N6 |
Ja |
Nee |
OpenMV AE3 |
Ja |
Ja |
OpenMV Cam RT1062 |
Ja |
Ja |
OpenMV Cam Pure Thermal |
Ja |
Nee |
OpenMV Cam M4 |
Ja |
Nee |
OpenMV Cam M7 |
Ja |
Nee |
OpenMV Cam H7 |
Ja |
Nee |
OpenMV Cam H7 Plus |
Ja |
Nee |
Arduino Giga |
Ja |
Nee |
Arduino Portenta H7 |
Ja |
Nee |
Arduino Nicla Vision |
Ja |
Nee |
Arduino Nano 33 BLE Sense |
Ja |
Nee |
Arduino Nano RP2040 Connect |
Ja |
Nee |
Klassen¶
- class deflate.DeflateIO(stream: Any, format: int = AUTO, wbits: int = 0, close: bool = False, /)¶
Deze klasse kan worden gebruikt om een stream te omhullen, wat elk stream-achtig object kan zijn, zoals een bestand, socket of stream (waaronder
io.BytesIO). Het is zelf een stream en implementeert de standaardmethoden read/readinto/write/close.De stream moet een blokkerende stream zijn. Niet-blokkerende streams worden momenteel niet ondersteund.
De format kan worden ingesteld op een van de hieronder gedefinieerde constanten, en is standaard
AUTO, wat bij decompressie automatisch gzip- of zlib-streams detecteert, en bij compressie een ruwe stream genereert.De parameter wbits stelt de logaritme met grondtal 2 van de venstergrootte van het DEFLATE-woordenboek in. Door wbits bijvoorbeeld op
10te zetten, wordt de venstergrootte op 1024 bytes ingesteld. Geldige waarden zijn5tot en met15(overeenkomend met venstergroottes van 32 tot 32k bytes).Als wbits op
0is ingesteld (de standaardwaarde), wordt bij compressie een venstergrootte van 256 bytes gebruikt (alsof wbits op 8 was ingesteld). Bij decompressie hangt het af van het formaat:RAWgebruikt 256 bytes (overeenkomend met wbits ingesteld op 8).ZLIB(ofAUTOmet zlib gedetecteerd) gebruikt de waarde uit de zlib-header.GZIP(ofAUTOmet gzip gedetecteerd) gebruikt 32 kilobytes (overeenkomend met wbits ingesteld op 15).
Zie de opmerkingen over de venstergrootte hieronder voor meer informatie over de venstergrootte en zlib- en gzip-streams.
Als close op
Trueis ingesteld, wordt de onderliggende stream automatisch gesloten wanneer dedeflate.DeflateIO-stream wordt gesloten. Dit is handig als je eendeflate.DeflateIO-stream wilt teruggeven die een andere stream omhult, zonder dat de aanroeper het beheer van de onderliggende stream hoeft te kennen.Als compressie is ingeschakeld, ondersteunt een gegeven
deflate.DeflateIO-instantie zowel lezen als schrijven. Zo kan bijvoorbeeld een bidirectionele stream zoals een socket worden omhuld, wat compressie/decompressie in beide richtingen mogelijk maakt.
Constanten¶
De vier format-constanten selecteren de framing die rond de ruwe deflate-bitstream wordt toegepast.
- deflate.AUTO: int¶
Detecteer bij decompressie automatisch het invoerformaat door de eerste bytes van de stream te inspecteren (zlib of gzip). Genereer bij compressie een ruwe deflate-stream zonder header of trailer (gelijkwaardig aan
RAW).
- deflate.RAW: int¶
Een ruwe deflate-stream (geen header, geen trailer, geen checksum). Omdat de stream geen metadata bevat, kan de decompressor de venstergrootte niet uit de data herstellen, dus moet wbits expliciet worden ingesteld bij decompressie – anders kan het standaardvenster van 256 bytes te klein zijn.
- deflate.ZLIB: int¶
Een in zlib verpakte deflate-stream zoals gedefinieerd door RFC 1950: een header van 2 bytes die de venstergrootte vastlegt, de deflate-payload en een afsluitende Adler-32-checksum. Compact en zelfbeschrijvend; goed geschikt voor embedded gebruik.
- deflate.GZIP: int¶
Een in gzip verpakte deflate-stream zoals gedefinieerd door RFC 1952: een header met optionele metadata zoals bestandsnaam/tijdstempel, de deflate-payload, en een afsluitende CRC-32 plus ongecomprimeerde lengte. Dit is het formaat dat wordt geproduceerd door de opdrachtregeltool
gzipen doorgzip.GzipFile. De header legt de venstergrootte niet vast, dus de decompressor moet 32 KiB aannemen tenzij wbits is ingesteld.
Voorbeelden¶
Een typisch gebruiksscenario voor deflate.DeflateIO is het lezen of schrijven van een gecomprimeerd bestand vanaf opslag:
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.
Omdat deflate.DeflateIO een stream is, kan het bijvoorbeeld worden gebruikt met json.dump() en json.load() (en op alle andere plaatsen waar streams kunnen worden gebruikt):
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)
Als je brondata niet in een streamformaat is, kun je io.BytesIO gebruiken om er een stream van te maken die geschikt is voor gebruik met 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()
Deflate-venstergrootte¶
De venstergrootte beperkt hoe ver terug in de stream de (de)compressor kan refereren. Het vergroten van de venstergrootte verbetert de compressie, maar vereist meer geheugen en maakt de compressor trager.
Als een invoerstream met een bepaalde venstergrootte werd gecomprimeerd, dan zal DeflateIO met een kleinere venstergrootte halverwege de decompressie mislukken met OSError, maar alleen als een terugverwijzing daadwerkelijk verder terug verwijst dan de venstergrootte van de decompressor. Dit betekent dat decompressie met een kleinere venstergrootte mogelijk kan zijn. Dit zou bijvoorbeeld triviaal het geval zijn als de oorspronkelijke ongecomprimeerde data korter is dan de venstergrootte.
Decompressie¶
Het zlib-formaat bevat een header die de venstergrootte aangeeft die werd gebruikt om de data te comprimeren. Dit geeft de maximale venstergrootte aan die nodig is om deze stream te decomprimeren. Als deze headerwaarde kleiner is dan de opgegeven wbits-waarde (of als wbits niet is ingesteld), wordt de headerwaarde gebruikt.
Het gzip-formaat bevat de venstergrootte niet in de header en gaat ervan uit dat alle gzip-compressors (bijv. het hulpprogramma gzip of CPython’s implementatie van gzip.GzipFile) de maximale venstergrootte van 32 KiB gebruiken. Om deze reden gebruikt de decompressor, als de parameter wbits niet is ingesteld, een venstergrootte van 32 KiB (overeenkomend met wbits ingesteld op 15). Dit betekent dat je minstens zoveel RAM beschikbaar moet hebben om een willekeurige gzip-stream te kunnen decomprimeren. Als je controle hebt over de brondata, overweeg dan in plaats daarvan het zlib-formaat met een kleinere venstergrootte.
Het ruwe formaat heeft geen header en bevat daarom geen informatie over de venstergrootte. Als wbits niet is ingesteld, wordt standaard een venstergrootte van 256 bytes gebruikt, wat mogelijk niet groot genoeg is voor een bepaalde stream. Daarom wordt aanbevolen wbits altijd expliciet in te stellen bij gebruik van het ruwe formaat.
Compressie¶
Voor compressie gebruikt MicroPython standaard een venstergrootte van 256 bytes voor alle formaten. Dit biedt een redelijke mate van compressie met minimaal geheugengebruik en een snelle compressietijd, en genereert uitvoer die met elke decompressor werkt.