Skenirani medicinski dijapozitiv, pločica zračnog snimanja, filmski kadar arhiviran u punom dinamičkom rasponu. To su slike koje pristižu kao JPEG 2000 i stižu takve s razlogom. Format zadržava 12 ili 16 bita po kanalu, komprimira se pomoću valićne transformacije umjesto blokovnog DCT-a kojeg koristi JPEG te može kodirati istu sliku i bez gubitaka i s gubicima iz jednog toka kodova (codestream). Kada dokument nastao iz takvih izvora mora postati PDF, slika treba proći kroz filter koji PDF specifikacija rezervira upravo za ovaj kodek
HotPDF v2.228.0 obnovio je ispravan JPEG 2000 pokretač za dekodiranje na tom putu. Ranija verzija isporučila je jedinicu s funkcijama zamjene (stub functions) koje su vraćale nil, tako da je API postojao, ali nije dekodirao ništa. Trenutačni pokretač statički veže OpenJPEG 2.5.4 i pretvara JP2 ili J2K izvor u piksele koje HotPDF može smjestiti na stranicu
Filter JPXDecode u PDF-u
ISO 32000-1 definira filter JPXDecode u §7.4.9. PDF slikovni XObjekt imenuje svoju kompresiju u unosu /Filter u rječniku toka, a JPXDecode je vrijednost koja kaže da su podaci toka zapravo JPEG 2000 tok kodova umjesto osnovnog JPEG-a kojeg nosi /DCTDecode. Ovaj filter dopušta PDF-u zadržavanje slikovnih podataka s valićnom kompresijom uz veliku dubinu bita te priznaje načine rada kodeka s i bez gubitaka, jer način rada predstavlja svojstvo samog toka kodova, a ne omotača oko njega
Te zadnje točke vrijedi se držati. JPEG 2000 je jedan algoritam s posebnim slučajem bez gubitaka, a ne dva odvojena formata. Povratni 5/3 valić precizno rekonstruira originalne uzorke; nepovratni 9/7 valić tu točnost mijenja za manju datoteku. Dekoder tretira oboje na isti način u trenutku čitanja, zbog čega je HotPDF-u potrebna samo jedna putanja dekodiranja za prihvaćanje onoga što god joj baci JPXDecode tok
Što dekoder radi s pikselima
U uobičajenom slučaju, PDF slikovni XObjekti očekuju 8 bita po komponenti u DeviceGray ili DeviceRGB. JPEG 2000 to redovito premašuje, a njegov model komponente općenitiji je od spakiranog rastera, tako da dekoder mora obaviti tri posla prije nego što podaci postanu upotrebljivi kao normalna slika
Prvo se komponente s velikom dubinom bita ponovno uzorkuju na 8 bita. Uzorak od 12 ili 16 bita smanjuje se na raspon od 0 do 255 kako bi rezultat bio običan 8-bitni raster. Komponente s predznakom prvo se pomiču u raspon bez predznaka. Taj je detalj važan jer sa sobom nosi gubitke: 16-bitno skeniranje u sivim tonovima gubi svoj duboki tonalni raspon u onom trenutku kada postane 8-bitna PDF slika, što predstavlja pravu pogodbu kod izlaza na zaslon i ispis, ali ne i za ponovno arhiviranje
Kao drugo, YCbCr (kodek ga naziva SYCC) prostor boja pretvara se u RGB. Radi učinkovitosti kompresije JPEG 2000 često pohranjuje boju u prostor luma-kroma, s istom idejom koju primjenjuje osnovni JPEG, a dekoder koristi standardnu inverznu transformaciju tako da stranica dobiva pravi RGB
Treće, poduzorkovane komponente naduzorkovane su umnožavanjem najbližeg susjeda. Kanali kromatičnosti često se pohranjuju u polovičnoj razlučivosti pa dekoder čita svaku komponentu u njezinim vlastitim dimenzijama i vlastitim faktorom uzorkovanja, a zatim replicira uzorke kako bi svaki kanal doveo do pune veličine slike prije isprepletanja. Najbliži susjed taj korak održava jeftinim; kromatičnost koju popunjava ionako je započela s niskom frekvencijom, tako da je vidljivi trošak malen
Spremnici JP2 naprema sirovom J2K toku kodova
Datoteka JPEG 2000 dolazi u dva oblika, a HotPDF iz prvih bajtova, umjesto iz datotečnog nastavka, prepoznaje onaj koji trenutno čita. JP2 datoteka je spremnik sa strukturom okvira: otvara se spremnikom potpisa od dvanaest bajtova 00 00 00 0C 6A 50 20 20 te obuhvaća tok kodova sa spremnicima koji opisuju prostor boja, razlučivost i metapodatke. Sirovi J2K tok kodova uopće ne nosi spremnik i započinje oznakom SOC FF 4F FF 51. Dekoder očitava ove početne bajtove, prepoznaje potpis i odabire podudarajući OpenJPEG kodek za svaki slučaj
Postupano je s oba oblika budući da se oba pojavljuju u prirodi. Uređaji za snimanje i arhive kojima su potrebni bočni metapodaci izbacuju JP2; alati koji žele što manju nosivost ispuštaju samo tok kodova. Tip formata oblikovan je kao enum, TJpeg2000FileType, s članovima jtInvalid, jtJP2, jtJ2K i jtJPT. Član JPT imenuje JPIP varijantu strujanja; detektor potpisa bajta razlučuje dva oblika koja može dekodirati, JP2 i J2K, te sve ostalo bilježi kao jtInvalid, tako da nepodržani unos ne uspijeva na jasan način umjesto da proizvodi smeće
uses
HPDFJpeg2000;
var
Decoder: THPDFJpeg2000Decoder;
Pixels: TJpeg2000ByteArray;
begin
Decoder := THPDFJpeg2000Decoder.Create;
try
if Decoder.LoadFromStream(Input) then // JP2 or J2K, auto-detected
if Decoder.GetImageData(Pixels) then
// Pixels is 8-bit interleaved, ColorComponents channels wide,
// row-major top to bottom: ready for a DeviceGray/DeviceRGB XObject.
ProcessRaster(Decoder.Width, Decoder.Height,
Decoder.ColorComponents, Pixels);
finally
Decoder.Free;
end;
end;
Sa i bez gubitaka na strani kodiranja
Dekoder iščitava oba načina bez da mu se kaže o kojem se radi. Taj odabir postaje parametar isključivo kada idete u suprotnom smjeru i proizvodite JPEG 2000 datoteku, što HotPDF također može učiniti putem TJpeg2000Bitmap klase, podrijetlom od TBitmap, koja očitava i sprema raster podatke kao JP2. Dva svojstva reguliraju izlaz. LosslessCompression je bool koji prebacuje povratni valić kada ima vrijednost true; CompressionQuality je raspon TJpeg2000QualityRange, cijeli broj od 1 do 100, pri čemu je 1 sitno i ružno, a 100 krupno i vjerno. Podrazumijevane vrijednosti žive u imenovanim konstantama: Jpeg2000DefaultLosslessCompression je False, a Jpeg2000DefaultLossyQuality je 80
To je odluka o sadržaju. Kompresija bez gubitaka odgovara glavnoj kopiji, medicinskom ili pravnom skeniranju i svemu onome što se kasnije može ponovno kodirati i ne smije nakupiti generacijski gubitak. Gubitak kvalitete 80 prikladan je za slike namijenjene ekranu ili ispisu, gdje elegantna degradacija valića omogućava primjetno manju datoteku bez izobličenja koja bi čitatelj mogao uočiti. Postoji i jedno upozorenje vezano za CMYK: bitmapa izlaže SetCMYK za postavljanje četverokanalnih podataka kao CMYK umjesto RGBA, a to je važno za tiskovne kanale koji separaciju drže netaknutom
uses
HPDFJpeg2000;
var
Bmp: TJpeg2000Bitmap;
begin
Bmp := TJpeg2000Bitmap.Create;
try
Bmp.LoadFromStream(Source); // decode an existing JP2/J2K
Bmp.LosslessCompression := True; // reversible 5/3 wavelet
// or, for a smaller lossy file:
// Bmp.LosslessCompression := False;
// Bmp.CompressionQuality := 80; // matches the default
Bmp.SaveToStream(Output); // always writes a JP2 file
finally
Bmp.Free;
end;
end;
Zašto nema procesa filtra dekodiranja po učitavanju
Jedna arhitektonska činjenica oblikuje kako koristite bilo što od navedenog, a vrlo je lako pretpostaviti suprotno. HotPDF ne nudi općeniti filter za slike dekodiranja po učitavanju (decode-on-load). Kada otvorite PDF koji u sebi već sadrži JPXDecode sliku, pokretač ne dekodira taj tok. On čuva JPEG 2000 bajtove točno takvima kakvi jesu, pa se kopiranjem stranice ili spajanjem dokumenata slika prenosi nedirnuta, bajt po bajt. Dekoder ima samo jednu točku ulaza i ona se nalazi na strani stvaranja: AddImage temeljen na datoteci, pokrenut po datotečnom nastavku i podržava izvore .jp2, .j2k, .jpt te .jpc
Ovakva je podjela pravi dizajn radije negoli ograničenje. Dekodiranje integriranog JPX toka po učitavanju, samo da bi se on pri spremanju ponovno kodirao, bi sliku arhiviranu bez gubitaka pretvorilo u nju s gubicima i preopteretilo svako spajanje, i to sve zbog slike koju ste samo planirali premjestiti iz jednog PDF-a u drugi. Propustiti tok doslovno iznimno je brza radnja koja ne podnosi gubitke. Dekodiranje se ostavlja za jedini trenutak kada se iskreno i zatraži: kada pokretaču proslijedite JPEG 2000 datoteku s diska i naredite mu da rasterizira takvu sliku za njezino plasiranje na novoj stranici. U tom trenutku datoteka mora postati prepuna piksela i dekoder započinje s radom
Registriranje podrške i postavljanje slike
Registracija slike za JPEG 2000 pristaje i na prekidač sa selektivnim sudjelovanjem HPDF_REGISTER_JPEG2000_PICTURE, koji je podrazumijevano isključen. Razlog u pozadini pravi je konflikt umjesto opreza: registracija navedenih datotečnih formata jp2, j2k i jpc globalno pomoću TPicture može se kositi s formatačkim okrivanjem BLOB na koje se u potpunosti oslanja TppDBImage aplikacije ReportBuilder. Definirajte taj prekidač kada slična integracija nije u igri pa se navedeni datotečni formati mogu registrirati kako bi ih TPicture prepoznao; ostavite ga nedefiniranim i proces proširenja funkcije AddImage još izravno dekodira JPEG 2000 datoteke, samo zato što dotični put uopće ne prolazi kroz TPicture
Nakon ovoga smo razjasnili da je plasiranje JPEG 2000 slika i dalje isti ritam unutar tri poziva za bilo koju HotPDF sliku. Dodijelite datoteci AddImage njenu vlastitu putanju .jp2 te kompresijski tip kako bi se takva slika trebala sačuvati unutar njenog vlastitog izlaza, i tada slobodno pozicionirajte vraćeni slikovni indeks na određenu stranicu unutar funkcije ShowImage
var
Pdf: THotPDF;
ImgIndex: Integer;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.BeginDoc;
Pdf.AddPage;
// The .jp2 source is decoded through the OpenJPEG backend, then
// re-embedded with the compression you request here.
ImgIndex := Pdf.AddImage('Scan_16bit.jp2', icJpeg);
// x, y, width, height in points; final 0 is the rotation angle.
Pdf.ShowImage(ImgIndex, 72, 72, 400, 300, 0);
Pdf.EndDoc;
finally
Pdf.Free;
end;
end;
Kompresija koju proslijeđujete prema AddImage upravlja onime kako je točno dekodirana slika ponovno sačuvana, a ne onime kako je i isčitana. Datoteka JPEG 2000 pretvorena u bitmapu slobodno može postati i DCTDecode JPEG, Flate raster ili neki drugi podržani filter, što god bude najbolje stajalo za specifičan dokument. Samo se dekodiranje iz JP2 ili J2K prvo poduzima bez obzira na to pa taj isti navedeni poziv prihvaća izvor zaštićen kompresijom s valićima dok će njime integrirati cjelokupni ostatak u željeni oblik kakav vaš naumljeni plinovod u potpunosti očekuje
Ako želite cjelovitiju sliku o tome kako uopće slike i fontovi završavaju sa kreiranim izlazom, proučite naše napomene o izvještajima ispisa vezanih za fontove i slike. Kad navedeni dokument prikuplja te nastavlja ponovno koristiti materijale za postojeći sadržaj iz ostalih PDF-ova, takvo specifično propusno stanje uparuje samo spajanje ujedno s mehanikom revizije pomoću objektnih tokova i postepenih nadogradnji. Mehanika dekodiranja na način JPEG 2000 isporučuje se unutar paketa alata HotPDF Component kreiranog za Delphi i C++Builder, usporedo s predivnom paletom za slike te pisma i najvažnije, s moćnim dokumentacijskim API-jima koje ćemo naknadno pročitati na ovom blogu