tiffFloatReader.cpp

//-
// ==========================================================================
// Copyright 1995,2006,2008 Autodesk, Inc. All rights reserved.
//
// Use of this software is subject to the terms of the Autodesk
// license agreement provided at the time of installation or download,
// or which otherwise accompanies this software in either electronic
// or hard copy form.
// ==========================================================================
//+

//
// DESCRIPTION: 
//      tiffFloatReader : Example floating point tif image file reader.
//

#include <maya/MPxImageFile.h>
#include <maya/MImageFileInfo.h>
#include <maya/MImage.h>
#include <maya/MFnPlugin.h>
#include <maya/MStringArray.h>
#include <maya/MIOStream.h>
#include <maya/MGlobal.h>

// #pragma warning( disable : 4290 )            // Disable STL warnings.

// Uncomment this to build with tif library
#define _TIFF_LIBRARY_AVAILABLE_
#if defined(_TIFF_LIBRARY_AVAILABLE_)
#include <tiff.h>
#include <tiffio.h>
#endif

MString kImagePluginName( "TIFF Float Reader");

#define _TIFF_SUCCESS   1

class tiffFloatReader : public MPxImageFile
{
public:
                    tiffFloatReader();
    virtual         ~tiffFloatReader();
    static void*        creator();
        virtual MStatus open( MString pathname, MImageFileInfo* info);
        virtual MStatus load( MImage& image, unsigned int idx);
        virtual MStatus close();

protected:
        unsigned int    fWidth;                         // Width
        unsigned int    fHeight;                        // Height
        unsigned int    fChannels;                      // Number of channels

#if defined(_TIFF_LIBRARY_AVAILABLE_)
        TIFF                    *fInputFile;            // Tif interface
#else
        void                    *fInputFile;            
#endif
};

//
// DESCRIPTION:
tiffFloatReader::tiffFloatReader()
: fInputFile( NULL), 
  fChannels( 0), 
  fWidth(0),
  fHeight(0)
{

}

//
// DESCRIPTION:
//              Destructor : close the file if opened
tiffFloatReader::~tiffFloatReader()
{
        close();
}

//
// DESCRIPTION:
//              Create a new instance of the reader
void * tiffFloatReader::creator()
{
    return new tiffFloatReader();
}

//
// DESCRIPTION:
//              Open up the file for read. Return "info" if requested.
MStatus tiffFloatReader::open( MString pathname, MImageFileInfo* info)
{
#if defined(_TIFF_LIBRARY_AVAILABLE_)
        try
        {
                // Open the tif file for read
                // (TIFF *) cast from integer required on Mac.
                fInputFile = (TIFF *) TIFFOpen( pathname.asChar(), "r" );
        }
        catch( ... )
        {
        }

        if( !fInputFile)
        {
                return MS::kFailure;
        }

        unsigned short num_samps;
        unsigned short bitsPerChannel;
        unsigned short sampleType = 0;
        short config;

        if (_TIFF_SUCCESS != TIFFGetField(fInputFile, TIFFTAG_IMAGEWIDTH, &fWidth ) || 
                fWidth < 1)
                goto no_support;
        if (_TIFF_SUCCESS != TIFFGetField(fInputFile, TIFFTAG_IMAGELENGTH, &fHeight ) || 
                fHeight < 1)
                goto no_support;


        // Suport 3 and 4 channel images only
        if (_TIFF_SUCCESS != TIFFGetField(fInputFile, TIFFTAG_SAMPLESPERPIXEL, &num_samps))
                goto no_support;
        if ((num_samps != 3) && (num_samps!= 4))
                goto no_support;
        fChannels = num_samps;

        // This is more robust than TIFFTAG_SAMPLEFORMAT since it may not be supported
        // properly as it's an extension. 

        if (_TIFF_SUCCESS != TIFFGetField(fInputFile, TIFFTAG_BITSPERSAMPLE, &bitsPerChannel))
                goto no_support;
        if (bitsPerChannel != 32)
                goto no_support;

        // Check the sample type. We only care about 32 bit 
        // floating point samples for this reader.
        // SAMPLEFORMAT_IEEEFP is specified as IEEE floating point.
        if (_TIFF_SUCCESS != TIFFGetField(fInputFile, TIFFTAG_SAMPLEFORMAT, &sampleType) ||
                sampleType != SAMPLEFORMAT_IEEEFP)
        {
                goto no_support;
        }

        // See how the data is stored in the scan line. Only support
        // contiguous scan line for now.
        // - PLANARCONFIG_SEPARATE is not supported.
        if (_TIFF_SUCCESS != TIFFGetField(fInputFile, TIFFTAG_PLANARCONFIG, &config) ||
                (config != PLANARCONFIG_CONTIG))
        {
                goto no_support;
        }

        // Compression not supported yet.. 
#if 0
        unsigned short compression;
        if (_TIFF_SUCCESS != TIFFGetField(fInputFile, TIFFTAG_COMPRESSION, &compression) ||
                (compression != COMPRESSION_NONE))
        {
                goto no_support;
        }
#endif

        //printf("Opened tif file successfully: w=%d,h=%d, ch=%d\n",
        //      fWidth, fHeight, fChannels );

        if( info)
        {
                // Set up the info structure to return
                //
                info->width( fWidth );
                info->height( fHeight );
                info->channels( fChannels );
                info->numberOfImages( 1 );
                info->pixelType( MImage::kFloat);
        }
        return MS::kSuccess;

no_support:
        close();
        return MS::kFailure;
#else
        return MS::kFailure;
#endif
}

//
// DESCRIPTION:
//              Close any open file
/* virtual */
MStatus tiffFloatReader::close()
{
#if defined(_TIFF_LIBRARY_AVAILABLE_)
        if (fInputFile)
                TIFFClose( fInputFile );
        fInputFile = NULL;
        return MS::kSuccess;
#else
        return MS::kFailure;
#endif
}

//
// DESCRIPTION:
//              Load the image into system memory (MImage)
MStatus tiffFloatReader::load( MImage& image, unsigned int imageNumber)
{
        MStatus rval = MS::kFailure;
#if defined(_TIFF_LIBRARY_AVAILABLE_)
        if (!fInputFile)
                return rval;

        // Configure our Maya image to hold the result
        image.create( fWidth, fHeight, fChannels, MImage::kFloat);
        float* outputBuffer = image.floatPixels();
        if (outputBuffer == NULL)
                return rval;
        
        // Maya expects images upside down
        unsigned int row = 0;
        bool flipVertically = true;
        if (flipVertically)
        {
                outputBuffer += (fHeight-1) * (fWidth * fChannels);
                for (row = 0; row < fHeight; row++)
                {
                        TIFFReadScanline (fInputFile, outputBuffer, row);
                        outputBuffer -= (fWidth * fChannels);
                }
        }
        else
        {
                for (row = 0; row < fHeight; row++)
                {
                        TIFFReadScanline (fInputFile, outputBuffer, row);
                        outputBuffer += (fWidth * fChannels);
                }
        }
        rval = MS::kSuccess;
#endif
        return rval;
}


MStatus initializePlugin( MObject obj )
{
    MFnPlugin plugin( obj, PLUGIN_COMPANY, "8.0", "Any" );
        MStringArray extensions;
        extensions.append( "tif");
    CHECK_MSTATUS( plugin.registerImageFile( 
                                        kImagePluginName,
                                        tiffFloatReader::creator, 
                                        extensions));
    
    return MS::kSuccess;
}

// DESCRIPTION:
MStatus uninitializePlugin( MObject obj )
{
    MFnPlugin plugin( obj );
    CHECK_MSTATUS( plugin.deregisterImageFile( kImagePluginName ) );

    return MS::kSuccess;
}


Autodesk® Maya® 2009 © 1997-2008 Autodesk, Inc. All rights reserved. Generated with doxygen 1.5.6