Example: TIFF File Writer
This example creates a file writer to write TIFF format files.
Example Code
The code for this example file writer is included in the file example1_writetiff__define.pro in the examples/doc/itools subdirectory of the IDL distribution. Run the example procedure by entering example1_writetiff__define at the IDL command prompt or view the file in an IDL Editor window by entering .EDIT example1_writetiff__define.pro.
Note
The standard TIFF file writer included with the iTools contains additional features not included in this example. In most cases, if a file writer is included in the standard iTool distribution, there is no need to create your own writer for files of the same type.
Class Definition File
The class definition for example1_writetiff consists of an Init method, a SetData method, 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).
Class Definition Discussion
Discussion
Our class definition routine is very simple. We create an IDL structure variable with the name example1_writetiff, specifying that the structure inherits from the IDLitWriter class. The object has no instance data, and thus no instance data fields.
Init Method
FUNCTION example1_writetiff::Init, _REF_EXTRA = _extra IF (self->IDLitWriter::Init('tiff', $ TYPES=['IDLIMAGE', 'IDLIMAGEPIXELS', 'IDLARRAY2D'], $ NAME="Tag Image File Format", $ DESCRIPTION="Tag Image File Format (TIFF)", $ _EXTRA = _extra) EQ 0) THEN $ RETURN, 0 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_writetiff. Note the use of the _REF_EXTRA keyword inheritance mechanism; this 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 IDLitWriter class; this provides us with all of the standard iTool file writer functionality automatically. Any "extra" keywords specified in the call to our Init method are passed to the IDLitWriter::Init method via the keyword inheritance mechanism.
We specify a list of accepted filename extensions (tiff, in this case) via the Extensions argument, and set the TYPES keyword equal to the iTool data type of data that can be written using this file writer. (The iTool data types specified by the TYPES keyword must match the iTool data type of the data selected in the iTool Export Wizard in order for the file writer to be available for selection.)
We specify a value for the NAME property of the writer object (this is displayed in the system preferences dialog) and include a description of the writer via the DESCRIPTION keyword. Finally, we use the _EXTRA keyword inheritance mechanism to pass through any keywords provided when the Init method is called.
Finally, we return the value 1 to indicate successful initialization.
SetData Method
FUNCTION example1_writetiff::SetData, oImageData ; We need a filename for the file we are about to write. strFilename = self->GetFilename() IF (strFilename EQ '') THEN $ RETURN, 0 ; failure ; Make sure that the object passed to this method is valid. IF (~ OBJ_VALID(oImageData)) THEN BEGIN MESSAGE, 'Invalid image data object.', /CONTINUE RETURN, 0 ; failure ENDIF ; First, we look for some image data. oData = (oImageData->GetByType('IDLIMAGEPIXELS'))[0] ; If we did not get any image data, try retrieving a ; 2D array. IF (~ OBJ_VALID(oData)) THEN BEGIN oData = (oImageData->GetByType('IDLARRAY2D'))[0] IF (~ OBJ_VALID(oData)) THEN RETURN, 0 ENDIF ; If we got neither image data nor a 2D array, ; exit with a failure code. IF (~ oData->GetData(image)) THEN BEGIN MESSAGE, 'Error retrieving image data.', /CONTINUE RETURN, 0 ; failure ENDIF ; Next, try to retrieve a palette object from the selected ; object. oPalette = (oImageData->GetByType('IDLPALETTE'))[0] ; If we got a palette object, retrive the palette data ; and store the information in the variables red, green, ; and blue. IF (OBJ_VALID(oPalette)) THEN BEGIN success = oPalette->GetData(palette) IF (N_ELEMENTS(palette) GT 0) THEN BEGIN red = REFORM(palette[0,*]) green = REFORM(palette[1,*]) blue = REFORM(palette[2,*]) ENDIF ENDIF ; Retrieve the number of dimensions in our image. ndim = SIZE(image, /N_DIMENSIONS) ; Write the file. The REVERSE ensures that other ; applications will read the image in right side up. WRITE_TIFF, strFilename, REVERSE(image, ndim), $ RED = red, GREEN = green, BLUE = blue RETURN, 1 ; success END
Discussion
The SetData method accepts an IDLitData object (oImageData) as its input parameter. Before processing the input data, the method prompts the user for a file in which to save the image, using the GetFilename method of the IDLitWriter object.
After securing a filename, the method proceeds to check the input data object. First it checks to make sure that the input object is valid. Then it attempts to retrieve a data object of the iTool data type IDLIMAGEPIXELS from the data object, using the GetByType method. If this fails, it attempts to retrieve a data object of the iTool data type IDLARRAY2D from the data object, again using the GetByType method. If this second attempt fails, we exit, returning 0.
Next, we use the GetData method to retrieve the image data from the data object. The method then checks the return value from the GetData method to determine whether the returned value is valid, and exits if it is not.
The method next attempts to retrieve a object of the data type IDLPALETTE from the input object. If a palette is retrieved, the palette data is reformed to suit the needs of the WRITE_TIFF procedure.
Finally, the method uses the WRITE_TIFF procedure to create an image file. The image data must be processed by the REVERSE function in order to make it appear in the output file with the correct orientation.