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;
};
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;
}
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;
}