Naskenovaný medicínsky preparat, dlaždica leteckého prieskumu, filmový záber archivovaný v plnom dynamickom rozsahu. To sú obrázky, ktoré prichádzajú vo formáte JPEG 2000, a prichádzajú tak z dobrého dôvodu. Formát uchováva 12 alebo 16 bitov na kanál, komprimuje vlnkovou transformáciou namiesto blokovej DCT, ktorú používa JPEG, a dokáže zakódovať ten istý obrázok bezstratovo alebo stratovo z jedného kódového toku. Keď sa dokument zostavený z takýchto zdrojov musí stať súborom PDF, obrázok musí prejsť filtrom, ktorý špecifikácia PDF vyhradila práve pre tento kodek
HotPDF v2.228.0 obnovil funkčný dekódovací modul JPEG 2000 pre tento zámer. Staršia verzia bola dodaná s jednotkou obsahujúcou stub funkcie, ktoré vracali nil, takže API existovalo, ale nič nedekódovalo. Súčasný modul staticky viaže OpenJPEG 2.5.4 a premieňa zdroj JP2 alebo J2K na pixely, ktoré HotPDF dokáže umiestniť na stránku
Filter JPXDecode v PDF
ISO 32000-1 definuje filter JPXDecode v §7.4.9. PDF obrazový XObject uvádza svoju kompresiu v zázname /Filter slovníka toku, pričom JPXDecode je hodnota, ktorá hovorí, že dáta toku sú kódový tok JPEG 2000, a nie bežný JPEG, ktorý nesie /DCTDecode. Filter umožňuje PDF uchovávať vlnkovo komprimované obrazové dáta s vysokou bitovou hĺbkou a prijíma bezstratový aj stratový režim kodeku, pretože režim je vlastnosťou samotného kódového toku a nie obalu okolo neho
Tento posledný bod stojí za zapamätanie. JPEG 2000 je jeden algoritmus s bezstratovým špeciálnym prípadom, nie dva samostatné formáty. Reverzibilná vlnka 5/3 rekonštruuje pôvodné vzorky presne; ireverzibilná vlnka 9/7 vymieňa túto presnosť za menší súbor. Dekodér sa správa k obom rovnako pri čítaní, a preto HotPDF potrebuje iba jednu dekódovaciu cestu na prijatie čohokoľvek, čo prúd JPXDecode predloží
Čo dekodér robí s pixelmi
PDF obrazové XObjecty v bežnom prípade očakávajú 8 bitov na komponent v DeviceGray alebo DeviceRGB. JPEG 2000 toto bežne presahuje a jeho model komponentov je všeobecnejší ako bežný rastrový formát, takže dekodér musí vykonať tri úlohy skôr, než sú dáta použiteľné ako normálny obrázok
Po prvé, komponenty s vysokou bitovou hĺbkou sú prevzorkované na 8 bitov. 12-bitová alebo 16-bitová vzorka sa zmenší na rozsah 0 až 255, takže výsledkom je bežný 8-bitový raster. Znamienkové komponenty sa najprv posunú do rozsahu bez znamienka. Na tomto detaile záleží, pretože sám o sebe je stratový: 16-bitové čiernobiele skenovanie stratí svoju hlbokú tónovú škálu v okamihu, keď sa stane 8-bitovým obrázkom PDF, čo je správna výmena pre výstup na obrazovke a tlač, ale nie pre rearchiváciu
Po druhé, farebný priestor YCbCr (kodek ho nazýva SYCC) sa konvertuje do RGB. JPEG 2000 často ukladá farbu v priestore jas-chroma pre efektivitu kompresie, rovnakú myšlienku, akú používa bežný JPEG, a dekodér aplikuje štandardnú inverznú transformáciu, takže stránka dostane skutočné RGB
Po tretie, podvzorkované komponenty sú prevzorkované nahor replikáciou najbližšieho suseda. Chroma kanály sú často uložené v polovičnom rozlíšení, takže dekodér číta každý komponent v jeho vlastných rozmeroch a vlastnom vzorkovacom faktore, potom replikuje vzorky, aby dostal každý kanál na plnú veľkosť obrázka pred prekladaním. Metóda najbližšieho suseda udržuje krok lacný; chroma, ktorú vypĺňa, bola od začiatku nízkofrekvenčná, takže viditeľné náklady sú malé
Boxy JP2 vs. surový kódový tok J2K
Súbor JPEG 2000 existuje v dvoch podobách a HotPDF zisťuje, ktorú číta, z prvých bajtov, nie z prípony súboru. Súbor JP2 je kontajner so štruktúrou boxov: otvára sa dvanásťbajtovým podpisovým boxom 00 00 00 0C 6A 50 20 20 a obklopuje kódový tok spolu s boxmi, ktoré popisujú farebný priestor, rozlíšenie a metadáta. Surový kódový tok J2K nemá žiadny kontajner a začína markérom SOC FF 4F FF 51. Dekodér číta tieto úvodné bajty, rozpozná podpis a vyberie zodpovedajúci kodek OpenJPEG pre každý prípad
Obe podoby sú spracované, pretože obe sa vyskytujú v praxi. Zariadenia na snímanie a archívy, ktoré potrebujú vedľajšie metadáta, vydávajú JP2; nástroje, ktoré chcú najmenšiu možnú záťaž, vydávajú holý kódový tok. Typ formátu je modelovaný ako enumerácia TJpeg2000FileType s členmi jtInvalid, jtJP2, jtJ2K a jtJPT. Člen JPT označuje variantu streamovania JPIP; detektor bajt-podpisu rozlišuje dve podoby, ktoré dokáže dekódovať, JP2 a J2K, a čokoľvek iné hlási ako jtInvalid, aby nepodporovaný vstup zlyhal čisto namiesto generovania neplatných dát
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;
Bezstratové a stratové kódovanie na strane enkodéra
Dekodér číta oba režimy bez toho, aby bol informovaný o tom, ktorý to je. Výber sa stáva parametrom až vtedy, keď idete opačnou cestou a vytvárate súbor JPEG 2000, čo HotPDF dokáže tiež prostredníctvom triedy TJpeg2000Bitmap, potomka TBitmap, ktorý načítava a ukladá rastrové dáta ako JP2. Výstup riadia dve vlastnosti. LosslessCompression je logická hodnota, ktorá pri hodnote true vyberá reverzibilnú vlnku; CompressionQuality je TJpeg2000QualityRange, celé číslo od 1 do 100, kde 1 je malé a nekvalitné a 100 je veľké a verné. Predvolené hodnoty sú v pomenovaných konštantách: Jpeg2000DefaultLosslessCompression je False a Jpeg2000DefaultLossyQuality je 80
Rozhodnutie je obsahové. Bezstratové kódovanie je vhodné pre hlavnú kópiu, medicínske alebo právne skenovanie, čokoľvek, čo môže byť neskôr prenkódované a nesmie hromadiť generačné straty. Stratové pri kvalite 80 je vhodné pre obrázok určený pre obrazovku alebo tlač, kde plynulá degradácia vlnky poskytuje výrazne menší súbor bez artefaktu, ktorý by čitateľ zachytil. Je tu jedna výhrada CMYK, ktorú treba uviesť: bitmapa poskytuje SetCMYK na označenie štvorkanálových dát ako CMYK namiesto RGBA, čo je dôležité pre tlačové potrubia, ktoré zachovávajú separácie
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;
Prečo neexistuje pipeline filtra dekódovania pri načítaní
Jeden architektonický fakt určuje spôsob použitia všetkého tohto a ľahko sa predpokladá opak. HotPDF nemá všeobecný filter obrazového dekódovania pri načítaní. Keď otvoríte PDF, ktorý už obsahuje obrázok JPXDecode, motor tento tok nedekóduje. Udržiava bajty JPEG 2000 presne také, aké sú, takže kopírovanie stránky alebo zlúčenie dokumentu prenáša obrázok bez zmeny, bajt po bajte. Dekodér má jeden vstupný bod a je na strane vytvárania: súborový AddImage, odoslaný podľa prípony súboru na spracovanie zdrojov .jp2, .j2k, .jpt a .jpc
Toto rozdelenie je správnym dizajnom, nie obmedzením. Dekódovanie vloženého toku JPX pri načítaní, len aby sa znova zakódoval pri ukladaní, by premenilo bezstratovo archivovaný obrázok na stratový a nafúklo by každé zlúčenie, a to všetko pre obrázok, ktorý ste chceli iba presunúť z jedného PDF do druhého. Priechod toku bez zmeny je bezstratová operácia a rýchla. Dekódovanie sa odkladá na jediný okamih, kedy je skutočne nevyhnutné: keď odovzdáte motoru súbor JPEG 2000 z disku a požiadate ho o rasterizáciu tohto obrázka pre umiestnenie na novú stránku. V tom okamihu sa súbor musí stať pixelmi a dekodér sa spustí
Registrácia podpory a umiestnenie obrázka
Registrácia obrázkov JPEG 2000 je dobrovoľná za prepínačom kompilácie HPDF_REGISTER_JPEG2000_PICTURE, ktorý je predvolene vypnutý. Dôvodom je skutočný konflikt, nie opatrnosť: globálna registrácia formátov súborov jp2, j2k a jpc s TPicture môže interferovať s detekciou formátu BLOB, na ktorú sa spolieha TppDBImage komponentu ReportBuilder. Definujte prepínač, keď táto integrácia nie je aktívna, a formáty súborov sa zaregistrujú, aby ich TPicture rozoznalo; nechajte ho nedefinovaný a odosielanie rozšírení AddImage stále dekóduje súbory JPEG 2000 priamo, pretože táto cesta vôbec neprechádza cez TPicture
S týmto pochopením je umiestnenie obrázka JPEG 2000 rovnaký rytmus troch volaní ako pri akomkoľvek inom obrázku HotPDF. Odovzdajte AddImage cestu .jp2 a typ kompresie pre spôsob uloženia obrázka vo výstupe, potom umiestnite vrátený index obrázka na stránku pomocou 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;
Kompresia, ktorú odovzdáte do AddImage, riadi spôsob opätovného uloženia dekódovaného obrázka, nie spôsob jeho načítania. Súbor JPEG 2000 dekódovaný do bitmapy môže byť opätovne vydaný ako DCTDecode JPEG, Flate raster alebo iný podporovaný filter, podľa toho, čo vyhovuje dokumentu. Dekódovanie z JP2 alebo J2K prebehne najprv bez ohľadu na to, takže rovnaké volanie prijme vlnkovo komprimovaný zdroj a vloží ho do akejkoľvek formy, ktorú zvyšok vášho pipeline očakáva
Pre širší prehľad o tom, ako obrázky a písma pristanú v generovanom výstupe, si pozrite naše poznámky o výstupe správ s písmami a obrázkami. Keď dokument, ktorý zostavujete, opätovne používa obsah z existujúcich PDF, správanie priechodu opísané tu sa spáruje s mechanikou zlúčenia a revízie v objektových tokoch a prírastkových aktualizáciách. Dekódovací modul JPEG 2000 sa dodáva ako súčasť HotPDF Component pre Delphi a C++Builder, spolu s obrázkovými, písmovými a dokumentovými API pokrytými inde na tomto blogu