ImageGear for C and C++ on Windows v19.10 - Updated
Manipulating Image Data
User Guide > How to Work with... > Common Operations > Manipulating Image Data

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:

Non-Image Data Format

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:
  • IG_METAD_VALUE_ITEM - this value specifies that the current item is a value of the simplest type, and the field Value contains the actual value of the item, and ValueType contains the identifier of the type of this item. ReadOnly can be either TRUE (read-only) or FALSE (read/ write). Name and/or Id contains textual and numerical identification of the item.
  • IG_METAD_LEVEL_START - this value specifies that the current item opens the sublevel of items and all the next items up to the corresponding item with the LEVEL_END value belonging to this sublevel.
  • IG_METAD_LEVEL_END - this value closes the current sublevel and tells that next item belongs to a higher level.
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.

  • For AM_TID_TXT_STRING it should indicate the number of characters in the string, excluding last null character (basically the length of the string).
  • For AM_TID_RAW_DATA it should indicate the number of bytes that the raw data occupies.
  • For the rest of the types it should indicate the number of values of the type, which textual representation is encoded into "Value".
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.

Processing Non-Image Data

There are two working scenarios of how ImageGear processes non-image data.

The first one is the LOAD operation:

  1. Application registers special callback function of type LPAFT_IG_METAD_ITEM_GET_CB.
  2. The application calls some of the filter loading functions (like IG_fltr_load_file()), and during the LOAD operation, the format filter calls the registered callback function to pass data for each item decoded from the image.

The reverse WRITE operation is more complex:

  1. Application registers callback functions of types LPAFT_IG_METAD_ITEM_SET_CB and LPAFT_IG_METAD_ITEM_ADD_CB.
  2. Application calls some filter writing functions (like IG_fltr_save_file()).
  3. While performing WRITE operation ImageGear uses callback functions to modify existing items or add additional items to required dataset.
    ImageGear provides special LPAFT_ callback functions for the non-image data processing described in this section. It also preserves the "old" callback functionality (LPFNIG_ callback functions) required for image processing control and perfection. Please see Working with ImageGear Callback Functions for detailed information about the structure of the ImageGear callback functionality.

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.