Mehr

Kennen Sie die Byte-Adresse und die Byte-Länge des „Streifens“ in LZW-komprimiertem GeoTiff mit Vanille-PHP?

Kennen Sie die Byte-Adresse und die Byte-Länge des „Streifens“ in LZW-komprimiertem GeoTiff mit Vanille-PHP?


Ich habe eine Situation, in der ich Zellenwerte aus einem GeoTiff mit Vanilla-PHP lesen muss, und obwohl ich erfolgreich Werte aus einem unkomprimierten TIF (~800 MB) gelesen habe, habe ich Schwierigkeiten beim Lesen von Werten aus demselben TIF nach der LZW-Komprimierung (~80 MB).

Ich glaube, mein Problem rührt daher, dass ich die Byte-Adresse eines "Streifens" und die Anzahl der zu diesem Streifen gehörenden Bytes kenne - da mein Verständnis von LZW ist, dass die Dekompressionsroutine einen ganzen Streifen benötigt, den sie verwendet, um eine Übersetzungstabelle relativ zu erstellen zu diesem Streifen, bevor einzelne Zellenwerte, die in diesem Streifen dargestellt werden, abgefragt werden können.

So interpretiere ich die TIFF-Spezifikation: Ich kann die Bytes für jeden "Streifen" lesen, indem ich beim Tag-Wert "Strip Offsets" starte (zur Information: mein RowsPerStrip-Tag-Wert ist 1) und den Offset für die genaue Scanlinie erhalte, die ich bin Ausrichtung wie folgt:

$stripOffset = $STRIP_OFFSETS + ($rowNum * 4); // d.h. 2 Byte pro Eintrag

Um dann die Anzahl der Bytes zu erhalten, die ich für meinen Zielstreifen/-scanline vorauslesen muss, mache ich dasselbe mit dem StripByteCounts-Tag:

$stripByteCount = $STRIP_BYTE_COUNTS + ($rowNum * 4); // auch 2 Byte pro Eintrag

Mit diesen Werten in der Hand dachte ich, ich könnte dann den gesamten Streifen extrahieren

// Tiff-Datei öffnen und auf die Byte-Adresse des Streifens zeigen… fseek($this->fp, $stripOffset); // N Bytes von der Byteadresse des Strips lesen $stripBytes = fread($this->fp, $stripByteCount); // DIESE BYTES SOLLTEN DER GANZE STREIFEN SEIN, ja? $strip_data = unpack('Vstrip_data', $stripBytes);

Es scheint jedoch, als würde ich mehr als einen Datenstreifen erhalten - da das, was zurückkommt, damit beginnt und mehrere wiederkehrende Instanzen von128darin, was den in der Spezifikation erwähnten sogenannten "ClearCode" darstellen soll.

"Der erste geschriebene Code ist ein ClearCode, der als Code 256 definiert ist."

Mein Eindruck ist also, dass ich entweder nicht richtig verstehe, wie man die Byte-Adresse und/oder die Byte-Anzahl eines Streifens/Scanline auswertet… oder… ich weiß es nicht!?! :)… es ist wichtig zu betonen, dass das, was zurückkommt, tatsächlich mit 128 beginnt, was ich relativ sicher bin, dass der ClearCode-Wert ist. Ich vermute also, dass ich den Anfang eines Streifens treffe, ich greife einfach nicht auf die richtige Anzahl von Bytes.

Bewerte ich die Byte-Adresse und die Anzahl der Bytes für einen Zielstreifen/eine Ziel-Scanlinie richtig?

Und angenommen nein – was mache ich hier falsch?

Wie bereits erwähnt – ich habe dies mit unkomprimierten TIFs zum Laufen gebracht, indem ich von dieser Frage und diesem Code mit freundlicher Genehmigung von Bob Osola profitiert habe. Daher bin ich mir sicher, dass meine Übersetzung Ost/Nord → Spalte/Zeile korrekt ist. Und FWIW, mein komprimiertes LZW-TIF verwendet einen Predictor=2 (horizontale Differenzierung), obwohl ich eine Variation mit Predictor=1 erstellt habe. Ich glaube jedoch nicht, dass der Prädiktor im Zusammenhang mit dieser Frage ein Thema ist.