CFreeImageLoader

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
tinhtoitrangtay
Posts: 70
Joined: Tue Oct 28, 2008 12:59 pm

CFreeImageLoader

Post by tinhtoitrangtay »

I try make with FreeImage and i fine work.

CImageFreeImageLoader.h

Code: Select all

// Copyright (C) 2004 Murphy McCauley
// Copyright (C) 2007-2009 Christian Stehno
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h
/*
 Thanks to:
 Max McGuire for his Flipcode article about WAL textures
 Nikolaus Gebhardt for the Irrlicht 3D engine
*/

#ifndef __C_IMAGE_FREEIMAGE_LOADER_H_INCLUDED__
#define __C_IMAGE_FREEIMAGE_LOADER_H_INCLUDED__

#include "IrrCompileConfig.h"

#include "IImageLoader.h"
#include "FreeImage/FreeImage.h"
#define  FREEIMAGE_LIB

#pragma comment(lib,"FreeImage/FreeImage.lib")

#define  _IRR_COMPILE_WITH_FREEIMAGE_LOADER_
#define  _IRR_COMPILE_WITH_FREEIMAGE_WRITER_

namespace irr
{
namespace video
{


#if defined(_IRR_COMPILE_WITH_FREEIMAGE_LOADER_) || defined(_IRR_COMPILE_WITH_FREEIMAGE_WRITER_)
#endif // defined with loader or writer

#ifdef _IRR_COMPILE_WITH_FREEIMAGE_LOADER_

/*!
	Surface Loader for Windows bitmaps
*/
class CFreeImageLoader : public IImageLoader
{
public:

	//! constructor
	CFreeImageLoader();

	//! Destructor
	virtual ~CFreeImageLoader();

	//! returns true if the file maybe is able to be loaded by this class
	//! based on the file extension (e.g. ".tga")
	virtual bool isALoadableFileExtension(const io::path& filename) const;

	//! returns true if the file maybe is able to be loaded by this class
	virtual bool isALoadableFileFormat(io::IReadFile* file) const;

	//! creates a surface from the file
	virtual IImage* loadImage(io::IReadFile* file) const;

private:
	

protected:
	
};


#endif // compiled with loader

} // end namespace video
} // end namespace irr

#endif
CImageFreeImageLoader.cpp

Code: Select all

// Copyright (C) 2002-2009 Nikolaus Gebhardt
// This file is part of the "Irrlicht Engine".
// For conditions of distribution and use, see copyright notice in irrlicht.h

#include "CImageFreeImageLoader.h"

#ifdef _IRR_COMPILE_WITH_FREEIMAGE_LOADER_

#include "IReadFile.h"
#include "SColor.h"
#include "CColorConverter.h"
#include "CImage.h"
#include "os.h"
#include "irrString.h"


namespace irr
{
namespace video
{

// ----------------------------------------------------------

/** Generic image loader
	@param lpszPathName Pointer to the full file name
	@param flag Optional load flag constant
	@return Returns the loaded dib if successful, returns NULL otherwise
*/
FIBITMAP* GenericLoader(const core::stringc lpszPathName, int flag) {
	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
	//core::stringc filename;
	
	//lpszPathName = file->getFileName();

	// check the file signature and deduce its format
	// (the second argument is currently not used by FreeImage)
	fif = FreeImage_GetFileType(lpszPathName.c_str(), 0);
	if(fif == FIF_UNKNOWN) {
		// no signature ?
		// try to guess the file format from the file extension
		fif = FreeImage_GetFIFFromFilename(lpszPathName.c_str());
	}
	// check that the plugin has reading capabilities ...
	if((fif != FIF_UNKNOWN) && FreeImage_FIFSupportsReading(fif)) {
		// ok, let's load the file
		FIBITMAP *dib = FreeImage_Load(fif, lpszPathName.c_str(), flag);
		// unless a bad file format, we are done !
		return dib;
	}
	return NULL;
}

/** Generic image writer
	@param dib Pointer to the dib to be saved
	@param lpszPathName Pointer to the full file name
	@param flag Optional save flag constant
	@return Returns true if successful, returns false otherwise
*/
bool GenericWriter(FIBITMAP* dib, const core::stringc lpszPathName, int flag) {
	FREE_IMAGE_FORMAT fif = FIF_UNKNOWN;
	BOOL bSuccess = FALSE;

	if(dib) {
		// try to guess the file format from the file extension
		fif = FreeImage_GetFIFFromFilename(lpszPathName.c_str());
		if(fif != FIF_UNKNOWN ) {
			// check that the plugin has sufficient writing and export capabilities ...
			WORD bpp = FreeImage_GetBPP(dib);
			if(FreeImage_FIFSupportsWriting(fif) && FreeImage_FIFSupportsExportBPP(fif, bpp)) {
				// ok, we can save the file
				bSuccess = FreeImage_Save(fif, dib, lpszPathName.c_str(), flag);
				// unless an abnormal bug, we are done !
			}
		}
	}
	return (bSuccess == TRUE) ? true : false;
}

// ----------------------------------------------------------

//! constructor
CFreeImageLoader::CFreeImageLoader()
{
	#ifdef _DEBUG
	setDebugName("CImageFreeImageLoader");
	#endif
	// call this ONLY when linking with FreeImage as a static library
	#ifdef FREEIMAGE_LIB
	FreeImage_Initialise();	
	#endif // FREEIMAGE_LIB
}

CFreeImageLoader::~CFreeImageLoader()
{
	// call this ONLY when linking with FreeImage as a static library
	#ifdef FREEIMAGE_LIB
	FreeImage_DeInitialise();
	#endif // FREEIMAGE_LIB
}

//! returns true if the file maybe is able to be loaded by this class
//! based on the file extension (e.g. ".tga")
bool CFreeImageLoader::isALoadableFileExtension(const io::path& filename) const
{
	//image format	
	return core::hasFileExtension( filename, "bmp", "jpg", "tga" ) ||
	       core::hasFileExtension( filename, "pcx", "png", "gif" );
}


//! returns true if the file maybe is able to be loaded by this class
bool CFreeImageLoader::isALoadableFileFormat(io::IReadFile* file) const
{
	u16 headerID;
	if (!file)
		return false;

	file->read(&headerID, sizeof(u16));
	return false;
}


//! creates a surface from the file
//IImage* CFreeImageLoader::loadImage(const io::path& file) const;
IImage* CFreeImageLoader::loadImage(io::IReadFile* file) const
{	
	u8* data = new u8[file->getSize()];	
	s32 len = file->getPos();	
    FIMEMORY *mem = NULL;
    FIBITMAP *img = NULL;
    IImage* retval = 0;	

	FIBITMAP *dib = GenericLoader(file->getFileName(), 0);
	if(!dib) os::Printer::log("You have to use a range from 0 to 64 of FadeID", irr::ELL_ERROR);
		
        mem = FreeImage_OpenMemory((BYTE*)data, len);
        if (mem == 0)
			os::Printer::log("Unable to open memory stream, FreeImage_OpenMemory failed", irr::ELL_ERROR);

        FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(mem, len);

        if (fif == FIF_UNKNOWN) // it may be that it's TARGA or MNG
        {
            fif = FIF_TARGA;
            img = FreeImage_LoadFromMemory(fif, mem, 0);

            if (img == 0)
            {
                fif = FIF_MNG;
                img = FreeImage_LoadFromMemory(fif, mem, 0);
            }
        }
        else
            img = FreeImage_LoadFromMemory(fif, mem, 0);

        if (img == 0)
			os::Printer::log("Unable to load image, FreeImage_LoadFromMemory failed", irr::ELL_ERROR);

        FIBITMAP *newImg = FreeImage_ConvertTo32Bits(img);
        if (newImg == 0)
			os::Printer::log("Unable to convert image, FreeImage_ConvertTo32Bits failed", irr::ELL_ERROR);
        FreeImage_Unload(img);
        img = newImg;
        newImg = 0;

        // FreeImage pixel format for little-endian architecture (which CEGUI
        // supports) is like BGRA. We need to convert that to RGBA.
        //
        // It is now:
        // RED_MASK		0x00FF0000
        // GREEN_MASK	0x0000FF00
        // BLUE_MASK	0x000000FF
        // ALPHA_MASK	0xFF000000
        //
        // It should be:
        // RED_MASK		0x000000FF
        // GREEN_MASK	0x0000FF00
        // BLUE_MASK	0x00FF0000
        // ALPHA_MASK	0xFF000000

  			// read image
		u32 pitch = FreeImage_GetPitch(img);
		u32 height = FreeImage_GetHeight(img);
		u32 width = FreeImage_GetWidth(img);	
		u8 *rawBuf = new u8[width * height << 2];	

        // convert the bitmap to raw bits (top-left pixel first) 
        FreeImage_ConvertToRawBits(rawBuf, img, pitch, 32,
            FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, true);

        // We need to convert pixel format a little
        // NB: little endian only - I think(!)
#if FREEIMAGE_COLORORDER == FREEIMAGE_COLORORDER_BGR
        for (u32 i = 0; i < height; ++i)
        {
            for (u32 j = 0; j < width; ++j)
            {
                s32 p = *(((s32*)(rawBuf + i * pitch)) + j);
                s32 r = (p >> 16) & 0x000000FF;
                s32 b = (p << 16) & 0x00FF0000;
                p &= 0xFF00FF00;
                p |= r | b;
                // write the adjusted pixel back
                *(((s32*)(rawBuf + i * pitch)) + j) = p;
            }
        }
#endif
        FreeImage_Unload(img);
        img = 0;

		// no default constructor from packed area! ARM problem!
		core::dimension2d<u32> dim;
		dim.Width = width;
		dim.Height = height;

		IImage* image = 0;

		//image = new CImage(ECF_A8R8G8B8, dim, rawBuf);
		image = new CImage(ECF_A8R8G8B8, dim);
		if (image)
			CColorConverter::convert32BitTo32Bit((s32*)rawBuf, (s32*)image->lock(), width, height, pitch, true);
		
		if (image)
		image->unlock();		

		// clean up
        		
		delete [] rawBuf;

		if (img != 0) FreeImage_Unload(img);
		if (mem != 0) FreeImage_CloseMemory(mem);
	
	return image;
}


//! creates a loader which is able to load windows bitmaps
IImageLoader* createFreeImageLoader()
{
	return new CFreeImageLoader();
}

} // end namespace video
} // end namespace irr

#endif
I hope somebody maybe development this code.
Thanks
Post Reply