När du utvecklar dokumentlösningar för företag kommer du oundvikligen att stöta på PDF-filer genererade av en mängd olika verktyg, från avancerad Adobe-programvara till buggiga bibliotek med öppen källkod eller virtuella skrivardrivrutiner. Ett av de mest ökända strukturella problemen du kommer att möta är PDF-filer med "hybridreferens" (hybrid-reference).
I den här artikeln förklarar vi vad hybridreferenser är, varför vissa kontorsprogram genererar dem, och hur man programmatiskt kan tolka och reparera dessa strukturer med hjälp av Delphi och robusta PDF-bibliotek.
Utvecklingen av PDF-korsreferenstabellen
För att snabbt hitta objekt (teckensnitt, bilder, sidor) utan att tolka hela filen använder PDF en korsreferenstabell (Cross-Reference Table, XRef). I tidigare PDF-specifikationer (PDF 1.4 och äldre) var detta bokstavligen en ASCII-texttabell i slutet av filen.
Från och med PDF 1.5 introducerade Adobe Cross-Reference Streams (XRefStm), vilket komprimerade korsreferensdata till en binär ström, vilket avsevärt minskade filstorlekarna. För bakåtkompatibilitet med äldre PDF-läsare började dock vissa generatorer producera hybridreferens-PDF:er. Dessa filer innehåller både en ASCII XRef-tabell i äldre stil och en XRef-ström i nyare stil.
Problemet med hybridreferenser
Hybridfiler är teoretiskt sett giltiga, men många PDF-generatorer (särskilt äldre "Spara som PDF"-plugins i äldre Office-paket) skriver dem felaktigt. En vanlig bugg är att skriva fel byteförskjutning (byte offset) för `startxref`-pekaren, eller att skapa osammanhängande objektströmmar där XRef-tabellen pekar på fel generationsnummer.
Om din Delphi-applikation försöker läsa en dåligt formaterad hybrid-PDF med en strikt tolkare, kommer tolkaren att misslyckas med ett undantag för "Corrupt XRef table" eller "Invalid Object Number".
Hantera reservlösningar för hybrider med PDFium
PDFium-motorn (ursprungligen utvecklad av Foxit och släppt som öppen källkod av Google) är mycket tolerant mot felaktiga PDF-filer. När den upptäcker en trasig XRef-tabell söker den automatiskt filen baklänges från EOF för att hitta den alternativa XRefStm.
När du arbetar med PDFium i Delphi behöver du inte manuellt tolka trailer-ordböckerna (trailer dictionaries). Du bör dock kontrollera efter strukturella varningar så att du kan varna användaren eller logga problemet.
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;
Korrigera och bygga om PDF:en
Om ditt arbetsflöde kräver att PDF:en skickas vidare till ett striktare nedströmssystem (som en äldre hårdvaru-RIP) måste du "platta till" hybridstrukturen. Det mest pålitliga sättet att fixa en trasig hybrid-PDF i Delphi är att ladda in den i en tolerant motor och utföra en Spara som-åtgärd. Detta tvingar tolkaren att bygga om en ren, enhetlig XRef-tabell från objektträdet i minnet.
// 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;
Att förstå och förutse korruption av hybridreferenser säkerställer att dina dokumentbearbetningsflöden förblir motståndskraftiga, även när du står inför årtionden gamla äldre filer.
Obs: Upplösning av hybridreferenser och automatiska strukturella reparationer stöds fullt ut av PDFium Component.