deflate — דחיסה ופענוח deflate

מודול זה מאפשר דחיסה ופענוח של נתונים בינאריים באמצעות אלגוריתם DEFLATE (הנפוץ בספריית zlib ובמארכב gzip). נוסף ב-MicroPython v1.21.

זמינות בלוחות הנתמכים על ידי OpenMV:

לוח

פענוח

דחיסה

OpenMV Cam N6

כן

לא

OpenMV AE3

כן

כן

OpenMV Cam RT1062

כן

כן

OpenMV Cam Pure Thermal

כן

לא

OpenMV Cam M4

כן

לא

OpenMV Cam M7

כן

לא

OpenMV Cam H7

כן

לא

OpenMV Cam H7 Plus

כן

לא

Arduino Giga

כן

לא

Arduino Portenta H7

כן

לא

Arduino Nicla Vision

כן

לא

Arduino Nano 33 BLE Sense

כן

לא

Arduino Nano RP2040 Connect

כן

לא

מחלקות

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

ניתן להשתמש במחלקה זו כדי לעטוף stream שהוא כל אובייקט דמוי-זרם כגון קובץ, socket, או זרם (כולל io.BytesIO). היא עצמה זרם ומממשת את המתודות הסטנדרטיות read/readinto/write/close.

ה-stream חייב להיות זרם חוסם. זרמים לא-חוסמים אינם נתמכים כעת.

ניתן להגדיר את ה-format לכל אחד מהקבועים המוגדרים להלן, וברירת המחדל היא AUTO אשר עבור פענוח תזהה אוטומטית זרמי gzip או zlib, ועבור דחיסה תפיק זרם גולמי.

הפרמטר wbits קובע את הלוגריתם בבסיס 2 של גודל חלון מילון ה-DEFLATE. כך למשל, הגדרת wbits ל-10 קובעת את גודל החלון ל-1024 בתים. ערכים חוקיים הם 5 עד 15 ועד בכלל (המתאימים לגדלי חלון של 32 עד 32k בתים).

אם wbits מוגדר ל-0 (ברירת המחדל), אזי עבור דחיסה יעשה שימוש בגודל חלון של 256 בתים (כאילו wbits הוגדר ל-8). עבור פענוח, הדבר תלוי בפורמט:

  • RAW ישתמש ב-256 בתים (המתאימים ל-wbits שהוגדר ל-8).

  • ZLIB (או AUTO עם זיהוי zlib) ישתמש בערך מכותרת ה-zlib.

  • GZIP (או AUTO עם זיהוי gzip) ישתמש ב-32 קילובתים (המתאימים ל-wbits שהוגדר ל-15).

ראו את הערות גודל החלון להלן למידע נוסף על גודל החלון, וזרמי zlib ו-gzip.

אם close מוגדר ל-True אזי הזרם הבסיסי ייסגר אוטומטית כאשר זרם ה-deflate.DeflateIO נסגר. הדבר שימושי אם ברצונכם להחזיר זרם deflate.DeflateIO שעוטף זרם אחר, מבלי שהקורא יצטרך לדעת על ניהול הזרם הבסיסי.

אם הדחיסה מופעלת, מופע נתון של deflate.DeflateIO תומך הן בקריאה והן בכתיבה. לדוגמה, ניתן לעטוף זרם דו-כיווני כגון socket, מה שמאפשר דחיסה/פענוח בשני הכיוונים.

קבועים

ארבעת קבועי ה-format בוחרים את המסגרת המיושמת סביב זרם הסיביות הגולמי של deflate.

deflate.AUTO: int

עבור פענוח, זהה אוטומטית את פורמט הקלט על ידי בדיקת הבתים הראשונים של הזרם (zlib או gzip). עבור דחיסה, הפק זרם deflate גולמי ללא כותרת או נספח (שווה ערך ל-RAW).

deflate.RAW: int

זרם deflate גולמי (ללא כותרת, ללא נספח, ללא סכום בדיקה). מכיוון שהזרם אינו מכיל מטא-נתונים, המפענח אינו יכול לשחזר את גודל החלון מהנתונים, ולכן יש להגדיר את wbits במפורש בעת הפענוח – אחרת חלון ברירת המחדל בן 256 הבתים עלול להיות קטן מדי.

deflate.ZLIB: int

זרם deflate עטוף ב-zlib כפי שמוגדר ב-RFC 1950: כותרת בת 2 בתים הרושמת את גודל החלון, מטען ה-deflate, וסכום בדיקה Adler-32 בנספח. קומפקטי ומתאר את עצמו; מתאים היטב לשימוש משובץ.

deflate.GZIP: int

זרם deflate עטוף ב-gzip כפי שמוגדר ב-RFC 1952: כותרת עם מטא-נתונים אופציונליים של שם קובץ/חותמת זמן, מטען ה-deflate, ובנספח CRC-32 בתוספת אורך לא-דחוס. זהו הפורמט המופק על ידי כלי שורת הפקודה gzip ועל ידי gzip.GzipFile. הכותרת אינה רושמת את גודל החלון, ולכן המפענח חייב להניח 32 KiB אלא אם wbits מוגדר.

דוגמאות

מקרה שימוש טיפוסי עבור deflate.DeflateIO הוא קריאה או כתיבה של קובץ דחוס מאחסון:

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.

מכיוון ש-deflate.DeflateIO הוא זרם, ניתן להשתמש בו למשל עם json.dump() ו-json.load() (ובכל מקום אחר שבו ניתן להשתמש בזרמים):

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)

אם נתוני המקור שלכם אינם בפורמט זרם, ניתן להשתמש ב-io.BytesIO כדי להפוך אותם לזרם המתאים לשימוש עם 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

גודל החלון מגביל עד כמה רחוק לאחור בזרם יכול הדוחס/המפענח להפנות. הגדלת גודל החלון תשפר את הדחיסה, אך תדרוש יותר זיכרון ותאט את הדוחס.

אם זרם קלט נדחס בגודל חלון נתון, אזי DeflateIO המשתמש בגודל חלון קטן יותר ייכשל באמצע הפענוח עם OSError, אך רק אם הפניה לאחור אכן מפנה רחוק יותר מגודל החלון של המפענח. משמעות הדבר היא שייתכן שאפשר יהיה לפענח בגודל חלון קטן יותר. לדוגמה, זה יהיה המקרה באופן טריוויאלי אם הנתונים המקוריים הלא-דחוסים קצרים יותר מגודל החלון.

פענוח

פורמט ה-zlib כולל כותרת המציינת את גודל החלון ששימש לדחיסת הנתונים. זה מציין את גודל החלון המרבי הנדרש לפענוח זרם זה. אם ערך כותרת זה קטן מערך ה-wbits שצוין (או אם wbits אינו מוגדר), אזי ייעשה שימוש בערך הכותרת.

פורמט ה-gzip אינו כולל את גודל החלון בכותרת, ומניח שכל דוחסי ה-gzip (למשל כלי השירות gzip, או מימוש ה-gzip.GzipFile של CPython) משתמשים בגודל החלון המרבי של 32kiB. מסיבה זו, אם הפרמטר wbits אינו מוגדר, המפענח ישתמש בגודל חלון של 32 kiB (המתאים ל-wbits שהוגדר ל-15). משמעות הדבר היא שכדי להיות מסוגלים לפענח זרם gzip שרירותי, עליכם שיהיה זמין לכל הפחות כמות זיכרון RAM זו. אם אתם שולטים בנתוני המקור, שקלו במקום זאת להשתמש בפורמט zlib עם גודל חלון קטן יותר.

לפורמט הגולמי אין כותרת ולכן הוא אינו כולל מידע כלשהו על גודל החלון. אם wbits אינו מוגדר, אזי ברירת המחדל תהיה גודל חלון של 256 בתים, שעלול שלא להיות גדול דיו עבור זרם נתון. לפיכך מומלץ שתמיד תגדירו במפורש את wbits בעת שימוש בפורמט הגולמי.

דחיסה

עבור דחיסה, MicroPython יקבע כברירת מחדל גודל חלון של 256 בתים עבור כל הפורמטים. זה מספק כמות סבירה של דחיסה עם שימוש מינימלי בזיכרון וזמן דחיסה מהיר, ויפיק פלט שיעבוד עם כל מפענח.