Re: libgdk_pixbuf, VC++ and TIFF files.



On 30 Nov 2010, at 15:47, John Emmas wrote:

gdk_pixbuf_new_from_file() opens the specified file using g_fopen() which in turn, calls _wfopen().  This 
returns a FILE*.  Next, _gdk_pixbuf_generic_image_load() gets used to read the subsequent TIFF data.  That 
process starts with the FILE* getting sent to _fileno() which returns a 'C' run time file handle.  That 
file handle eventually gets passed to TIFFFdOpen() which in turn, calls TIFFClientOpen() to read in the 
TIFF header.

Unfortunately, the Win32 version tries to read the TIFF header courtesy of the Windows function 
'ReadFile()'.  AFAIK, ReadFile() will only accept file handles returned from CreateFile() - not from 
fopen() or _wfopen().  Consequently, libgdk_pixbuf fails to read the TIFF data (on Win32/VC++) because it 
used g_fopen() to open the file, instead of using TIFF's own TIFFOpen() function, which would have opened 
the file using CreateFile()


After posting a question on the libTIFF mailing list I discovered that there were already some POSIX style 
file handlers available (read() / write() etc) that I could use instead of the Win32 ones.  This solved my 
problem but it threw up another problem in the TIFF handler for libgdk-pixbuf, namely in the module 
'io-tiff.c'.  Here's the relevant section from the function  'gdk_pixbuf__tiff_image_load()'  (not sure if my 
formatting will work via the mailing list):-


static GdkPixbuf*
gdk_pixbuf__tiff_image_load (FILE *f, GError **error) 
{ 
TIFF *tiff; 
int fd; 
GdkPixbuf *pixbuf; 

      [ ... ]

      fd = fileno (f); 

      tiff = TIFFFdOpen (fd, "libpixbuf-tiff", "r"); 

      if (!tiff || global_error) { 
            tiff_set_error (error, 
            GDK_PIXBUF_ERROR_CORRUPT_IMAGE, 
            _("Failed to open TIFF image")); 
            tiff_pop_handlers (); 
            return NULL; 
      } 

      pixbuf = tiff_image_parse (tiff, NULL, error); 

      TIFFClose(tiff);

      [ ... ]

      return pixbuf;
} 

The important thing to note is that TIFFFdOpen() does not actually open a file.  The file must have already 
been opened by some external process, prior to calling the above function.  However, TIFFClose() does in fact 
close the file.  This means that when the external process tries to close it, there's a risk of it crashing 
or asserting.  AFAICT the call to TIFFClose(tiff); should really have been TIFFCleanup(tiff);

I tried substituting the alternative function and it seemed to fix the problem.  This needs to be fixed quite 
urgently in libgdk-pixbuf because if it's currently working on any given compiler, it's purely by luck..!

John


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]