Tekninen artikkeli

PDF:n automaattiset esitarkistukset Delphissä

Tiedosto avautuu omalla koneella ja näyttää oikealta, mutta painotalo tai kuukausierän vastaanottava arkistojärjestelmä hylkää sen: CMYK-työssä on RGB-kuvia, /Trapped-avain puuttuu tai output intent ei vastaa painoa. Näkyvä asiakirja ei ollut rikki, vaan se rikkoi muualla tarkistettua profiilia. Preflight on tämän tarkistuksen painotuotantotermi. Delphi-koodin itse tuottamille PDF-tiedostoille olennaista on valita oikea tarkistuskohta

HotPDF ei tarjoa kutsuttavaa preflight-toimintoa. Komponentin GUI demo sisältää preflight report -ikkunan, mutta sen takana ei ole palvelun tai build script -prosessin käyttämää API:a. Itse tuotetuissa tiedostoissa parempi jako on estää generaattoria luomasta virheellistä tiedostoa ja todistaa tulos riippumattomalla työkalulla

Miksi oma tuloste tarkistetaan eri tavalla

Perinteinen preflight tutkii tuntemattoman tiedoston, jonka sovellusta ja muokkausketjua ei tunneta. Oman koodin tuottamassa tiedostossa ohjelma päätti juuri fonttien upotuksen, väriavaruuden, output intent -rakenteen ja metadatan. Näiden valintojen jälkikäteisen löytämisen sijasta rajaa ne niin, ettei vaatimustenvastaista tiedostoa voi syntyä

Pidä todentaminen ulkoisena myös uskottavuuden vuoksi. Kirjaston omalle tulokselleen antama hyväksyntä ei auta, kun asiakkaan arkisto tai painon RIP hylkää tiedoston. veraPDF- tai Acrobat-tulos on merkityksellinen, koska vastaanottaja käyttää samoja työkaluja

Tee vaatimustenmukaisuudesta asetus, ei tarkistuslista

Aseta PDFACompliance tai PDFXCompliance ennen BeginDoc-kutsua. HotPDF ylläpitää sääntöjä koko generoinnin ajan: se upottaa fontit, vertaa DeviceRGB- ja DeviceCMYK-käyttöä määritettyyn output intent -rakenteeseen ja torjuu profiilin kieltämät ominaisuudet. Ristiriidat nostetaan EndDoc-kutsussa. Tallennuksen jälkeen samat ominaisuudet kertovat, mitä todella pakotettiin, joten kirjaa ne pipeline-lokiin:

// After EndDoc: record the enforced profiles with the run metadata
if Pdf.PDFACompliance <> '' then
  Log('Generated as PDF/A level ' + Pdf.PDFACompliance);
if Pdf.PDFXCompliance <> '' then
  Log('Generated as PDF/X profile ' + Pdf.PDFXCompliance);

Kirjaa liput samalle riville input data hash- ja HotPDF version -tietojen kanssa. Kun validator ja generator ovat eri mieltä, rivistä selviävät template ja ladattu library build. Output intents, ICC profiles ja tagging on kuvattu HotPDFin PDF/A-, PDF/X- ja PDF/UA-oppaassa

Edullinen ensiportti muualta saatuihin tiedostoihin

Asiakkaiden latauksia, skannerituloksia ja kumppaneiden liitteitä ei kannata lähettää täyteen rakennevalidointiin, jos ne eivät edes avaudu. HotPDFin Direct File API lukee riittävästi rakennetta vastatakseen, onko tiedosto käyttökelpoinen PDF, lataamatta koko objektipuuta:

function TriagePdf(Pdf: THotPDF; const FileName: string): Boolean;
var
  Handle, Pages: Integer;
begin
  Result := False;
  Handle := Pdf.DAOpenFileReadOnly(FileName, '');
  if Handle <= 0 then
    Exit;  // structurally unreadable: quarantine, do not validate
  try
    Pages := Pdf.DAGetPageCount(Handle);
    Result := Pages > 0;
  finally
    Pdf.DACloseFile(Handle);
  end;
end;

Flat-memory-oikopolku toimii vain salaamattomalle syötteelle. Salasanan antaminen DAOpenFileReadOnly-kutsulle siirtää käsittelyn hiljaisesti täyteen jäsennykseen, joten tunnetusti salattu tiedosto puretaan DecryptFile-kutsulla tavalliseksi työkopioksi ennen triage-vaihetta. DAGetPageCount ei merkitse mitään epäonnistuneella handle-arvolla: pidä handle-tarkistus tiukkana ja hylkää ei-positiivinen tulos. Lisää malleja on suurten PDF-työnkulkujen Direct File API -artikkelissa

veraPDF osana build-prosessia

PDF/A- ja PDF/UA-väitteille käytä veraPDF-validaattoria. Se toimii headless-tilassa, käsittelee erän, tuottaa XML- tai JSON-raportin ja nimeää virheet ISO-kohdittain. Esimerkiksi ISO 19005-1 kohdan 6.2.2 virhe johtaa suoraan generator-asetukseen. Delphistä käyttö on tavallista prosessinhallintaa:

function RunVeraPdf(const PdfFile, ReportFile: string): Cardinal;
var
  Cmd: string;
  SI: TStartupInfo;
  PI: TProcessInformation;
begin
  Cmd := Format('cmd /c verapdf.bat --format xml "%s" > "%s"',
    [PdfFile, ReportFile]);
  FillChar(SI, SizeOf(SI), 0);
  SI.cb := SizeOf(SI);
  if not CreateProcess(nil, PChar(Cmd), nil, nil, False,
      CREATE_NO_WINDOW, nil, nil, SI, PI) then
    RaiseLastOSError;
  try
    WaitForSingleObject(PI.hProcess, 120000);  // bound the wait per file
    GetExitCodeProcess(PI.hProcess, Result);
  finally
    CloseHandle(PI.hThread);
    CloseHandle(PI.hProcess);
  end;
end;

Timeout estää malformed file -tapauksen pysäyttämästä queue worker -prosessia ja koko jonoa. Rajaa odotus, anna aikakatkaisulle oma failure code ja siirrä tiedosto ihmisen tarkistettavaksi. Jäsennä XML:stä rule identifiers, älä viestitekstiä: tunnisteet säilyvät validator upgrades -muutoksissa ja niitä voi hakea vanhoista tukipyynnöistä

Käynnistä yksi process per file, jotta vaarallinen syöte kuluttaa vain oman aikakatkaisunsa. Rajoita validator processes enintään core count -määrään, koska XML-raportin rakentaminen on CPU-bound ja ylimerkintä aiheuttaa thrashing-ilmiön. Aseta myös intake size ceiling, sillä kahden gigatavun skannattu kirja voi vallata jonon. Näin portti kestää kuukauden lopun kuorman eikä sitä poisteta käytöstä ensimmäisen yöllisen pysähdyksen jälkeen

veraPDF ei validoi PDF/X-tiedostoja. Käytännön tarkistus on Acrobat Preflight painon nimeämällä ISO 15930 -profiililla. Koska Acrobat vaatii ihmisen, tarkista uuden templaten ensimmäinen tiedosto ja pieni satunnaisotos jokaisesta erästä; automaattinen portti kattaa muun sisällön

Raportti, jota tarvitaan vielä vuoden kuluttua

Säilytä jokaisesta tarkistetusta tiedostosta input hash, generator compliance flags ja library version, validator name ja version, käytetty profile, pass/fail sekä failed rule IDs ja page numbers aina kun validaattori antaa ne. Tallenna raportti kuvaamansa tiedoston viereen, jotta erillinen raportointijärjestelmä ei katoa ennen arkistoa

Kirjaa myös poikkeukset. Jos asiakas vaatii hylätyn tiedoston toimittamista, älä löysää sääntöä kaikille. Tallenna hyväksyjä, peruste ja voimassaolon päättymispäivä sekä liitä waiver raporttiin. Nimetyllä omistajalla ja expiry-arvolla varustettu poikkeus on hallittu päätös; väliaikaisesti kommentoitu tarkistus on tuleva häiriö

Kun tiedosto epäonnistuu, kopioi se nimettyyn regression folder -hakemistoon ennen muokkausta. Useimmat preflight-ongelmat palautuvat yhteen syötteeseen, ja sen säilyttäminen nopeuttaa toistuvan virheen korjausta. Tässä käytetyt compliance properties ja Direct File API kuuluvat Delphin ja C++Builderin HotPDF Component -tuotteeseen, jonka dokumentaatio kuvaa kutsut kokonaan