This example creates a file reader to read TIFF format files.
Note |
example1_readtiff__define.pro
in the examples/doc/itools
subdirectory of the IDL distribution. Enter
example1tool
.compile example1_readtiff
.pro
file in the IDL editor.
Note |
The class definition for example1_readtiff
consists of an Init method, an IsA method, a GetData method, GetProperty and SetProperty methods, and a class structure definition routine. As with all object class definition files, the class structure definition routine is the last routine in the file, and the file is given the same name as the class definition routine (with the suffix .pro
appended).
FUNCTION example1_readtiff::Init, _REF_EXTRA = _extra ; Call the superclass Init method IF (self->IDLitReader::Init(["tiff", "tif"],$ FILETYPE="TIFF", NAME="Tiff Files", $ DESCRIPTION="TIFF File format", $ _EXTRA = _extra) NE 1) THEN $ RETURN, 0 ; Initialize the instance data field self._index = 0 ; Register the index property self->RegisterProperty, 'IMAGE_INDEX', /INTEGER, $ Description='Index of the image to read from the TIFF file.' RETURN,1 END
The first item in our class definition file is the Init method. The Init method's function signature is defined first, using the class name example1_readtiff. The _REF_EXTRA keyword inheritance mechanism allows any keywords specified in a call to the Init method to be passed through to routines that are called within the Init method even if we do not know the names of those keywords in advance.
Next, we call the Init method of the superclass. In this case, we are creating a subclass of the IDLitReader class; this provides us with all of the standard iTool file reader functionality automatically. Any "extra" keywords specified in the call to our Init method are passed to the IDLitReader::Init method via the keyword inheritance mechanism.
We specify a list of accepted filename extensions (tiff
and tif
, in this case) via the Extensions argument, and set the FILETYPE keyword. We specify a value for the NAME property of the reader object (this is displayed in the system preferences dialog) and include a description of the reader via the DESCRIPTION keyword. Finally, we use the _EXTRA keyword inheritance mechanism to pass through any keywords provided when the Init method is called.
Our TIFF reader object has a single instance data field: _index, which is used to store the index number of the image to read from a multi-image TIFF file. We initialize this instance data field to 0, and register the IMAGE_INDEX property to provide access to this field via the property sheet interface.
Finally, we return the value 1 to indicate successful initialization.
FUNCTION example1_readtiff::Isa, strFilename RETURN, QUERY_TIFF(strFilename); END
The IsA method for our TIFF file reader is simple: we use the IDL QUERY_TIFF function to determine whether the specified file is a TIFF file, returning the function's return value.
FUNCTION example1_readtiff::GetData, oImageData filename = self->GetFilename() IF (QUERY_TIFF(filename, fInfo, IMAGE_INDEX = self._index) EQ 0) $ THEN RETURN, 0 IF (fInfo.has_palette) THEN BEGIN image = READ_TIFF(filename, palRed, palGreen, palBlue, $ IMAGE_INDEX = self._index) ELSE image = READ_TIFF(filename, IMAGE_INDEX = self._index) ENDIF ; Store image data in Image Data object. oImageData = OBJ_NEW('IDLitDataImage', $ NAME = FILE_BASENAME(fileName)) result = oImageData->SetData(image, 'Image', /NO_COPY) IF (result EQ 0) THEN $ RETURN, 0 ; Store palette data in Image Data object. IF (fInfo.has_palette) THEN $ result = oImageData->SetData( TRANSPOSE([[palRed], $ [palGreen], [palBlue]]), 'Palette') IF fInfo.num_images GT 1 THEN $ self->IDLitIMessaging::StatusMessage, $ 'Read channel ' + strtrim(self._index,2) RETURN, result END
The GetData method for our TIFF file reader begins by retrieving the name of the file associated with the reader object. We then use the IDL QUERY_TIFF function to check whether the image specified by the value of the IMAGE_INDEX property (stored in the _index
instance data field) exists, returning 0 for failure if the specified image does not exist.
QUERY_TIFF also returns a structure containing information about the image; we use this structure to determine whether the image has a palette. We use the presence of a palette to choose the correct call to the READ_TIFF function, which places the image data in a set of local variables.
Next, we construct an IDLitDataImage object to store the image data, using the base name of the image file for the object's NAME property. We use the SetData method to place the image data into the newly created image data object, specifying the string 'Image'
as the data object's identifier. A check of the return value from the SetData method allows us to return 0 from our GetData method if we are unable to store the image data in the image object for any reason.
If the image includes palette data, we store the array of red, green, and blue values using the SetData method, specifying 'Palette'
as the identifier. The palette variables returned by READ_TIFF represent image planes; since the IDLitVisImage visualization type that we will use to display the image expects data interleaved by pixel, we use the TRANSPOSE function to convert the palette data into the correct format.
Finally, we use the StatusMessage method of the IDLitIMessaging class to report to the user which image was retrieved from the TIFF file. The message is displayed in the status area of the iTool window.
PRO example1_readtiff::GetProperty, IMAGE_INDEX = image_index, $ _REF_EXTRA = _extra IF (ARG_PRESENT(image_index)) THEN $ image_index = self._index IF (N_ELEMENTS(_extra) GT 0) THEN $ self->IDLitReader::GetProperty, _EXTRA = _extra END
The GetProperty method for our TIFF file reader supports a single property named IMAGE_INDEX. If this property is specified in the call to the GetProperty method, its value is retrieved from the _index
instance data field. Any other properties included in the method call are passed to the superclass' GetProperty method.
PRO example1_readtiff::SetProperty, IMAGE_INDEX = image_index, $ _REF_EXTRA = _extra IF (N_ELEMENTS(image_index) GT 0) THEN $ self._index = image_index IF (N_ELEMENTS(_extra) GT 0) THEN $ self->IDLitReader::SetProperty, _EXTRA = _extra END
The SetProperty method for our TIFF file reader supports a single property named IMAGE_INDEX. If this property is specified in the call to the SetProperty method, its value is placed in the _index
instance data field. Any other properties included in the method call are passed to the superclass' SetProperty method.
PRO example1_readtiff__Define struct = {example1_readtiff, $ inherits IDLitReader, $ _index : 0 $ } END
Our class definition routine is very simple. We create an IDL structure variable with the name example1_readtiff
, specifying that the structure inherits from the IDLitReader class. The structure has a single instance data field named _index
, which we specify as an integer value.