Nói đúng cách (Có thể sử dụng libtiff ...?), có. Nó liên quan đến một số hack, nhưng không quá nhiều.
Sự thật: dữ liệu sẽ bao gồm một dải, vì không có bất kỳ thông tin bù đắp nào, do đó, chênh lệch duy nhất của chúng tôi bằng 0. Chúng tôi chỉ cần đọc dải đó.
Sự thật: dữ liệu này là nén của ma trận điểm ảnh sâu 1 bit W * H.
Bước 1: ước tính độ dài tối đa có thể có của luồng nén. Điều này xuất hiện vào khoảng 15% W * H, tức là với W = 1000 và H = 1000 bạn nhận được 150000 byte. Giá trị này sẽ luôn là nhiều hơn so với giá trị thực tế. Nếu chúng tôi có ước tính tốt hơn nhờ có vị trí thẻ hình ảnh cuối EI thích hợp, điều đó thậm chí còn tốt hơn nhưng không cần thiết.
Bước 2: tạo tệp TIF "ảo". Điều này sẽ được tạo thành từ tiêu đề của biểu mẫu 49 49 2a 00 AA BB CC DD
, trong đó 0xDDCCBBAA là chiều dài ước tính cộng 8; tiếp theo là luồng dữ liệu ước tính của chúng tôi; tiếp theo là một thư mục TIFF.
Bước 3: thư mục TIFF sẽ luôn có cùng cấu trúc; một số giá trị trong đó là bù trừ và phụ thuộc trivially từ vị trí IFD 0xDDCCBBAA. Trích dẫn từ thông số kỹ thuật TIFF6 (lưu ý rằng thứ tự byte được đảo ngược - Motorola, không 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”
Ở phía trên, 0xDDCCBBAA thực sự là 0014 và tất cả các offsets khác làm theo.
Tôi đã thực hiện một số thử nghiệm bằng một hình ảnh TIFFG4 dải đơn mà tôi đã tạo bằng định dạng CCITT 1Một hình ảnh và định dạng 1Magick và tiffcp
'. Tiêu đề có hơi khác (tôi không thấy thẻ Phần mềm và Thẻ ngày giờ mà thông số nói nên có ở đó). Nếu không nó sẽ kiểm tra.
Hiện tại, chúng tôi có một ảnh bị hư hỏng TIFF với một dải quá dài và nó nằm trong bộ nhớ.
Sử dụng TIFFClientOpen
, chúng tôi có thể access it as if it was a disk image.
Cố gắng đọc các dải đầu tiên bây giờ sẽ dẫn đến một lỗi và hủy chương trình:
TIFFFillStrip: Read error on strip 0; got 143151 bytes, expected 762826.
Bằng cách sử dụng TIFFSetErrorHandler
và TIFFSetErrorHandlerExt
chúng tôi thiết lập chính mình để ngăn chặn lỗi này, và phân tích nó, qua đó khôi phục 143151
thông tin, thay vì hủy bỏ.
Chúng ta cần phải cung cấp các callbacks để TIFFClientOpen
, nhưng tất cả họ đều rất dễ dàng:
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
Việc xử lý thực sự là vụng về và phức tạp, nhưng đối với tính khả thi, nó thể được thực hiện.
Tôi đã chạy thử nghiệm bằng ngôn ngữ C, trích xuất thủ công luồng CCITT từ một tệp BI/ID/EI PDF nội tuyến tôi tìm thấy trực tuyến và đọc nó như mô tả ở trên.
Nếu tôi có cách chắc chắn để xác định EI chính xác - tôi đã nạo vét a message by Tilman Hausherr giải thích một hack để nhận ra các nhà khai thác PDF hợp lệ theo EI để làm như vậy. nhiều phương pháp tốt hơn - tôi luôn có thể ước tính độ lệch chính xác và trực tiếp tạo ra một tệp TIFF chính xác và có thể đọc được từ tệp PDF mà không hề liên quan đến libtiff.
Tại sao bạn không thể sử dụng thuộc tính 'Chiều dài' của luồng? (['Độ dài' là thuộc tính bắt buộc đối với luồng] (http://www.printmyfolders.com/understanding-pdf), nó phải luôn có mặt.) – Phillip
Đăng tệp mẫu để chúng tôi có thể xem bạn đang làm việc gì với. – BitBank
@Phillip Không dành cho các đối tượng hình ảnh nội tuyến, xuất hiện trực tiếp bên trong mô tả trang. – Brian