Tehnični članek

Nativna binarnoslojna kompresija JBIG2 v PDF-jih Delphi

Skenirano pogodbo sestavljajo prek sto pik na palec črnega črnila na belem papirju. Shranjena kot enobiten bitmapa je že majhna, pa vendarle sto takšnih strani napihne PDF čez vse meje, ki bi jih poslali po e-pošti. Pravi filter spremeni to aritmetiko. JBIG2 je kompresija z najvišjim razmerjem, ki jo ISO 32000-1 opredeljuje za binarnoslojevne slike, in na svežnju skeniranega besedila rutinsko prepolovi to, kar ustvari CCITT Group 4. To je filter, ki ga posežete, ko je vhod faksiran, skeniran ali kako drugače zreduciran na dve barvi, HotPDF pa ga lahko zapiše neposredno v PDF

Format si to razmerje zasluži z dvema idejama, ki ju generični kodek za slike nima. Modelira, kako se črni nizi prilegajo belemu ozadju, in opazi, da je skenirana stran večinoma iste petstotine oblik glifov, ki se ponavljajo tisočkrat. Razumevanje obojega vam omogoča, da možnosti kodiranja izbirate premišljeno in ne na slepo

Kje JBIG2 sedi v specifikaciji PDF

ISO 32000-1 navaja JBIG2Decode med filtri tokov v §7.4.7, na voljo od PDF 1.4 naprej. Velja za eno samo mesto: slikovni XObjects, katerih /BitsPerComponent je 1 in katerih barvni prostor se razreši na en kanal. To je bistvo. JBIG2 je binarnoslojevni kodek, zato nikoli ne tekmuje z DCT ali JPXDecode na fotografijah. Tekmuje s CCITTFaxDecode, filtri faks Group 3 in Group 4, natanko na vrsti dvotonskih strani, ki jih ustvarja dokumentni skener

Dekoder porabi vgrajeno organizacijo JBIG2, ki jo standard imenuje profil PDF, kjer vsak tok slike vsebuje zaporedje segmentov namesto golega bitnega toka. Neobvezni tok /JBIG2Globals nosi segmente, skupne za več slik v istem dokumentu, kar je mehanizem, ki omogoča, da se ponavljajoča vsebina shrani enkrat za celotno datoteko in ne enkrat na stran. HotPDF privzeto oddaja tok za posamezno sliko in pusti kanal globalnih spremenljivk prost, razen če ga zaledni sistem ne zahteva

Arhitektura kodirnika z zaledjem

Popoln kodirnik JBIG2 je obsežna programska oprema, in njeni najagresivnejši deli so bili zgodovinsko obremenjeni s patenti in licencirani na načine, ki ne ustrezajo vsakemu izdelku. HotPDF to napetost razreši z ločitvijo vmesnika od pogona. Enota HPDFJBIG2 opredeljuje klice, ki jih preostali del knjižnice izvaja, in vsebuje skromen vgrajeni kodirnik, tako da JBIG2 deluje takoj po namestitvi. Ko potrebujete produkcijsko kakovostna razmerja, registrirate močnejši pogon in knjižnica mu delegira, brez spremembe klicne kode

Stikalo je en sam klic registracije. Brez registriranega zaledja kodirnik pade nazaj na vgrajeno pot. Registrirajte eno in vsako naslednje kodiranje teče skozi njega

uses
  HPDFJBIG2;

// Query what is active, then optionally install a stronger engine.
if not IsJBIG2EncoderBackendAvailable then
  // Production backend not present: HotPDF uses its built-in MMR path.
  RegisterJBIG2EncoderBackend(MyVendorJBIG2Encode);

// Later, to return to the built-in behaviour:
// ClearJBIG2Backends;

Enak kljukišče obstaja za dekodiranje prek RegisterJBIG2DecoderBackend, s IsJBIG2DecoderBackendAvailable za preverjanje. Zato knjižnica vsebuje majhno vgrajeno pot in šiv zaledja namesto enega monolitnega kodirnika. Vgrajena pot ohranja binarno datoteko majhno in prosto licenčnih obremenitev, medtem ko šiv ekipi, ki je licencirala popoln kodirnik, omogoča, da ga priključi, ne da bi se dotikala plasti pisanja PDF

Kaj možnosti kodiranja dejansko zamenjujejo

Kodiranje se konfigurira prek TJBIG2EncodeOptions, zapisa s polji Lossless, UseGlobalSegments, UseSymbolDictionary in LossyLevel. Ovoj, prijazen do komponent, THPDFJBIG2Options objavlja Lossless, UseSymbolDictionary in LossyLevel, tako da jih je mogoče nastaviti iz Object Inspector, interno pa pretvori v zapis. Tri namene določajo nastavitve

Brezizgubna rekonstrukcija ohrani vsak piksel. Nastavite Lossless na True in pustite LossyLevel pri nič, dekodirani bitmapa pa je bit za bitom identičen vhodu. To je edina varna izbira za linijsko grafiko, tehnične risbe in vsako stran, kjer bi izpadli piksel lahko spremenil pomen, na primer podpis ali žig. Slovarsko kodiranje simbolov vklopi deduplikacijo, usmerjeno v besedilo, in je možnost, ki JBIG2 loči od faks filtrov. Stopnja izgube - celo število od 0 do 9 - dovoli sposobnemu zaledju zamenjati zvestobo za velikost z obravnavo skoraj enakih oznak kot istega simbola. Nič pomeni brezizgubno. Vgrajeni kodirnik upošteva le brezizgubno pot in prezre vsako stopnjo izgube, ki ni nič, tako da višje stopnje začnejo delovati šele, ko je registrirano zaledni sistem, ki jih implementira

var
  Options: TJBIG2EncodeOptions;
begin
  Options := DefaultJBIG2EncodeOptions;   // Lossless True, symbol dictionary on
  Options.Lossless := True;
  Options.LossyLevel := 0;                // 0 keeps every pixel
  Options.UseSymbolDictionary := True;    // dedupe repeated glyphs
  // Pass Options to a backend, or let THPDFJBIG2Options carry them.
end;

Slovarji simbolov in zakaj besedilna skeniranja zmagajo

Stran skeniranega besedila v resnici ni slika besed. Je ista črka e, natisnjena večkrat sto krat, ista črka t, ista vejica - vsak primerek rahlo hrupna kopija ene temeljne oblike. Slovar simbolov zajame to strukturo. Kodirnik zbere različne oznake na strani v slovar, vsako obliko shrani enkrat, nato pa zabeleži stran kot seznam položajev, ki se sklicujejo na vnose slovarja. Tisoč pojavitev istega glifa stane eno shranjeno bitmapa in tisoč poceni postavitev

Točno tukaj JBIG2 preseže CCITT Group 4. Group 4 kodira vsako vrstico skeniranja glede na vrstico nad njo brez pojma glifa, zato plača polno ceno vsake črke vsakič, ko se črka pojavi. JBIG2 plača enkrat. Ko se isti slovar promovira v tok globalnih spremenljivk na ravni dokumenta, se prihranek sešteji prek večstranskega skeniranja, ker so oblike, ki si jih delijo stran za stranjo, shranjene enkrat za celotno datoteko. Pri gostih besedilih razlika ni robna. To je razlog, zakaj JBIG2 obstaja

Generično območje in MMR za vse ostalo

Ni vsaka binarnoslojevna slika besedilo. Zemljevidi, sheme, inženirske risbe in mešane strani vsebujejo linijsko grafiko, ki je noben slovar ne more povzeti. Za te JBIG2 kodira generično območje - pravokotnik pikslov, stisnjen neposredno brez kakršnega koli učenja simbolov. Standard dovoljuje generičnemu območju uporabo MMR, modificiranega modificiranega branja (READ), ki ga faks Group 4 že uporablja in ki modelira vsako vrstico pikslov glede na vrstico nad njo

To je pot, ki jo HotPDF vključuje v svojem vgrajenem koderniku. Ko ni registriranega zaledja in je zahteva brezizgubna, knjižnica stisne bitmapa kot eno generično območje MMR in ga ovije v strukturo segmentov JBIG2, ki jo profil PDF zahteva. Ne potrebuje slovarja, učnega prehoda ali druge slike za sklicevanje, zato je zanesljiva privzeta vrednost za linijsko grafiko in mešano binarnoslojevno vsebino. Ne bo dosegla polnega kodirnika s slovarji simbolov na čistem besedilu, a je vedno pravilna, vedno brezizgubna in vedno prisotna. Površina kodirnika zanjo je en sam klic

var
  Encoder: THPDFJBIG2Encoder;
  ImageData: TJBIG2ByteArray;
  Scanlines: TJBIG2ScanlineArray;  // one byte array per row, MSB-first
  W, H: Integer;
begin
  // Scanlines, W and H describe a 1-bit page; each row is (W + 7) div 8 bytes.
  Encoder := THPDFJBIG2Encoder.Create;
  try
    if Encoder.EncodeToByteArray(Scanlines, W, H, ImageData) then
      // ImageData now holds a JBIG2 stream ready for a /JBIG2Decode XObject.
      ;
  finally
    Encoder.Free;
  end;
end;

Vklop pri gradnji dokumenta

Pri vsakodnevni uporabi se razredom kodirnika ne dotikate neposredno. HotPDF razkrije JBIG2 kot možnost stiskanja slik v dokumentu. Naštevanje THPDFImageCompressionType vključuje icJBIG2 ob možnostih Flate, JPEG in CCITT, dokument pa nosi lastnost JBIG2Options tipa THPDFJBIG2Options, ki vsebuje nastavitve, ki se uporabijo pri izbiri tega stiskanja. Obe nastavitve konfigurirajte, preden dodate binarnoslojevne slike, ki jih želite stisniti na ta način

var
  Pdf: THotPDF;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.ImageCompressionType := icJBIG2;     // route 1-bit images through JBIG2
    Pdf.JBIG2Options.Lossless := True;        // keep every pixel
    Pdf.JBIG2Options.UseSymbolDictionary := True;
    Pdf.JBIG2Options.LossyLevel := 0;
    // Add pages and place your scanned 1-bit images here.
  finally
    Pdf.Free;
  end;
end;

Ena prikladnost, ki je vredna omembe, je dodatek DBGridHotPDFExport, ki izrisuje TDBGrid neposredno v PDF. Njegov izhod je večinoma binarnoslojevne vrstice in besedilo, zato dokument, konfiguriran za JBIG2, ohranja te izvoze kompaktne brez kakršne koli dodatne obravnave z vaše strani. Dve sorodni temi na tem blogu se poglabljata v okoliški potek dela. Za informacije o tem, kako se slike in pisave razporedijo pri gradnji poročil, glejte izhod poročil s pisavami in slikami v Delphiju. Ko mora stisnjen dokument ustrezati arhivskemu profilu, pravila v validaciji PDF/A, PDF/X in PDF/UA v Delphiju povedo, katere filtre sprejema določena raven skladnosti. JBIG2 je del komponente HotPDF Component za Delphi in C++Builder, skupaj z vmesniki API za nalaganje, urejanje in šifriranje, opisanimi drugje na tem blogu