TIFF Image Loader

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
porcus
Posts: 149
Joined: Sun May 27, 2007 6:24 pm
Location: Germany

TIFF Image Loader

Post by porcus »

Hi,

I created an IImageLoader implementation for TIFF files:

TIFFImageLoader.h:

Code: Select all

#include <irrlicht.h>
 
class TIFFImageLoader : public irr::video::IImageLoader{
 
    public:
 
    TIFFImageLoader(irr::video::IVideoDriver* driver);
 
    bool isALoadableFileExtension(const irr::io::path &filename) const;
 
    bool isALoadableFileFormat(irr::io::IReadFile *file) const;
 
    irr::video::IImage* loadImage(irr::io::IReadFile* file) const;
 
    private:
 
    irr::video::IVideoDriver* driver;
 
};
TIFFImageLoader.cpp

Code: Select all

#include <tiffio.h>
#include "TIFFImageLoader.h"
 
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
static tsize_t tiff_Read(thandle_t st,tdata_t buffer,tsize_t size)
{
    irr::io::IReadFile* file = (irr::io::IReadFile*)st;
    return file->read((void*)buffer, (irr::u32)size);
}
 
static tsize_t tiff_Write(thandle_t st,tdata_t buffer,tsize_t size)
{
    return 0;//writing not possible with IReadFile
}
 
static int tiff_Close(thandle_t)
{
    return 0;//close not required
}
 
static toff_t tiff_Seek(thandle_t st, toff_t pos, int whence)
{
    if(pos == 0xFFFFFFFF) return 0xFFFFFFFF;
    irr::io::IReadFile* file = (irr::io::IReadFile*)st;
    long finalPos = pos;
    switch(whence)
    {
    case SEEK_SET:
        break;
    case SEEK_CUR:
        finalPos += file->getPos();
        break;
    case SEEK_END:
        finalPos = file->getSize()-finalPos-1;
        break;
    }
    file->seek(finalPos, false);
    return file->getPos();
}
 
static toff_t tiff_Size(thandle_t st)
{
    irr::io::IReadFile* file = (irr::io::IReadFile*)st;
    return file->getSize();
}
 
static int tiff_Map(thandle_t, tdata_t*, toff_t*)
{
    return 0;
}
 
static void tiff_Unmap(thandle_t, tdata_t, toff_t)
{
    return;
}
 
TIFFImageLoader::TIFFImageLoader(irr::video::IVideoDriver* driver){
    this->driver = driver;
}
 
bool TIFFImageLoader::isALoadableFileExtension (const irr::io::path &filename) const{
    return filename[filename.size()-4]=='.' && (filename[filename.size()-3]=='t' || filename[filename.size()-3]=='T') && (filename[filename.size()-2]=='i' || filename[filename.size()-2]=='I') && (filename[filename.size()-1]=='f' || filename[filename.size()-1]=='F');
}
 
bool TIFFImageLoader::isALoadableFileFormat(irr::io::IReadFile* file) const{
    TIFF* tif = TIFFClientOpen("File", "r", (thandle_t)file, tiff_Read, tiff_Write, tiff_Seek, tiff_Close, tiff_Size, tiff_Map, tiff_Unmap);
    if(tif){
        TIFFClose(tif);
        return true;
    }
    return false;
}
 
irr::video::IImage* TIFFImageLoader::loadImage(irr::io::IReadFile* file) const{
    TIFF* tif = TIFFClientOpen("File", "r", (thandle_t)file, tiff_Read, tiff_Write, tiff_Seek, tiff_Close, tiff_Size, tiff_Map, tiff_Unmap);
    if(tif){
        u32 w, h;
        TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
        irr::video::IImage* img = driver->createImage(ECF_A8R8G8B8, dimension2d<u32>(w, h));
        uint32* data = (uint32*)img->lock();
        //bool succ = TIFFReadRGBAImage(tif, w, h, (uint32*)data, 0);
        bool succ = TIFFReadRGBAImageOriented(tif, w, h, data, ORIENTATION_TOPLEFT, 0);
        //exchange red and blue channels
        int size = w*h;
        unsigned char* cdata = (unsigned char*)data;
        for(int i=0; i<size; i++){
            unsigned char tmp = cdata[i*4];
            cdata[i*4] = cdata[i*4+2];
            cdata[i*4+2] = tmp;
        }
        img->unlock();
        TIFFClose(tif);
        if(!succ){
            img->drop();
            img = NULL;
        }
        return img;
    }
    return NULL;
}
test.cpp: (Loads a TIFF and saves it as png)

Code: Select all

#include <irrlicht.h>
#include "TIFFImageLoader.h"
 
 
using namespace std;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
 
int main(int argc, char *argv[]){
 
    IrrlichtDevice* device = createDevice(EDT_NULL);
 
    IVideoDriver* driver = device->getVideoDriver();
    driver->addExternalImageLoader(new TIFFImageLoader(driver));
 
    IImage* tiff = driver->createImageFromFile("test.tiff");
    driver->writeImageToFile(tiff, "test.png");
 
    device->drop();
 
    return 0;
}
Don't forget to use -ltiff to link with the tiff library.
Post Reply