TWAIN規範的第四章的翻譯
本文是對TWAIN規範的第四章《應用程式端的高階實現》的翻譯。因工作需要了解TWAIN,所以順便譯了一下。這是私人工作,您可以參考,但本人不保證不存在翻譯的差錯或不合宜。如果您發現有不妥的地方,敬請告之我(yedaoq@126.com)。
4.1 效能
應用程式與源進行效能協商的能力使人們能夠控制TWAIN相容的程式。在第四章“應用程式端的高階實現”中,你將看到對CAP_XFERCOUNT效能的協商。效能在並且總是在狀態4期間進行協商,除非應用程式和源雙方同意延遲協商。事實上,關於效能還有更多需要我們去了解。
4.1.1 效能值
TWAIN為每種效能定義了一個預設值和一組允許使用的值(見第10章)。應用程式不允許修改預設值,但允許將向使用者提供的值限定為一個允許使用值的子集,以及選擇效能的當前值。
4.1.1.1 預設值
一個源被開啟時,每種效能的當前值都被設定為TWAIN定義的預設值。若TWAIN未定義,則源將選擇一個值作為預設值。程式可以使用DG_CONTROL/ DAT_CAPABILITY / MSG_RESET操作將某效能重置為TWAIN定義的預設值。
雖然TWAIN為許多種效能定義了預設值,源也可能因為能夠獲得更高的效率而首選一個不同的值。例如,源通常在黑白影象中用位值0來代表白色,但是ICAP_FIXELFLAVOR的預設值為TWPF_CHOCOLATE,此值表示0代表黑色。即使TAWIN預設值為TWPF_CHOCOLATE,源也可能將TWPF_VANILLA作為首選值。當應用程式發出一個DG_CONTROL/DAT_CAPABILITY/MSG_GETDEFAULT操作時,源將返回它的首選值的資訊。基於此資訊源和應用程式將能夠協商出一個更有效的傳送方式。
注意這並不是在暗示TWAIN定義的預設值應被完全忽略。在處理特殊資料來源效能的首選值和TWAIN預設值之間的衝突時,應考慮到此問題與在會話間儲存和恢復影象屬性類似。假定一個資料來源想儲存某些效能的當前值以在將來的某個會話中恢復是合理的,期望恢復值能夠反映效能的當前設定也是合理的。若儲存設定對影象屬性確實有用,那麼應宣告資料來源的首選值也採用同樣方式進行處理。
載入資料來源時,相關效能的當前值應被設定為從上一個會話恢復的值或資料來源首選的值。此值將保持直至被應用程式顯式更改或應用程式發出MSG_RESET操作。
並非所有效能都適用首選值,另外許多效能不適合在多個會話間儲存和恢復。
以下是最好的例子:
例1:掃描引數在一個會話中儲存並在另一個會話中恢復
1. 使用者使用以下引數配置資料來源使用者介面:24位4*6英寸影象,水平豎直方向的DPI均為200。
2. 使用者選擇“掃描”然後資料來源通知程式進行傳送。
3. 應用程式成功獲得影象。
4. 應用程式禁用資料來源。
5. 應用程式狀態4下詢問幀,畫素型別,位深度和解析度的當前值。
6. 資料來源報告使用者設定的當前值:24位4*6英寸影象,水平豎直方向的DPI均為200。
7. 應用程式關閉資料來源。
8. 在關閉期間,資料來源儲存當前幀,畫素型別,位深度和解析度。
9. 應用程式開啟資料來源。
10. 在開啟期間,資料來源恢復幀,畫素型別,位深度和解析度。
11. 應用程式在狀態4下詢問幀,畫素型別,位深度和解析度和當前值。
12. 資料來源報告從上一個會話中恢復的資料:24位4*6英寸影象,水平豎直方向的DPI均為200。
例2:資料來源使用首選Pixel Flavor代替TWAIN定義的預設值
1. 應用程式首次開啟資料來源。
2. 應用程式在狀態4下詢問預設Pixel Flavor。
3. 資料來源報告Pixel Flavor預設為TWPF_CHOCOLATE。
4. 應用程式在狀態4下詢問當前Pixel Flavor。
5. 資料來源報告Pixel Flavor當前為TWPF_VANILLA(因為裝置本身採用這種方式返回資料)。
6. 應用程式要求重置Pixel Flavor。
7. 在重置期間,資料來源將當前值變更為TWPF_CHOCOLATE並準備在傳輸過程中轉換資料以適應應用程式要求。
此邏輯在一種情況下會失效。如果資料要對一個受限制的效能的MSG_GET返回TW_ENUMERATION, TAWIN定義的預設值有可能不在值的約束集合內。在這種情況下,應用程式將認為預設值未定義。一個常識是,出於安全性的考慮,資料來源應在當前可用值集合中提供一些合理的預設值(TW_ENUMERATION中儲存一個壞索引是災難性的)。當預設值事實上正被使用時(通過MSG_RESET),此限制將無效並且當前預設值可再次存在並被定義。這是一個僅限於TW_ENUMERATION容器的問題,因為它包含預設值的索引。
4.1.1.2 當前值
應用程式可能要求設定效能的當前值。如果源的使用者介面正在顯示,當前值也許能從中看出(例如高亮)。如果應用程式設定了當前值,它用於採集和傳輸直至被使用者或一個自動源程式更改。應用程式可在狀態6下通過檢查當前值判斷是否有更改發生。
若僅需要確定效能的當前值,請使用MSG_CONTROL / DAT_CAPABILITY / MSG_GETCURRENT;若要確定當前值以及可用值,請用DG_CONTROL / DAT_CAPABILITY / MSG_GET。例如您可以對ICAP_PIXELTYPE使用MSG_GET,源將返回一個包含可用值TWPT_BW、TWPT_GRAY和TWPT_RGB的TW_ENUMERATION容器。
若要設定當前值,請使用DG_CONTROL / DAT_CAPABILITY / MSG_SET以及下列容器之一:
• TWON_ONEVALUE:將TW_ONEVALUE.Item置為要求的值。
• TWON_ARRAY:將TW_ARRAY.ItemList置為要求的值。
其中值必須為MSG_GET操作返回值的一個子集。
同樣還可以通過TW_ENUMERATION和TW_RANGE容器來設定當前值。
4.1.1.3 可用值
為了限制在獲取和傳送過程中限制源可用的設定,應用程式可限定可用值,源不會使用這些值以外的值。這些限制將體現在源的使用者介面上,因此不可用的值將不會提供給使用者。
例如,如果ICAP_PIXELTYPE上的操作MSG_GET表明源支援TWPT_BW,TWPT_GRAY和TWPT_RGB影象,但應用程式只想要黑白影象,那麼它可以要求限制可用值為TWPT_BW。
若要設定可用值,請使用DG_CONTROL / DAT_CAPABILITY / MSG_SET以及下列容器之一:
• TWON_ENUMERATION:將TW_ENUMERATION.ItemList域置為要求的值。通過將CurrentIndex指定為ItemList中某個值的索引,也可在此時設定當前值。
• TWON_RANGE:將TW_RANGE域設定為要求的值。此時同樣可設定當前值。
注:TW_ONEVALUE和TW_ARRAY容器不可用於限制可用值。
4.1.2 效能協商
協商過程包括以下幾個基本的部分:
• 應用程式確定源支援哪些效能。
• 應用程式按要求設定支援的效能。
• 應用程式校驗設定是否已被源接受。
4.1.2.1 確定源支援哪些效能
步驟一
應用程式分配一個TW_CAPABILITY結構並如下填充:
Cap = 感興趣的效能的名稱,一般為CAP_name或ICAP_name
ConType = TWON_DONTCARE16
hContainer = 設定為NULL
步驟二
執行DG_CONTROL / DAT_CAPABILITY / MSG_GET並傳遞TW_CAPABILITY。
步驟三
源檢查Cap域並判斷是否支援此效能。若支援,則為應用程式生成資訊,否則設定一個合適的返回值。
步驟四
應用程式檢查操作的返回值(也許是狀態碼):
若為TWRC_SUCCESS,則源支援該效能並且:
• 源將一個容器(TWON_ARRAY,TWON_ENUMERATION,TWON_ONEVALUE,TWON_ONEVLUE或TWON_RANGE)識別符號填充到ConType域。
• 源分配一個ConType指定型別的容器結構並使hContainer域引用此結構。然後用效能的當前值、預設值和可用值填充此結構。
根據容器的型別和內容(型別由其ItemType域指定),應用程式可讀取其中的值。應用程式必須負責釋放容器。
若TWRC_FAILURE或TWCC_CAPUNSUPPORTED,則源不支援該效能。
應用程式可對任何它想了解的效能重複此操作過程。若應用只想獲取效能的當前值,可以使用MSG_GETCURRENT代替。在那種情況下,ConType只可能是TWON_ONEVALUE或TWON_ARRAY而不可能是TWON_RANGE或TWON_ENUMERATION。
注:效能CAP_SUPPORTEDCAPS返回源所支援的效能列表,但沒有表示支援的效能是否能夠協商。若源不支援效能CAP_SUPPORTEDCAPS,則返回TWRC_FAILURE或TWCC_CAPUNSUPPORTED。
4.1.2.2 按要求設定支援的效能
步驟一
應用程式分配一個TW_CAPABILITY結構並如下填充:
CAP = 感興趣的效能名稱,一般為CAP_name或ICAP_name
ConType = TWON_ARRAY,TWON_ENUMERATION,TWON_ONEVALUE或TWON_RANGE
hContainer = 應用程式應分配一個ConType所指示的結構並關聯到此域。
步驟二
應用程式分配一個ConType指定的結構並填充它,根據MSG_GET操作返回的值,可指定所要求的當前值和可用值。應用程式不應嘗試設定源的預設值,而只應該為該域施加合理的限制。
注:操作完成後,應用程式應負責在操作完成後釋放此容器結構。
步驟三
使用DG_CONTROL/DAT_CAPABILITY/MSG_SET操作傳送請求。
4.1.2.3 檢查請求的返回值
步驟一
源支援某些效能不代表源支援設定此效能。應用程式必須檢查MSG_GET的返回值以確定發生了什麼:
返回TWRC_SUCCESS表示源按要求設定了效能。
返回TWRC_CHECKSTATUS表示源無法使用一個或多個您限定的值。例如,你要求值310但它只能接受100、200、300或400。您的請求不在它的有效範圍內,因此它選擇一個最接近的有效值。
此時使用DG_CONTROL / DAT_CAPABILITY / MSG_GET操作來獲取當前值和可用值是判斷源的選擇對應用程式是否可接受的唯一途徑。
返回TWRC_FAILURE或TWCC_BADVALUE表示:
• 源不允許您設定或限定值的請求。或
• 請求的值不在有效值範圍內,源可能嘗試設定為一個最接近的可用值。
此時應同樣使用DG_CONTROL/DAT_CAPABILITY/MSG_GET來確定應用程式是否能繼續工作。
4.1.3 常用的效能
TWAIN定義了超過150種的效能。雖然數量看起來很大,但如果認識到只有一部分是常用的,你就會覺得輕鬆點。以下是其中一些:
4.1.3.1 基礎效能
Units(單位)
ICAP_UNITS效能用於確定源所使用的計量單位。預設為英寸,其它允許的值為釐米、畫素等。此效能的值用於衡量其它一些效能或結構的值,包括:
ICAP_PHYSICALHEIGHT,
ICAP_PHYSICALWIDTH,
ICAP_XNATIVERESOLUTION,
ICAP_YNATIVERESOLUTION,
ICAP_XRESOLUTION,
ICAP_YRESOLUTION,
TW_FRAME,TW_IMAGEINFO.XResolution,
TW_IMAGE.YResolution
Sense of the Pixel(畫素涵義)
ICAP_PIXELFLAVOR描述從源傳送到應用程式後位資料應如何解釋。預設值為TWPF_CHOCOLATE,它表示0為黑色(最深的顏色);另一個值為TWPF_VANILLA,它表示0為白色(最淺的顏色)。
3Resolution(解析度)
影象解析度在TW_IMAGEINFO結構中提供。若要查詢或設定源的解析度,請使用ICAP_XRESOLUTION,ICAP_YRESOLUTION。
同樣還有CAP_XNATIVERESOLUTION,ICAP_YNATIVERESOLUTION。
4.1.3.2 影象型別效能
Types of Pixel(畫素型別)
應用程式應協商ICAP_PIXELTYPE和ICAP_BITDEPTH,除非它能在所有位深度上處理所有畫素型別。允許的畫素型別包括TWPT_BW,TWPT_GRAY,TWPT_RGB、TWPT_PALETTE,TWPT_CMY,TWPT_CMYK,TWPT_YUV,TWPT_YUVK,TWPT-CIEXYZ和TWPT_INFRARED。
Depth of the Pixels(in bits) 畫素位深度
對於TWPT_BW這樣的畫素型別,一個畫素僅佔一位。其它畫素型別允許每個畫素佔多個位(4位或8位灰度影象或24位彩色影象)。請確保先設定ICAP_PIXELTYPE,然後再設定ICAP_BITDEPTH。
4.1.3.3 圖形採集引數
Exposure(曝光)
許多效能對此有影響,包括ICAP_BRIGHTNESS,ICAP_CONTRAST,ICAP_SHADOW,ICAP_HIGHLIGHT,ICAP_GAMMA和ICAP_AUTOBRIGHT。
Scaling(縮放)
若要通知源在傳輸前縮放影象,請參考ICAP_XSCALING和ICAP_YSCALING。
Rotation(旋轉)
若要通知源在傳輸前旋轉影象,請參考ICAP_ROTATION和ICAP_ORIENTATION。
4.1.4 限制效能以及訊息響應
在應用程式給效能支援的值施行了限制後,資料來源在響應效能的相關查詢時會存在不確定性。以下指南有助於釐清這種狀況。
MSG_RESET
我們已經知道這將使效能的值重置為預設值,但還必須宣告一點:這也會重置任何應用程式施加在效能上的限制。
MSG_GETCURRENT和MSG_GETDEFAULT
顯然沒有當前或預設值的效能將不會支援這些訊息。但第10章描述了另一種可能性,在這種情況下,簡單地採用與MSG_GET相同的方式響應這些訊息是有意義的。
同樣直觀的是資料來源將在所有允許的情況下使用TW_ONEVALUE來響應對效能的請求。
MSG_GET
如果應用程式對當前效能施加了限制,那麼資料來源將根據這些限制來響應此訊息。否則將以將所有源支援的值作為響應。當然,響應中能夠包含的值的數量要受到容器的限制。
MSG_SET
第7章有關此三聯碼的描述:
“當容器為TW_ONEVALUE或TW_ARRAY時設定當前值,當容器為TW_ENUMERATION或TW_RANGE時設定可用值以及當前值”
為進一步說明此操作,必須先宣告一點:當應用程式施加一個限制時,源必須考慮所支援的值以及要求的限制。結果應為即支援又被限定使用的值的集合。
施加限制後會產生一種情況,即預設值不再在支援的值集合當中時。使用TW_ENUMERATION時,報告的的預設值索引應被資料來源設定為限制集合中的某個值。這是一個確保索引有效的預防措施。在這種情況下,TW_ENUMERATION中的預設值不再有意義,應用程式可將其忽略,直至限制被MSG_RESET操作取消。
4.1.5 程式碼中的效能容器
效能資訊在應用程式和源之間通過一種稱為容器的結構進行傳遞:TW_ARRAY,TW_ENUMERATION,TW_ONEVALUE以及TW_RANGE。建立和讀取容器所需的操作用下列程式碼段說明。容器可靈活地定義用於包含許多種資料之一。請參考工具包以瞭解容器可用的所有封裝和拆包功能。
4.1.6 延遲協商-在狀態4之後進行效能協商
應用程式可能在會話期間的任何時刻向源詢問效能資料。但是,一個原則是應用程式只能在狀態4下請求設定效能。此限制背後的基本原因與源啟用時源使用者介面的顯示有關。許多源需要更改其使用者介面的內容以響應應用程式的設定請求。這些更改可預防使用者選擇與應用程式要求不一致的選項。源使用者介面不會在狀態4下顯示因而可以在使用者不查覺的情況下改變。而使用者介面在狀態5至7時則會顯示。
一些效能對使用者介面沒有影響並且應用程式可能希望在狀態4之後進行設定。為了允許延遲協商,應用程式必須在狀態4下請求特定的效能能夠在稍後進行設定(狀態5至6),源可以同意或拒絕此請求。此請求通過在CAP_EXTENDEDCAPS上使用DG_CONTROL/DAT_CAPABILITY操作來協商。
在CAP_EXTENDEDCAPS效能上的DG_CONTROL / DAT_CAPABILITY操作:
MSG_GET
指示源希望在狀態5至6下進行協商的所有效能。
MSG_SET
指定應用程式希望在狀態5至6下協商哪些效能。
MSG_GETCURRENT
指示源和應用程式均同意在狀態5至6下協商的所有效能。
與其它效能一樣,若源不支援CAP_EXTENDEDCAPS,它將返回返回碼TWRC_FAILURE和狀態碼TWCC_CAPUNSUPPORTED。
若應用程式嘗試在狀態5或6下設定效能但源沒有事先同意此安排,此操作將失敗,其返回碼為TWRC_FAILURE,狀態碼為TWCC_SEQERROR。
若應用程式不使用源使用者介面,則應用程式將控制源的狀態。若應用程式想設定效能的值,它可以使源返回狀態4再進行此操作。因此使用自己的使用者介面的應用程式無需使用CAP_EXTENDEDCAPS。
4.2 資料傳送選項
之前已經討論過,TWAIN為資料傳送定義了三種模式:本地、檔案和快取模式。
源被要求支援本地和快取傳送模式。
4.2.1 本地傳輸模式
此模式的使用在第3章中已介紹。本地模式的一個潛在的侷限是可能沒有足夠大的RAM塊可用於儲存影象。這種情況直到應用程式傳送DG_IMAGE / DAT_IMAGENATIVEXFER / MSG_GET操作嘗試進行傳輸時才會被發現。
當出現記憶體不足的情況下,源可能的響應方式有多種:
• 簡單地使操作失敗。
• 裁剪影象使其能夠置入可用的記憶體。源應通知使用者由於記憶體限制而進行了此操作。裁剪應保持影象和外觀比例和起點(左上角)。
• 和使用者進行溝通以允許變更影象尺寸或取消操作。
DG_IMAGE / DAT_IMAGENATIVEXFER / MSG_GET返回的返回碼/狀態碼可指示發生了哪種動作:
TWRC_XFERDONE:
表示傳輸已完成並且會話狀態為7。但這不能保證源沒有裁剪影象。即使應用程式在傳輸前使用DG_IMAGE/DAT_IMAGEINFO/MSG_GET來確定影象尺寸,也不能認為返回的ImageWidth和ImageHeight適用於最終傳輸過來的影象。如果影象尺寸對應用程式很重要,則應在傳輸完成後卻檢查最終的影象尺寸,如下:
• 呼叫DG_CONTROL / DAT_PENDINGXFERS / MSG_ENDXFER操作使會話狀態從7變更為6(或5)。
• 判斷傳輸的真實的影象的尺寸: Windows —— 讀取DIB頭資訊;Macintosh—— 檢查影象的PicFrame。
TWRC_CANCEL:
獲取操作被使用者取消,會話狀態為7。執行DG_CONTROL / DAT_PENDINGXFERS / MSG_ENDXFER操作以使會話狀態從7變更為6(或5)。
TWRC_FAILURE:
檢查狀態碼以確定失敗的原因。會話狀態為6。沒有為DIB或PICT分配任何記憶體。影象依然處於掛起狀態。如果是由記憶體不足引起,可以選擇釋放額外的記憶體或執行DG_CONTROL / DAT_PENDINGXFERS /MSG_ENDXFER以丟棄掛起的影象。
4.2.2 磁碟檔案傳輸模式
從版本1.9開始,有兩種可用的檔案傳輸機制。Windows開發者可繼續使用TWSX_FILE選項,Macintosh開發者則必須使用TWSX_FILE2,以在新版本的作業系統上正確地定點陣圖像和音訊檔案。
判斷源是否支援磁碟檔案傳輸模式:
• 使用DG_CONTROL / DAT_CAPABILITY / MSG_GET操作。
• 將TW_CAPABILITY.Cap域設定為ICAP_XFERMECH。
• 源通過TW_CAPABILITY.hContainer返回它所支援的傳輸模式資訊。磁碟檔案模式用TWSX_FILE或TWSX_FILE2標識。源沒有被強制要求支援磁碟檔案傳輸模式,因此驗證十分必要。
4.2.2.1 確定支援檔案傳輸模式後,啟動傳輸
在狀態4下:
• 使用DG_CONTROL / DAT_CAPABILITY / MSG_SET操作,ICAP_XFERMECH設定為TWSX_FILE 或 TWSX_FILE2。
• 將 TW_CAPABILITY. Cap設定為ICAP_IMAGEFILEFORMAT,使用 DG_CONTROL / DAT_CAPABILITY / MSG_GET 確定源支援何種檔案格式。源返回所支援的格式的識別符號,這些識別符號以 TWFF_ 為字首,包括 TWFF_PICT, TWFF_BMP, TWFF_TIFF等。
在狀態4、5、6下:
可使用DG_CONTROL/ DAT_SETUPFILEXFER 的 SG_GET,MSG_GETDEFAULT 和 MSG_SET 操作。此操作相關的資料結構是TW_SETUPFILEXFER 。
應用程式可使用MSG_GETDEFAULT操作來確定預設檔案格式和檔名(TWAIN.TMP或TWAIN.AUD)。若要設定檔名和格式:
1. 分配一個TW_SETUPFILEXFER結構,填充適當的域:
a. FileName - 在Windows中請確保包含完整的路徑。
b. Format - 以TWFF_開始的常量,如果設定為不支援的格式,則操作將返回TWRC_FAILURE / TWCC_BADVALUE,並且源將重圍為輸出資料到預設檔案。
c. VrefNum - 在Macintosh中,設定為檔案的卷標;在Windows中設定為TWON_DONTCARE16。
2. 呼叫DG_CONTROL / DAT_SETUPFILEXFER / MSG_SET。
4.2.2.2 傳輸到檔案
在應用程式收到MSG_XFERREADY通知併傳送DG_CONTROL / DAT_SETUPFILEXFER / MSG_GET後:使用DG_IMAGE /DAT_IMAGEFILEXFER / MSG_GET ,此操作沒有與之關聯的資料結構,在DSM_Entry呼叫中pData為NULL。
• 如果應用程式未指定檔名(在Set Up中),源將使用預設檔名或最後一次指定的檔案資訊。
• 如果應用程式指定的檔案不存在,源將建立該檔案。
• 如果檔案存在但已包含資料,源將覆蓋已有資料。所以若對多個檔案傳輸使用相同的檔名,則必須在兩次傳輸之間將檔案資料複製到其它地方。
注:一旦開始,應用程式就無法取消檔案傳輸操作。但是,源可能通過其使用者介面向使用者提供取消傳輸的功能。
在此操作後,確保檢查返回碼:
TWRC_XFERDONE:檔案成功寫入。應用程式應呼叫DG_CONTROL / DAT_PENDINGXFERS / MSG_ENDXFER使會話返回狀態6(或5)。
TWRC_CANCEL:使用者取消傳輸。檔案內容未定義,呼叫DG_CONTROL / DAT_PENDINGXFERS / MSG_ENDXFER使會話返回狀態6(或5)。
TWRC_FAILURE:源處於狀態6;檔案內容未定義;影象依然處於掛起狀態。若要放棄影象,可使用DG_CONTROL / DAT_PENDINGXFERS /MSG_ENDXFER。
檢查狀態以確定失敗的原因:
TWCC_BADDEST——指定了無效源。
TWCC_OPERATIONERROR——檔案存在但無法存取或在寫入時發生系統錯誤。
TWCC_SEQERROR——在無效狀態下操作。
4.2.3 快取傳輸模式
資料通常以非壓縮格式傳輸,如果想知道源在快取傳輸模式下是否能傳輸壓縮資料,請對ICAP_COMPRESSION使用DG_CONTROL /DAT_CAPABILITY / MSG_GET操作,結果可能為TWCP_NONE ,也可能為TWCP_PACKBITS 、TWCP_JPEG等。
4.2.3.1 啟動傳輸
在狀態4下:
使用DG_CONTROL / DAT_CAPABILITY / MSG_SET,ICAP_XFERMECH 設定為TWSX_MEMORY。
在狀態4、5、6下:
應用程式使用DG_CONTROL / DAT_SETUPMEMXFER / MSG_GET來確定源想要多大的快取來傳輸。在狀態6下源可能有更精確的資訊。此操作相關資料結構為TW_SETUPMEMXFER,源將根據裝置填充合適的值。
對用於非壓縮傳輸的快取:
• 應用程式負責分配和釋放快取傳輸所用的所有記憶體。
• 作為一個可選行為,建立一個所選尺寸大小的快取。
• 在所有情況下,分配的記憶體應遵循MinBufSize和MaxBufSize的限制。否則源將操作失敗(返回TWRC_FAILURE/TWCC_BADVALUE)。
• 使用多個緩衝區時,各個緩衝區大小必須相同。
• 建議光柵線應對齊到雙字並以0填充。
4.2.3.2 執行快取傳輸:
應用程式收到MSG_XFERREADY通知併發出DG_CONTROL / DAT_SETUPMEMXFER / MSG_GET後:
• 分配一個或多個相同尺寸的緩衝區,最好是TW_SETUPMEMXFER.Freferred域所宣告的尺寸。如果不能,則確保緩衝區尺寸在MinBufSize和MaxBufSize之間。
• 分配一個 TW_IMAGEMEMXFER,第一個域設定為TWON_DONTCARE16,接下來六個域設定為 TWON_DONTCARE32。最後一個TW_MEMORY結構的Memory域如下填充:
Memory.Flags - 描述Memory.TheMem的型別,值為TWMF_POINTER 或 TWMF_HANDLE。
Memory.Length - 緩衝區尺寸,以字元為單位
Memory.TheMem - 指向上述分配的緩衝區的控制程式碼或指標(是控制程式碼還是指標由Flags域指定)。
每傳輸完一個緩衝區後,源將填充除Memory外的所有域。
快取傳輸的流程如下:
步驟一:
快取傳輸不提供嵌入的頭資訊,因此,應用程式必須確定影象屬性。例如在狀態6下收到MSG_XFERREADY後,傳送DG_IMAGE /DAT_IMAGEINFO / MSG_GET 和DG_IMAGE / DAT_IMAGELAYOUT / MSG_GET來了解影象的點陣圖特徵、尺寸以及在當前頁面上的位置。若需要其它額外的資訊,請使用 DG_CONTROL / DAT_CAPABILITY / MSG_GET操作。
步驟二:
傳送DG_IMAGE / DAT_IMAGEMEMXFER / MSG_GET。
步驟三:
檢查返回碼
• TWRC_SUCCESS - 檢查TW_IMAGEMEMXFER結構中關於緩衝區的資訊。如果想重用緩衝區,將資料拷貝到其它地方去。
若有必要,回到步驟二,重新獲取一個緩衝區,重新初始化TW_IMAGEMEMXFER結構,再傳送另一個DG_IMAGE /DAT_IMAGEMEMXFER / MSG_GET。
• TWRC_XFERDONE - 這表示源已經成功地傳輸完了最後一個緩衝區。
• TWRC_CANCEL - 使用者取消了傳輸,應用程式必須傳送 DG_CONTROL / DAT_PENDINGXFERS / MSG_ENDXFER以從狀態7回到狀態6(或5)。
• TWRC_FAILURE - 檢查狀態碼以確定原因。如果失敗在首個緩衝區的傳輸過程中,則會話仍處於狀態6;若發生在隨後的緩衝區傳輸過程中,則會話處於狀態7。此時緩衝區內容無效且緩衝區傳輸仍處於掛起狀態,若要取消,請使用DG_CONTROL / DAT_PENDINGXFERS / MSG_ENDXFER。
步驟四:
一旦返回了TWRC_XFERDONE,應用程式就必須傳送 DG_CONTROL / DAT_PENDINGXFERS /MSG_ENDXFER來結束傳輸。
注:在使用快取傳輸時,大多數源將影象資料分割成條。每個條是一個水平帶,從影象左端開始橫跨整個影象寬度,但只覆蓋部分影象長度(高度)。如果在源返回的TW_IMAGEMEMXFER中,XOffset域為零,Columns域等於TW_IMAGEINFO.ImageWidth域,則可以斷定源採用了這種分割方式。
還有一種只有少數源使用的片方式。請參見第八章有關TW_IMAGEMEMXFER的資訊。
4.2.4 檔案格式的快取傳輸模式
此方式與緩衝傳輸模式非常類似,只是傳輸的資料遵循之前通過DG_IMAGE / DAT_SETUPFILEXFER / MSG_GET指定的影象檔案格式。此方式不要求資料作為完整的影象線傳輸和任何填充,資料被認為是自包含和自描述的。
4.3 影象資料及其佈局
從源傳送到應用程式的影象有數個屬性。其中一些描述影象尺寸,一些描述影象在原始頁面中的位置,還有一些描述解析度或畫素位數等資訊。TWAIN為應用程式提供了了解這些屬性的途徑。
使用者通常可通過源使用者介面選擇和更改影象的屬性。額外地,TWAIN也提供了支援在採集和傳輸前影響這些屬性的的效能和操作。
4.3.1 獲取將要傳輸的影象的資訊
在傳輸開始前(狀態6),源可向應用程式提供將要傳輸的真實影象的資訊。注意一旦傳輸開始這樣資訊將丟失,因此應用程式應在必要時將其儲存。這些資訊可通過以下操作查詢:
DG_IMAGE / DAT_IMAGELAYOUT / MSG_GET
DG_IMAGE / DAT_IMAGEINFO / MSG_GET
採集的影象區域始終是一個稱為“框架”(Frame)的矩形。在一個頁面上可能分配有多個框架。框架可由使用者選擇或應用程式指定。TW_IMAGELAYOUT結構指示影象在當前頁面上相對於頁面起點的位置,同時其FrameNumber域指示這是從頁面上採集到的第幾個框架。
TW_FRAME結構描述框架的Top、Bottom、Left和Right值。其單位由ICAP_UNITS指定。
圖4-1 TW_FRAME結構
DG_IMAGE / DAT_IMAGEINFO / MSG_GET操作傳達將被傳輸的影象的其它一些資訊。
請注意TW_IMAGEINFO中ImageWidth、ImageLength和TW_IMAGELAYOUT中描述的框架之間的關聯。
4.3.2 變更影象屬性
通常使用者會去選擇所要求的屬性,但應用程式可能希望在狀態4進行初始化。例如,如果使用者介面不會被顯示,程式則可能希望選取框架。程式可使用DG_IMAGE / DAT_IMAGELAYOUT / MSG_SET操作來定義要獲取的區域(框架)。但是並不存在相應的DG_IMAGE / DAT_IMAGEINFO / MSG_SET操作。
TW_IMAGEINFO 域 |
效能或相關資料結構 |
XResolution |
ICAP_XRESOLUTION |
YResolution |
ICAP_YRESOLUTION |
ImageWidth * |
TW_IMAGELAYOUT.TW_FRAME.Right - TW_FRAME.Left |
ImageLength * |
TW_IMAGELAYOUT.TW_FRAME.Bottom - TW_FRAME.Top |
SamplesPerPixel |
ICAP_PIXELTYPE |
BitsPerSample |
BitsPerPixel 除以SamplesPerPixel |
BitsPerPixel |
ICAP_BITDEPTH |
Planar |
ICAP_PLANARCHUNKY |
PixelType |
ICAP_PIXELTYPE |
Compression |
ICAP_COMPRESSION |
注:ImageWidth和ImageLength以畫素為單位,而TW_FRAME使用ICAP_UNITS。
4.3.3 解決ICAP_FRAMES、ICAP_SUPPORTEDSIZES和DAT_IMAGELAYOUT之間的衝突
由於有幾種方式可用於協商掃描區域,可能難以確定應優先使用哪種方式。一種合理的方案是用設定上一個框架的方式來設定當前框架。不過對於MSG_GET操作而言這三種方式依然難以確定。下列行為是推薦的:
注:框架區域只被ICAP_PHYSICALWIDTH和ICAP_PHYSICALHEIGHT限制,設定ICAP_SUPPORTEDSIZES不會增加新的限制。TWSS_xxxx是隻預定義的固定框架尺寸。
若框架由DAT_IMAGELAYOUT設定:
ICAP_FRAMES應以DAT_IMAGELAYOUT呼叫中設定的框架尺寸來響應MSG_GETCURRENT。
ICAP_SUPPORTEDSIZES應用TWSS_NONE來響應MSG_GETCURRENT。
若當前框架由ICAP_FRAMES設定:
ICAP_FRAMES應以ICAP_FRAMES中設定的當前框架尺寸作為響應。
ICAP_SUPPORTEDSIZES應用TWSS_NONE來響應MSG_GETCURRENT。
若當前固定框架由ICAP_SUPPORTEDSIZES設定,則:
DAT_IMAGELAYOUT應以ICAP_SUPPORTEDSIZES中指定的固定框架尺寸來響應MSG_GET。
ICAP_FRAMES應以ICAP_SUPPORTEDSIZES中指定的固定框架尺寸來響應MSG_GETCURRENT。
4.3.4 ICAP_RETATION,ICAP_ORIENTATION對ICAP_FRAMES,DAT_IMAGELAYOUT、DAT_IMAGEINFO的影響
在嘗試處理對當前框架和影象佈局的旋轉和取向的影響時存在更大的混亂。出於規範化的考慮,約定ICAP_ROTATION and ICAP_ORIENTATION應該在ICAP_FRAMES 和 DAT_IMAGELAYOUT之後應用。
顯然取向的改變會影響到輸出圖形的尺寸,因此DAT_IMAGEINFO中必須予以考慮(狀態6)。源報告的作為結果的影象尺寸應考慮當前框架的旋轉。
ICAP_ORIENTATION 和 ICAP_ROTATION 是疊加的。最初的框架在從裝置下載到源時被ICAP_ORIENTATION修改,體現所掃描的紙張的朝向。然後應用ICAP_ROTATION,得到最終報告給應用程式的框架資訊(狀態6至7)。結合這兩個值的一個可能的理由是使用它們互相抵消。例如,某些內建文件自動傳送機的掃描器可通過將ICAP_ORIENTATION設定為TWOR_LANDSCAPE結合將ICAP_ROTATION設定為90度,來獲得更好的效能。因為這將允許使用者橫向傳送它們的影象(傳送得更快),然後再通過旋轉使採集到的影象重新變為豎向(使用者觀察的方式)。
4.4 傳輸多個影象
第3章討論了單個影象的傳輸。傳輸多個影象只是簡單地重複單個影象傳輸的處理過程。在TWAIN下傳輸多個影象有兩類問題:
1. 當會話處於中間影象的邊界時傳輸可處於什麼狀態?
2. 什麼能力可用於支援文件傳送機操作?這關係到掃描的高效性。
本段以對單個影象傳輸過程的回顧作為開始。然後再討論單個影象傳輸完畢後應用程式可執行的操作,最後再展示文件傳送機。
以下為對單影象傳輸的簡要回顧:
1. 程式啟動源,會話狀態從4變為5。
2. 準備好影象後,源向程式傳送MSG_XFERREADY。
3. 程式使用DG_IMAGE / DAT_IMAGEINFO / MSG_GET和DG_IMAGE / DAT_IMAGELAYOUT / MSG_GET獲取將要傳輸的影象資訊。
4. 程式使用DG_CONTROL / DAT_IMAGExxxxFER / MSG_GET操作初始化傳輸。
5. 傳送成功後,源返回TWRC_XFERDONE。
6. 程式傳送DG_CONTROL / DAT_PENDINGXFERSR / MSG_ENDXFER操作通知傳輸結束並獲取掛起的傳輸數量。
如果單個影象傳輸的背後只是為了將其從源中清除的話,那麼一個操作就可以了:
• 傳送DG_CONTROL / DAT_PENDINGXFERSR / MSG_ENDXFER操作。正如普通影象傳輸那樣,此操作告訴源程式已經獲取完當前影象,並且源報告掛起的傳輸數量作為響應。
4.4.1 多影象傳輸的準備
影象傳輸完成後的DG_CONTROL / DAT_PENDINGXFERSR / MSG_ENDXFER操作有兩個重要的功能:
1. 它返回掛起的傳輸數量(TW_PENDINGXFERS.Count)
2. 若掛起的傳輸數量大於0,它使會話狀態變更為6(準備傳輸);否則變更為5(源啟用)。前面說過當源知道可獲取的影象數量時,它返回的數量值為一個正整數;若源不知道可用的影象數量,則返回的數量值為-1。後者在諸如使用了文件傳送機的時候可能出現。需要注意的是不知道可用的影象數量也包括了沒有可用影象的可能性。請參考DG_CONTROL / DAT_PENDINGXFERSR /MSG_ENDXFER以獲取更多相關資訊。
我們剛剛瞭解到MSG_ENDXFER傳送後,會話狀態可能處於5或6,也就是說會話依然處於活動狀態。如果會話處於狀態6,則程式可以採取兩種行為以使會話狀態最終變為5:
• 繼續執行單個影象的傳輸處理過程直至沒有更多影象可用。
• 傳送一個DG_CONTROL / DAT_PENDINGXFERS / MSG_RESET 清空源中所有掛起的傳輸。
一旦會話狀態返回5,程式就必須決定是停留在狀態5還是變更為4。這裡有兩種可用的方案:
• 程式讓源控制未來的狀態變更。若源傳送MSG_XFERREADY訊息,程式重新開始進行多影象傳輸;如果源傳送MSG_CLOSEDSREQ(例如使用者啟用了源顯示的UI上的“關閉”觸發器),程式應返回一個DG_CONTROL/ DAT_USERINTERFACE / MSG_DISABLEDS使會話回到狀態4。
• 程式直接控制會話狀態。例如,程式可能希望在當前批次的影象傳輸完成後關閉,在這上,程式將在沒有可用影象後立即傳送DG_CONTROL / DAT_USERINTERFACE /MSG_DISABLEDS。
需要注意的是,在當前影象集傳輸完成後,並沒有什麼“正確”、“錯誤”或“首選”的方案可供程式遵照執行。如果程式希望明確地由使用者來控制會話的結束,它可以等待源傳送MSG_CLOSEDSREQ給它。另一方面,程式可能非常清楚會話的構成,例如,它可能希望掃描會話在遇到一張空白紙張時結束。在這種情況下,程式可能希望藉助MSG_DISABLEDS來進行控制。
4.4.2 使用文件傳送機(Document Feeder)
文件傳送機這個名詞即可指物理實體上的自動送稿機(例如用於掃描器的),也可指邏輯上的影象庫的傳送功能。兩種輸入機制都適用於下列討論的內容。此部分的主題是:
1. 對掃描來自文件傳送機還是還是platen(滾筒)的頁面進行控制。
2. 檢測是否有紙張已準備掃描。
3. 控制預掃描。
注意:這些概念適用於沒有傳送機的掃描器。
4.4.2.1 選擇文件傳送機
有時使用文件傳送機將改變影象採集的方式。舉例來說,當一張紙放置在臺板上時,掃描器需要在紙上移動它的游標,若使用文件傳送器,則掃描器可能使其游標固定而掃描移動的紙張。為應對這種差異,程式和源可明確地同意是否使用文件傳送機。此行為的協商必須在狀態4(源啟用前)下進行。
CAP_FEEDERENABLED
判斷源是否有可用的文件傳送機,若是,則選擇相關設定。
1. 使用DG_CONTROL / DAT_CAPABILITY / MSG_GET 操作來判斷源是否支援此效能。TWRC_FAILURE / TWCC_CAPUNSUPPORTED 表示源不支援選擇文件傳送機。
2. 若支援,則在狀態4下使用DG_CONTROL / DAT_CAPABILITY / MSG_SET操作。
3. 將TW_CAPABILITY.Cap設定為CAP_FEEDERENABLED。
4. 建立一個TW_ONEVALUE視窗並置為TRUE,將TW_CAPABILITY.hContainer指向此結構。
5. 執行MSG_SET操作並檢查返回值。
若返回TWRC_SUCCESS,則傳送機可用,並且您要求使用它的請求已被接受。程式現在可以設定文件傳送機的其它效能了。
若返回TWRC_FAILURE 、TWCC_CAPUNSUPPORTED,TWCC_CAPBADOPERATION或TWCC_BADVALUE,則源不支援文件傳送機或不允許使用。
注:如果程式想防止使用者使用文件傳送機,程式應使用MSG_SET將 CAP_FEEDERENABLED效能設定為FALSE。
4.4.2.2 檢查是否有影象已準備好被獲取
源設定中是否有影象已準備好被獲取與是否有可用的文件傳送機無關,這有三種可能:
1. 源無法辨別是否有可用影象。
2. 影象可用於獲取,或
3. 無影象可用於獲取。
要檢測這些情況,請先判斷源是否能辨別是否有影象可用於獲取,然後再判斷是否有可用影象。以下效能用於完成此工作:
CAP_PAPERDETECTABLE
判斷源是否能辨別文件是否已載入。
1. 使用DG_CONTROL / DAT_CAPABILITY / MSG_GET操作。
2. 將TW_CAPABILITY.Cap 域設定為 CAP_PAPERDETECTABLE。
3. 源返回TWRC_SUCCESS及一個HContainer結構。若它能夠檢測可用於獲取的文件,則值為TRUE。如果返回值為WRC_FAILURE 和TWCC_CAPUNSUPPORTED 或 TWCC_BADVALUE,則源不能檢測文件是否已載入。
注:CAP_PAPERDETECTABLE可獨立於 CAP_FEEDERENABLED進行使用。同樣,源並不一定需要一個自動傳送機才能支援此效能。一個能夠檢測是否有紙張在臺板上的掃描器也將返回TRUE。
程式不能設定此效能,源只在必要時報告。
CAP_FEEDERLOADED
判斷傳送機中是否有文件載入。
1. 使用 DG_CONTROL / DAT_CAPABILITY / MSG_GET操作。
2. 將 TW_CAPABILITY.Cap 域設定為 CAP_FEEDERLOADED。
3. 有文件載入時源將返回TRUE。
注:對CAP_FEEDERENABLED 和 CAP_PAPERDETECTABLE都一樣,TRUE或FALSE並不表示可否使用此效能,FALSE只是表示沒有可用文件或無法辨別。為了得到確定的答案,請務必先檢查CAP_PAPERDETECTABLE 。
4.4.2.3 控制預掃描
使用低端掃描器時,CPU通常都能實時或在不同紙張的掃描間隔期間處理輸入的影象資料。但是,在使用高效掃描器時,CPU可用於處理一張紙的影象資料的時間可能顯著地少於掃描的時間。如果掃描器能夠掃描CPU將要獲取的影象的頭資料,則能夠緩解此問題。此資料在CPU處理當前影象時快取到掃描器本地快取或通過DMA儲存到記憶體中。
不過預掃描並不總是適合的,因為是否需要繼續掃描有時候是由當前掃描的影象決定的。例如掃描程式可能要求在遇到空白紙張時終止掃描。如果啟用預掃描,空白紙張之後的一張或多張紙張都有可能被掃描並傳送到掃描器的輸出區,從應用程式設計的觀點來說這種行為是錯誤的。
我們已經闡述了控制預掃描功能的必要性。但是,一個簡單的“啟用預掃描”命令並不足以控制一些掃描器提供的豐富功能。TWAIN的文件輸送模型將每個影象的傳輸分為三個階段:
1. 影象在輸入區域中。此動作由使用者完成(例如將一疊紙放到自動傳送機中)。
2. 影象準備好被掃描。此行為導致下一個可用影象被輸送到掃描區域的起點處。設定CAP_AUTOFEED效能以自動將影象輸送到掃描區域的起點。
3. 影象被掃描。此行為導致影象被掃描。例如,DG_IMAGE / DAT_IMAGEMEMXFER / MSG_GET操作啟動影象傳輸(通過內在快取傳輸給程式)。通過設定 CAP_AUTOSCAN效能,TWAIN允許源將影象預取至源本地的儲存器(即使程式尚未請求)。
CAP_AUTOFEED
啟用源的自動傳送文件程式。
1. 使用DG_CONTROL / DAT_CAPABILITY / MSG_SET操作。
2. 將 TW_CAPABILITY.Cap 域設定為 CAP_AUTOFEED 並將效能設定為TRUE。
3. 設定為TRUE時,源的行為是在頁面的所有區域都已獲取後彈出此頁面,然後傳送下一頁面。有影象資料可獲取(並且源處於啟用狀態)時此自動傳送過程將一直持續。 CAP_FEEDERLOADED為TRUE表示紙張在文件傳送機中。
注:要使用此效能,CAP_FEEDERENABLED 必須設定為TRUE,否則源將返回 TWRC_FAILURE / TWCC_CAPUNSUPPORTED。
CAP_AUTOSCAN
啟用源的文件自動掃描程式。
• 使用DG_CONTROL / DAT_CAPABILITY / MSG_SET。
• 將TW_CAPABILITY.Cap域設定為CAP_AUTOSCAN並將效能設定為TRUE。
• 設定為TRUE時,源的行為是在頁面的所有區域都已獲取後彈出頁面,並開始掃描下一頁面。有影象資料可獲取(並且源處於啟用狀態)時此自動掃描過程將一直持續。
注:將 CAP_AUTOSCAN 設定為TRUE將使 CAP_AUTOFEED 隱式被置為TRUE。
應用程式使用文件自動傳送時:
• 將CAP_XFERCOUNT設定為-1以表示程式可接受多個影象。
• 預期源返回的TW_PENDINGXFERS.Count值為-1,表示源有更多的影象用於傳輸但數量未知。
• 使用文件自動傳送不會導致多文件傳輸過程產生變化。
4.4.2.4 程式控制文件傳送
除了文件自動傳送以外,TWAIN也提供了由應用程式手動控制文件傳送的選項。這隻有在源同意狀態5和6下協商(通過CAP_EXTENDEDCAPS)以下效能時才有可能。如果CAP_AUTOFEED為TRUE,將影響到尖對以下效能的響應。
CAP_FEEDPAGE
• 如果程式將此效能設定為TRUE,源將彈出當前頁面並輸送下一頁面(若存在)。
• 為了能正常工作,要求 CAP_FEEDERENABLED 和CAP_FEEDERLOADED為TRUE。
• 在 CAP_AUTOFEED為TRUE時也將是同樣的動作。
• 彈出的頁面對應程式正在獲取或將要獲取的影象,因此,若 CAP_AUTOSCAN 為TRUE並且有不確定數量的頁面已被掃描,則彈出的頁面可能是已經掃描到源的本地快取中的頁面。
CAP_CLEARPAGE
• 如果程式將此效能設定為TRUE,源將彈出當前頁面並使傳送區域為空(即無可獲取影象)。
• 為了能像描述的那樣工作,要求 CAP_FEEDERENABLED 為TRUE。
• 若 CAP_AUTOFEED 為TRUE,則下一頁面將被推送至獲取區域。
• 若CAP_AUTOSCAN為TRUE,設定此效能將返回TWRC_FAILURE及TWCC_BADVALUE。
CAP_REWINDPAGE
• 若設定此效能為TRUE,源將把當前頁送回輸入區域並把輸出區域中的最後一個頁面送回獲取區域。
• 為了能正常工作,要求 CAP_FEEDERENABLED 為TRUE。
• 若 CAP_AUTOFEED 為TRUE,則將在頁面的所有區域已獲取後進行常規的傳送。
• 回溯的頁面對應程式正在獲取的影象。因此,若CAP_AUTOSCAN為TRUE,並且不確定數量的頁面已被掃描,則回溯的頁面可能對應已掃描至源的本地快取中的頁面。
4.5 傳送壓縮資料
在使用快取傳輸模式時,某些源可能支援以壓縮格式傳送資料。
為確定源是否支援傳送壓縮資料並設定其效能:
1. 使用 DG_CONTROL / DAT_CAPABILITY / MSG_GET操作。
2. 將TW_CAPABILITY.Cap 域設定為 ICAP_COMPRESSION。
3. 源通過TW_CAPABILITY.hContainer指向的一個容器指定所支援的壓縮方式資訊。可選的壓縮方式的識別符號均帶字首TWCP_(例如TWCP_PACKBITS),可在第8章的Constants部分和TWAIN.H檔案中找到。
4. 若希望協商使用某種壓縮方式,請使用 DG_CONTROL / DAT_CAPABILITY / MSG_SET操作。
TW_IMAGEMEMXFER結構用於DG_IMAGE / AT_IMAGEMEMXFER / MSG_GET操作。
傳輸壓縮資料流時(邊壓縮邊傳輸):
• BytesPerRow域應設定為0,Columns、Rows、XOffset和YOffset域應包含TWON_DONTCARE32 以表示這些域持有無效值(當前圖形的尺寸可通過DG_IMAGE / DAT_IMAGEINFO / MSG_GET獲取)。
• 緩衝區總是由源進行完整的填充。對於壓縮資料則很可能有超過一條的不完整資料被寫入快取。
• 應用程式必須負責銷燬快取。
傳輸壓縮資料塊時(先壓縮再傳輸):
• 此結構中的所有域包含有效值。BytesPerRow,Columns,Rows,XOffset和YOffset描述解壓因子,Compression和BytesWritten描述壓縮因子。
• 與壓縮資料流的傳輸不同的是,此時由源分配傳輸緩衝。這允許源建立不同尺寸的緩衝區以完整地(未分割到一系列的緩衝區中)將壓縮資料傳輸給程式。在這種情況下,程式應這樣設定TW_MEMORY結構:Flags為TWMF_DSOWNS,Length為 TWON_DONTCARE32,TheMem為NULL。源應假定程式將保持之前的緩衝區而不會釋放它,因此,源應為每次傳輸分配一個新的緩衝區。
• 應用程式必須負責銷燬快取。
• 最後,應用程式不應假定tiles會以任何特定的或邏輯的順序進行傳輸。
4.5.1 JPEG壓縮
TWAIN支援傳輸多種格式的壓縮資料,JPEG壓縮是其中一種。JPEG壓縮演算法為灰度和真彩影象提供了比例從10:1到25:1的壓縮比例,代價則是影象質量的下降。此壓縮由應用程式通過一系列“感知性的”過濾器分三個階段完成:
4.5.1.1 顏色空間轉換和分量二次取樣(針對彩色影象)
由於平均擁有100百萬個光線感知器(桿狀細胞)和僅約6萬個顏色感知器(視錐細胞),人眼對光的強度(亮度)的感知要比對光頻率(色度,或“色彩”)敏感得多。通過將彩色影象轉換到一個更有效的亮度/色度顏色空間並對色度分量進行二次取樣能夠輕易地將影象壓縮許多。
此轉換使用TW_JPEGCOMPRESSION。將TW_JPEGCOMPRESSION.ColorSpace指定為TWPT_YUV,RGB資料被轉換為空間上更高效的YUV資料(以CCIR 601-1或YCbCr最廣為人知)。
TW_JPEGCOMPRESSION.SubSampling指定最終的YUV資料流中亮度和色度樣本的比例。典型的選擇是每個色彩樣本對兩個亮度樣本,這通過將TW_JPEGCOMPRESSION.SubSampling值設定為0x21102110來指定。一個更大的比例“每個色彩樣本對4個亮度樣本”由0x41104110表示。
4.5.1.2 應用離散餘弦變換(DCT)和量子化
接下來原分量(經過或未經過顏色空間轉換)通過DCT被算術地轉換到一個空間頻率表示法,然後使用量子矩陣進行過濾(每個頻率都被劃分到量子矩陣上相關的成員)。量子矩陣由TW_JPEGCOMPRESSION.QuantTable[]指定,可為最多四種不同的
源分量定義最多四個量子矩陣。TW_JPEGCOMPRESSION.QuantMap[]將特定的源分量對映到各個的量子矩陣。
注:JPEG網際網路草案標準的K部分推薦為量子對映和量子矩陣提供預設值。TWAIN使用10918-1版本作為QuantTable、HuffmanDC和HuffmanAC和預設表。預設值通過將NULL選入TW_JPEGCOMPRESSION.QuantTable[]來指定。
4.5.1.3 哈夫曼編碼
經過DCT和量子化的結果最後通過一個稱為哈夫曼編碼的無失真壓縮演算法進行進一步壓縮。應用程式開發者可提供哈夫曼表,不過一般都使用預設的表(將NULL選入TW_JPEGCOMPRESSION.HuffmanDC[]和TW_JPEGCOMPRESSION.HuffmanAC[])。
此演算法選擇支援使用重啟標記程式碼,以允許隨機讀取JPEG資料流進行解壓。更多描述請參考JPEG規範。
4.6 可選使用者介面
是否使用源管理器提供的源選擇對話方塊是可選的。
TWAIN包裝了源管理器程式碼以作為應用程式和源的通訊中介。源管理器提供的服務之一是找出匹配使用者要求的可用源並將它們顯示給使用者進行選擇。
我們推薦應用程式使用此介面,但沒有強制要求,存在兩種可選的替代方式:
1. 程式可開發並顯示自定義的選擇介面,這在響應使用者從選單中選擇“Select Source...”時顯示。
2. 如果程式專注於控制某個特定源,程式可直接選擇此源。在這種情況下,從功能上說程式並不需要選單項“Select Source..”,不過為保持與其它TWAIN相容程式的一致性,應顯示一個灰色的不可用選單項。
顯示自定義選擇介面:
1. 使用DG_CONTROL / DAT_IDENTITY / MSG_GETFIRST操作使源管理器查詢第一個可用源。源的名稱包含在TW_IDENTITY.ProductName域中。儲存此TW_IDENTITY結構。
2. 使用DG_CONTROL / DAT_IDENTITY / MSG_GETNEXT操作使源管理器獲取下一個,重複此操作直到它返回一個表示沒有其它可用源的TWRC_ENDOFLIST。同樣應儲存此TW_IDENTITY結構。
3. 將ProductName資訊展示給使用者進行選擇。作出選擇後,使用相關的TW_IDENTITY結構和DG_CONTROL / DAT_IDENTITY / MSG_OPENDS操作來使源管理器開啟指定的源。
注:使用這種方式時,與MSG_USERSELECT 操作相對地,源管理器不會更新系統預設源資訊以反映使用者的選擇。
直接選擇源:
若程式想開啟系統預設源,可使用DG_CONTROL / DAT_IDENTITY / MSG_GETDEFAULT操作來使源管理器查詢預設源並用其資訊填充TW_IDENTITY。
另外,如果想要使用的源不是預設源但知道其名稱,可以使用DG_CONTROL / DAT_IDENTITY / MSG_GETFIRST和G_CONTROL /DAT_IDENTITY / MSG_GETNEXT操作來遍歷所有源直至找到與指定名稱匹配的源,然後使用相應的TW_IDENTITY結構來開啟源。
注:使用這種方式時,源管理器同樣不會更新系統預設源資訊以反映使用者的選擇。
4.6.1 可選源使用者介面
與源管理器的源選擇對話方塊一樣,程式可能要求不使用源的使用者介面。例如某些文字識別外掛只希望協商少數效能(如畫素型別、解析度、頁面尺寸等)然後就直接獲取和傳輸資料。
為了在不顯示使用者介面的情況下啟用源:
• 使用 DG_CONTROL / DAT_USERINTERFACE / MSG_ENABLEDS。
• 將TW_USERINTERFACE.ShowUI域設定為FALSE。
• 收到並接受命令後,源將不顯示使用者介面但將開始採集資料。例如對於平板掃描器,游標光將發光並開始移動;對於手持式掃描器,將準備在“GO”按鈕被按下時開始採集資料。其它裝置可能有不同的響應,但都將立即開始採集或準備在使用者觸發後立即採集資料。
不顯示源使用者介面時效能協商非常重要:
• 因為源使用者介面不顯示,源無法向使用者提供選擇要採集資訊的機會等。除非預設值是可接受的,否則所有有關影象採集的當前值和控制引數都必須在源啟用前協商好(狀態4)。
若TW_USERINTERFACE.ShowUI 被設定為FALSE:
• 源啟用時,程式仍然要將所有事件傳遞給源(通過DG_CONTROL / DAT_EVENT / MSG_PROCESSEVENT)。
• 源應顯示僅包含使裝置在上下文中可用所必須的控制項的儘可能小的使用者介面。通常這意味著不顯示使用者介面,但有些裝置還是要求一個觸發器來啟動掃描。
• 在採集過程中源仍然顯示進度條、錯誤和其它一些與裝置操作有關訊息。若源指定CAP_UICONTROLLABLE為TRUE,則程式可通過設定CAP_INDICATORS為FALSE來禁用它。
• 資料準備好被傳輸時,源仍然將向程式傳送MSG_XFERREADY通知。
• 由於通常由使用者觸發,源也許會,也許不會向程式傳送MSG_CLOSEDSREQ訊息以要求關閉。因此,在源回到狀態5後(緊隨DG_CONTROL / DAT_PENDINGXFERS /MSG_ENDXFER操作並且TW_PENDINGXFERS.Count為0),程式可傳送DG_CONTROL / DAT_USERINTERFACE / MSG_DISABLEDS操作。
總結:在ShowUI被設為FALSE後,一些源仍可能顯示UI。程式可通過CAP_UICONTROLLABLE效能來查詢ShowUI能否被設定。如果CAP_UICONTROLLABLE 為FALSE而 ShowUI也被設為FALSE,則啟用源的操作將返回TWRC_CHECKSTATUS,但會顯示UI。因此,想要禁用UI的程式應先查詢CAP_UICONTROLLABLE。
4.6.2 模態和非模態使用者介面
源管理器的使用者介面是是模態的,但源可能提供模態或非模態的介面,下面是兩者間的差別:
非模態:
當源使用非模態介面時,雖然源介面是顯示的,但使用者仍然可以通過單擊程式視窗並啟用它以操作程式。
使用者被期望在想停止顯示源使用者介面時單擊其關閉按鈕。程式不應在任何傳輸動作後自動關閉一個非模態源,即使程式只想要單次傳輸。如果程式在使用者請求前關閉了源,則使用者很可能會迷惑於窗體為什麼消失了。請等到使用者表示希望關閉後再關閉源的介面,並在程式關閉源之前等待源傳送MSG_CLOSEDSREQ請求。
模態:
使用模態使用者介面的源不允許使用者操作其它視窗。對Windows來說,如果介面是程式模態,則使用者不能操作其它應用程式但仍然可能作業系統程式。如果介面是系統模態(這很少見),則使用者無法在應用程式和系統級操作任何東西。系統模態對話方塊可能被用於顯示高階錯誤訊息,例如UAE。
若使用模態介面,則在一次會話期間源只能進行一次採集,不過每次採集可能包含多個框架。資料傳輸完畢後源將向程式傳送關閉請求,相對地,源等待該請求。
源將在程式通過DG_CONTROL / DAT_USERINTERFACE / MSG_ENABLEDS啟用它之後表明它將使用模態或非模態介面。此操作中使用的TW_USERINTERFACE結構包含一個ShowUI域,由程式設定用於宣告源是否應顯示使用者介面。如果程式要求顯示使用者介面,則它也將通過此域來宣告希望源採用模態(TRUE)還是非模態(FALSE)介面。
若源有請求,則可通過DG_CONTROL / DAT_USERINTERFACE / MSG_DISABLEDS 操作來去掉源使用者介面。
4.7 灰度和影象資訊
TWAIN中有一些操作元組允許應用程式開發者交流和影響影象(從源傳輸到程式)的灰度和顏色外觀等資訊。以下操作提供了此能力:
• CIE Color Descriptors
DG_IMAGE / DAT_CIECOLOR / MSG_GET
• Grayscale Changes
DG_IMAGE / DAT_GRAYRESPONSE / MSG_RESET
DG_IMAGE / DAT_GRAYRESPONSE / MSG_SET
• Palette Color Data
DG_IMAGE / DAT_PALETTE8 / MSG_GET
DG_IMAGE / DAT_PALETTE8 / MSG_GETDEFAUL
DG_IMAGE / DAT_PALETTE8 / MSG_RESET
DG_IMAGE / DAT_PALETTE8 / MSG_SET
• RGB Response Curve Data
DG_IMAGE / DAT_RGBRESPONSE / MSG_RESET
DG_IMAGE / DAT_RGBRESPONSE / MSG_RESET
4.7.1 CIE Color Descriptors(顏色描述子)
CIE XYZ是一種能夠簡化對資料的數學操作的顏色儲存方式。(附錄A討論有關XYZ顏色空間和話題)。
若程式希望以此格式接收影象資料:
1. 確保源支援CIE XYZ格式。可通過對效能 ICAP_PIXELTYPE的DG_CONTROL / DAT_CAPABILITY / MSG_GET操作來檢查。若支援則返回的支援型別中將包含TWPT_CIEXYZ。
2. 通過對效能 ICAP_PIXELTYPE的DG_CONTROL / DAT_CAPABILITY / MSG_SET操作來指定應使用CIE XYZ格式來傳輸資料,操作使用一個值為TWPT_CIEXYZ的TW_ONEVALUE容器。
為確定源將顏色資料轉換為CIE XYZ格式時所使用的引數,請在影象傳輸後使用 DG_IMAGE / DAT_CIECOLOR / MSG_GET 操作。
4.7.2 灰度轉換
(假定程式已經通過將ICAP_PIXELTYPE設定為TWPT_GRAY來通知源提供灰度資料並且源已接受)
程式可要求源在將資料傳輸至程式前對灰度資料進行曲線變換,相關操作為 DG_IMAGE / DAT_GRAYRESPONSE / MSG_SET,變換曲線資訊由程式通過一個TW_GRAYRESPONSE結構指定。程式務必檢查此請求的返回值,若返回TWRC_FAILURE並且狀態碼為TWCC_BADPROTOCOL,則表示程式不支援灰度的響應轉換(與支援灰度資料無關)。
如果源允許程式設定灰度轉換,則應有重置轉換的途徑。因此,源應有一種直接傳輸而不轉換任何灰度資料的“恆等轉換”。程式可通過DG_IMAGE / DAT_GRAYRESPONSE / MSG_RESET請求來重置轉換。
4.7.3 調色盤顏色資料
(假定程式已經通知源將ICAP_PIXELTYPE置為TWPT_PALETTE且源已接受)
DAT_PALETTE8操作允許程式請求源對調色盤顏色資料的支援並啟動調色盤顏色的傳輸。此操作限定為8位資料,不論是灰度還是采色(8位或24位)。MSG_GET操作允許程式瞭解源在採集資料時使用的調色盤。程式應總是在立即在影象傳輸後而不是之前執行此操作,因為源可能在採集過程中優化調色盤。某些源可能允許程式通過MSG_SET來定義影象採集使用調色盤。務必檢查返回值以核實操作返回了TRRC_SUCCESS,這是確定你要求的調色盤是否會真實的用於隨後的調色盤傳輸的唯一方法。
4.7.4 RGB響應曲線資料
(假定程式已經通過將ICAP_PIXELTYPE設定為TWPT_RGB來通知源提供RGB資料並且源已接受)
程式可要求源在將資料傳輸至程式前對資料作曲線變換,相關操作為DG_IMAGE / DAT_RGBRESPONSE / MSG_SET。變換曲線資訊由程式通過一個TW_RGBRESPONSE結構指定。程式務必檢查此請求的返回值,若返回TWRC_FAILURE並且狀態碼為TWCC_BADPROTOCOL,則表示程式不支援RGB的響應轉換(與支援RGB資料無關)。
如果源允許程式設定RGB響應轉換,則應有重置轉換的途徑。源應有一種直接傳輸而不轉換任何RGB資料的“恆等轉換”。程式可通過DG_IMAGE / DAT_RGBRESPONSE / MSG_RESET請求來重置轉換。
4.8 對比度、亮度和陰影
一個難以明確的問題是什麼才是最合適的表達一個特定裝置的這些真實特性的方式。所有嘗試支援這些效能的人都清楚推薦的範圍並沒有真實的反映現實世界中的裝置。資料來源開發者已經嘗試了許多種不同的方法來獲取正確的響應,不是所有的能夠一致。
通過提供一個有意義的步進值或提供不同的容器,資料來源可向程式提供足夠的資訊以準確地為裝置的真實能力建模。對於一個希望展示關於這類效能的自定義使用者介面的程式來說,提供從-1000到1000的2000個等級並沒有太多作用,尤其是當裝置實際上僅支援少數幾個等級的時候。
由於資料來源開發者和應用程式開發者都閱讀相同的規範,因此可以想象為此類效能提供一個與指定範圍不匹配的值是不會被接受的。
以下建議是一個如何遵循此規範的一個例子,它們為指定的資料來源指定最準確的值。
例1: ICAP_BRIGHTNESS僅支援三個等級
第10章中宣告的規範要求如下:
“源應將值校正到範圍內,確保'0'是當前值的一個可用值。如果源的正負範圍相對於0不對稱,將範圍數量設為正負1000並從0值在兩個方向上進行等比分割。這將產生一個步進值不同的正範圍與負範圍。”
注:從這段關於正負範圍步進值不一致的描述延伸一下,應使用 TW_ENUMERATION容器。 TW_RANGE無法表達非線性的步進值。
假設真實裝置只支援普通、淺、深三種選項,則可以通過將真實值對映到請求值來適應此約束:
Normal = 0
Lighten = -1000
Darken = 1000
這些值可以放置在一個步進值為1000的TW_RANGE容器中,也可以放置在一個包含{-1000,0,1000}、當前值和預設值為0的TW_ENUMERATION容器中。
相關文章
- 【翻譯】Python PEP8編碼規範(中文版)Python
- 【譯】 Promises/A+ 規範Promise
- 【譯】Android API 規範AndroidAPI
- 【譯】Android NDK API 規範AndroidAPI
- 騰訊互動翻譯的坑爹翻譯
- [非專業翻譯] Mapster - 基於規則的對映
- Symbol 的作用[翻譯]Symbol
- [翻譯]JavaScript的成本JavaScript
- Arctime怎麼翻譯字幕?Arctime批次翻譯字幕的技巧
- 多翻譯引擎的程式
- 實用的Word文件翻譯方法分享,讓Word文件快速翻譯
- 人工翻譯的分類 安睿傑線上翻譯平臺
- 跨越專業翻譯的語言之牆:百度翻譯的技術攀登
- 自己的Java規範文件Java
- Java的13個規範Java
- stylelint 規範你的 cssCSS
- 規範你的commit msgMIT
- Java中的命名規範。Java
- 用ASP.NET Core 2.1 建立規範的 REST API -- 翻頁/排序/過濾等ASP.NETRESTAPI排序
- MySQL資料庫規範 (設計規範+開發規範+操作規範)MySql資料庫
- [Web翻譯]JavaScript中的編譯與填充WebJavaScript編譯
- 谷歌翻譯的UI設計谷歌UI
- [Flutter翻譯]Flutter中的剪下Flutter
- Mysql-基本的規則與規範MySql
- PendingIntent 是個啥?官方文件描述的很到位。我給翻譯翻譯Intent
- 翻譯英文軟體哪個好?中文翻譯英文最便捷的方法
- 告別生硬翻譯!AI谷歌翻譯:讓你的文字"說人話"AI谷歌
- 最佳 AI 翻譯工作流:全世界最信達雅的翻譯AI
- 翻譯
- 規範與偏離規範
- 前端規範之HTML 規範前端HTML
- 前端規範之javascript規範前端JavaScript
- 前端規範之CSS規範前端CSS
- 前端規範之nodeJs 規範前端NodeJS
- 簡化服裝ERP系統的規範流程和規範功用
- 從規則到神經網路:機器翻譯技術的演化之路神經網路
- 中文翻譯英語的軟體哪個好?如何完成中翻譯英
- 安卓的切圖規範安卓
- 我的專案命名規範