Streng genommen (Ist es möglich, libtiff zu verwenden ...?), ja. Es beinhaltet etwas Hacking, aber nicht zu viel.
Fakt: die Daten werden aus einem Streifen bestehen, da es keine Offset-Informationen gibt, so dass unser einziger Offset Null ist. Wir müssen nur den Streifen einlesen.
Fakt: Diese Daten sind die Komprimierung einer W * H 1-Bit tiefen Pixelmatrix.
Schritt 1: Schätzung der maximal möglichen Länge des komprimierten Datenstroms. Dies ergibt ungefähr 15% von W * H, d.h. mit W = 1000 und H = 1000 erhält man 150000 Bytes. Dieser Wert ist immer mehr als der tatsächliche Wert. Wenn wir eine bessere Schätzung haben, weil wir das richtige EI-End-Image-Tag gefunden haben, ist das noch besser, aber nicht notwendig.
Schritt 2: Erstellen Sie eine "virtuelle" TIF-Datei. Dies wird aus einem Header der Form 49 49 2a 00 AA BB CC DD
bestehen, wobei 0xDDCCBBAA die geschätzte Länge plus 8 ist; gefolgt von unserem geschätzten Datenstrom; gefolgt von einem TIFF-Verzeichnis.
Schritt 3: Das TIFF-Verzeichnis wird immer die gleiche Struktur haben; einige Werte darin sind Offsets und hängen trivial von der IFD-Position 0xDDCCBBAA ab. Zitiert aus den TIFF6 Spezifikationen (beachten Sie, dass Byte-Reihenfolge umgekehrt wird - Motorola, nicht Intel-Endian):
TIFF 6.0 Specification Final—June 3, 1992 20
Putting it all together (along with a couple of less-important fields that are discussed
later), a sample bilevel image file might contain the following fields
A Sample Bilevel TIFF File
Offset Description Value
(hex) (numeric values are expressed in hexadecimal notation)
Header:
0000 Byte Order 4D4D
0002 42 002A
0004 1st IFD offset 00000014
IFD:
0014 Number of Directory Entries 000C
0016 NewSubfileType 00FE 0004 00000001 00000000
0022 ImageWidth 0100 0004 00000001 000007D0
002E ImageLength 0101 0004 00000001 00000BB8
003A Compression 0103 0003 00000001 8005 0000
0046 PhotometricInterpretation 0106 0003 00000001 0001 0000
0052 StripOffsets 0111 0004 000000BC 000000B6(*1)
005E RowsPerStrip 0116 0004 00000001 00000010
006A StripByteCounts 0117 0003 000000BC 000003A6(*2)
0076 XResolution 011A 0005 00000001 00000696(*3)
0082 YResolution 011B 0005 00000001 0000069E(*4)
008E Software 0131 0002 0000000E 000006A6(*5)
009A DateTime 0132 0002 00000014 000006B6(*6)
00A6 Next IFD offset 00000000
Values longer than 4 bytes:
(*1) StripOffsets Offset0 00000008
(*2) StripByteCounts Count0
(*3) XResolution 0000012C 00000001
(*4) YResolution 0000012C 00000001
(*5) Software “PageMaker 4.0”
(*6) DateTime “1988:02:18 13:59:59”
Im obigen 0xDDCCBBAA tatsächlich 0014 ist und alle anderen Offsets folgen.
Ich habe einige Tests mit einem Single-Strip-TIFFG4-Bild, das ich mit ImageMagick erstellt und tiffcp
'ed to 1-strip CCITT-Format gemacht. Der Header dort ist etwas anders (Ich sehe nicht die Software und Datetime Tags, die die Spezifikation sagen sollte dort sein). Sonst überprüft es.
Wir haben jetzt ein beschädigtes TIFF-Bild mit einem überlangen Streifen, und es ist im Speicher.
Mit TIFFClientOpen
können wir access it as if it was a disk image.
den ersten Streifen zu lesen Versuch führt nun zu einem Fehler und das Programm Abbruch:
TIFFFillStrip: Read error on strip 0; got 143151 bytes, expected 762826.
Durch die Verwendung von TIFFSetErrorHandler
und TIFFSetErrorHandlerExt
wir uns einrichten diesen Fehler abzufangen und analysieren sie, um dadurch die 143151
erholt Information, anstatt abzubrechen.
Wir müssen die Rückrufe TIFFClientOpen
, aber sie sind alle sehr einfach liefern:
TIFFReadWriteProc readproc(h, *ptr, n) // copy n bytes from FakeBuffer+pos into ptr, update pos to pos + n, ignore h.
TIFFReadWriteProc writeproc // Throw an error. We don't write
TIFFSeekProc seekproc // update pos appropriately
TIFFCloseProc closeproc // do nothing
TIFFSizeProc sizeproc // return total buffer size
TIFFMapFileProc mapproc // Set to NULL
TIFFUnmapFileProc unmapproc // Set to NULL
Die Verarbeitung ist in der Tat schwierig und verworren, aber wie für Machbarkeit, es kann erfolgen.
Ich habe Tests in C-Sprache ausgeführt, den CCITT-Stream von Hand aus einem BI/ID/EI-PDF, das ich online gefunden habe, extrahiert und wie oben beschrieben gelesen.
Wenn ich eine sichere Methode zur Identifizierung der richtigen EI hatte - ich habe a message by Tilman Hausherr ausgebaggert, einen Hack zu erklären, gültige PDF-Operatoren zu folgen, die dem EI folgen, um dies zu tun, was mich denken lässt, dass es wahrscheinlich nicht ist viele bessere Methoden - ich konnte immer den korrekten Offset schätzen und direkt aus dem PDF eine korrekte und lesbare TIFF-Datei erzeugen, ohne überhaupt libtiff zu verwenden.
Warum können Sie die Eigenschaft 'Length' des Streams nicht verwenden? ([Länge ist eine obligatorische Eigenschaft für einen Stream] (http://www.printmyfolders.com/understanding-pdf), sollte es immer vorhanden sein.) – Phillip
Posten Sie eine Beispieldatei, damit wir sehen können, was Sie arbeiten mit. – BitBank
@Phillip Nicht für eingebettete Bildobjekte, die direkt in einer Seitenbeschreibung angezeigt werden. – Brian