Kodak KDS TWAIN Driver
Extended Image Info (DAT_EXTIMAGEINFO)
17-January-2013
Contents
1. Overview...................................................................................................................... 2
2. CAP_EXTIMAGEINFO.............................................................................................. 3
3. MSG_GETSPECIAL................................................................................................... 4
4. Supported Information................................................................................................... 5
5. Sample Code................................................................................................................ 7
One of TWAIN’s strengths is its ability to decouple the negotiation phase (state 4/5) from the image capture phase (state 6/7). For this to work the application need image meta-data to describe each image so that it doesn’t have to rely on the negotiated values to understand what it is getting. Take for example the image width and height, if ICAP_AUTOMATICBORDERDETECTION is TRUE then these values will vary from image to image. Now in this case DAT_IMAGEINFO is sufficient to collect the needed information, but the TW_IMAGEINFO structure is fixed, and only contains a fraction of the possible meta-data values that can be associated with an image.
Extended Image Info (DAT_EXTIMAGEINFO) was introduced in 1.7 of the TWAIN specification as a way to collect a tagged list of meta-data for every captured image. The Kodak Document Scanners significantly extend this list with custom data. The purpose of this document is to detail what information is present and how to get it.
The term “All of the Kodak Document Scanners” refers to the following models or families:
3000/4000
5000/7000/9000
i30/i40
i200
i600
i700
i800
i900
i1100
i1200
i1300
i1400
i1800
i2000
i2900
i3000
i4000
i5000
PS50/PS80
All of the Kodak Document Scanners support DAT_EXTIMAGEINFO, however a well designed TWAIN application should confirm this by testing that the capability CAP_EXTIMAGEINFO is TRUE.
The TWAIN specification (currently at 2.1) indicates that DG_IMAGE / DAT_EXTIMAGEINFO / MSG_GET is only supported in state 7, after the image has been fully transferred (that is after the receipt of TWRC_XFERDONE). All of the Kodak Document Scanners are able to report everything there is to know about an image in state 6, prior to transferring the image (this applies to DAT_IMAGEINFO, as well).
In order to support this behavior without violating the TWAIN specification we have added a new custom message MSG_GETSPECIAL. DG_IMAGE / DAT_EXTIMAGEINFO / MSG_GETSPECIAL can be used in state 6 or 7, and will report identical information for an image in either state.
The following Extended Image Information values are supported by the TWAIN driver. Those fields followed by a TWAIN name (such as ICAP_COMPRESSION) indicate that the values for that field come from that capability (ex: TWCP_GROUP4).
Not all fields are supported for all scanners. The following codes can be used to figure out which scanner family/models support a given item.
g - 5000/7000/9000 series support
v - 3000/4000 series support
p - i800 series support
a - i200 series support
m - i30/i40/i55/i65 series support
f - i1100 series support
o - i600/i700/i1800 series support
h - i1200/i1300/i1400 series support
d - i2000/i2900/i3000/i4000/i5000/PS50/PS80 series support
r - i900 series support
* - Reference Gemini Integrator’s Guide for further information
If a field is unsupported, TWRC_INFONOTSUPPORTED (8) will be returned as the condition code.
TWAIN Standard |
Type |
Description |
Supported Models |
TWEI_BOOKNAME |
TWTY_STR255 |
- Image Address fixed field |
g,p,i1800 |
TWEI_CAMERA |
TWTY_STR255 |
- DAT_FILESYSTEM camera |
all |
TWEI_CHAPTERNUMBER |
TWTY_UINT32 |
- Image Address level 3 |
p,i1800 |
TWEI_DESKEWSTATUS |
TWTY_UINT32 |
- Disabled (3), Pass(0), Fail(2) |
all |
TWEI_DOCUMENTNUMBER |
TWTY_UINT32 |
- Document count |
all |
TWEI_FILESYSTEMSOURCE |
TW_STR255 |
- The camera that captured the image data |
d,r |
TWEI_FRAME |
TWTY_FRAME |
- Similar to ICAP_FRAME |
all |
TWEI_FRAMENUMBER |
TWTY_UINT32 |
- Always 1 (only 1 cropping region per image) |
all |
TWEI_IMAGEMERGED |
TW_BOOL |
- Indicates that the current image is merged between the front and rear images |
d,r |
TWEI_PAGENUMBER |
TWTY_UINT32 |
- Page count |
all |
TWEI_PAGESIDE |
TWTY_UINT16 |
- Page side TWCS_TOP/TWCS_BOTTOM |
d,r |
TWEI_PIXELFLAVOR |
TWTY_UINT16 |
- Similar to ICAP_PIXELFLAVOR |
all |
TWEI_SKEWORIGINALANGLE |
TWTY_UINT32 |
- The amount of skew in the original image |
all |
|
|
|
|
Custom Data |
|
|
|
TWEI_HDR_AUTOCOLORAMOUNT |
TWTY_UINT32 |
- Auto color amount |
all (except g,v,p,a,m,f) |
TWEI_HDR_AUTOCOLORDETECTED |
TWTY_UINT32 |
- Auto color detected |
all (except g,v,p,a,m,f) |
TWEI_HDR_AUTOCOLORTHRESHOLD |
TWTY_UINT32 |
- Auto color threshold |
all (except g,v,p,a,m,f) |
TWEI_HDR_BARCODE |
TWTY_STR255 |
- KDIS formatted barcodes* |
g |
TWEI_HDR_BINARIZATIONQUALITY |
TWTY_UINT32 |
- Conveys the quality level of the binarized image |
d,r |
TWEI_HDR_BITONALCONTRAST |
TWTY_UINT32 |
- Bitonal contrast (0-FFFh) |
o |
TWEI_HDR_BITONALCONTRASTPERCENTAGE |
TWTY_UINT32 |
- Bitonal contrast percentage (0-100d) |
o |
TWEI_HDR_BITONALTHRESHOLD |
TWTY_UINT32 |
- Bitonal threshold (0-255d) |
o |
TWEI_HDR_BITORDER |
TWTY_UINT32 |
- Similar to ICAP_BITORDER (MSB->LSB) |
all |
TWEI_HDR_BOOKNAME_A |
TWTY_STR255 |
- Fixed field A (unsupported unless field A is fixed) |
g,p,i1800 |
TWEI_HDR_BOOKNAME_B |
TWTY_STR255 |
- Fixed field B (unsupported unless field B is fixed) |
p,i1800 |
TWEI_HDR_BOOKNAME_C |
TWTY_STR255 |
- Fixed field C (unsupported unless field C is fixed) |
p,i1800 |
TWEI_HDR_BOOKNAME_D |
TWTY_STR255 |
- Fixed field D (unsupported unless field D is fixed) |
p,i1800 |
TWEI_HDR_COMPRESSION |
TWTY_UINT32 |
- Similar to ICAP_COMPRESSION |
all |
TWEI_HDR_DATE |
TWTY_UINT32 |
- Date (YYMMDD) |
all |
TWEI_HDR_DESKEW |
TWTY_UINT32 |
- Image Manager deskew flag: Yes(1), No(0), Disabled(-1). If -1 check TWEI_DESKEWSTATUS. |
all |
TWEI_HDR_DESKEWANGLE |
TWTY_UINT32 |
- Angle in 1/10000 degrees - Example: 4.7 degress is represented as 47000 |
h,d,r |
TWEI_HDR_DESKEWANGLEACTUAL |
TWTY_INT32 |
- Angle (-450 to 450 degrees, -450,450 = Fail, signed 10ths of a degree) |
o |
TWEI_HDR_DESKEWCONFIDENCEFACTOR |
TWTY_UINT32 |
- Deskew confidence (1-99d, 1%=Fail, 99%=Success) |
o |
TWEI_HDR_DIFFERENCEHISTOGRAM |
TWTY_UINT8 |
- Difference histogram (256 bytes) |
o |
TWEI_HDR_DITHER |
TWTY_STR255 |
- Similar to ICAP_HALFTONES |
g,v,p,a,m,f,o,h |
TWEI_HDR_DOCUMENTCOUNT |
TWTY_UINT32 |
- Doc counter (CAP_PRINTERINDEX for gp, for va only if printer installed)) |
all |
TWEI_HDR_DROPOUTSTATUS |
TWTY_INT32 |
- ECDO Algorithm Status (0 = Success, >0 Algorithm Specific Error) |
h,d |
TWEI_HDR_DUALSTACKINGSTACK |
TWTY_UINT32 |
- When dual stacking is enabled, contains output tray a document was dropped into (1,2) |
d-i5000 only |
TWEI_HDR_FEATUREPATCH |
TWTY_UINT32 |
- Feature patch value (1,4,6) |
p,a,o,i1400,i3000,i4000,i5000 |
TWEI_HDR_FOLDEDCORNERPERCENTAGE |
TWTY_UINT32 |
- Folded corner percentage (0-100d) 0->Not folded, 100->Folded along the diagonal |
o |
TWEI_HDR_GAMMATABLE |
TWTY_UINT8 |
- Gamma table (256 bytes) |
o |
TWEI_HDR_IMAGEADDRESSDEFS |
TWTY_STR255 |
- IA definitions (ex: FFF.333.222.111) (where each field is and how they are formatted) |
p,i1800 |
TWEI_HDR_IMAGEADDRESSSTRING |
TWTY_STR255 |
- Formatted image address string |
p,i1800 |
TWEI_HDR_IMAGENUMBER |
TWTY_UINT32 |
- Count of images in this session (since starting the application) |
all |
TWEI_HDR_IMAGESTATUS |
TWTY_UINT32 |
- Image status |
none |
TWEI_HDR_LATCHEDFLAG |
TWTY_UINT32 |
- Latch switch flag* |
g |
TWEI_HDR_LENGTH |
TWTY_UINT32 |
- Size of image data from scanner (bytes) |
all |
TWEI_HDR_LEVEL |
TWTY_UINT32 |
- Image Address Level (0,1,2,3) |
g,p,i1800 |
TWEI_HDR_LINELENGTH |
TWTY_UINT32 |
- Image width (pixels) |
all |
TWEI_HDR_LONGPAPERLASTSEGMENT |
TWTY_UINT32 |
- Image last segment |
a |
TWEI_HDR_LONGPAPERSEGMENTNUMBER |
TWTY_UINT32 |
- Image segment number |
a |
TWEI_HDR_MODE |
TWTY_UINT32 |
- Mode* |
g |
TWEI_HDR_MULTIFEED |
TWTY_UINT32 |
- Multifeed detected: Yes(1), No(0)) |
all (except g,v,p) |
TWEI_HDR_MOMENTARYFLAG |
TWTY_UINT32 |
- Momentary flag* |
g |
TWEI_HDR_PAGEIMAGENUMBER |
TWTY_UINT32 |
- Image count on sheet (1 – 4) |
all |
TWEI_HDR_PAGELENGTH |
TWTY_UINT32 |
- Image height (pixels) |
all |
TWEI_HDR_PAGENUMBER |
TWTY_UINT32 |
- Count of sheets in this session |
all |
TWEI_HDR_PAGESIDE |
TWTY_UINT32 |
- Page side: Front(0), Rear(1) |
all |
TWEI_HDR_PATCHDETECTED |
TWTY_UINT32 |
- Patch code detected on this sheet |
p,a,o,i1400,i3000,i4000,i5000 |
TWEI_HDR_PCARD_HEADER |
TWTY_STR255 |
- Personality-Card Header |
none |
TWEI_HDR_PCARD_FOOTER |
TWTY_STR255 |
- Personality-Card Footer |
none |
TWEI_HDR_POLARITY |
TWTY_UINT32 |
- SCSI RIF value: 0 is White(0), 1 is White(1) |
gvpam |
TWEI_HDR_PRINTERINDEX |
TWTY_UINT32 |
- String Doc counter (CAP_PRINTERINDEX) |
all |
TWEI_HDR_PRINTERSTRING |
TWTY_STR255 |
- String printed on document |
v,p,a,d,i1400 |
TWEI_HDR_PROCESSINGSTATUS |
TWTY_UINT32 |
- Processing Status (0 = Disabled, 1 = Success, 2 = Skipped, 4 = Fail) |
none |
TWEI_HDR_RAWIMAGEHEADER |
TWTY_STR255 |
- Raw image header from scanner |
p,o |
TWEI_HDR_REGENERATION |
TWTY_UINT32 |
- Retry count |
none |
TWEI_HDR_RESOLUTION |
TWTY_UINT32 |
- ICAP_RESOLUTION |
all |
TWEI_HDR_ROLL |
TWTY_UINT32 |
- Roll number* |
g-990 only |
TWEI_HDR_SKEW |
TWTY_UINT32 |
- Skew flag detect: Yes(1), No(0)* |
g-5000/7000 only |
TWEI_HDR_SUMHISTOGRAM |
TWTY_UINT8 |
- Sum histogram (256 bytes) |
none |
TWEI_HDR_TIME |
TWTY_UINT32 |
- Time (HHMMSS) |
all |
TWEI_HDR_TOKEN_COUNT |
TWTY_UINT32 |
- Token flag |
none |
TWEI_HDR_XOFFSET |
TWTY_UINT32 |
- X-offset of image (pixels) |
all |
TWEI_HDR_XML |
TWTY_HANDLE |
- Everything in XML format (<reportimage> data) |
d,r |
TWEI_HDR_YOFFSET |
TWTY_UINT32 |
- Y-offset of image (pixels) |
all |
This section shows all the fields being collected in a single DAT_EXTIMAGEINFO call. Hopefully this is enough information to get the information needed by your application. We strongly recommend against getting fields you don’t need, especially ones that require memory allocations, as this can impact the performance of the system (especially on the faster scanners).
// This function creates a huge string that has ExtImageData in
// it along with some text headers. The main purpose of the
// function is to show how to collect different kinds of data.
// Real applications should whittle this function down to exactly
// what they need.
#define cvtf(x) (((float)(x.Whole))+(((float)x.Frac)/65536.0))
#define FI(x) FindIndex(eii,x)
int FindIndex
(
TW_EXTIMAGEINFO *eii,
int InfoID
)
{
for (int ii=0; eii->Info[ii].InfoID; ii++)
{
if (eii->Info[ii].InfoID == InfoID) return(ii);
}
return(0);
}
void ShowExtImageInfo
(
void
)
{
int ii;
int sts;
int len;
int tmpint;
char *str;
TW_EXTIMAGEINFO *eii;
TW_FRAME *f;
char hdr_titles[8192];
char hdr_data[8192];
// Allocate the string...
str = (char*)GlobalAlloc(GPTR,65536);
if (!str)
{
// GlobalAlloc failed...
return;
}
// Allocate the table...
eii = (TW_EXTIMAGEINFO*)GlobalAlloc
(
GPTR,
sizeof(TW_EXTIMAGEINFO)+(sizeof(TW_INFO)*64)
);
if (!eii)
{
// GlobalAlloc failed...
return;
}
// Build the table...
ii = 0;
eii->Info[ii++].InfoID = TWEI_BOOKNAME;
eii->Info[ii++].InfoID = TWEI_CAMERA;
eii->Info[ii++].InfoID = TWEI_CHAPTERNUMBER;
eii->Info[ii++].InfoID = TWEI_DESKEWSTATUS;
eii->Info[ii++].InfoID = TWEI_DOCUMENTNUMBER;
eii->Info[ii++].InfoID = TWEI_FRAME;
eii->Info[ii++].InfoID = TWEI_FRAMENUMBER;
eii->Info[ii++].InfoID = TWEI_PAGENUMBER;
eii->Info[ii++].InfoID = TWEI_PIXELFLAVOR;
eii->Info[ii++].InfoID = TWEI_SKEWORIGINALANGLE;
eii->Info[ii++].InfoID = TWEI_HDR_BARCODE;
eii->Info[ii++].InfoID = TWEI_HDR_BITORDER;
eii->Info[ii++].InfoID = TWEI_HDR_COMPRESSION;
eii->Info[ii++].InfoID = TWEI_HDR_DATE;
eii->Info[ii++].InfoID = TWEI_HDR_DESKEW;
eii->Info[ii++].InfoID = TWEI_HDR_DESKEWANGLE;
eii->Info[ii++].InfoID = TWEI_HDR_DESKEWANGLEACTUAL;
eii->Info[ii++].InfoID = TWEI_HDR_DOCUMENTCOUNT;
eii->Info[ii++].InfoID = TWEI_HDR_DUALSTACKINGSTACK;
eii->Info[ii++].InfoID = TWEI_HDR_FEATUREPATCH;
eii->Info[ii++].InfoID = TWEI_HDR_IMAGEADDRESSSTRING;
eii->Info[ii++].InfoID = TWEI_HDR_IMAGEADDRESSDEFS;
eii->Info[ii++].InfoID = TWEI_HDR_IMAGENUMBER;
eii->Info[ii++].InfoID = TWEI_HDR_LATCHEDFLAG;
eii->Info[ii++].InfoID = TWEI_HDR_LENGTH;
eii->Info[ii++].InfoID = TWEI_HDR_LEVEL;
eii->Info[ii++].InfoID = TWEI_HDR_LINELENGTH;
eii->Info[ii++].InfoID = TWEI_HDR_LONGPAPERLASTSEGMENT;
eii->Info[ii++].InfoID = TWEI_HDR_LONGPAPERSEGMENTNUMBER;
eii->Info[ii++].InfoID = TWEI_HDR_MODE;
eii->Info[ii++].InfoID = TWEI_HDR_MOMENTARYFLAG;
eii->Info[ii++].InfoID = TWEI_HDR_PAGEIMAGENUMBER;
eii->Info[ii++].InfoID = TWEI_HDR_PAGELENGTH;
eii->Info[ii++].InfoID = TWEI_HDR_PAGENUMBER;
eii->Info[ii++].InfoID = TWEI_HDR_PAGESIDE;
eii->Info[ii++].InfoID = TWEI_HDR_POLARITY;
eii->Info[ii++].InfoID = TWEI_HDR_PRINTERSTRING;
eii->Info[ii++].InfoID = TWEI_HDR_RESOLUTION;
eii->Info[ii++].InfoID = TWEI_HDR_ROLL;
eii->Info[ii++].InfoID = TWEI_HDR_SKEW;
eii->Info[ii++].InfoID = TWEI_HDR_TIME;
eii->Info[ii++].InfoID = TWEI_HDR_XOFFSET;
eii->Info[ii++].InfoID = TWEI_HDR_YOFFSET;
eii->Info[ii++].InfoID = TWEI_HDR_XML;
eii->NumInfos = ii;
// Issue the command to the driver...
sts = (*pDSM_Entry)
(
&AppId,
&SourceId,
DG_IMAGE,
DAT_EXTIMAGEINFO,
MSG_GETSPECIAL,
(TW_MEMREF)eii
);
if (sts != TWRC_SUCCESS)
{
// DAT_EXTIMAGEINFO failed…
return;
}
// Grab the barcode length (if there is one)…
if (eii->Info[FI(TWEI_HDR_BARCODE)].CondCode == TWRC_SUCCESS)
{
len = strlen((char*)eii->Info[FI(TWEI_HDR_BARCODE)].Item);
}
else
{
len = 0;
}
// Format the headers...
str[0] = 0;
sprintf(&str[strlen(str)],"Standard Extensions\n");
sprintf(&str[strlen(str)],"TWEI_CAMERA:\n");
sprintf(&str[strlen(str)],"TWEI_FRAME:\n");
sprintf(&str[strlen(str)],"TWEI_PIXELFLAVOR:\n");
sprintf(&str[strlen(str)],"TWEI_DESKEWSTATUS:\n");
sprintf(&str[strlen(str)],"TWEI_SKEWORIGINALANGLE:\n");
sprintf(&str[strlen(str)],"\nImage Address\n");
sprintf(&str[strlen(str)],"TWEI_BOOKNAME:\n");
sprintf(&str[strlen(str)],"TWEI_CHAPTERNUMBER:\n");
sprintf(&str[strlen(str)],"TWEI_DOCUMENTNUMBER:\n");
sprintf(&str[strlen(str)],"TWEI_PAGENUMBER:\n");
sprintf(&str[strlen(str)],"TWEI_FRAMENUMBER:\n");
sprintf(&str[strlen(str)],"\nCustom Extensions\n");
if (len < 40) {
sprintf(&str[strlen(str)],"TWEI_HDR_BARCODE:\n");
} else if (len < 80) {
sprintf(&str[strlen(str)],"TWEI_HDR_BARCODE:\n\n");
} else {
sprintf(&str[strlen(str)],"TWEI_HDR_BARCODE:\n\n\n");
}
sprintf(&str[strlen(str)],"TWEI_HDR_BITORDER:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_COMPRESSION:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_DATE:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_DESKEW:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_DESKEWANGLE:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_DESKEWANGLEACTUAL:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_DOCUMENTCOUNT:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_DUALSTACKINGSTACK:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_FEATUREPATCH:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_IMAGEADDRESDEFS:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_IMAGEADDRESSTRING:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_IMAGENUMBER:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_LATCHEDFLAG:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_LENGTH:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_LEVEL:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_LINELENGTH:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_LONGPAPERLASTSEGMENT:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_LONGPAPERSEGMENTNUMBER:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_MODE:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_MOMENTARYFLAG:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_PAGEIMAGENUMBER:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_PAGELENGTH:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_PAGENUMBER:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_PAGESIDE:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_POLARITY:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_PRINTERSTRING:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_RESOLUTION:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_ROLL:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_SKEW:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_TIME:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_XOFFSET:\n");
sprintf(&str[strlen(str)],"TWEI_HDR_YOFFSET:\n");
strcpy(hdr_titles,str);
// Blank lines...
str[0] = 0;
sprintf(&str[strlen(str)],"\n");
// Camera...
if (eii->Info[ii=FI(TWEI_CAMERA)].CondCode != TWRC_SUCCESS)
{
sprintf(&str[strlen(str)],"*** unsupported ***\n");
}
else
{
sprintf(&str[strlen(str)],"<%s>\n",eii->Info[ii].Item);
GlobalFree((void*)eii->Info[ii].Item);
}
// Frame...
if (eii->Info[ii=FI(TWEI_FRAME)].CondCode != TWRC_SUCCESS)
{
sprintf(&str[strlen(str)],"*** unsupported ***\n");
}
else
{
f = (TW_FRAME*)eii->Info[ii].Item;
sprintf
(
&str[strlen(str)],
"L%.2f R%.2f T%.2f B%.2f\n",
cvtf(f->Left),
cvtf(f->Top),
cvtf(f->Right),
cvtf(f->Bottom)
);
GlobalFree((void*)eii->Info[ii].Item);
}
// PixelFlavor...
if (eii->Info[ii=FI(TWEI_PIXELFLAVOR)].CondCode != TWRC_SUCCESS)
{
sprintf(&str[strlen(str)],"*** unsupported ***\n");
}
else
{
switch (eii->Info[ii].Item)
{
default:
sprintf(&str[strlen(str)],"*** ERROR ***\n");
break;
case TWPF_CHOCOLATE:
sprintf(&str[strlen(str)],"TWPF_CHOCOLATE\n");
break;
case TWPF_VANILLA:
sprintf(&str[strlen(str)],"TWPF_VANILLA\n");
break;
}
}
// DeskewStatus...
if (eii->Info[ii=FI(TWEI_DESKEWSTATUS)].CondCode != TWRC_SUCCESS)
{
sprintf(&str[strlen(str)],"*** unsupported ***\n");
}
else
{
switch (eii->Info[ii].Item)
{
default:
sprintf(&str[strlen(str)],"*** ERROR ***\n");
break;
case TWDSK_SUCCESS:
sprintf(&str[strlen(str)],"TWDSK_SUCCESS\n");
break;
case TWDSK_REPORTONLY:
sprintf(&str[strlen(str)],"TWDSK_REPORTONLY\n");
break;
case TWDSK_FAIL:
sprintf(&str[strlen(str)],"TWDSK_FAIL\n");
break;
case TWDSK_DISABLED:
sprintf(&str[strlen(str)],"TWDSK_DISABLED\n");
break;
}
}
// SkewOriginalAngle...
if (eii->Info[ii=FI(TWEI_SKEWORIGINALANGLE)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// Blank lines...
sprintf(&str[strlen(str)],"\n\n");
// BookName...
if (eii->Info[ii=FI(TWEI_BOOKNAME)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"<%s>\n",eii->Info[ii].Item);
GlobalFree((void*)eii->Info[ii].Item);
}
// ChapterNumber...
if (eii->Info[ii=FI(TWEI_CHAPTERNUMBER)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// DocumentNumber...
if (eii->Info[ii=FI(TWEI_DOCUMENTNUMBER)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// PageNumber...
if (eii->Info[ii=FI(TWEI_PAGENUMBER)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// FrameNumber...
if (eii->Info[ii=FI(TWEI_FRAMENUMBER)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// Blank lines...
sprintf(&str[strlen(str)],"\n\n");
// Barcode...
if (eii->Info[ii=FI(TWEI_HDR_BARCODE)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
if (len <= 0) {
sprintf(&str[strlen(str)],"<>\n");
} else if (len < 40) {
sprintf(&str[strlen(str)],"<%s>\n",eii->Info[ii].Item);
str[strlen(str)-3] = '$';
} else if (len < 80) {
char xxx[512];
strcpy(xxx,(char*)eii->Info[ii].Item);
xxx[40] = 0;
sprintf(&str[strlen(str)],"<%s\n",xxx);
strcpy(xxx,&((char*)eii->Info[ii].Item)[40]);
sprintf(&str[strlen(str)],"%s>\n",xxx);
str[strlen(str)-3] = '$';
} else {
char xxx[512];
strcpy(xxx,(char*)eii->Info[ii].Item);
xxx[40] = 0;
sprintf(&str[strlen(str)],"<%s\n",xxx);
strcpy(xxx,&((char*)eii->Info[ii].Item)[40]);
xxx[40] = 0;
sprintf(&str[strlen(str)],"%s\n",xxx);
strcpy(xxx,&((char*)eii->Info[ii].Item)[80]);
sprintf(&str[strlen(str)],"%s>\n",xxx);
str[strlen(str)-3] = '$';
}
GlobalFree((void*)eii->Info[ii].Item);
}
// BitOrder...
if (eii->Info[ii=FI(TWEI_HDR_BITORDER)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// Compression...
if (eii->Info[ii=FI(TWEI_HDR_COMPRESSION)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// Date...
if (eii->Info[ii=FI(TWEI_HDR_DATE)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
tmpint = eii->Info[ii].Item;
sprintf
(
&str[strlen(str)],
"%02d/%02d/%02d\n",
tmpint/10000,
(tmpint/100)-((tmpint/10000)*100),
tmpint-((tmpint/100)*100)
);
}
// Deskew...
if (eii->Info[ii=FI(TWEI_HDR_DESKEW)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// DeskewAngle...
if (eii->Info[ii=FI(TWEI_HDR_DESKEWANGLE)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// DeskewAngleActual...
if (eii->Info[ii=FI(TWEI_HDR_DESKEWANGLEACTUAL)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d.%d\n",((TW_INT32)eii->Info[ii].Item)/10,abs(((TW_INT32)eii->Info[ii].Item)) % 10);
}
// DocumentCount...
if (eii->Info[ii=FI(TWEI_HDR_DOCUMENTCOUNT)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// Dropout Status...
if (eii->Info[ii=FI(TWEI_HDR_DROPOUTSTATUS)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// Dualstackingstack...
if (eii->Info[ii=FI(TWEI_HDR_DUALSTACKINGSTACK)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// FeaturePatch...
if (eii->Info[ii=FI(TWEI_HDR_FEATUREPATCH)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// ImageAddressDefs...
if (eii->Info[ii=FI(TWEI_HDR_IMAGEADDRESSDEFS)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"<%s>\n",eii->Info[ii].Item);
GlobalFree((void*)eii->Info[ii].Item);
}
// ImageAddressString...
if (eii->Info[ii=FI(TWEI_HDR_IMAGEADDRESSSTRING)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"<%s>\n",eii->Info[ii].Item);
GlobalFree((void*)eii->Info[ii].Item);
}
// ImageNumber...
if (eii->Info[ii=FI(TWEI_HDR_IMAGENUMBER)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// LatchedFlag...
if (eii->Info[ii=FI(TWEI_HDR_LATCHEDFLAG)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// Length...
if (eii->Info[ii=FI(TWEI_HDR_LENGTH)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// Level...
if (eii->Info[ii=FI(TWEI_HDR_LEVEL)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// LineLength...
if (eii->Info[ii=FI(TWEI_HDR_LINELENGTH)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// LongPaperLastSegment...
if (eii->Info[ii=FI(TWEI_HDR_LONGPAPERLASTSEGMENT)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// LongPaperSegmentNumber...
if (eii->Info[ii=FI(TWEI_HDR_LONGPAPERSEGMENTNUMBER].CondCode != TWRC_SUCCESS){
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// Mode...
if (eii->Info[ii=FI(TWEI_HDR_MODE)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// MomentaryFlag...
if (eii->Info[ii=FI(TWEI_HDR_MOMENTARYFLAG)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// PageImageNumber...
if (eii->Info[ii=FI(TWEI_HDR_PAGEIMAGENUMBER)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// PageLength...
if (eii->Info[ii=FI(TWEI_HDR_PAGELENGTH)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// PageNumber...
if (eii->Info[ii=FI(TWEI_HDR_PAGENUMBER)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// PageSide...
if (eii->Info[ii=FI(TWEI_HDR_PAGESIDE)].CondCode != TWRC_SUCCESS) {
sprintf(&str[strlen(str)],"*** unsupported ***\n");
} else {
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// Polarity...
if (eii->Info[ii=FI(TWEI_HDR_POLARITY)].CondCode != TWRC_SUCCESS)
{
sprintf(&str[strlen(str)],"*** unsupported ***\n");
}
else
{
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// PrinterString...
if (eii->Info[ii=FI(TWEI_HDR_PRINTERSTRING)].CondCode != TWRC_SUCCESS)
{
sprintf(&str[strlen(str)],"*** unsupported ***\n");
}
else
{
sprintf(&str[strlen(str)],"<%s>\n",eii->Info[ii].Item);
GlobalFree((void*)eii->Info[ii].Item);
}
// Resolution...
if (eii->Info[ii=FI(TWEI_HDR_RESOLUTION)].CondCode != TWRC_SUCCESS)
{
sprintf(&str[strlen(str)],"*** unsupported ***\n");
}
else
{
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// Roll...
if (eii->Info[ii=FI(TWEI_HDR_ROLL)].CondCode != TWRC_SUCCESS)
{
sprintf(&str[strlen(str)],"*** unsupported ***\n");
}
else
{
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// Skew...
if (eii->Info[ii=FI(TWEI_HDR_SKEW)].CondCode != TWRC_SUCCESS)
{
sprintf(&str[strlen(str)],"*** unsupported ***\n");
}
else
{
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// Time...
if (eii->Info[ii=FI(TWEI_HDR_TIME)].CondCode != TWRC_SUCCESS)
{
sprintf(&str[strlen(str)],"*** unsupported ***\n");
}
else
{
tmpint = eii->Info[ii].Item;
sprintf
(
&str[strlen(str)],
"%02d:%02d:%02d\n",
tmpint/10000,
(tmpint/100)-((tmpint/10000)*100),
tmpint-((tmpint/100)*100)
);
}
// Xoffset...
if (eii->Info[ii=FI(TWEI_HDR_XOFFSET)].CondCode != TWRC_SUCCESS)
{
sprintf(&str[strlen(str)],"*** unsupported ***\n");
}
else
{
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// Yoffset...
if (eii->Info[ii=FI(TWEI_HDR_YOFFSET)].CondCode != TWRC_SUCCESS)
{
sprintf(&str[strlen(str)],"*** unsupported ***\n");
}
else
{
sprintf(&str[strlen(str)],"%d\n",eii->Info[ii].Item);
}
// XML...
if
(eii->Info[ii=FI(TWEI_HDR_XML)].CondCode != TWRC_SUCCESS)
{
sprintf
(&str[strlen(str)],"*** unsupported ***\n");
}
else
{
sprintf
(&str[strlen(str)],"<%s>\n",eii->Info[ii].Item);
GlobalFree((void*)eii->Info[ii].Item);
}
strcpy(hdr_data,str);
// At this point hdr_titles is an array of the TWEI* names, and hdr_data is the array of the data for the TWEI*’s
// Final cleanup
GlobalFree(eii);
}