Tehnički članak

Izvorna JBIG2 dvorazinska kompresija slika u Delphi PDF-ovima

Skenirani ugovor iznosi nekoliko stotina točaka po inču crne tinte na bijelom papiru. Pohranjen kao jednobitna po pikselu bitmapa, već je mali, a ipak stotinu takvih stranica napuhuje PDF više nego što biste poslali e-poštom. Pravi filter mijenja aritmetiku. JBIG2 ima najveći omjer kompresije koji ISO 32000-1 definira za dvorazinske slike, a na hrpi skeniranog teksta redovito prepolovi ono što proizvodi CCITT Group 4. Ovo je filter za kojim trebate posegnuti kada je unos faksiran, skeniran ili na drugi način reduciran na dvije boje, a HotPDF ga može izravno upisati u PDF

Format postiže ovaj omjer s dvije ideje koje generički kodek slika nema. On modelira kako crni tragovi sjede na bijeloj pozadini te uočava da se skenirana stranica sastoji uglavnom od istih nekoliko stotina oblika glifova ponovljenih tisućama puta. Razumijevanje obojeg omogućava vam da svjesno odaberete opcije kodiranja umjesto nagađanja

Gdje JBIG2 pripada u PDF specifikaciji

ISO 32000-1 navodi JBIG2Decode među stream filterima u §7.4.7, dostupnim od PDF 1.4 pa nadalje. Primjenjuje se samo na jedno mjesto: slikovne XObjekte čiji je /BitsPerComponent 1 i čiji se prostor boja rješava u jednom kanalu. U tome je cijela poanta. JBIG2 je dvorazinski kodek, tako da se nikada ne natječe s DCT ili JPXDecode na fotografijama. Natječe se sa CCITTFaxDecode, faks filterima Group 3 i Group 4, upravo na vrsti dvotonske stranice kakvu proizvodi skener dokumenata

Dekoder konzumira ugrađenu organizaciju JBIG2 koju standard naziva PDF profilom, gdje svaki tok slike sadrži niz segmenata umjesto samog toka bitova. Opcionalni /JBIG2Globals tok nosi segmente podijeljene između nekoliko slika u istom dokumentu, što je mehanizam koji omogućava pohranu ponovljenog sadržaja samo jednom za cijelu datoteku, a ne jednom po stranici. HotPDF podrazumijevano emitira tok za svaku pojedinu sliku i drži globals kanal slobodnim osim ako ga pozadina ne zatraži

Arhitektura kodera usmjerena na pozadinu

Cjeloviti JBIG2 koder opsežan je komad softvera, a njegovi najagresivniji dijelovi povijesno su bili opterećeni patentima i isporučivani pod licencama koje ne odgovaraju svakom proizvodu. HotPDF rješava tu napetost odvajanjem sučelja od pokretača. Jedinica HPDFJBIG2 definira pozive koje ostatak biblioteke donosi i isporučuje skromni ugrađeni koder kako bi JBIG2 radio odmah po instalaciji. Kada su vam potrebni omjeri proizvodne klase, registrirate snažniji pokretač, a biblioteka ga delegira bez promjene vašeg pozivajućeg koda

Prekidač je jedinstven poziv za registraciju. Bez registrirane pozadine, koder se vraća na svoju ugrađenu putanju. Registrirajte jednu i svako sljedeće kodiranje ide kroz nju

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 spojnica postoji za dekodiranje preko RegisterJBIG2DecoderBackend, s IsJBIG2DecoderBackendAvailable za sondiranje. Zbog toga se biblioteka isporučuje s malom ugrađenom putanjom i pozadinskim priključkom umjesto s jednim monolitnim koderom. Ugrađena putanja održava binarne datoteke tankima i slobodnima od licencnih zapleta, dok priključak omogućava timu koji je licencirao cjeloviti koder da ga priključi bez ikakvog diranja sloja za pisanje PDF-ova

Što opcije kodiranja zapravo nude

Kodiranje je konfigurirano pomoću TJBIG2EncodeOptions, zapisa s poljima Lossless, UseGlobalSegments, UseSymbolDictionary i LossyLevel. Komponentama prilagođen omotač THPDFJBIG2Options objavljuje Lossless, UseSymbolDictionary i LossyLevel tako da se mogu postaviti iz Object Inspectora, a interno pretvara u zapis. Tri namjere pokreću postavke

Rekonstrukcija bez gubitaka čuva svaki piksel. Postavite Lossless na True te ostavite LossyLevel na nuli, a dekodirana bitmapa je bit-po-bit identična unosu. To je jedini siguran izbor za linijski crtež, tehničke nacrte i svaku stranicu na kojoj bi ispušteni piksel mogao promijeniti značenje, poput potpisa ili pečata. Kodiranje sa simbolnim rječnikom uključuje deduplikaciju svjesnu teksta i opcija je koja odvaja JBIG2 od faks filtera. Razina s gubicima, cijeli broj od 0 do 9, omogućava sposobnoj pozadini razmjenu vjernosti za veličinu tretiranjem gotovo identičnih oznaka kao istog simbola. Nula označava bez gubitaka. Ugrađeni koder poštuje isključivo putanju bez gubitaka i zanemaruje svaku razinu gubitka različitu od nule, pa više razine stupaju na snagu samo kada je registrirana pozadina koja 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;

Simbolički rječnici i zašto tekstualna skeniranja pobjeđuju

Stranica skeniranog teksta zapravo nije slika riječi. To je isto slovo e ispisano nekoliko stotina puta, isto t, isti zarez, a svaki je primjerak blago šumna kopija jednog temeljnog oblika. Simbolni rječnik bilježi takvu strukturu. Koder prikuplja različite oznake na stranici u rječnik, pohranjuje svaki oblik jednom, a zatim zapisuje stranicu kao popis pozicija koje upućuju na rječničke unose. Tisuću pojavljivanja istog glifa stoji jednu pohranjenu bitmapu uz tisuću jeftinih plasmana

Upravo ovdje JBIG2 nadmašuje CCITT Group 4. Group 4 kodira svaku skeniranu liniju s obzirom na liniju iznad nje bez shvaćanja glifa, tako da plaća puni trošak svakog slova svaki put kad se slovo pojavi. JBIG2 plaća jednom. Kada se isti rječnik promovira na globalni tok na razini dokumenta, ušteda se multiplicira tijekom skeniranja s više stranica, budući da se oblici koje dijele mnogobrojne stranice pohranjuju samo jednom za cijelu datoteku. U gustom tekstu razlika nije zanemariva. Zato JBIG2 i postoji

Generička regija i MMR za sve ostalo

Nije svaka dvorazinska slika tekst. Karte, sheme, tehnički nacrti i mješovite stranice sadrže linijsku grafiku koju niti jedan rječnik ne može sažeti. Za njih, JBIG2 kodira generičku regiju, pravokutnik piksela komprimiran izravno bez ikakvog vježbanja na simbolima. Standard dozvoljava generičkoj regiji upotrebu MMR-a (modified modified READ kodiranje koje se već koristi kod faksa Group 4), što modelira svaki red piksela na onaj red iznad njega

To je putanja s kojom HotPDF isporučuje svoj ugrađeni koder. Kad ni jedna pozadina nije registrirana i zahtjev je bez gubitaka, biblioteka komprimira bitmapu kao jednu MMR generičku regiju i omotava je u JBIG2 segmentnu strukturu koja je potrebna za PDF profil. Za nju nije potreban rječnik, vježbanje i slika za referencu, pa je pouzdana podrazumijevana postavka za linijsku grafiku te mješoviti dvorazinski sadržaj. Neće se nositi s punim koderom simbolnog rječnika na čistom tekstu, ali je uvijek točna, bez gubitaka i uvijek dostupna. Površina kodera za nju je samo 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;

Uključivanje prilkom izrade dokumenta

Za svakodnevnu upotrebu ne trebate izravno mijenjati klasu kodera. HotPDF nudi JBIG2 kao opciju kompresije slike na dokumentu. Enumeracija THPDFImageCompressionType uključuje icJBIG2 usporedo s opcijama Flate, JPEG i CCITT, a dokument posjeduje i svojstvo JBIG2Options tipa THPDFJBIG2Options koje zadržava postavke koje se koriste kada se takva kompresija odabere. Konfigurirajte obje prije nego što dodate dvorazinske slike koje želite tako komprimirati

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;

Zgodna značajka koju vrijedi napomenuti je DBGridHotPDFExport dodatak, koji pretvara TDBGrid izravno u PDF. Izlaz koji pruža najvećim se dijelom sastoji od dvorazinskih pravila i teksta, tako da dokument konfiguriran za JBIG2 takve izvoze održava kompaktnima bez ikakve dodatne obrade s vaše strane. Dvije srodne teme na ovom blogu dublje razmatraju povezani radni tijek. Za to kako se slike i fontovi postavljaju prilikom izrade izvještaja, pogledajte ispis izvještaja s fontovima i slikama u Delphiju. Kada komprimirani dokument mora zadovoljiti arhivski profil, pravila za validaciju PDF/A, PDF/X i PDF/UA u Delphiju pojašnjavaju vam koji su filtri dopušteni na zadanoj razini usklađenosti. JBIG2 isporučuje se u sklopu komponente HotPDF Component za Delphi i C++Builder, usporedo s API-jima za učitavanje, uređivanje i šifriranje o kojima se raspravlja negdje drugdje na ovom blogu