Amikor vállalati dokumentummegoldásokat fejleszt, elkerülhetetlenül találkozni fog olyan PDF-ekkel, amelyeket a legkülönfélébb eszközökkel generáltak—a csúcskategóriás Adobe szoftverektől kezdve a hibás nyílt forráskódú könyvtárakig vagy virtuális nyomtató-illesztőprogramokig. Az egyik leghírhedtebb strukturális probléma, amellyel szembesülni fog, a "hibrid hivatkozású" PDF.
Ebben a cikkben elmagyarázzuk, mik azok a hibrid hivatkozások, miért generálják őket bizonyos irodai alkalmazások, és hogyan lehet programozottan elemezni és javítani ezeket a struktúrákat a Delphi és robusztus PDF könyvtárak segítségével.
A PDF kereszthivatkozási tábla evolúciója
Annak érdekében, hogy az objektumokat (betűtípusokat, képeket, oldalakat) gyorsan meg lehessen találni a teljes fájl elemzése nélkül, a PDF egy kereszthivatkozási táblát (Cross-Reference Table, XRef) használ. A korábbi PDF specifikációkban (PDF 1.4 és régebbi) ez egy egyszerű ASCII szöveges tábla volt a fájl végén.
A PDF 1.5-től kezdődően az Adobe bevezette a Kereszthivatkozási streameket (Cross-Reference Streams, XRefStm), amelyek a kereszthivatkozási adatokat egy bináris streambe tömörítették, jelentősen csökkentve a fájlméretet. Azonban a régebbi PDF-olvasókkal való visszafelé kompatibilitás érdekében egyes generátorok hibrid hivatkozású PDF-eket kezdtek el előállítani. Ezek a fájlok mind egy régi stílusú ASCII XRef táblát, mind egy új stílusú XRef streamet tartalmaznak.
A probléma a hibrid hivatkozásokkal
A hibrid fájlok elméletileg érvényesek, de sok PDF-generátor (különösen a régebbi Office csomagok "Mentés PDF-ként" beépülő moduljai) helytelenül írja meg őket. Egy gyakori hiba a startxref mutató helytelen bájteltolásának beírása, vagy olyan szétkapcsolt objektumstreamek létrehozása, ahol az XRef tábla rossz generációs számra mutat.
Ha a Delphi alkalmazása megpróbál beolvasni egy rosszul formázott hibrid PDF-et egy szigorú elemzővel, az elemző "Sérült XRef tábla" vagy "Érvénytelen objektumszám" kivétellel leáll.
Hibrid tartalékok kezelése a PDFium segítségével
A PDFium motor (amelyet eredetileg a Foxit fejlesztett, majd a Google tett nyílt forráskódúvá) rendkívül toleráns a hibás PDF-ekkel szemben. Amikor sérült XRef táblát észlel, automatikusan visszafelé pásztázza a fájlt az EOF-tól (fájl végétől), hogy megtalálja az alternatív XRefStm-et.
Delphiben, amikor a PDFiummal dolgozik, nem kell manuálisan elemeznie a trailer szótárakat. Ugyanakkor érdemes ellenőriznie a strukturális figyelmeztetéseket, hogy riaszthassa a felhasználót vagy naplózhassa a problémát.
uses
System.SysUtils, pdfium_lib;
procedure LoadAndCheckHybridPDF(const FileName: string);
var
Doc: FPDF_DOCUMENT;
LastError: ULONG;
begin
FPDF_InitLibrary();
try
Doc := FPDF_LoadDocument(PAnsiChar(AnsiString(FileName)), nil);
if Doc = nil then
begin
LastError := FPDF_GetLastError();
case LastError of
FPDF_ERR_FILE: Writeln('File not found or could not be opened.');
FPDF_ERR_FORMAT: Writeln('File not in PDF format or corrupted.');
FPDF_ERR_PASSWORD: Writeln('Password required or incorrect password.');
FPDF_ERR_SECURITY: Writeln('Unsupported security scheme.');
FPDF_ERR_XFDF: Writeln('Invalid XRef or Hybrid Reference structure.');
else
Writeln('Unknown error occurred loading PDF.');
end;
Exit;
end;
Writeln('PDF loaded successfully despite hybrid or structural anomalies.');
// Proceed with processing...
FPDF_CloseDocument(Doc);
finally
FPDF_DestroyLibrary();
end;
end;
A PDF javítása és újraépítése
Ha a munkafolyamata megköveteli, hogy a PDF-et egy szigorúbb, a folyamatban hátrébb lévő rendszernek (például egy régebbi hardveres RIP-nek) adja át, "lelapítania" (flatten) a hibrid struktúrát. Egy hibás hibrid PDF javításának legmegbízhatóbb módja Delphiben, ha betölti egy toleráns motorba, és végrehajt egy Mentés másként műveletet. Ez arra kényszeríti az elemzőt, hogy a memóriában lévő objektumfából újraépítsen egy tiszta, egységes XRef táblát.
// Conceptual example using a high-level wrapper
procedure RebuildPdfStructure(const InputFile, OutputFile: string);
var
Doc: TlxPDFDocument;
begin
Doc := TlxPDFDocument.Create;
try
// Tolerant engine ignores the broken hybrid XRef and walks the objects
Doc.LoadFromFile(InputFile);
// Saving rewrites the file with a clean PDF 1.7 XRef stream
Doc.SaveToFile(OutputFile);
Writeln('PDF structure successfully rebuilt.');
finally
Doc.Free;
end;
end;
A hibrid hivatkozások sérülésének megértése és előrejelzése biztosítja, hogy a dokumentumfeldolgozási folyamatai rugalmasak maradjanak, még akkor is, ha évtizedes, elavult fájlokkal találkozik.
Megjegyzés: A hibrid hivatkozások feloldását és az automatikus strukturális javításokat teljes mértékben támogatja a PDFium Component.