Some format filters, such as EXIF-JPEG, EXIF-TIFF, TIFF, JPEG, PNG and some others contain non-image data, generally referred to as metadata. ImageGear provides a mechanism for reading the metadata during image loading and modifying it during image saving. Non-image data itself can be of any possible complex type, depending on the nature of the file format. ImageGear processes this complex data through a single interface and allows uniform processing that does not depend on the actual data format, and starts from information fields of such simple formats as BMP and PCX, up to the complex metadata support in the EXIF filter and the IPTC non-image data format in such filters as TIFF and JPEG.
While EXIF-JPEG and EXIF-TIFF are separate image file formats using JPEG or TIFF image data compressions, IPTC is a format used only for non-image data storage in such imaging format filters as JPEG and TIFF. For more detailed information about these formats, see the EXIF-TIFF Non-Image Data Structure, EXIF-JPEG Non-image Data Structure, and the IPTC Non-Image Data Structure sections in Non-Image Data Storage as well as the EXIF-JPEG and EXIF-TIFF sections in the File Format Reference.
ImageGear is responsible for translating this format-dependent data into a standard uniform format. There are at least two operations that include such data processing:
This section provides the following information:
This topic provides the following information:
The key thing of non-image data processing in ImageGear is a uniform data format that is used to convert to and from the format filter. As soon as the format filter decodes the data fields one after another during the loading operation, and encodes it in the reverse direction during the saving operation, all data consists of the set of items where each item is a minimal atom of information. The order of items is fixed, and the format filter processes item after item in the given order. The same order is used when data is passed through the stream.
The low-level format of the data consists of the list of items where each item represents a minimal unit of information. Each item also should have some unique name that allows you to connect it with the physical value inside of the file format. The definition of the data item can be described by the following fields:
Copy Code
|
|
---|---|
typedef struct tagAT_DATALIST_ITEM{
AT_MODE FormatID
LPCHAR Name;
DWORD Id;
AT_MODE Type;
LPVOID Value;
AT_MODE ValueType;
DWORD Length;
AT_MODE ValueAccessMode;
}AT_DATALIST_ITEM;
|
Please see the descriptions of these fields below:
Name | Description |
---|---|
FormatID | The ID of the filter that reads or writes a file (IG_FORMAT_... constant value). |
Name | The name of the item. Can be any string value. |
Id | Numerical ID of item. Can be any value of DWORD size. |
Type |
Specifies the type of item and reflects the status of the given record. Possible values are:
|
Value | Contains the value of the item when Type = IG_METAD_VALUE_ITEM. Note that possible values of this field are fixed and define the exact list of allowed data types. It also depends on the ImageGear platform and FLTR.METADATA_FORMAT global control parameter. This global parameter has two allowed values: "text" and "binary". See the "AT_DATALIST_ITEM Metadata Structure ValueType and Value Elements" sub-section of Metadata Structures for possible values. |
ValueType | Contains the type identifier of the item when Type = IG_METAD_VALUE_ITEM. Possible values of this field are fixed and define the exact list of allowed data types. See the "AT_DATALIST_ITEM Metadata Structure ValueType and Value Elements" sub-section of Metadata Structures for possible values. |
Length |
Identifies the number of values to be written.
|
ValueAccessMode | Identifies whether data can be changed or not. "Read only" value means that its value is information only and cannot be changed after setting the initial value. It also means that its value will be ignored during a WRITE operation. |
So, this data structure allows you to "linearize" hierarchical and complex data into an array of simplest data types.
You can transfer different non-image data using the general data structure described in this section. Please see Non-Image Data Storage.
There are two working scenarios of how ImageGear processes non-image data.
The first one is the LOAD operation:
The reverse WRITE operation is more complex:
You can see from the declaration below that LPAFT_IG_METAD_ITEM_GET_CB accepts parameters that provide all necessary information about one data item. All parameters except the first one are fields of the data structure AT_DATALIST_ITEM described in "Non-Image Data Format" above:
Copy Code
|
|
---|---|
LPAFT_IG_METAD_ITEM_GET_CB(LPVOID lpPrivate, LPCHAR ItemName, DWORD ItemID, AT_MODE ItemType, LPVOID ItemValue, AT_MODE ValueType, DWORD ValueLength, AT_BOOL ReadOnlyValue ) |
By implementing and providing a callback function of this type, the application can receive every decoded item and process it as needed.
Some items from the dataset are informational only and cannot be changed during the WRITE operation. So, if the ReadOnlyValue field is set to TRUE, then the item will not be changed during the WRITE operation. Actually, during this operation, the format filter prepares all necessary items and puts required values to them to make sure that the file format itself is not violated. For example, if an item requires a particular number of strips in the image, then if the value of this item is changed, the image cannot be loaded.
The format filter prepares a minimal set of items and default values for them, and before writing its values to the output stream it calls the callback function of type LPAFT_IG_METAD_ITEM_SET_CB so that the application can change its values. In addition, the format filter may call the function of type LPAFT_IG_METAD_ITEM_ADD_CB to get additional items to append the dataset. The application should provide its implementation in such a way that it returns TRUE until it is necessary to insert more items. If this function returns FALSE, all custom items have been added, and the filter can proceed.
It may happen that the application provides an item with the name or ID of a different type than the format filter is expecting. For example, the format filter may expect the item named SOFTWARE with text as a String, but the application provides its value as an Integer. In this case the filter may ignore this item and trigger a warning that this type of item is not expected. Also, the application may provide an item that the format filter is not able to handle because it does not fit the format defined by the corresponding image file format. In this case it may simply ignore the item and give a warning.
The exact specification of the callback function types can be found in Core Component API Function Reference, but the following is a quick reference for better understanding:
Copy Code
|
|
---|---|
LPAFT_IG_METAD_ITEM_SET_CB)(LPVOID lpPrivate, LPCHAR ItemName, DWORD ItemID, AT_MODE ItemType, LPVOID ItemValue, AT_MODE ValueType, DWORD ValueLength, AT_BOOL ReadOnlyValue, LPVOID *NewItemValue, LPAT_MODE *NewValueType, LPDWORD *NewValueLength ) |
*NewItemValue, *NewValueType, *NewValueLength are arguments with a new value for a given item. If ReadOnlyValue is TRUE, the value of this item is unchangeable.
You can add a new non-image item during the filter WRITE operation using the callback function prototype:
Copy Code
|
|
---|---|
LPAFT_IG_METAD_ITEM_ADD_CB(LPVOID lpPrivate, LPCHAR ItemName, DWORD ItemID, AT_MODE ItemType, LPVOID ItemValue, AT_MODE ValueType, DWORD ValueLength, AT_BOOL ReadOnlyValue ) |
All arguments in this function are parameters for the new item and its value.
To exchange the non-image tag information provided by these three callback functions between the application and the internal ImageGear structure levels, you should use two functions:
Copy Code
|
|
---|---|
IG_fltr_metad_callback_get(LPVOID *lpPrivate, LPAFT_IG_METAD_ITEM_SET_CB *lplpfnSetCB, LPAFT_IG_METAD_ITEM_ADD_CB *lplpfnAddCB, LPAFT_IG_METAD_ITEM_GET_CB *lplpfnGetCB ) IG_fltr_metad_callback_set(LPVOID *lpPrivate, LPAFT_IG_METAD_ITEM_SET_CB *lplpfnSetCB, LPAFT_IG_METAD_ITEM_ADD_CB *lplpfnAddCB, LPAFT_IG_METAD_ITEM_GET_CB *lplpfnGetCB ) |
The first function allows you to provide the current callback non-image tag data from the internal ImageGear structure to an application level during load/save processes. If some callback information is not necessary, you can set the respective argument of this function to NULL. For instance, if you do not need information about newly added non-image items, set lplpfnAddCB = NULL.
The second _set() function provides the new non-image callback data from the application level to the internal ImageGear level during the load/save processes. Again, if some callback information is not necessary, you can set the respective argument of this function to NULL.
An example of how to use these callback functions is too complex to include in this manual. The GUI implementation that is provided in the source form demonstrates all aspects of working with these callback functions.