Help using libtiff with Blender

Compiling, libraries, modules, coding guidelines and porting

Moderators: jesterKing, stiv

Post Reply
LethalSideParting
Posts: 71
Joined: Mon Oct 21, 2002 12:53 am
Location: Bucks, England

Help using libtiff with Blender

Post by LethalSideParting » Thu Jun 24, 2004 11:49 pm

Hiya guys,
Well I've finally taken the plunge and have started tinkering about with Blender :D. I decided to try and code in TIFF image support after reading the readme in source/blender/imbuf/ about how you code in new image formats... After a bit of research into the format I decided to use libtiff for all the grunt-work of loading / saving the images.

Anyway, down to the point, in the readme that I mentioned about adding in new image formats, it mentions the following:
Step 1:
create a new file named after the format for example lets say we were
creating an openexr read/writer use openexr.c
It should contain functions to match the following prototypes:

struct ImBuf *imb_loadopenexr(unsigned char *mem,int size,int flags);
...
Coding in a save function was easy enough, but when writing my tiff loading function I ran into problems. As far as I can tell, when loading in an image, Blender loads the contents of the image file into memory first, then tries to work out what type it is, then calls that particular type's load function (eg img_loadtiff) and gives it a pointer to the memory where the image file was loaded in. This is a problem when trying to code something that uses libtiff, because according to the libtiff documents I've read (both the man page and IBM DeveloperWorks) pretty much all libtiff functions that I'd be using to load the tiff in need a special "TIFF handle", which you get using the following:

Code: Select all

TIFF* outputFile = TIFFOpen("output.tif", "w");
The problem is that TIFFOpen() needs the filename, but Blender doesn't give my function the filename, it just gives a pointer to a location in memory where the file is already loaded in :( So, does anyone have any suggestions here? For example, is there a way to get Blender to pass my function the filename instead? (it seems that there are some functions in jpeg.c that do this, but I had a look in writeimage.c to see how this happens, but I don't have a clue!) Does anyone understand how the code in writeimage.c works, and how to coax it into giving my function a filename instead? Or, is there a way that I could use the libtiff functions on the data in memory instead of having to give them a TIFF handle? I've searched the forum and the web, but have found nothing...

Sorry for the long post, thanks for any help you can give me guys!

LethalSideParting

alien-xmp
Posts: 0
Joined: Sun Apr 06, 2003 2:22 pm
Location: Wellington, New Zealand
Contact:

Post by alien-xmp » Sat Jun 26, 2004 11:32 am

TIFFClientOpen is what you want - you supply the read, write, and other file system emulation functions to read the file. (The PNG reader does this too.)

The thing is, the image may be packed into a .blend file, and there may not be a filename for the image.

LethalSideParting
Posts: 71
Joined: Mon Oct 21, 2002 12:53 am
Location: Bucks, England

Post by LethalSideParting » Sat Jun 26, 2004 8:32 pm

Thanks alien-xmp!

Yeah, I've spent most of today looking over the source code for dealing with images and started to come to the same conclusion myself... I found load_image() and realised that it's not just a case of trying to get a filename - like you said, there might not always be one if the image is being loaded in from a packed blend file (I'd completely forgotten about that feature, dammit...). I had also been thinking about saving out the memory contents to a temporary TIFF file and then reading it back in, but compared to the TIFFClientOpen method that's just plain ugly ;)

Thanks again! *runs off and starts coding wildly*

phase
Posts: 83
Joined: Mon Oct 14, 2002 1:59 pm

Post by phase » Thu Jul 01, 2004 4:59 pm

I got a piece of code lying around that allows blender to load images
through Imagemagick... maybe you're interested, then i'll dig it up for you.
Since Imagemagick was a beast to install/compile for windows i didn't
proceed the development and focused on Quicktime instead.
I know... not that friendly to *nix users :wink:

LethalSideParting
Posts: 71
Joined: Mon Oct 21, 2002 12:53 am
Location: Bucks, England

Post by LethalSideParting » Thu Jul 01, 2004 10:50 pm

Ooh, that sounds very useful indeed phase, thank you :D ... I wouldn't say no to having a look at that, if it's not too much trouble! I'm interested to see how code for something like that would tie in with Blender, if only for curiosity's sake.

Speaking of curiosity, why didnt you commit the Imagemagick code to Blender anyway, with some code to make it *nix only? After all, while Imagemagick might be a pain to compile on Windows, Quicktime is pretty much impossible to compile on *nix ;).....

phase
Posts: 83
Joined: Mon Oct 14, 2002 1:59 pm

Post by phase » Fri Jul 02, 2004 9:31 pm

Here is a zipfile with the corresponding files, the code can be found
in the first tuhopuu cvs as well.
http://www.captainvideo.nl/rob/imagick_imbuf.zip

Search the files for build flag WITH_IMAGEMAGICK to see what
additions were made to the Blender code. Note that this code only
allows loading images through Imagemagick, there is no export
functionality.

At some point Sirdude succesfully wrote code so Blender could save
rendered images through Imagemagick, but this never made it to cvs.
I guess we were both afraid to write the complex export userinterface
that is required for exporting to this many different image formats.

Nevertheless, when you integrate this code in Blender and link with the
required Imagemagick libs, it all should work. This part of the Blender
sourcecode didn't change much since it went opensource.
Hope it suits you... do with it as you please :D

LethalSideParting
Posts: 71
Joined: Mon Oct 21, 2002 12:53 am
Location: Bucks, England

Post by LethalSideParting » Sat Jul 10, 2004 1:49 am

Aw brilliant, thanks very much phase :D! Grabbed it, compiled it, worked a charm, though I can see what you mean about the Windows side of things causing difficulties... (trying to open the image a second time if it fails the first time being a prime example...)

There's one question I'd like to ask you about the code, if I may... In imagemagick.c, I noticed the following code:

Code: Select all

if (flags & IB_test) {
    ibuf = IMB_allocImBuf(x, y, depth, 0, 0);
} else {
....
I've seen this a lot in all the various image importers, but I have no idea what it's actually there for. I've looked through all the image formats, and whilst they all do something similar none of them have comments explaining what it's there for (not to mention that my TIFF code works fine without it). I've also looked at the code for IMB_allocImBuf(), but all I could really tell is that this way of calling IMB_allocImBuf won't allocate any space for the image itself to be stored in... Looking up IB_test also yielded more questions that it answered. So, do you know what that code's there for?
Thanks again!

LethalSideParting

phase
Posts: 83
Joined: Mon Oct 14, 2002 1:59 pm

Post by phase » Sun Jul 11, 2004 12:59 pm

LethalSideParting wrote:There's one question I'd like to ask you about the code, if I may... In imagemagick.c, I noticed the following code:

Code: Select all

if (flags & IB_test) {
    ibuf = IMB_allocImBuf(x, y, depth, 0, 0);
} else {
....
I've seen this a lot in all the various image importers, but I have no idea what it's actually there for. I've looked through all the image formats, and whilst they all do something similar none of them have comments explaining what it's there for (not to mention that my TIFF code works fine without it).
The IB_test variable in the code above says it all, it is a test call to see
if the imagebuffer is valid, and what it's dimensions are.
Afaik the only place where it is used is in the image thumbnail browser.
I predict you get weird display artifacts when you use the thumbnail
browser with your libtiff implementation. :D

*edit: Found a pic to show what happens when you leave out the IB_test:
http://www.captainvideo.nl/rob/dump/doh.jpg

LethalSideParting
Posts: 71
Joined: Mon Oct 21, 2002 12:53 am
Location: Bucks, England

Post by LethalSideParting » Mon Sep 13, 2004 10:59 pm

Many thanks for your help Phase, this is really starting to get somewhere now, almost to the point where I might be able to submit a patch (!)... I've got TIFF reading and writing pretty much sorted out (B&W, RGB and RGBA), and on Linux it all works pretty well. I'm trying to get a Cygwin environment up and running so I can check it works on Windows, but I'm not terribly worried about that to be honest....

In fact the only thing that's stopping me submitting it is two small issues:

1) I cant get the image browser to recognise TIFF files and display a preview. I've checked my code by putting some printf's in there, and it's not that the TIFF loading code is wrong, but that it's never called in the first place. I've checked the readme on what files you need to edit to add new image support, but it isnt in any of the files mentioned there... I've also searched the whole source tree, but couldnt find anything helpful... So does anyone know how/where the image browser calls the image loader from?

2) In files like the JPEG loader, you've got "#ifndef WITH_JPEG" in there to stop Blender *needing* libjpeg. I was gonna do the same thing, except that I dont know where "WITH_JPEG" and the like are "#define"ed in the first place, and a search revealed nothing. Does anyone know?

Thanks for any help!!

LethalSideParting

theeth
Posts: 500
Joined: Wed Oct 16, 2002 5:47 am
Location: Montreal
Contact:

Post by theeth » Mon Sep 13, 2004 11:10 pm

1) The formats are probably defined in the image selection code directly (imasel.c I *think*)

2) Those would be makefiles/scons/<insert building engine> options more than likely.

Martin
Life is what happens to you when you're busy making other plans.
- John Lennon

phase
Posts: 83
Joined: Mon Oct 14, 2002 1:59 pm

Post by phase » Tue Sep 14, 2004 3:16 pm

LethalSideParting wrote:1) I cant get the image browser to recognise TIFF files and display a preview. I've checked my code by putting some printf's in there, and it's not that the TIFF loading code is wrong, but that it's never called in the first place. I've checked the readme on what files you need to edit to add new image support, but it isnt in any of the files mentioned there... I've also searched the whole source tree, but couldnt find anything helpful... So does anyone know how/where the image browser calls the image loader from?
Well... that would be the call to IMB_loadiffname(...) at line 529 in src\imasel.c.

Then IMB_loadiffname(...) calls IMB_loadifffile(...) which loads the entire file in RAM
and then calls IMB_ibImageFromMemory(...). These are all in imbuf\intern\readimage.c.
Your libtiff imageloader routine should go in IMB_ibImageFromMemory(...) if you want
thumbnails in the imagebrowser.

Pretty weird that the imagebrowser doesn't use the recognition routines in
imbuf\intern\util.c. Guess that's why it is disabled by default... :)

*edit: seems that the imagebrowser *does* use the recog stuff from util.c
Dunno what might be wrong then, i shoud see your code.
Maybe add the .tiff extension to util.c ?

LethalSideParting
Posts: 71
Joined: Mon Oct 21, 2002 12:53 am
Location: Bucks, England

Post by LethalSideParting » Thu Sep 16, 2004 8:21 pm

*edit: seems that the imagebrowser *does* use the recog stuff from util.c
Dunno what might be wrong then, i shoud see your code.
Maybe add the .tiff extension to util.c ?
Aha, yup, that's exactly where the problem was. I had no idea that anything had to be coded into util.c - the readme about adding new image formats never mentioned it, so I never looked... It was only when I took a second look at your imagemagick code that I worked out what I'd missed :oops: Ah well, I'm an idiot :D

Anyway, I've updated the readme to reflect this. Image browser now works perfectly, I'm pleased to say, thanks again guys! Getting there...

phase
Posts: 83
Joined: Mon Oct 14, 2002 1:59 pm

Post by phase » Fri Sep 17, 2004 11:58 am

LethalSideParting wrote:Aha, yup, that's exactly where the problem was. I had no idea that anything had to be coded into util.c - the readme about adding new image formats never mentioned it, so I never looked... It was only when I took a second look at your imagemagick code that I worked out what I'd missed :oops: Ah well, I'm an idiot :D
Heh, not at all. I'm glad you sorted it out.

SirDude
Posts: 233
Joined: Sun Oct 13, 2002 7:37 pm
Location: University of Minnesota (USA)
Contact:

Post by SirDude » Fri Sep 17, 2004 1:32 pm

I'll update the readme :)

Sorry I didn't have to do that with bmp because it was already
in there. I just wrote the readme as I went to make it
easier for other people.

LethalSideParting
Posts: 71
Joined: Mon Oct 21, 2002 12:53 am
Location: Bucks, England

Post by LethalSideParting » Sat Sep 18, 2004 3:19 pm

No need to apologise, the readme's been an absolute godsend to me actually, I dont think I would've even gotten started without it!! :D

Post Reply