Versuche, zlib / deflate in PNG-Dateien zu verstehen
Ich bin gerade dabei, selbst eine kleine PNG-Bild-E / A-Bibliothek für Lernzwecke zu schreiben. Mein Problem ist folgendes:
Ich habe ein kleines PNG mit einer Größe von nur 2 x 2 Pixel erstellt und es in einem Hex-Editor geöffnet, um den Inhalt zu untersuchen. Dies ist das Bild, das ich mit GIMP erstellt und mit einer Komprimierung von "9" gespeichert habe.
(Bitte beachten Sie, dass dies ein vergrößertes Bild des 2 x 2 Pixel Originalbildes ist;))
So ich denke, unkomprimiert, würde dies in Erinnerung etwa so aussehen:
00 00 00 FF 00 00 00 00 FF 00 FF 00
wenn ohne Alphakanal gespeichert.
(Ich habe dies hier nur aus Gründen der Klarheit angegeben. Ich kenne die Komprimierung und habe nicht erwartet, dieses Bytemuster in der Datei zu sehen.)
Ich extrahierte den IDAT-Chunk und entfernte die Chunk-ID ("IDAT") und den abschließenden CRC-Wert und erhielt diese Folge von Bytes:
08 D7 05 C1 01 01 00 00 00 80 10 FF 4F 17 10 48 06 0F FE 02 FE
Now die ersten zwei Bytes08 D7
enthält Informationen zum codierten Block. Und die letzten vier Bytes0F FE 02 FE
muss die ADLER32-Prüfsumme sein.
Dies lässt mich letztendlich mit den folgenden Bytes zurück:
05 C1 01 01 00 00 00 80 10 FF 4F 17 10 48 06
In binärer Darstellung geschrieben sind diese Bytes:
0000 0101 1100 0001 0000 0001 0000 0001
0000 0000 0000 0000 0000 0000 1000 0000
0001 0000 1111 1111 0100 1111 0001 0111
0001 0000 0100 1000 0000 0110
Um DEFLATE besser zu verstehen, habe ich versucht, diese Sequenz von Hand zu "entpacken", bevor ich sie gut genug verstehe, um ein kleines Tool zu schreiben. Aber ich bin sehr schnell festgefahren.
RFC 1951 "DEFLATE Compressed Data Format Specification") gibt an, dass jeder codierte Block mit einem Drei-Bit-Header beginnt. Ein Bit gibt an, ob dies der letzte Block ist oder nicht, und zwei weitere Blöcke geben die Komprimierungsmethode an. Da ich davon ausgehe, dass der Encoder hier nur einen Block verwendet hat (dh der erste Block ist automatisch der letzte) und einen nicht statischen Huffmann-Baum verwendet hat, suche ich nach der Bitfolge "101", kann sie aber nicht finden (und finde andere wahrscheinlich nicht) Überschriften "100" oder "110").
Auch der RFC sagt, dass es zwei Zwei-Byte-Werte LEN und NLEN geben muss, die die Länge des Blocks speichern, wobei NLEN das Einerkomplement von LEN ist, aber ich bin wieder nicht in der Lage, vier solcher Bytes zu finden, die diese Bedingung erfüllen. Ich werde nicht einmal das Glück haben, etwas zu finden, das die beiden Huffmann-Bäume repräsentieren könnte.
Ich las RFCs 1951 und 1950 "ZLIB Compressed Data Format Specification" sowie die Wikipedia-Artikel zu zlib, DEFLATE, LZ77 und Huffman-Codierung sowie einige kleine und wenig hilfreiche Artikel im Web und ein paar Antworten zu Stack Overflow, aber keiner konnte mir bei meinem Unverständnis weiterhelfen.
Ich wäre wirklich dankbar für jede Hilfe oder Hinweis!