deflate --- kompresi & dekompresi deflate

Modul ini memungkinkan kompresi dan dekompresi data biner menggunakan algoritma DEFLATE (yang umum digunakan dalam library zlib dan pengarsip gzip). Ditambahkan di MicroPython v1.21.

Ketersediaan pada board yang didukung OpenMV:

Board

Dekompresi

Kompresi

OpenMV Cam N6

Ya

Tidak

OpenMV AE3

Ya

Ya

OpenMV Cam RT1062

Ya

Ya

OpenMV Cam Pure Thermal

Ya

Tidak

OpenMV Cam M4

Ya

Tidak

OpenMV Cam M7

Ya

Tidak

OpenMV Cam H7

Ya

Tidak

OpenMV Cam H7 Plus

Ya

Tidak

Arduino Giga

Ya

Tidak

Arduino Portenta H7

Ya

Tidak

Arduino Nicla Vision

Ya

Tidak

Arduino Nano 33 BLE Sense

Ya

Tidak

Arduino Nano RP2040 Connect

Ya

Tidak

Kelas

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

Kelas ini dapat digunakan untuk membungkus sebuah stream yang merupakan objek mirip-stream seperti file, soket, atau stream (termasuk io.BytesIO). Kelas ini sendiri adalah stream dan mengimplementasikan metode standar read/readinto/write/close.

Stream stream harus berupa stream yang memblokir. Stream non-blokir saat ini tidak didukung.

Format format dapat diatur ke salah satu konstanta yang didefinisikan di bawah ini, dan defaultnya adalah AUTO yang untuk dekompresi akan mendeteksi otomatis stream gzip atau zlib, serta untuk kompresi akan menghasilkan stream mentah.

Parameter wbits mengatur logaritma basis-2 dari ukuran jendela kamus DEFLATE. Misalnya, menetapkan wbits ke 10 menetapkan ukuran jendela menjadi 1024 byte. Nilai yang valid adalah 5 hingga 15 inklusif (sesuai dengan ukuran jendela 32 hingga 32k byte).

Jika wbits diatur ke 0 (default), maka untuk kompresi ukuran jendela 256 byte akan digunakan (seolah-olah wbits diatur ke 8). Untuk dekompresi, bergantung pada formatnya:

  • RAW akan menggunakan 256 byte (sesuai dengan wbits yang diatur ke 8).

  • ZLIB (atau AUTO dengan zlib terdeteksi) akan menggunakan nilai dari header zlib.

  • GZIP (atau AUTO dengan gzip terdeteksi) akan menggunakan 32 kilobyte (sesuai dengan wbits yang diatur ke 15).

Lihat catatan ukuran jendela di bawah untuk informasi lebih lanjut tentang ukuran jendela, zlib, dan stream gzip.

Jika close diatur ke True, maka stream yang mendasarinya akan ditutup secara otomatis saat stream deflate.DeflateIO ditutup. Ini berguna jika Anda ingin mengembalikan stream deflate.DeflateIO yang membungkus stream lain dan tidak ingin pemanggil perlu mengelola stream yang mendasarinya.

Jika kompresi diaktifkan, instans deflate.DeflateIO tertentu mendukung pembacaan dan penulisan. Misalnya, stream dua arah seperti soket dapat dibungkus, yang memungkinkan kompresi/dekompresi di kedua arah.

Konstanta

Empat konstanta format memilih framing yang diterapkan di sekitar bit-stream deflate mentah.

deflate.AUTO: int

Untuk dekompresi, deteksi otomatis format input dengan memeriksa byte pertama stream (zlib atau gzip). Untuk kompresi, hasilkan stream deflate mentah tanpa header atau trailer (setara dengan RAW).

deflate.RAW: int

Stream deflate mentah (tanpa header, tanpa trailer, tanpa checksum). Karena stream tidak berisi metadata, dekompresor tidak dapat memulihkan ukuran jendela dari data, sehingga wbits harus ditetapkan secara eksplisit saat dekompresi -- jika tidak, jendela default 256-byte mungkin terlalu kecil.

deflate.ZLIB: int

Stream deflate yang dibungkus zlib sesuai definisi RFC 1950: header 2-byte yang mencatat ukuran jendela, payload deflate, dan checksum Adler-32 di bagian akhir. Ringkas dan mandiri-mendeskripsikan; sangat cocok untuk penggunaan tertanam.

deflate.GZIP: int

Stream deflate yang dibungkus gzip sesuai definisi RFC 1952: header dengan metadata nama file/stempel waktu opsional, payload deflate, dan CRC-32 serta panjang tidak terkompresi di bagian akhir. Ini adalah format yang dihasilkan oleh alat baris perintah gzip dan oleh gzip.GzipFile. Header tidak mencatat ukuran jendela, sehingga dekompresor harus mengasumsikan 32 KiB kecuali wbits ditetapkan.

Contoh

Kasus penggunaan umum untuk deflate.DeflateIO adalah membaca atau menulis file terkompresi dari penyimpanan:

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.

Karena deflate.DeflateIO adalah stream, ia dapat digunakan misalnya dengan json.dump() dan json.load() (dan di tempat lain mana pun stream dapat digunakan):

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)

Jika data sumber Anda tidak dalam format stream, Anda dapat menggunakan io.BytesIO untuk mengubahnya menjadi stream yang sesuai untuk digunakan dengan 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()

Ukuran jendela Deflate

Ukuran jendela membatasi seberapa jauh ke belakang dalam stream (de)kompresor dapat merujuk. Meningkatkan ukuran jendela akan meningkatkan kompresi, tetapi memerlukan lebih banyak memori dan membuat kompresor lebih lambat.

Jika stream input dikompresi dengan ukuran jendela tertentu, maka DeflateIO menggunakan ukuran jendela yang lebih kecil akan gagal di tengah jalan saat dekompresi dengan OSError, tetapi hanya jika referensi-balik sebenarnya merujuk lebih jauh dari ukuran jendela dekompresor. Ini berarti mungkin saja melakukan dekompresi dengan ukuran jendela yang lebih kecil. Misalnya, ini akan menjadi kasus sepele jika data tidak terkompresi asli lebih pendek dari ukuran jendela.

Dekompresi

Format zlib menyertakan header yang menentukan ukuran jendela yang digunakan untuk mengompresi data. Ini menunjukkan ukuran jendela maksimum yang diperlukan untuk mendekompresi stream ini. Jika nilai header ini lebih kecil dari nilai wbits yang ditentukan (atau jika wbits tidak ditetapkan), maka nilai header akan digunakan.

Format gzip tidak menyertakan ukuran jendela dalam header, dan mengasumsikan bahwa semua kompresor gzip (mis. utilitas gzip, atau implementasi CPython dari gzip.GzipFile) menggunakan ukuran jendela maksimum 32kiB. Untuk alasan ini, jika parameter wbits tidak ditetapkan, dekompresor akan menggunakan ukuran jendela 32 kiB (sesuai dengan wbits yang diatur ke 15). Ini berarti untuk dapat mendekompresi stream gzip sembarang, Anda harus memiliki setidaknya RAM sebesar ini tersedia. Jika Anda mengendalikan data sumber, pertimbangkan untuk menggunakan format zlib dengan ukuran jendela yang lebih kecil.

Format mentah tidak memiliki header dan karena itu tidak menyertakan informasi apa pun tentang ukuran jendela. Jika wbits tidak ditetapkan, maka akan default ke ukuran jendela 256 byte, yang mungkin tidak cukup besar untuk stream tertentu. Oleh karena itu, disarankan agar Anda selalu menetapkan wbits secara eksplisit jika menggunakan format mentah.

Kompresi

Untuk kompresi, MicroPython akan default ke ukuran jendela 256 byte untuk semua format. Ini memberikan jumlah kompresi yang wajar dengan penggunaan memori minimal dan waktu kompresi yang cepat, dan akan menghasilkan output yang akan berfungsi dengan dekompresor mana pun.