deflate — compressione e decompressione deflate

Questo modulo consente la compressione e la decompressione di dati binari con l”algoritmo DEFLATE (comunemente usato nella libreria zlib e nell’archiviatore gzip). Aggiunto in MicroPython v1.21.

Disponibilità sulle schede supportate da OpenMV:

Scheda

Decompressione

Compressione

OpenMV Cam N6

No

OpenMV AE3

OpenMV Cam RT1062

OpenMV Cam Pure Thermal

No

OpenMV Cam M4

No

OpenMV Cam M7

No

OpenMV Cam H7

No

OpenMV Cam H7 Plus

No

Arduino Giga

No

Arduino Portenta H7

No

Arduino Nicla Vision

No

Arduino Nano 33 BLE Sense

No

Arduino Nano RP2040 Connect

No

Classi

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

Questa classe può essere usata per incapsulare uno stream che è un qualsiasi oggetto simile a uno stream come un file, un socket o uno stream (incluso io.BytesIO). È essa stessa uno stream e implementa i metodi standard read/readinto/write/close.

Lo stream deve essere uno stream bloccante. Gli stream non bloccanti attualmente non sono supportati.

Il parametro format può essere impostato a una qualsiasi delle costanti definite di seguito, e il valore predefinito è AUTO che per la decompressione rileverà automaticamente gli stream gzip o zlib, mentre per la compressione genererà uno stream raw.

Il parametro wbits imposta il logaritmo in base 2 della dimensione della finestra del dizionario DEFLATE. Quindi, per esempio, impostando wbits a 10 si imposta la dimensione della finestra a 1024 byte. I valori validi vanno da 5 a 15 inclusi (corrispondenti a dimensioni della finestra da 32 a 32k byte).

Se wbits è impostato a 0 (il valore predefinito), allora per la compressione verrà usata una dimensione della finestra di 256 byte (come se wbits fosse impostato a 8). Per la decompressione, dipende dal formato:

  • RAW userà 256 byte (corrispondenti a wbits impostato a 8).

  • ZLIB (o AUTO con zlib rilevato) userà il valore dell’header zlib.

  • GZIP (o AUTO con gzip rilevato) userà 32 kilobyte (corrispondenti a wbits impostato a 15).

Vedi le note sulla dimensione della finestra più avanti per maggiori informazioni sulla dimensione della finestra e sugli stream zlib e gzip.

Se close è impostato a True allora lo stream sottostante verrà chiuso automaticamente quando lo stream deflate.DeflateIO viene chiuso. Questo è utile se vuoi restituire uno stream deflate.DeflateIO che incapsula un altro stream senza che il chiamante debba preoccuparsi di gestire lo stream sottostante.

Se la compressione è abilitata, una data istanza deflate.DeflateIO supporta sia la lettura che la scrittura. Per esempio, è possibile incapsulare uno stream bidirezionale come un socket, il che consente la compressione/decompressione in entrambe le direzioni.

Costanti

Le quattro costanti format selezionano l’incapsulamento applicato attorno al bit-stream deflate grezzo.

deflate.AUTO: int

Per la decompressione, rileva automaticamente il formato dell’input ispezionando i primi byte dello stream (zlib o gzip). Per la compressione, genera uno stream deflate grezzo senza header né trailer (equivalente a RAW).

deflate.RAW: int

Uno stream deflate grezzo (nessun header, nessun trailer, nessun checksum). Poiché lo stream non contiene metadati, il decompressore non può recuperare la dimensione della finestra dai dati, quindi wbits dovrebbe essere impostato esplicitamente durante la decompressione — altrimenti la finestra predefinita di 256 byte potrebbe essere troppo piccola.

deflate.ZLIB: int

Uno stream deflate incapsulato in zlib come definito da RFC 1950: un header di 2 byte che registra la dimensione della finestra, il payload deflate e un checksum Adler-32 finale. Compatto e auto-descrittivo; ben adatto all’uso in ambito embedded.

deflate.GZIP: int

Uno stream deflate incapsulato in gzip come definito da RFC 1952: un header con metadati opzionali di nome file/timestamp, il payload deflate e un CRC-32 finale più la lunghezza non compressa. Questo è il formato prodotto dallo strumento da riga di comando gzip e da gzip.GzipFile. L’header non registra la dimensione della finestra, quindi il decompressore deve assumere 32 KiB a meno che wbits non sia impostato.

Esempi

Un caso d’uso tipico di deflate.DeflateIO è leggere o scrivere un file compresso dalla memoria:

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.

Poiché deflate.DeflateIO è uno stream, può essere usato per esempio con json.dump() e json.load() (e in qualsiasi altro punto in cui possono essere usati gli stream):

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)

Se i tuoi dati di origine non sono in formato stream, puoi usare io.BytesIO per trasformarli in uno stream adatto all’uso con 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()

Dimensione della finestra deflate

La dimensione della finestra limita quanto indietro nello stream il (de)compressore può fare riferimento. Aumentare la dimensione della finestra migliorerà la compressione, ma richiederà più memoria e renderà il compressore più lento.

Se uno stream di input è stato compresso con una data dimensione della finestra, allora DeflateIO che usa una dimensione della finestra più piccola fallirà a metà durante la decompressione con OSError, ma solo se un riferimento all’indietro fa effettivamente riferimento più indietro rispetto alla dimensione della finestra del decompressore. Ciò significa che potrebbe essere possibile decomprimere con una dimensione della finestra più piccola. Per esempio, questo sarebbe banalmente vero se i dati originali non compressi fossero più corti della dimensione della finestra.

Decompressione

Il formato zlib include un header che specifica la dimensione della finestra usata per comprimere i dati. Questo indica la dimensione massima della finestra richiesta per decomprimere questo stream. Se questo valore dell’header è inferiore al valore wbits specificato (o se wbits non è impostato), verrà usato il valore dell’header.

Il formato gzip non include la dimensione della finestra nell’header e presume che tutti i compressori gzip (ad esempio l’utilità gzip o l’implementazione di gzip.GzipFile di CPython) usino la dimensione massima della finestra di 32 kiB. Per questo motivo, se il parametro wbits non è impostato, il decompressore userà una dimensione della finestra di 32 kiB (corrispondente a wbits impostato a 15). Ciò significa che per poter decomprimere uno stream gzip arbitrario devi disporre almeno di questa quantità di RAM. Se controlli i dati di origine, considera invece l’uso del formato zlib con una dimensione della finestra più piccola.

Il formato raw non ha header e quindi non include alcuna informazione sulla dimensione della finestra. Se wbits non è impostato, assumerà come valore predefinito una dimensione della finestra di 256 byte, che potrebbe non essere abbastanza grande per un dato stream. Pertanto si raccomanda di impostare sempre esplicitamente wbits quando si usa il formato raw.

Compressione

Per la compressione, MicroPython userà come valore predefinito una dimensione della finestra di 256 byte per tutti i formati. Questo fornisce una quantità ragionevole di compressione con un utilizzo minimo di memoria e tempi di compressione rapidi, e genererà un output che funzionerà con qualsiasi decompressore.