FreeImage for Java wrapper

Started by zapmya, May 02, 2009, 12:38:14

Previous topic - Next topic

zapmya

Hi,

I wrote a little Java wrapper for the FreeImage(http://freeimage.sourceforge.net/) library in order to use it with LWJGL for texture loading. Not all functions are wrapped but the most important ones are. This includes of course image loading and saving, some conversion functions and simple image manipulation like contrast and brightness adjustment, rotation and scaling. The garbage collector is taking care of no longer needed images. So you do not have to call "UnloadImage" or stuff like that to get back your memory. Here is a sample loadTexture method:

    private int loadTexture(String path) {

    	FreeImage fi = null;
    	try {
    		fi	= new FreeImage(new File(path));
    	} catch ( FreeImageException e ) {
    		e.printStackTrace();
    	}
    	if (fi.getBitsPerPixel() != 24 ) {
    		fi	= fi.convertTo24Bits();
    	}

        // Create A IntBuffer For Image Address In Memory
        IntBuffer buf = ByteBuffer.allocateDirect(4).order(ByteOrder.nativeOrder()).asIntBuffer();
        GL11.glGenTextures(buf); // Create Texture In OpenGL

        // Create MipMapped Texture
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, buf.get(0));
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
        GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR_MIPMAP_NEAREST);
        GLU.gluBuild2DMipmaps(GL11.GL_TEXTURE_2D, GL11.GL_RGB, fi.getWidth(),fi.getHeight(), GL12.GL_BGR, GL11.GL_UNSIGNED_BYTE, fi.getPixelBuffer());

        return int buf.get(0);     // Return TextureId
    }


Finally here are the links:

http://www.goto3d.de/freeimage4j/freeimage4j.jar (java classes)
http://www.goto3d.de/freeimage4j/freeimage4j.dll (win32 dll)
http://www.goto3d.de/freeimage4j/libfreeimage4j.so (linux x86_64 shared object)
http://www.goto3d.de/freeimage4j/freeimage4j-docs.zip (javadocs)
http://www.goto3d.de/freeimage4j/freeimage4j-src.zip (the complete source code)

If you want to build the source code by yourself please read the included README file.

Cheers!

quas4

hello,

freeimage is nice library and i'd like to use you port, but i think your swig binding has important bug.
Imagine simple jython example:

from de.goto3d.freeimage import FreeImage
print "hello world"


this script hang before end.

I'm not sure about java programming, but are you sure that you don't have to call FreeImage_DeInitialise() at the end inside wrapper?

zapmya

Hi quas4,

I know about this problem. At the end of your Java application you have to call

System.exit(0);


I don't know exactly how to do this in Python but there has to be a similar method. This is necessary because freeimage4j spawns a new thread that is listening on a so called "ReferenceQueue". The Garbage Collector pushes no longer needed references to FreeImage instances into this queue. This way freeimage4j can free no longer needed C memory by calling

FreeImage_Unload(..)


When your main method returns the main thread dies but not the FreeImage thread. Therefore your application does not shut down automatically. Maybe I could add a shutdown hook or something like that. I do remember the same problem occurred when building Swing applications because it also spawned a new thread polling the event queue. I don't know if this problem was solved or not. If anybody has an idea please let me know!

According to the FreeImage documentation (http://surfnet.dl.sourceforge.net/sourceforge/freeimage/FreeImage3120.pdf) FreeImage_Deinitialise does not have to be called when using the FreeImage library as DLL or SO. It is only needed when statically linking against it. So this should be ok.

zapmya

As some people seem to be interested in this library I started a project at sourceforge.net http://sourceforge.net/projects/freeimage4j/

broumbroum

Does freeimage feature a *magic* function to enhance pictures/photographics automatically ? i mean some process to make a scanned or an old picture lightened with color correction/recovery etc. that be interesting.

zapmya

As far as I know there is no such magic function. However there are functions for adjusting brightness, contrast and gamma values. Maybe this helps.

Rene

Quote from: zapmya on June 06, 2009, 16:46:23
Hi quas4,

I know about this problem. At the end of your Java application you have to call

System.exit(0);


I don't know exactly how to do this in Python but there has to be a similar method. This is necessary because freeimage4j spawns a new thread that is listening on a so called "ReferenceQueue". The Garbage Collector pushes no longer needed references to FreeImage instances into this queue. This way freeimage4j can free no longer needed C memory by calling

FreeImage_Unload(..)


When your main method returns the main thread dies but not the FreeImage thread. Therefore your application does not shut down automatically. Maybe I could add a shutdown hook or something like that. I do remember the same problem occurred when building Swing applications because it also spawned a new thread polling the event queue. I don't know if this problem was solved or not. If anybody has an idea please let me know!

How about you make the ReferenceQueue thread a daemon thread?

Thread t = new Thread();
t.setDaemon(true);
t.start();

Daemon-threads are killed when all non-daemon threads are finished.
When I am king, they shall not have bread and shelter only, but also teachings out of books, for a full belly is little worth where the mind is starved - Mark Twain

zapmya

Hi Rene,

that sounds like a proper solution. I will try it as soon as I find some spare time.

Thanks a lot!

I just ran a quick test and it works like a charm! Thanks again Rene. I have already committed the changes to the svn repository. I will update the precompiled binaries some days later.

Rene

No problem, glad I could help.  ;)

Just keep in mind that you can only call setDeamon() before you call start(). Also, if a deamon thread creates a new thread, it will be a daemon thread by default. If a non-daemon thread creates a  new thread, it will be a non-daemon thread by default.
When I am king, they shall not have bread and shelter only, but also teachings out of books, for a full belly is little worth where the mind is starved - Mark Twain