tiff_image_parse (TIFF *tiff, TiffContext *context, GError **error)
{
	guchar *pixels = NULL;
	guchar *tmppix;
	uint32 *rast, *tmp_rast;
	gint w, h, x, y, num_pixs;
	GdkPixbuf *pixbuf;

        /* We're called with the lock held. */
        
        g_return_val_if_fail (global_error == NULL, NULL);

	if (!TIFFGetField (tiff, TIFFTAG_IMAGEWIDTH, &w) || global_error) {
                tiff_set_error (error,
                                GDK_PIXBUF_ERROR_FAILED,
                                _("Could not get image width (bad TIFF file)"));
                return NULL;
        }
        
        if (!TIFFGetField (tiff, TIFFTAG_IMAGELENGTH, &h) || global_error) {
                tiff_set_error (error,
                                GDK_PIXBUF_ERROR_FAILED,
                                _("Could not get image height (bad TIFF file)"));
                return NULL;
        }

	num_pixs = w * h;

        if (num_pixs == 0) {
                g_set_error (error,
                             GDK_PIXBUF_ERROR,
                             GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
                             _("Width or height of TIFF image is zero"));
                return NULL;                
        }
        
	pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, w, h);
        if (!pixbuf) {
                g_set_error (error,
                             GDK_PIXBUF_ERROR,
                             GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
                             _("Insufficient memory to open TIFF file"));
                return NULL;
        }


        G_UNLOCK (tiff_loader);
	if (context)
		(* context->prepare_func) (pixbuf, NULL, context->user_data);
        G_LOCK (tiff_loader);
        
	/* Yes, it needs to be _TIFFMalloc... */
        rast = (uint32 *) _TIFFmalloc (num_pixs * sizeof (uint32));
	if (!rast) {
                g_set_error (error,
                             GDK_PIXBUF_ERROR,
                             GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
                             _("Insufficient memory to open TIFF file"));
                return NULL;
	}
        
	if (!TIFFReadRGBAImage (tiff, w, h, rast, 0) || global_error) {
                tiff_set_error (error,
                                GDK_PIXBUF_ERROR_FAILED,
                                _("Failed to load RGB data from TIFF file"));
                _TIFFfree (rast);

                return NULL;
        }
        
        pixels = gdk_pixbuf_get_pixels (pixbuf);
        
        g_assert (pixels);
        
        tmppix = pixels;
        
        for (y = 0; y < h; y++) {
                /* Unexplainable...are tiffs backwards? */
                /* Also looking at the GIMP plugin, this
                 * whole reading thing can be a bit more
                 * robust.
                 */
                tmp_rast = rast + ((h - y - 1) * w);
                for (x = 0; x < w; x++) {
                        tmppix[0] = TIFFGetR (*tmp_rast);
                        tmppix[1] = TIFFGetG (*tmp_rast);
                        tmppix[2] = TIFFGetB (*tmp_rast);
                        tmppix[3] = TIFFGetA (*tmp_rast);
                        tmp_rast++;
                        tmppix += 4;
                }
        }

        _TIFFfree (rast);

        G_UNLOCK (tiff_loader);
	if (context)
		(* context->update_func) (pixbuf, 0, 0, w, h, context->user_data);
        G_LOCK (tiff_loader);
        
        return pixbuf;
}