1. Jasper庫(kù)
1.1. 介紹
JasPer軟件的核心是Jasper庫(kù)。實(shí)際上,大部分Jasper的代碼都和這個(gè)庫(kù)有關(guān)系。Jasper庫(kù)提供表現(xiàn)圖像、色彩(色彩空間定義)和其他相關(guān)的入口類。這些類都有很好的接口,通過(guò)這些接口程序可以和類對(duì)象交互。可以使用這個(gè)餓庫(kù)來(lái)操作圖像、導(dǎo)入/導(dǎo)出各種格式的圖像并執(zhí)行基本的色彩管理操作。
理論上,Jasper庫(kù)的結(jié)構(gòu)在3.1中顯示。庫(kù)由兩個(gè)不同的類型代碼組成:
1. 核心代碼
2. 編碼驅(qū)動(dòng)

核心代碼提供在庫(kù)上的基本框架,而編碼驅(qū)動(dòng)僅僅提供編碼和解碼各種格式圖像數(shù)據(jù)的方式。所有的應(yīng)用程序接口都通過(guò)核心代碼;編碼驅(qū)動(dòng)僅僅被核心代碼直接調(diào)用,其他應(yīng)用程序從來(lái)不需要。
Jasper庫(kù)中支持的編碼既是模塊的也是可擴(kuò)展的。在核心代碼和編碼驅(qū)動(dòng)之間有定義良好的接口;而且,對(duì)于新圖像格式的支持能在不修改庫(kù)的情況下很容易添加。為了這樣,新格式的編碼驅(qū)動(dòng)要提供。而且,應(yīng)用程序僅僅需要包含它要使用的圖像格式的編碼驅(qū)動(dòng)。在這種情況下,應(yīng)用程序能避免將內(nèi)存花在從來(lái)都不使用的編碼驅(qū)動(dòng)上。
1.2. 核心代碼
核心代碼提供下面這些關(guān)鍵的代碼。(為了避免名字沖突,所有核心代碼使用的的標(biāo)識(shí)符都以jas_或JAS_前綴)。
1.2.1. 圖像類
圖像類以jas_image_t開始。這些類用來(lái)表示一個(gè)圖形。提供了下面這些方法:
1. 圖像創(chuàng)建/銷毀
2. 查詢通用的圖像屬性(例如:引用grid的寬度和高度,色彩)
3. 查詢組件屬性(例如:寬度、高度、grid的偏移、grid的空間、組件類型、采樣精度)
4. 設(shè)置各種圖像屬性
5. 裝載和保存圖像(例如:編碼/解碼)
6. 復(fù)制圖像
7. 添加和刪除組件
8. 讀寫組件數(shù)據(jù)
1.2.2. 色彩類
這些類以jas_cmprof_t開始。這個(gè)類用來(lái)定義色彩空間。這樣的一個(gè)定義被重定向?yàn)橄嚓P(guān)的色彩空間,例如CIE XYZ和CIE LAB。
1.2.3. 色彩轉(zhuǎn)換類
色彩轉(zhuǎn)換類以jas_cmxform_t開始。這個(gè)類用來(lái)在一個(gè)圖像數(shù)據(jù)上進(jìn)行色彩空間轉(zhuǎn)換。一個(gè)色彩空間被轉(zhuǎn)換自兩個(gè)或更多的色彩。
1.2.4. 流類
以jas_stream_t開始,這個(gè)類提供類似與標(biāo)準(zhǔn)C庫(kù)的I/O流輸出;其還額外提供了Jasper庫(kù)中要求的其他代碼。這些功能包括:
1. 使用一個(gè)流(例如內(nèi)存緩沖區(qū))來(lái)關(guān)聯(lián)一個(gè)對(duì)象而不是一個(gè)文件描述符。
2. 多個(gè)字符的獲取
1.2.5. 固定點(diǎn)數(shù)字類
這是一個(gè)模板類(一系列的宏)提供定點(diǎn)數(shù)字類。用來(lái)支持基本的算法操作、類型轉(zhuǎn)換。
1.2.6. Tag值解析類
這個(gè)類以jas_tvp_t開始;這個(gè)類用來(lái)解析包含一個(gè)或多個(gè)tag的字符串。一個(gè)tag值對(duì)是一個(gè)“tag=value”形式的字符串。Tag值在Jasper的一些接口使用來(lái)傳遞參數(shù)。例如:這個(gè)對(duì)用在傳遞給編碼驅(qū)動(dòng)的編碼和解碼操作的選項(xiàng)。
除了上面的類,還有一些其他的功能:命令行解析程序(和UNIX的getopt相似)。
1.3. 編碼驅(qū)動(dòng)
核心編碼提供一個(gè)框架來(lái)house編碼驅(qū)動(dòng)。一個(gè)編碼驅(qū)動(dòng)提供某特殊格式圖象的編碼和解碼。每個(gè)驅(qū)動(dòng)提供三個(gè)方法:
1. 一個(gè)編碼
2. 解碼
3. 驗(yàn)證方法
編碼方法將某圖像(一個(gè)jas_image_t_object)版本的轉(zhuǎn)換到一個(gè)流(一個(gè)jas_stream_t_object)。解碼方法從流中的數(shù)據(jù)來(lái)創(chuàng)建一個(gè)圖像。驗(yàn)證方法用來(lái)測(cè)試流中的數(shù)據(jù)是否符合指定的格式;這個(gè)特殊的方法一般用來(lái)自動(dòng)檢測(cè)圖像特使。
Jasper發(fā)布中提供的編碼驅(qū)動(dòng)是為了適應(yīng)流數(shù)據(jù);換句話說(shuō),圖像數(shù)據(jù)流一直在單個(gè)的pass中處理。這個(gè)設(shè)計(jì)理念去掉可尋找的流對(duì)象的需要。因此,寫接受和發(fā)送數(shù)據(jù)的應(yīng)用程序、管道和其他不支持隨機(jī)訪問(wèn)的是可能的。
1.4. 圖像模型
圖像是由一個(gè)到多個(gè)部分組成;每個(gè)部分都是由采樣的矩形數(shù)組組成。這個(gè)結(jié)構(gòu)在圖3.2中描述。

每個(gè)組件的采樣值是整數(shù)值并且是有符號(hào)或無(wú)符號(hào)的1到16bit/sample。采樣數(shù)據(jù)的符號(hào)和精度按照顏色來(lái)指定的。所有這些組件和圖像中相同的空間擴(kuò)展相關(guān)聯(lián),但表示不同類型的信息。
在詮釋組件時(shí)有相當(dāng)大的彈性。一個(gè)組件可以表達(dá)光譜信息(例如:彩色空間)或輔助信息(例如:一個(gè)不透明平面)。例如:一個(gè)RGB圖像有三個(gè)組件,三個(gè)組件分別和紅、綠、藍(lán)顏色面相關(guān)聯(lián);一個(gè)RGBA(例如:帶有透明度的RGB)圖像有四個(gè)顏色面,分別和紅、綠、藍(lán)以及alpha平面相關(guān)聯(lián)。各種組件不需要以相同的分辨率來(lái)采樣;換句話說(shuō),不同組件可能有不同的采樣周期。例如:以亮度和色調(diào)表示的彩色圖像,亮度信息比色度信息更好采樣并不罕見。
由于一個(gè)圖像可以由很多組件組成,因此必須有一個(gè)描述怎么樣用這些組件來(lái)組成一個(gè)符合圖形的方法。為了這個(gè)目的,我們使用一個(gè)整數(shù)格子叫做引用網(wǎng)格。引用網(wǎng)格為一個(gè)圖像的各個(gè)組件提供一個(gè)點(diǎn),并建立他們之間相對(duì)對(duì)齊的方式。
每個(gè)組件和一個(gè)矩形的采樣網(wǎng)格相關(guān)聯(lián),這樣的網(wǎng)格通過(guò)四個(gè)參數(shù)來(lái)指定:水平偏移量、垂直偏移量、水平空間、垂直空間。一個(gè)組件的采樣被映射到采樣網(wǎng)格和引用網(wǎng)格交叉的點(diǎn);這種情況下:采樣(i , j)被 映射到引用網(wǎng)格的(HO + iHS, VO+ jVS)。
為了澄清上面的文字,我們現(xiàn)在介紹一個(gè)范例。考慮一個(gè)有三個(gè)組件的圖形。對(duì)于第k個(gè)組件來(lái)說(shuō),讓我們指示水平網(wǎng)格偏移、垂直網(wǎng)格偏移、水平網(wǎng)格空間和垂直網(wǎng)格空間,分別對(duì)應(yīng)于HOk、VOk、HSk、VSk。假定這些參數(shù)有下面的值:
K |
(HOk, VOk) |
(HSk, VSk) |
0 |
(0,0) |
(2,2) |
1 |
(2,3) |
(3,4) |
2 |
(3,2) |
(4,3) |
這種情況下,各組件采樣值將對(duì)齊到引用網(wǎng)格上,圖3.3描述。

圖中,顏色面0的坐標(biāo)原點(diǎn)是(0,0);水平間隔是2個(gè)引用網(wǎng)格,垂直間隔是2個(gè)引用網(wǎng)格。其他同上解釋。
從上面的內(nèi)容,我們可以看到Jasper的圖形模式是很普通的。使用這個(gè)模型的主要約束在于使用矩形采樣。不過(guò)大多數(shù)的應(yīng)用程序都使用這個(gè)采樣。同樣使用Jasper的應(yīng)用程序能夠很容易的適應(yīng)灰度、彩色和其他多帶數(shù)據(jù)(使用或不使用不透明信息)。
1.5. JasPer頭文件
為了使用Jasper庫(kù),C文件通常必須包含主要的Jasper庫(kù)的頭文件jasper/japser.h。使用下面的預(yù)編譯指令:
#include <jasper/japser.h>
主要的頭文件包含了所有其他庫(kù)的頭文件。因此,為了是應(yīng)用程序隔離其他庫(kù)文件名稱的改變,應(yīng)用程序僅僅應(yīng)該包含主頭文件。
1.6. 初始化庫(kù)
第一次使用庫(kù)總是初始化庫(kù)。這通過(guò)調(diào)用jas_init來(lái)完成。如果在調(diào)用該函數(shù)之前調(diào)用任何其他庫(kù)函數(shù),結(jié)構(gòu)是未知的。
1.7. 內(nèi)存分配
所有libjasper中的內(nèi)存分配都是通過(guò)jas_malloc和jas_realloc、jas_calloc和jas_free來(lái)完成的。如果有人想要將Jasper代碼導(dǎo)入到嵌入式平臺(tái),應(yīng)該需要將這些函數(shù)改為指定平臺(tái)的內(nèi)存分配方式,而不是malloc等。
1.8. 為新的圖形格式添加支持
支持新圖象格式的編碼引擎能很容易被添加到Jasper中,為了能夠?qū)π挛募袷降闹С郑仨毺峁┫旅嫒齻€(gè)函數(shù):
1. 一個(gè)編碼函數(shù)
2. 一個(gè)解碼函數(shù)
3. 一個(gè)驗(yàn)證函數(shù)
編碼函數(shù)發(fā)布一個(gè)圖像的編碼版本到流(一個(gè)jas_image_t對(duì)象到jas_stream_t對(duì)象)。解碼函數(shù)從流(jas_stream_t對(duì)象)中的編碼數(shù)據(jù)創(chuàng)建一個(gè)圖像(一個(gè)jas_image_t對(duì)象)。驗(yàn)證函數(shù)用來(lái)快速的測(cè)試數(shù)據(jù)流是不是正確格式的圖像數(shù)據(jù)(這個(gè)函數(shù)通常用來(lái)自動(dòng)檢查圖像格式)。
在編碼、解碼和驗(yàn)證函數(shù)中的具體類型和參數(shù)可以通過(guò)檢查Jasper中已經(jīng)存在的PNM、BMP、JPEG函數(shù)。一旦上面的函數(shù)寫好了,可以通過(guò)調(diào)用jas_image_addfmt來(lái)通知Jasper新的圖形格式引擎已經(jīng)安裝。當(dāng)然這個(gè)調(diào)用必須在Jasper被初始化之后調(diào)用;jas_init函數(shù)代碼給出了幾個(gè)關(guān)于如何調(diào)用jas_image_addfmt函數(shù)的例子。