ImageGear for C and C++ on Windows v19.10 - Updated
Functions for Working with ISIS Tags
User Guide > How to Work with... > Common Operations > Scanning > ISIS Scanning > Work with Tags > Functions for Working with ISIS Tags

Following is a list of tag functions and their use. The "..." in many of the function names is replaced by Ascii, Long, or Rational, according to the type of tag to which the function is being directed.

Tag Function

Purpose

IG_ISIS_tag_get...

Get the current value of a tag.

IG_ISIS_tag_get...default

Get the default value of a tag.

IG_ISIS_tag_get_length()

Get the number of elements in the current value of a numeric tag, or the number of characters in the current value of an ASCII tag including the NULL terminating character.

IG_ISIS_tag_get_length_default()

Get the number of elements in the default value of a numeric tag, or the number of characters in the default value of an ASCII tag including the NULL terminating character.

IG_ISIS_tag_get_type()

Get the type of a tag.

IG_ISIS_tag_save_file()

Save current scanner tag values to a file.

IG_ISIS_tag_restore_file()

Restore saved scanner tag values from a file.

IG_ISIS_tag_save_value()

Save current tag value(s) to a memory buffer.

IG_ISIS_tag_restore_value()

Restore tag value(s) saved in a memory buffer.

IG_ISIS_tag_set...

Set the value of a tag.

IG_ISIS_tag_set...default

Set a tag to its default value.

This function only sets a tag to its predefined default value. Default values are determined by the driver. Default values for tags cannot be set by an application developer or user.

IG_ISIS_tag_set_length()

Set the number of elements in a multi-element tag.

Tag Function

Purpose

PixTagCreate

Create a tag in a driver.

PixTagSetAffect

Establish a tag setting relationship in a driver.

PixTagSetAffectCount

Allocate space for a PixTagSetAffect array.

PixTagGet...

Get the current value of a tag.

PixTagGet...Default

Get the default value of a tag.

PixTagGetLength

Get the number of elements in the current value of a numeric tag, or the number of characters in the current value of an ASCII tag.

PixTagGetLengthDefault

Get the number of elements in the default value of a numeric tag, or the number of characters in the default value of an ASCII tag.

PixTagGetType

Get the type of a tag.

PixTagSaveFile

Save current tag values in a file.

PixTagRestoreFile

Restore saved tag values from a file.

PixTagSaveValue

Save current tag value(s) in a memory buffer.

PixTagRestoreValue

Restore tag value(s) saved in a memory buffer.

PixTagSet...

Set the value of a tag.

PixTagSetDefault

Set a tag to its default value.

This function only sets a tag to its predefined default value. Default values are determined in the driver by the first value to which a tag is set. Default values for tags cannot be set by an application developer or user. 

PixTagSetLength

Set the number of elements in a multi-element tag.

ISIS Tag Types

Before setting a tag, it is important to know the type of the tag. There are five distinct type of tags and three sets of functions for getting and setting their values, as shown in the following table. Byte, short, and long tag types are all manipulated by using IG_ISIS_tag...long functions.

Tag Type

Typical Tag Functions

IG_ISIS_TAG_TYPE_BYTE
IG_ISIS_TAG_TYPE_SHORT
IG_ISIS_TAG_TYPE_LONG

IG_ISIS_tag_get_long(hDriver, wTag, wIndex, &dwValue);
IG_ISIS_tag_set_long(hDriver, wTag, wIndex, &dwValue);
IG_ISIS_tag_get_long_default(hDriver, wTag, wIndex, &dwValue);

IG_ISIS_TAG_TYPE_RATIONAL

IG_ISIS_tag_get_rational(hDriver, wTag, wIndex, &ratValue);
IG_ISIS_tag_set_rational(hDriver, wTag, wIndex, &ratValue);
IG_ISIS_tag_get_rational_default(hDriver, wTag, wIndex, &ratValue);

IG_ISIS_TAG_TYPE_STRING

IG_ISIS_tag_get_ascii(hDriver, wTag, wLength, lpcBuffer);
IG_ISIS_tag_set_ascii(hDriver, wTag, lpcBuffer);
IG_ISIS_tag_get_ascii_default(hDriver, wTag, wLength, lpcBuffer);

There are very few IG_ISIS_TAG_TYPE_BYTE type tags in drivers. Most application developers can remain completely unaware of whether they are working with a byte, short, or long type tag.

Some tags store their values in arrays. The wIndex parameter of each of the tag functions then specifies which element of the array you want to access. This is important for tags that control dither patterns, gamma tables, and other data that is stored in a table. Rather than have, for example, 64 different tags (one for each value in a dither pattern), drivers will use an array of 64 elements for a single tag. You can iterate on the value of wIndex from 0-63 to get or set all of the elements of the tag.

An ASCII tag is a special case. You cannot have multiple strings within an ASCII tag. The ASCII tag functions, therefore, do not have a wIndex parameter because the toolkit assumes that you always will want to get or set the entire string. (A string is stored as an array of bytes, and an index would simply take you to a particular character in the string.

Tag Initialization

When a driver is initialized, its tags are set to default values as determined by the person who wrote the driver. Once a driver has been initialized, tag values can be changed repeatedly by an application. To return a tag to its default value, use the IG_ISIS_tag_set_default function. The application can also save current tag values in a file, and then load them later (perhaps right after initialization). This gives the application the capability to implement settings that appear to the user to be defaults.

User-Settable Tag Defaults

Despite what was just explained about tags not having default values that can be set by the user, each scanner driver has from zero to four special tags that actually can be set by the user to default values during scanner selection. Most scanners that employ user-settable defaults use only one or two of the four available tags. The tags are named IG_ISIS_TAG_CONFIG_1 through IG_ISIS_TAG_CONFIG_4 and are assigned to particular driver tags by the driver developer. Typical uses for these tags are default SCSI address, default page size, default color dropout, default I/O address, and so forth.

Under Windows, a dialog box appears if the user chooses a scanner by using the built-in Select Scanner dialog and the scanner has user-settable default tags, and the user clicks the Setup button after choosing a scanner. It also appears if the user chooses a scanner for which default values have not yet been set and tries to close the dialog.

The actual settings available in this dialog box will vary according to the implementation of the driver. The driver that displays the above dialog box has default tags for default paper size and default SCSI address. These values will be set each time the scanner driver is initialized. The values for IG_ISIS_TAG_CONFIG_1 through IG_ISIS_TAG_CONFIG_4 are saved in a scanner-specific section of the SETSCAN.INI file. In the dialog box shown above, the values would be saved in a section named [FUJIGINX].

Determining Tag Default Values

The IG_ISIS_tag...default function gets the default value of a tag without resetting it to its default value. To set a tag to its default value, you could use the value returned by IG_ISIS_tag...default to set the tag, but it is easier to simply use IG_ISIS_tag_set_default.

Tag Values and Interdependencies

Some tags are independent of other tags, and some tags are dependent on other tags' values. A dependent tag's value can be reset or changed when the value of a tag upon which it is dependent changes. Tag dependencies are described in the Tag Reference later in this document. By always setting tags in order of their dependence, you can always ensure the desired results.

As an example, for a particular scanner, IG_ISIS_TAG_DITHER may have legal values other than "None" when IG_ISIS_TAG_BITSPERSAMPLE and IG_ISIS_TAG_SAMPLESPERPIXEL are both one (indicating binary scanning mode). But when these tags are set to values that set a grayscale or color scanning mode, IG_ISIS_TAG_DITHER may have a legal value of "None" only.

Because of interdependencies, it is possible, and in fact common, for an application to set a tag to an intermediate illegal value. Note that the toolkit does not query to determine the legal choices for a tag when the tag is set. There are two reasons for this:

  1. Previous versions of the toolkit did not check tags as they were set because it is a very slow process. Changing it now would break many existing applications.
  2. It is possible that while an application is en route to setting a legal group of tag values, it sets tags to values that are temporarily illegal until all other interdependent tags in the group are set.

Because the toolkit does not check each tag as it is set, the order in which many tags are set does not matter to the toolkit. It may, however, matter to the application. If you set TAG2 to a legal value, and then set TAG1 on whose value TAG2 depends, TAG2 may be changed to a different value and produce results different from what you expect or require. Furthermore, if you call IG_ISIS_run_zone on a pipe that has tags set to illegal values, you might get an error such as "Bad parameter."

It is possible for a tag's default value to become illegal due to the application changing the values of tags that have a higher precedence. In this case, the toolkit performs some calculations to attempt to reset the default tag value to a legal value.

Tags and Choices

The way in which ISIS drivers decide and communicate the legal values for a particular tag is with choices. Each ISIS driver must establish legal choices for a tag based on other interdependent tag values. The application can then query choices to find out the current legal values for a tag.

Choices are a separate entity from tags. Tags generally only hold one value each at a given time (unless the tag is an array that has several elements such as gamma tables). Choices for a given tag change based on the value of other interdependent tags.

For example, if your application is scanning in binary mode, specific dither options are available. If the user changes the scanner mode to grayscale, in which mode most scanners do not allow dither, the choices for the dither tag change to reflect the new available settings (probably "None"). Therefore, if you set IG_ISIS_TAG_BITSPERSAMPLE and IG_ISIS_TAG_SAMPLESPERPIXEL to 1 (indicating binary), you can query choices for IG_ISIS_TAG_DITHER and obtain a list of legal dither patterns. If you then set IG_ISIS_TAG_BITSPERSAMPLE to 8 (indicating grayscale), the choices for IG_ISIS_TAG_DITHER may contain only one value (None).

As you can see from the example above, it is generally not safe to query the choices for a particular tag and assume that they will remain the same for as long as you are working with the scanner. You should query a tag's value right before its use in your application.

Choices and relationships between tags are established by the person who wrote the ISIS driver. The application developer has no control over what choices are available and what their relationships are. Application developers can only get a tag's value, set a tag to one of its legal values, or find out how many choices a tag has and what they are.

Tag Choice Data Types

As previously mentioned, it is important to know the data type of a tag before setting it. The choices for a tag have the same data type as the tag itself. Issuing a IG_ISIS_tag_get_type() function will return the data type of the tag and its choices. There is no separate function for getting the type of a choice.

Querying Choices

Choices can only be queried by an application; there are no PixTools/Scan API functions for setting choices. The functions for querying choices are shown in the following table:

Tag Choice Function

Purpose

IG_ISIS_choice_get_flags()

Gets the type of choice for the tag: list (IG_ISIS_CONT_LIST) or range (IG_ISIS_CONT_RANGE). A list has multiple values; a range has a low value, a high value, and a step value.

IG_ISIS_choice_get_count()

Gets the number of legal values for a choice. Although valid for both list and range choices, it usually is not used for ranges, because you do not need to know how many valid values there are in the range.

IG_ISIS_choice_get_long()
IG_ISIS_choice_get_rational()
IG_ISIS_choice_get_ascii_len()
IG_ISIS_choice_get_ascii()

Gets the values of choices for a particular tag. Generally, the application must iterate through the index of the array of choices that is determined by IG_ISIS_choice_get_count.

Choice Lists Versus Choice Ranges

Choices can be set up in the driver as lists or ranges. A list makes sense when there are multiple, non-sequential choices. IG_ISIS_choice_get_count() is useful for lists, where the application must determine how many choices there are so that they can be listed for the user. A range is more useful for tags such as IG_ISIS_TAG_IMAGEWIDTH which may contain hundreds or even thousands of individual choices (3300 pixels wide with 8 bits between values, for example). Using a range eliminates the need to specify hundreds or thousands of choices in a list within a driver, and makes dealing with the choice much easier for the application. Using IG_ISIS_choice_get_count() with a range generally is not useful.

The special indexes of IG_ISIS_CHOICE_LOW, IG_ISIS_CHOICE_HIGH, and IG_ISIS_CHOICE_STEP may be used to access the range of a choice. IG_ISIS_CHOICE_LOW always returns the lowest value and IG_ISIS_CHOICE_HIGH always returns the highest value of the range (or list). Only if the choice is a range, IG_ISIS_CHOICE_STEP returns the difference between any two consecutive values. If the choice is not a range, IG_ISIS_CHOICE_STEP's value is undefined. Note also that individual indexes always return valid values, even if the choice is a range. Thus, you can always access the nth possible value of a tag, whether the choices are represented as a list or a range.

Tags with No Choices

An ISIS driver is not required to specify choices for every tag. If you query the choices for tags that do not have choices, IG_ISIS_choice_get_flags() will indicate that the choices are a list, and IG_ISIS_choice_get_count() will indicate that there is only one valid value. There is no way for an application developer to know that a tag has no choices, nor should the developer care. If a tag has only one valid choice, it will always be set to that choice.

Checking Choices before Setting Tags

It is important to check the choices for a tag before setting the tag. If you ignore the fact that a tag has choices, and you pick a value and set the tag to it, and then you ask for the legal values for the tag, the driver may return the (possibly illegal) value to which you just set the tag. Then, when you invoke the pipe, you will likely receive a Bad Parameter error. If you set tags without checking their choices, you will eventually set illegal values and either get a Bad Parameter error or a system crash.

Choice Function Examples

The following are typical function calls for the functions used with choices:

 
Copy Code
IG_ISIS_choice_get_long(hScan, wTag, iIndex, &dwValue);
IG_ISIS_choice_get_count(hScan, wTag, &wCount);

IG_ISIS_CONT_RANGE:

 
Copy Code
IG_ISIS_choice_get_long(hScan, wTag, IG_ISIS_CHOICE_LOW, &ValueLow);
IG_ISIS_choice_get_long(hScan, wTag, IG_ISIS_CHOICE_HIGH, &ValueHigh);
IG_ISIS_choice_get_long(hScan, wTag, IG_ISIS_CHOICE_STEP, &ValueStep);

IG_ISIS_CONT_LIST:

 
Copy Code
for (index=0; index < wCount; index++)
{
     IG_ISIS_choice_get_long(hScan, wTag, index, &lValue);
}