deflate — compressão e descompressão deflate¶
Este módulo permite a compressão e descompressão de dados binários com o algoritmo DEFLATE (comumente usado na biblioteca zlib e no arquivador gzip). Adicionado no MicroPython v1.21.
Disponibilidade nas placas suportadas pela OpenMV:
Placa |
Descompressão |
Compressão |
|---|---|---|
OpenMV Cam N6 |
Sim |
Não |
OpenMV AE3 |
Sim |
Sim |
OpenMV Cam RT1062 |
Sim |
Sim |
OpenMV Cam Pure Thermal |
Sim |
Não |
OpenMV Cam M4 |
Sim |
Não |
OpenMV Cam M7 |
Sim |
Não |
OpenMV Cam H7 |
Sim |
Não |
OpenMV Cam H7 Plus |
Sim |
Não |
Arduino Giga |
Sim |
Não |
Arduino Portenta H7 |
Sim |
Não |
Arduino Nicla Vision |
Sim |
Não |
Arduino Nano 33 BLE Sense |
Sim |
Não |
Arduino Nano RP2040 Connect |
Sim |
Não |
Classes¶
- class deflate.DeflateIO(stream: Any, format: int = AUTO, wbits: int = 0, close: bool = False, /)¶
Esta classe pode ser usada para encapsular um stream, que é qualquer objeto stream-like como um arquivo, socket ou stream (incluindo
io.BytesIO). Ela própria é um stream e implementa os métodos padrão read/readinto/write/close.O stream deve ser um stream bloqueante. Streams não bloqueantes não são suportados atualmente.
O format pode ser definido como qualquer uma das constantes definidas abaixo, e o padrão é
AUTO, que para descompressão detectará automaticamente streams gzip ou zlib, e para compressão gerará um stream bruto (raw).O parâmetro wbits define o logaritmo na base 2 do tamanho da janela do dicionário DEFLATE. Assim, por exemplo, definir wbits como
10define o tamanho da janela como 1024 bytes. Os valores válidos vão de5a15inclusive (correspondendo a tamanhos de janela de 32 a 32k bytes).Se wbits for definido como
0(o padrão), então para compressão será usado um tamanho de janela de 256 bytes (como se wbits fosse definido como 8). Para descompressão, depende do formato:RAWusará 256 bytes (correspondendo a wbits definido como 8).ZLIB(ouAUTOcom zlib detectado) usará o valor do cabeçalho zlib.GZIP(ouAUTOcom gzip detectado) usará 32 kilobytes (correspondendo a wbits definido como 15).
Consulte as notas sobre o tamanho da janela abaixo para mais informações sobre o tamanho da janela e os streams zlib e gzip.
Se close for definido como
True, então o stream subjacente será fechado automaticamente quando o streamdeflate.DeflateIOfor fechado. Isso é útil se você quiser retornar um streamdeflate.DeflateIOque encapsula outro stream sem que o chamador precise saber como gerenciar o stream subjacente.Se a compressão estiver habilitada, uma dada instância de
deflate.DeflateIOoferece suporte tanto a leitura quanto a escrita. Por exemplo, um stream bidirecional como um socket pode ser encapsulado, o que permite compressão/descompressão em ambas as direções.
Constantes¶
As quatro constantes format selecionam o enquadramento aplicado ao redor do fluxo de bits deflate bruto.
- deflate.AUTO: int¶
Para descompressão, detecta automaticamente o formato de entrada inspecionando os primeiros bytes do stream (zlib ou gzip). Para compressão, gera um stream deflate bruto sem cabeçalho ou rodapé (equivalente a
RAW).
- deflate.RAW: int¶
Um stream deflate bruto (sem cabeçalho, sem rodapé, sem checksum). Como o stream não contém metadados, o descompressor não pode recuperar o tamanho da janela a partir dos dados, portanto wbits deve ser definido explicitamente ao descomprimir – caso contrário, a janela padrão de 256 bytes pode ser pequena demais.
- deflate.ZLIB: int¶
Um stream deflate encapsulado em zlib conforme definido pela RFC 1950: um cabeçalho de 2 bytes que registra o tamanho da janela, a carga útil deflate e um checksum Adler-32 ao final. Compacto e autodescritivo; bem adequado para uso embarcado.
- deflate.GZIP: int¶
Um stream deflate encapsulado em gzip conforme definido pela RFC 1952: um cabeçalho com metadados opcionais de nome de arquivo/timestamp, a carga útil deflate e um CRC-32 ao final mais o comprimento não comprimido. Este é o formato produzido pela ferramenta de linha de comando
gzipe porgzip.GzipFile. O cabeçalho não registra o tamanho da janela, portanto o descompressor deve assumir 32 KiB a menos que wbits seja definido.
Exemplos¶
Um caso de uso típico para deflate.DeflateIO é ler ou escrever um arquivo comprimido a partir do armazenamento:
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.
Como deflate.DeflateIO é um stream, ele pode ser usado, por exemplo, com json.dump() e json.load() (e em qualquer outro lugar onde streams possam ser usados):
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 seus dados de origem não estiverem em formato de stream, você pode usar io.BytesIO para transformá-los em um stream adequado para uso com 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()
Tamanho da janela do deflate¶
O tamanho da janela limita o quão longe no stream o (des)compressor pode fazer referências. Aumentar o tamanho da janela melhorará a compressão, mas exigirá mais memória e tornará o compressor mais lento.
Se um stream de entrada foi comprimido com um determinado tamanho de janela, então DeflateIO usando um tamanho de janela menor falhará no meio da descompressão com OSError, mas apenas se uma referência retroativa realmente apontar para mais longe do que o tamanho da janela do descompressor. Isso significa que pode ser possível descomprimir com um tamanho de janela menor. Por exemplo, isso seria trivialmente o caso se os dados originais não comprimidos forem mais curtos que o tamanho da janela.
Descompressão¶
O formato zlib inclui um cabeçalho que especifica o tamanho da janela que foi usado para comprimir os dados. Isso indica o tamanho máximo de janela necessário para descomprimir este stream. Se esse valor do cabeçalho for menor que o valor de wbits especificado (ou se wbits não estiver definido), então o valor do cabeçalho será usado.
O formato gzip não inclui o tamanho da janela no cabeçalho e assume que todos os compressores gzip (por exemplo, o utilitário gzip ou a implementação de gzip.GzipFile do CPython) usam o tamanho máximo de janela de 32kiB. Por essa razão, se o parâmetro wbits não for definido, o descompressor usará um tamanho de janela de 32 kiB (correspondendo a wbits definido como 15). Isso significa que, para conseguir descomprimir um stream gzip arbitrário, você deve ter pelo menos essa quantidade de RAM disponível. Se você controla os dados de origem, considere usar o formato zlib com um tamanho de janela menor.
O formato raw não tem cabeçalho e, portanto, não inclui nenhuma informação sobre o tamanho da janela. Se wbits não for definido, ele assumirá por padrão um tamanho de janela de 256 bytes, que pode não ser grande o suficiente para um determinado stream. Portanto, recomenda-se que você sempre defina wbits explicitamente ao usar o formato raw.
Compressão¶
Para compressão, o MicroPython assumirá por padrão um tamanho de janela de 256 bytes para todos os formatos. Isso fornece uma quantidade razoável de compressão com uso mínimo de memória e tempo de compressão rápido, e gerará uma saída que funcionará com qualquer descompressor.