Home | Categories | Alphabetical | Classes | All Contents | [ < ] | [ > ]

Example: TIFF File Reader


This example creates a file reader to read TIFF format files.

Note
The code for this example file reader is included in the file example1_readtiff__define.pro in the examples/doc/itools subdirectory of the IDL distribution. Enter

example1tool

at the IDL prompt to create an instance of an iTool that registers this file reader, or

.compile example1_readtiff


to open the .pro file in the IDL editor.

Note
The standard TIFF file reader included with the iTools contains additional features not included in this example. In most cases, if a file reader is included in the standard iTool distribution, there is no need to create your own reader for files of the same type.

Class Definition File

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).

Init Method

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 
Discussion

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.

IsA Method

FUNCTION example1_readtiff::Isa, strFilename 
 
   RETURN, QUERY_TIFF(strFilename); 
 
END 
Discussion

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.

GetData Method

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 
Discussion

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.

GetProperty Method

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 
Discussion

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.

SetProperty 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 
Discussion

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.

Class Definition

PRO example1_readtiff__Define 
 
   struct = {example1_readtiff,        $ 
             inherits IDLitReader, $ 
             _index : 0            $ 
           } 
END 
Discussion

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.


Home | Categories | Alphabetical | Classes | All Contents | [ < ] | [ > ]