2010-12-29 5 views
4

Ich entwickle einen PDF Parser/Writer, aber ich bin beim Erzeugen von Cross Reference Streams festgefahren. Mein Programm liest this Datei und entfernt dann seine Linearisierung und dekomprimiert alle Objekte in Objektströmen. Schließlich erstellt es die PDF-Datei und speichert sie.PDF Cross Reference Streams

Das funktioniert wirklich gut, wenn ich den normalen Querverweis & Anhänger verwende, wie Sie in this Datei sehen können.

Wenn ich versuche stattdessen einen Querverweis Stream-Objekt zu erzeugen (die in this Datei führt, kann Adobe Reader nicht anzeigen.

Hat mit PDF-Dateien jemand Erfahrung und kann mir helfen, suchen, was das Problem ist?

Beachten sie, dass der Querverweis der einzige Unterschied zwischen Datei 2 und Datei 3. das erste 34127 Bytes gleich ist.

Wenn jemand den Inhalt des decodierten Referenzstrom benötigt, this Datei herunterladen und in einem öffnen HEX-Editor Ich habe diese Referenztabelle agai überprüft immer wieder, aber ich konnte nichts falsch finden. Aber das Wörterbuch scheint auch in Ordnung zu sein.

Vielen Dank für Ihre Hilfe !!!

aktualisieren

ich jetzt habe das Problem vollständig gelöst. Sie können das neue PDF here finden.

Antwort

6

Zwei Probleme, die ich sehen (ohne sich auf der Stream-Daten zu suchen.

  1. "Größe integer (Erforderlich) Die Nummer eins größer als die höchste Objektnummer in diesem Abschnitt oder in jedem Abschnitt verwendet für welche das soll ein Update sein. Er wird in einem Anhänger Wörterbuch zum Eintrag Größe entsprechen. „

    Ihre Größe sein sollte ... 14.

  2. Index Array (Optional) Ein Array, das ein Paar Ganzzahlen für jeden Unterabschnitt in diesem Abschnitt enthält.Die erste ganze Zahl ist die erste Objektnummer im Unterabschnitt; die zweite ganze Zahl ist die Anzahl der Einträge im Unterabschnitt . Das Array ist aufsteigend nach Objektnummer zu sortieren. Unterabschnitte dürfen nicht überlappen; Eine Objektnummer darf höchstens einen Eintrag in einem Abschnitt enthalten. Standardwert: [0 Size] „

    Ihr Index sollte wahrscheinlich um ein bisschen überspringen Sie haben keine Objekte 2-4 oder 7. Der Index-Array, das reflektieren muss

  3. Ihre Daten Ain'... t Rechts entweder (und ich haben gerade erfahren, aus einem xref Stream zu lesen. yay me.)


00 00 00
01 00 0a
01 00 47
01 01 01
01 01 70
01 02 fd
01 76 f1
01 84 6b
01 84 a1
01 85 4f

nach diesen Daten, die wegen Ihres „kein Index“ als Objektnummern interpretieren 0 bis 9, haben die folgenden ng offset:

0 ist nicht belegt. Fein.
1 ist bei 0x0a. Ja, sicher ist
2 ist bei 0x47. Nee. Das landet in der Nähe des Anfanges von "1 0". Das ist wahrscheinlich kein Zufall.
3 ist bei 0x101. Nee. 0x101 ist immer noch im Stream von "1 0".
4 ist bei 0x170. Dito
5 ist bei 0x2fd. Dito
6 ist bei 0x76f1. Nein, und dieses Mal in diesem Bildstrom vergraben.

Ich denke, Sie bekommen die Idee. Selbst wenn Sie einen korrekten \ Index hatten, sind Ihre Offsets alle falsch (und völlig anders als in resultNormal.pdf, selbst wenn Sie Dezimal-Hex-Verwechslung zulassen).

Was Sie wollen, können in resultNormal des xref finden:

xref
0 2
0000000000 65535 f
0000000010 00000 n
5 2
0000003460 00000 n
0000003514 00000 n
8 5
0000003688 00000 n
0000003749 00000 n
0000003935 00000 n
0000004046 00000 n
0000004443 00000 n

So sollte Ihr Index sein (wenn ich das richtig bin Lesen): \ Index [0 2 5 2 8 5]. Und die Daten:
1 0 ein
1 3460 (das ist dezimal)
1 3514 (dito)
etc

Interessanterweise ist die PDF-Spezifikation sagt, dass die Größe muss BEIDE Anzahl der Einträge in diesem und allen vorherigen XRefs AND die Nummer eins höher als die höchste verwendete Objektnummer sein.

Ich glaube nicht, dass der spätere Teil jemals durchgesetzt wird, aber ich wäre nicht überrascht zu finden, dass Xref-Streams mehr Remanenz als die normalen Cross-Reference-Tabellen sind. Könnte der gleiche Code sein, der beide behandelt, möglicherweise nicht.


@mtraut:

Hier ist, was ich sehe:

13 0 obj
<</Size 10/Length 44/Filter /FlateDecode/DecodeParms <</Columns 3/Predictor 12>>/W [1 2 0]/Type /XRef/Root 8 0 R>>
Strom
...
endstream
endobj

+0

Vielen Dank !!! Ich denke, es ist die Sache mit dem/Index-Tag. Weil es optional ist, habe ich es ignoriert. Aber da meine Objekte nicht von 0 bis 9 sind, ist es erforderlich. –

+0

Ok, jetzt habe ich den Ref Stream ohne Verschlüsselung gespeichert und das/Index Array zum Dictionary hinzugefügt. Jetzt funktioniert es großartig! Vielen Dank!! –

+0

Ich weiß ... Ich weiß: Ich * rocke *. Und ich bin auch super bescheiden! Und gut aussehend. Vergessen wir nicht "gutaussehend". Ähm ... ich meine ... "Gern geschehen". –

0

Die Datei "resultstream.pdf" hat keinen gültigen Crossref-Stream.

Wenn ich es in meinem Viewer öffne, versucht er das Objekt "13 0" als einen Cross Ref Stream zu lesen, aber es ist ein einfaches Wörterbuch (Stream Tags und Daten fehlen).

Etwas außerhalb des Themas: In welcher Sprache entwickeln Sie? Zumindest in Java kennt man drei wertvolle Möglichkeiten (PDFBox, iText und jPod, wobei ich mich persönlich als einer der Entwickler für jPod entscheide, sehr saubere Umsetzung :-). Wenn dies nicht zu Ihrer Plattform passt, können Sie sich zumindest Algorithmen und Datenstrukturen ansehen.

EDIT

Nun - wenn "resultstream.pdf" das fragliche Dokument ist, dann ist es das, was mein Redakteur (scite)

... 
13 0 obj 
<</Size 0/W [1 2 0]/Type /XRef/Root 8 0 R>> 
endobj 
startxref 
34127 
%%EOF 

Es gibt keinen Strom sieht.

+0

Ich glaube nicht, dass das Problem. Ich sehe "stream .... endstream" im Editor. Vielleicht hat dein Zuschauer ein Problem? –

+0

siehe oben bearbeiten! – mtraut

+0

SciTE ist ein Texteditor (richtig?), Also ist das nicht das Problem. Ich vermute, dass Sie das PDF in einer Viewer-App geöffnet und dann von dort gespeichert haben, anstatt direkt vom Link zu speichern. SPEICHERN SIE IMMER vor dem Link, insbesondere beim Umgang mit einem bekanntermaßen beschädigten PDF. Zuschauer neigen dazu, die Datei zu reparieren, daher kann sich die Version, die sie speichern, von der geladenen Version unterscheiden. –