deflate — deflate-komprimering och -dekomprimering

Denna modul tillåter komprimering och dekomprimering av binärdata med DEFLATE-algoritmen (vanligt förekommande i zlib-biblioteket och gzip-arkiveraren). Tillagd i MicroPython v1.21.

Tillgänglighet på OpenMV-stödda kort:

Kort

Dekomprimering

Komprimering

OpenMV Cam N6

Ja

Nej

OpenMV AE3

Ja

Ja

OpenMV Cam RT1062

Ja

Ja

OpenMV Cam Pure Thermal

Ja

Nej

OpenMV Cam M4

Ja

Nej

OpenMV Cam M7

Ja

Nej

OpenMV Cam H7

Ja

Nej

OpenMV Cam H7 Plus

Ja

Nej

Arduino Giga

Ja

Nej

Arduino Portenta H7

Ja

Nej

Arduino Nicla Vision

Ja

Nej

Arduino Nano 33 BLE Sense

Ja

Nej

Arduino Nano RP2040 Connect

Ja

Nej

Klasser

class deflate.DeflateIO(stream: Any, format: int = AUTO, wbits: int = 0, close: bool = False, /)

Denna klass kan användas för att kapsla in en stream som är vilket strömliknande objekt som helst, såsom en fil, en socket eller en ström (inklusive io.BytesIO). Den är själv en ström och implementerar standardmetoderna read/readinto/write/close.

Strömmen stream måste vara en blockerande ström. Icke-blockerande strömmar stöds för närvarande inte.

Parametern format kan sättas till någon av de konstanter som definieras nedan, och har standardvärdet AUTO som vid dekomprimering automatiskt detekterar gzip- eller zlib-strömmar, och vid komprimering genererar en rå ström.

Parametern wbits anger 2-logaritmen av storleken på DEFLATE-ordbokens fönster. Om wbits till exempel sätts till 10 blir fönsterstorleken 1024 byte. Giltiga värden är 5 till 15 inklusive (motsvarande fönsterstorlekar på 32 till 32k byte).

Om wbits sätts till 0 (standardvärdet) används för komprimering en fönsterstorlek på 256 byte (som om wbits hade satts till 8). För dekomprimering beror det på formatet:

  • RAW använder 256 byte (motsvarande wbits satt till 8).

  • ZLIB (eller AUTO med zlib detekterat) använder värdet från zlib-huvudet.

  • GZIP (eller AUTO med gzip detekterat) använder 32 kilobyte (motsvarande wbits satt till 15).

Se anmärkningarna om fönsterstorlek nedan för mer information om fönsterstorlek samt zlib- och gzip-strömmar.

Om close sätts till True stängs den underliggande strömmen automatiskt när deflate.DeflateIO-strömmen stängs. Detta är användbart om du vill returnera en deflate.DeflateIO-ström som kapslar in en annan ström utan att anroparen behöver känna till hanteringen av den underliggande strömmen.

Om komprimering är aktiverad stöder en given deflate.DeflateIO-instans både läsning och skrivning. Till exempel kan en dubbelriktad ström som en socket kapslas in, vilket möjliggör komprimering/dekomprimering i båda riktningarna.

Konstanter

De fyra format-konstanterna väljer den inramning som tillämpas runt den råa deflate-bitströmmen.

deflate.AUTO: int

För dekomprimering, detektera indataformatet automatiskt genom att inspektera strömmens första byte (zlib eller gzip). För komprimering, generera en rå deflate-ström utan huvud eller släp (motsvarande RAW).

deflate.RAW: int

En rå deflate-ström (inget huvud, inget släp, ingen kontrollsumma). Eftersom strömmen inte innehåller någon metadata kan dekompressorn inte återskapa fönsterstorleken från datan, så wbits bör anges explicit vid dekomprimering – annars kan standardfönstret på 256 byte vara för litet.

deflate.ZLIB: int

En zlib-inkapslad deflate-ström enligt definitionen i RFC 1950: ett 2-bytes huvud som anger fönsterstorleken, deflate-nyttolasten och en avslutande Adler-32-kontrollsumma. Kompakt och självbeskrivande; väl lämpad för inbäddad användning.

deflate.GZIP: int

En gzip-inkapslad deflate-ström enligt definitionen i RFC 1952: ett huvud med valfri metadata för filnamn/tidsstämpel, deflate-nyttolasten och en avslutande CRC-32 plus okomprimerad längd. Detta är formatet som produceras av kommandoradsverktyget gzip och av gzip.GzipFile. Huvudet anger inte fönsterstorleken, så dekompressorn måste anta 32 KiB om inte wbits anges.

Exempel

Ett typiskt användningsfall för deflate.DeflateIO är att läsa eller skriva en komprimerad fil från lagring:

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.

Eftersom deflate.DeflateIO är en ström kan den till exempel användas med json.dump() och json.load() (och alla andra platser där strömmar kan användas):

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)

Om dina källdata inte är i ett strömformat kan du använda io.BytesIO för att omvandla dem till en ström som lämpar sig för användning med 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-fönsterstorlek

Fönsterstorleken begränsar hur långt tillbaka i strömmen (de)kompressorn kan referera. En ökad fönsterstorlek förbättrar komprimeringen, men kräver mer minne och gör kompressorn långsammare.

Om en indataström komprimerades med en given fönsterstorlek kommer DeflateIO med en mindre fönsterstorlek att misslyckas mitt under dekomprimeringen med OSError, men endast om en bakåtreferens faktiskt refererar längre tillbaka än dekompressorns fönsterstorlek. Detta innebär att det kan vara möjligt att dekomprimera med en mindre fönsterstorlek. Detta skulle till exempel trivialt vara fallet om de ursprungliga okomprimerade datan är kortare än fönsterstorleken.

Dekomprimering

zlib-formatet inkluderar ett huvud som anger den fönsterstorlek som användes för att komprimera datan. Detta indikerar den maximala fönsterstorlek som krävs för att dekomprimera strömmen. Om detta huvudvärde är mindre än det angivna wbits-värdet (eller om wbits inte är satt) används huvudvärdet.

gzip-formatet inkluderar inte fönsterstorleken i huvudet och antar att alla gzip-kompressorer (t.ex. verktyget gzip eller CPythons implementering av gzip.GzipFile) använder den maximala fönsterstorleken på 32 KiB. Av denna anledning kommer dekompressorn, om parametern wbits inte är satt, att använda en fönsterstorlek på 32 KiB (motsvarande wbits satt till 15). Detta innebär att du måste ha minst så här mycket RAM tillgängligt för att kunna dekomprimera en godtycklig gzip-ström. Om du kontrollerar källdatan, överväg istället att använda zlib-formatet med en mindre fönsterstorlek.

Det råa formatet har inget huvud och inkluderar därför ingen information om fönsterstorleken. Om wbits inte är satt får det standardvärdet 256 byte som fönsterstorlek, vilket kanske inte är tillräckligt stort för en given ström. Därför rekommenderas att du alltid explicit anger wbits om du använder det råa formatet.

Komprimering

För komprimering använder MicroPython som standard en fönsterstorlek på 256 byte för alla format. Detta ger en rimlig grad av komprimering med minimal minnesanvändning och snabb komprimeringstid, och genererar utdata som fungerar med vilken dekompressor som helst.