Строго говоря (Можно ли использовать LibTIFF? ...), да. Это связано с некоторыми взломами, но не слишком много.
Факт: данные будут состоять из одной полосы, так как нет никакой информации о смещении, поэтому наше единственное смещение равно нулю. Нам просто нужно прочитать полосу.
Фактически: эти данные представляют собой сжатие матричной матрицы глубин W * H 1 бит.
Шаг 1: оцените максимально возможную длину сжатого потока. Это составляет около 15% от W * H, т. Е. С W = 1000 и H = 1000 вы получаете 150000 байт. Это значение всегда будет больше, чем фактическое значение. Если мы получим более точную оценку благодаря расположению правильного тега конечного изображения EI, это еще лучше, но не обязательно.
Шаг 2: постройте «виртуальный» файл TIF. Это будет состоять из заголовка формы 49 49 2a 00 AA BB CC DD
, где 0xDDCCBBAA - расчетная длина плюс 8; за которым следует наш оценочный поток данных; за которым следует каталог TIFF.
Шаг 3: каталог TIFF всегда будет иметь одинаковую структуру; некоторые значения в нем являются смещениями и тривиально зависят от позиции IFD 0xDDCCBBAA. Цитирование из TIFF6 спецификации (обратите внимание, что порядок байт обратная - Motorola, не 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”
В вышеприведенном 0xDDCCBBAA на самом деле 0014 и все остальные смещения следуют.
Я провел несколько тестов с использованием однополосного изображения TIFFG4, которое я создал с помощью ImageMagick и tiffcp
'ed в 1-полосный формат CCITT. Заголовок там немного отличается (я не вижу теги Software и Datetime, которые, по словам спецификации, должны быть там). В противном случае он проверяет.
У нас теперь есть поврежденный Изображение TIFF с одной накладной полосой, и оно находится в памяти.
Использование TIFFClientOpen
, мы можем access it as if it was a disk image.
Попытка прочитать первую полосу теперь будет приводить к ошибке и программа закрывается:
TIFFFillStrip: Read error on strip 0; got 143151 bytes, expected 762826.
Используя TIFFSetErrorHandler
и TIFFSetErrorHandlerExt
мы создали сами, чтобы перехватить эту ошибку, и разобрать его, таким образом, восстанавливая 143151
информации, а не прерывания.
Мы должны поставить обратные вызовы TIFFClientOpen
, но все они очень легко:
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
обработки действительно неловко и запутанная, но и для возможности, он может быть сделан.
Я провел тесты на языке C, извлекая вручную поток CCITT из встроенного образа BI/ID/EI PDF, который я нашел в Интернете, и прочитал его, как описано выше.
Если у меня был верный способ определения правильного EI - я выкопал a message by Tilman Hausherr, объяснив взломам, чтобы признать действительные операторы PDF, следуя за EI, чтобы сделать это, что заставляет меня думать, что, вероятно, нет многие лучшие методы - я всегда мог оценить правильное смещение и напрямую создавать корректный и читаемый файл TIFF из PDF, даже не затрагивая libtiff.
Почему вы не можете использовать свойство 'Length' в потоке? (['Length' является обязательным свойством для потока] (http://www.printmyfolders.com/understanding-pdf), он всегда должен присутствовать.) – Phillip
Опубликовать образец файла, чтобы мы могли видеть, что вы работаете с. – BitBank
@Phillip Не для встроенных объектов изображения, которые отображаются непосредственно в описании страницы. – Brian