Technical Article

Nativna JBIG2 bilevel kompresija slika u Delphi PDF-ovima

Skeniran ugovor je nekoliko stotina tacaka po incu crnog mastila na beloj hartiji. Smesten kao bitmapa s jednim bitom po pikselu vec je mali, ali sto takvih stranica i dalje naduvava PDF izvan svega sto biste poslali mejlom. Pravi filter menja aritmetiku. JBIG2 je kompresija s najvecim odnosom smanjenjas kojom ISO 32000-1 definise za bilevel slike, i na gomili skeniranog teksta rutinski prepolovi ono sto CCITT Group 4 proizvede. Ovo je filter za koji treba posegnuti kada je ulaz faksovan, skeniran ili inace sveden na dve boje, i HotPDF moze da ga upisuje direktno u PDF

Format zaradjuje taj odnos s dve ideje koje genericki kodek slike nema. Modelira kako crni nizovi stoje na beloj pozadini, i primecuje da se skeniranastrana u sustini sastoji od istih nekoliko stotina oblika glifova koji se ponavljaju hiljadama puta. Razumevanje oba sto vam omogucava da brate opcije kodiranja namerno umesto da pogadjate

Gde JBIG2 sedi u PDF specifikaciji

ISO 32000-1 navodi JBIG2Decode medju filterima tokova u §7.4.7, dostupan od PDF 1.4 nadalje. Primenjuje se na jedno mesto jedino: XObject slike ciji je /BitsPerComponent 1 i ciji se prostor boja razresava u jedan kanal. To je cela poenta. JBIG2 je bilevel kodek, pa nikad ne konkurise DCT ili JPXDecode na fotografijama. Konkurise CCITTFaxDecode, filterima faksa Group 3 i Group 4, na tacno onoj vrsti dvobojne stranice koju skener dokumenata proizvodi

Dekoder trosi ugradenu JBIG2 organizaciju koju standard zove PDF profilom, gde svaki tok slike sadrzi niz segmenata umesto golih bitova. Opcioni tok /JBIG2Globals nosi segmente deljene medju vise slika u istom dokumentu, sto je mehanizam koji dozvoljava da se ponavljajuci sadrzaj cuva jednom za celu datoteku umesto jednom po stranici. HotPDF podrazumevano emituje tok po slici i drzi kanal globals slobodnim osim ako ga backend ne zatrazi

Arhitektura enkodera s backendima na prvom mestu

Kompletan JBIG2 enkoder je velik deo softvera, i njegovi najagresivniji delovi su istorijski bili optereceni patentima i isporucivani pod licencama koje ne odgovaraju svakom proizvodu. HotPDF resava tu tenziju razdvajanjem interfejsa od endzina. Jedinica HPDFJBIG2 definise pozive koje ostatak biblioteke upucuje, i isporucuje skroman ugradjen enkoder tako da JBIG2 radi odmah. Kada su vam potrebni omjeri produkcijskog kvaliteta, registrujete jacis endzin i biblioteka mu delegira, bez ikakve promene u vasem kodu koji poziva

Prekidac je jedan poziv registracije. Bez registrovanog backenda, enkoder se vraca na ugradjenu putanju. Registrujte jedan i svako naknadno kodiranje prolazi kroz 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;

Ista kuka postoji za dekodiranje kroz RegisterJBIG2DecoderBackend, s IsJBIG2DecoderBackendAvailable za ispitivanje. Zato biblioteka isporucuje malu ugradjenu putanju plus spojnicu za backend umesto jednog monolitnog enkodera. Ugradjena putanja drzi binarni fajl malim i slobodnim od licencnih opterecenja, dok spojnica dozvoljava timu koji je licencirao pun enkoder da ga prikljuci bez dodirivanja sloja za upisivanje PDF-a uopste

Sta opcije kodiranja zapravo razmenjuju

Kodiranje se konfigurise kroz TJBIG2EncodeOptions, zapis s poljima Lossless, UseGlobalSegments, UseSymbolDictionary i LossyLevel. Omotac prilagodjen komponentama THPDFJBIG2Options objavljuje Lossless, UseSymbolDictionary i LossyLevel tako da se mogu postaviti iz Object Inspector-a, i interno ih konvertuje u zapis. Tri namere pokrecus postavke

Lossless rekonstrukcija cuva svaki piksel. Postavite Lossless na True i ostavite LossyLevel na nuli, i dekodovana bitmapa je bit-po-bit identicna ulazu. Ovo je jedini bezbedan izbor za linijsku umetnost, tehnicke crtezes i svaku stranicu gde bi izgubljen piksel mogao da promeni znacenje, kao sto su potpis ili pecat. Kodiranje recnikom simbola ukljucuje deduplikaciju svesnu teksta i opcija je koja razdvaja JBIG2 od faks filtera. Lossy nivo, ceo broj od 0 do 9, dozvoljava sposobnom backendu da trguje vernoscu za velicinu tretiranjem gotovo identicnih oznaka kao istog simbola. Nula znaci lossless. Ugradjen enkoder postuje samo lossless putanju i ignorise bilo koji nenulti lossy nivo, pa visi nivoi stupaju na snagu tek jednom kada je registrovan backend koji ih 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;

Recnici simbola i zasto tekstualni skenovi pobedjuju

Stranica skeniranog teksta zapravo nije slika reci. To je isto slovo e odstampano nekoliko stotina puta, isto t, isti zarez, svaka instanca malo bucna kopija jednog osnovnog oblika. Recnik simbola hvata tu strukturu. Enkoder prikuplja razlicite oznake na stranici u recnik, cuva svaki oblik jednom, a zatim beleizi stranicu kao listu pozicija koje upucuju na stavke recnika. Hiljadu pojava istog glifa kostaju jednu sacuvanu bitmapu plus hiljadu jeftinih plasiranja

Upravo tu JBIG2 pretice CCITT Group 4. Group 4 kodira svaki red skeniranja u odnosu na red iznad njega bez ikakvog pojma o glifu, pa placa pun troskak svakog slova svaki put kad se slovo pojavi. JBIG2 placa jednom. Kada se isti recnik promovise u tok globals na nivou dokumenta, usteda se mnozi kroz visestrani sken, jer su oblici zajednicki od stranice do stranice sacuvani jednom za celu datoteku. Na gustom tekstu razlika nije marginalna. To je razlog zasto JBIG2 postoji

Genericki region i MMR za sve ostalo

Nije svaka bilevel slika tekst. Karte, sheme, inzenjerski crtezes i mesovite stranice imaju linijsku umetnost koju nijedan recnik ne moze da sazme. Za njih, JBIG2 kodira genericki region, pravougaonik piksela kompresovan direktno bez ikakvog treninga simbola. Standard dozvoljava generickom regionu da koristi MMR, modifikovano modifikovano READ kodiranje koje Group 4 faks vec koristi, koje modelira svaki red piksela u odnosu na red iznad njega

Ovo je putanja koju HotPDF isporucuje u svom ugradjenom enkoderu. Kada nijedan backend nije registrovan i zahtev je lossless, biblioteka kompresuje bitmapu kao jedan MMR genericki region i umotava ga u JBIG2 strukturu segmenata koju PDF profil zahteva. Ne treba joj recnik, ni trening prolaz, ni druga slika za referencu, pa je pouzdana podrazumevana vrednost za linijsku umetnost i mesovit bilevel sadrzaj. Nece odgovarati punom enkoderu recnika simbola na cistom tekstu, ali je uvek tacan, uvek lossless i uvek prisutan. Povrsina enkodera za to je jedan poziv

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;

Ukljucivanje pri gradnji dokumenta

Za svakodnevnu upotrebu ne dodirujete klasu enkodera direktno. HotPDF izlaze JBIG2 kao izbor kompresije slike na dokumentu. Enumeracija THPDFImageCompressionType ukljucuje icJBIG2 pored Flate, JPEG i CCITT opcija, i dokument nosi osobinu JBIG2Options tipa THPDFJBIG2Options koja cuva postavke koriscene kada je izabrana ta kompresija. Podesite oba pre nego sto dodate bilevel slike koje zelite da kompresujete na ovaj nacin

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;

Jedna pogodnost vredna napomene je dodatak DBGridHotPDFExport, koji renderuje TDBGrid direktno u PDF. Njegov izlaz je uglavnom bilevel linije i tekst, pa dokument konfigurisan za JBIG2 drzi te izvoze kompaktnim bez ikakvog dodatnog rukovanja s vase strane. Dve srodne teme na ovom blogu idu dublje u okruzujuci tok rada. Za nacin na koji se slike i fontovi polazu kada gradite izvestaje, pogledajte izlaz izvestaja s fontovima i slikama u Delphi-ju. Kada kompresovan dokument mora da zadovolji arhivski profil, pravila u PDF/A, PDF/X i PDF/UA validaciji u Delphi-ju govore vam koje filtere odredjeni nivo uskladjenosti prihvata. JBIG2 se isporucuje kao deo HotPDF Component za Delphi i C++Builder, pored API-ja za ucitavanje, uredjivanje i sifrovanje pokrivenih na drugim mestima ovde