tiffFloatReader.cpp
#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>
#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;                         
        unsigned int    fHeight;                        
        unsigned int    fChannels;                      
#if defined(_TIFF_LIBRARY_AVAILABLE_)
        TIFF                    *fInputFile;            
#else
        void                    *fInputFile;            
#endif
};
tiffFloatReader::tiffFloatReader()
: fInputFile( NULL), 
  fChannels( 0), 
  fWidth(0),
  fHeight(0)
{
}
tiffFloatReader::~tiffFloatReader()
{
        close();
}
void * tiffFloatReader::creator()
{
    return new tiffFloatReader();
}
MStatus tiffFloatReader::open( MString pathname, MImageFileInfo* info)
{
#if defined(_TIFF_LIBRARY_AVAILABLE_)
        try
        {
                
                
                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;
        
        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;
        
        
        if (_TIFF_SUCCESS != TIFFGetField(fInputFile, TIFFTAG_BITSPERSAMPLE, &bitsPerChannel))
                goto no_support;
        if (bitsPerChannel != 32)
                goto no_support;
        
        
        
        if (_TIFF_SUCCESS != TIFFGetField(fInputFile, TIFFTAG_SAMPLEFORMAT, &sampleType) ||
                sampleType != SAMPLEFORMAT_IEEEFP)
        {
                goto no_support;
        }
        
        
        
        if (_TIFF_SUCCESS != TIFFGetField(fInputFile, TIFFTAG_PLANARCONFIG, &config) ||
                (config != PLANARCONFIG_CONTIG))
        {
                goto no_support;
        }
        
#if 0
        unsigned short compression;
        if (_TIFF_SUCCESS != TIFFGetField(fInputFile, TIFFTAG_COMPRESSION, &compression) ||
                (compression != COMPRESSION_NONE))
        {
                goto no_support;
        }
#endif
        
        
        if( info)
        {
                
                
                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
}
MStatus tiffFloatReader::close()
{
#if defined(_TIFF_LIBRARY_AVAILABLE_)
        if (fInputFile)
                TIFFClose( fInputFile );
        fInputFile = NULL;
        return MS::kSuccess;
#else
        return MS::kFailure;
#endif
}
MStatus tiffFloatReader::load( MImage& image, unsigned int imageNumber)
{
        MStatus rval = MS::kFailure;
#if defined(_TIFF_LIBRARY_AVAILABLE_)
        if (!fInputFile)
                return rval;
        
        image.create( fWidth, fHeight, fChannels, MImage::kFloat);
        float* outputBuffer = image.floatPixels();
        if (outputBuffer == NULL)
                return rval;
        
        
        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;
}
MStatus uninitializePlugin( MObject obj )
{
    MFnPlugin plugin( obj );
    CHECK_MSTATUS( plugin.deregisterImageFile( kImagePluginName ) );
    return MS::kSuccess;
}