ZLIB ohne Level 9

Viele Probleme meiner Arbeit am GATE Projekt liegen bei den Compilern. Man würde glauben, wenn dieses gelöst sind, also alles kompiliert, wäre man fertig.

Leider nicht ganz, denn plötzlich schlägt z.B.: die Initialisierung der ZLIB zur Laufzeit fehl.


Die ZLIB nutzt beim Komprimieren einige Parameter wie etwas Compression-Level, Memory-Level und Window-Bits. Hierfür existieren Konstanten wie

  • compression-level: Z_BEST_COMPRESSION (==9)
  • memory-level: MAX_MEM_LEVEL (==9)
  • window-bits: MAX_WBITS (==15)

Da ich die besten Ergebnisse haben möchte, nutzte ich diese Werte als Standard in meine Codes, nur das Compression-Level war von außen einstellbar.

Unter DOS kompiliert dieser Code zwar, kann jedoch dann nicht ausgeführt werden, es kommt zum Abbruch der Initialisierung in deflateInit2_().

Mit jeder Menge printf() Debugging kam ich dann zu den Zeilen, die die Parameter umsetzen und hier findet die Allokation eines Puffers statt, die vereinfacht so aussieht:

1Byte* window = malloc((1 << window_size) * 2 * sizeof(Byte));

Bei 2^15 * 2 landen wir bei 2^16 bytes, also 65536. Theoretisch würde das ein vollständiges DOS Segment sein, doch mit malloc können wir kein ganzes Segment in einem kapern.

Etwas ähnliches passiert dann auch noch beim Memory-Level, denn da wird zum Level 7 addiert, womit man auch wieder auf 16 Bits kommt.

Lösung: Kleinere Parameter

Meine Lösung war dann denkbar einfach (und wurde zusätzlich auch gleich auf Windows CE angewendet):

1#if defined(GATE_SYS_WINCE) || defined(GATE_SYS_DOS)
2        int memlevel = MAX_MEM_LEVEL - 2;
3        int window_bits = MAX_WBITS - 1;
4#else
5        int memlevel = MAX_MEM_LEVEL;
6        int window_bits = MAX_WBITS;
7#endif

Mit den gepatchten Parameter läuft die ZLib brav weiter und generiert mit deflate komprimierte Ergebnisse, allerdings sind die jetzt potentiell etwas schlechter, weil die Wörterbücher kleiner sind. Aber damit kann man auf diesen Plattformen leben.

Fazit

Ab sofort kann das arch Tool .gz und .zip Archive erzeugen und auch wieder unter DOS auspacken.
Damit bin ich schon zufrieden.

Ich müsste jetzt noch Tests mit Archiven machen, die unter Windows oder Linux erzeugt wurden und größere Window-Bits hatten und ob die beim Entpacken Probleme machen. Allerdings sehe ich im inflate() Code keine Allokationen, die davon abhängen, zumindest nicht bei der Initialisierung.

DOS ist inzwischen eine wichtige Plattform für mich geworden, um zu verifizieren, ob Code wirklich plattformunabhängig läuft. Die Window-Bits sind ein schönes Beispiel für Einschränkungen, die man einfach nur wissen muss, um sie mit wenig Code überwinden zu können.

📧 📋 🐘 | 🔔
 

Meine Dokus über:
 
Weitere externe Links zu:
Alle extern verlinkten Webseiten stehen nicht in Zusammenhang mit opengate.at.
Für deren Inhalt wird keine Haftung übernommen.



Wenn sich eine triviale Erkenntnis mit Dummheit in der Interpretation paart, dann gibt es in der Regel Kollateralschäden in der Anwendung.
frei zitiert nach A. Van der Bellen
... also dann paaren wir mal eine komplexe Erkenntnis mit Klugheit in der Interpretation!