TWAIN规范的第四章
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
TWAIN Specification Chapter 4 “Advanced Application Implementation”译——应用程序端的高级实现
本文是对TWAIN规范的第四章《应用程序端的高级实现》的翻译。
因工作需要了解TWAIN,所以顺便译了一下。
这是私人工作,您可以参考,但本人不保证不存在翻译的差错或不合宜。
如果您发现有不妥的地方,敬请告之我(yedaoq@)。
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以及下列容器之一:
• TWO N_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操作。
注: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操作通知传输结束并获取挂起的传输数量。