]> Pileus Git - ~andy/gtk/commitdiff
Bump libtiff requirement to 3.6.0, by requiring presence of
authorMichael J. Chudobiak <mjc@cvs.gnome.org>
Fri, 18 May 2007 14:19:47 +0000 (14:19 +0000)
committerMichael J. Chudobiak <mjc@src.gnome.org>
Fri, 18 May 2007 14:19:47 +0000 (14:19 +0000)
2007-05-18  Michael J. Chudobiak  <mjc@cvs.gnome.org>

        * INSTALL.in:
        * README.in:
        * configure.in: Bump libtiff requirement to 3.6.0, by requiring
          presence of TIFFReadRGBAImageOriented.

        * gdk-pixbuf-scaled-anim.c: (get_scaled_pixbuf):
        Preserve pixbuf options when generating a new scaled pixbuf.

        * io-jpeg.c: (get_orientation), (gdk_pixbuf__jpeg_image_load),
        (gdk_pixbuf__jpeg_image_load_increment): Read the exif
        orientation tag and associate it with the "orientation" pixbuf
        option. Renders libexif unnecessary in some applications.

        * io-tiff.c: (tiff_image_parse): Read the tiff orientation tag,
        compensate for the partial rotations performed by libtiff,
        and generate an "orientation" option for the pixbuf.

svn path=/trunk/; revision=17863

ChangeLog
INSTALL
INSTALL.in
README.in
configure.in
gdk-pixbuf/ChangeLog
gdk-pixbuf/gdk-pixbuf-scaled-anim.c
gdk-pixbuf/io-jpeg.c
gdk-pixbuf/io-tiff.c

index fa4a83404085f0f5246bc046d73701ad44014a16..5fee42cbf88744a0c0084cc70dc3834aef3a7f77 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,22 @@
+2007-05-18  Michael J. Chudobiak  <mjc@cvs.gnome.org>
+
+       * INSTALL.in:
+       * README.in:
+       * configure.in: Bump libtiff requirement to 3.6.0, by requiring
+         presence of TIFFReadRGBAImageOriented.
+
+        * gdk-pixbuf-scaled-anim.c: (get_scaled_pixbuf):
+        Preserve pixbuf options when generating a new scaled pixbuf.
+
+        * io-jpeg.c: (get_orientation), (gdk_pixbuf__jpeg_image_load),
+        (gdk_pixbuf__jpeg_image_load_increment): Read the exif
+        orientation tag and associate it with the "orientation" pixbuf
+        option. Renders libexif unnecessary in some applications.
+
+        * io-tiff.c: (tiff_image_parse): Read the tiff orientation tag,
+        compensate for the partial rotations performed by libtiff,
+        and generate an "orientation" option for the pixbuf.
+
 2007-05-18  Carlos Garnacho  <carlos@imendio.com>
 
        * gtk/gtkexpander.c: remove c++ style comment.
diff --git a/INSTALL b/INSTALL
index 2be180e9a4887c57c746a5f673bbb4f27054e2e1..cf80c2fae226fa15f34189038c84b3dcc9f9b729 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -15,6 +15,8 @@ GTK+ requires the following packages:
     http://www.libpng.org/
     http://www.ijg.org/
 
+    libtiff must be version 3.6.0 or higher.
+
 Simple install procedure
 ========================
 
index 9d149238d3602ef537f5d931c23ce4b46c23f476..742d782803d9f0860f4fb3bcfb4cd2d138fd05b9 100644 (file)
@@ -15,6 +15,8 @@ GTK+ requires the following packages:
     http://www.libpng.org/
     http://www.ijg.org/
 
+    libtiff must be version 3.6.0 or higher.
+
 Simple install procedure
 ========================
 
index cf6b373bcf8ac45c76d276aae9be0b05ac211670..302696e4a916ad4e1a38f39cb7228742ceeb56b4 100644 (file)
--- a/README.in
+++ b/README.in
@@ -37,6 +37,8 @@ Release notes for 2.12
 Release notes for 2.10
 ======================
 
+* The tiff loader now requires libtiff 3.6.0 or later.
+
 * The hexadecimal Unicode input feature has been reworked. It no longer
   blocks the use of the sixteen Ctrl-Shift-<hex digit> key sequences. Now
   it only uses Ctrl-Shift-u.
index 99371439c588cc0ee0c430c247d8141073d72f2e..f95973663030e0bef2a631e20244946b3db8e51f 100644 (file)
@@ -747,7 +747,7 @@ AC_ARG_WITH(libtiff,
 
 dnl Test for libtiff
   if test x$with_libtiff != xno && test -z "$LIBTIFF"; then
-    AC_CHECK_LIB(tiff, TIFFReadScanline,
+    AC_CHECK_LIB(tiff, TIFFReadRGBAImageOriented,
       [AC_CHECK_HEADER(tiffio.h,
         TIFF='tiff'; LIBTIFF='-ltiff',
         AC_MSG_WARN(*** TIFF loader will not be built (TIFF header files not found) ***))],
index df7c7461c53f541fe9afeae07c1f9b0b60d9b6eb..029793c14fc3181c92881326391becd2b705bf43 100644 (file)
@@ -1,3 +1,17 @@
+2007-05-18  Michael J. Chudobiak  <mjc@cvs.gnome.org>
+
+       * gdk-pixbuf-scaled-anim.c: (get_scaled_pixbuf):
+       Preserve pixbuf options when generating a new scaled pixbuf.
+
+       * io-jpeg.c: (get_orientation), (gdk_pixbuf__jpeg_image_load),
+       (gdk_pixbuf__jpeg_image_load_increment): Read the exif
+       orientation tag and associate it with the "orientation" pixbuf
+       option. Renders libexif unnecessary in some applications.
+
+       * io-tiff.c: (tiff_image_parse): Read the tiff orientation tag,
+       compensate for the partial rotations performed by libtiff,
+       and generate an "orientation" option for the pixbuf.
+
 2007-04-29  Matthias Clasen <mclasen@redhat.com>
 
        * io-jpeg.c: Remove a pointless check from the previous
index 1a848f3c6308b3504412e92199e7c9f66cbf7ee4..26f105bd380239b3e73b8e1c7b9766d1ee1abb09 100644 (file)
@@ -121,14 +121,32 @@ static GdkPixbuf *
 get_scaled_pixbuf (GdkPixbufScaledAnim *scaled, 
                    GdkPixbuf           *pixbuf)
 {
+       GQuark  quark;
+       gchar **options;
+
        if (scaled->current) 
                g_object_unref (scaled->current);
 
+       /* Preserve the options associated with the original pixbuf 
+          (if present), mostly so that client programs can use the
+          "orientation" option (if present) to rotate the image 
+          appropriately. gdk_pixbuf_scale_simple (and most other
+           gdk transform operations) does not preserve the attached
+           options when returning a new pixbuf. */
+
+       quark = g_quark_from_static_string ("gdk_pixbuf_options");
+       options = g_object_get_qdata (G_OBJECT (pixbuf), quark);
+
+       /* Get a new scaled pixbuf */
        scaled->current  = gdk_pixbuf_scale_simple (pixbuf, 
                        (int) (gdk_pixbuf_get_width (pixbuf) * scaled->xscale),
                        (int) (gdk_pixbuf_get_height (pixbuf) * scaled->yscale),
                        GDK_INTERP_BILINEAR);
 
+       /* Copy the original pixbuf options to the scaled pixbuf */
+        if (options && scaled->current)
+                 g_object_set_qdata (G_OBJECT (scaled->current), quark, g_strdupv (options));
+
        return scaled->current;
 }
 
index 1df2b813cac8edd34317fe0ace347a3ceb0c2967..6a1fde0b1e3bb37b0ca7c21d12ed14aea296341c 100644 (file)
@@ -277,11 +277,161 @@ colorspace_name (const J_COLOR_SPACE jpeg_color_space)
        }
 }
 
+
+const char leth[]  = {0x49, 0x49, 0x2a, 0x00}; // Little endian TIFF header
+const char beth[]  = {0x4d, 0x4d, 0x00, 0x2a}; // Big endian TIFF header
+const char types[] = {0x00, 0x01, 0x01, 0x02, 0x04, 0x08, 0x00, 
+                     0x08, 0x00, 0x04, 0x08};  // size in bytes for EXIF types
+#define DE_ENDIAN16(val) endian == G_BIG_ENDIAN ? GUINT16_FROM_BE(val) : GUINT16_FROM_LE(val)
+#define DE_ENDIAN32(val) endian == G_BIG_ENDIAN ? GUINT32_FROM_BE(val) : GUINT32_FROM_LE(val)
+#define ENDIAN16_IT(val) endian == G_BIG_ENDIAN ? GUINT16_TO_BE(val) : GUINT16_TO_LE(val)
+#define ENDIAN32_IT(val) endian == G_BIG_ENDIAN ? GUINT32_TO_BE(val) : GUINT32_TO_LE(val)
+#define EXIF_JPEG_MARKER   JPEG_APP0+1
+#define EXIF_IDENT_STRING  "Exif\000\000"
+
+static gint 
+get_orientation (j_decompress_ptr cinfo)
+{
+       /* This function looks through the meta data in the libjpeg decompress structure to
+          determine if an EXIF Orientation tag is present and if so return its value (1-8). 
+          If no EXIF Orientation tag is found 0 (zero) is returned. */
+
+       guint   i;              /* index into working buffer */
+       guint   orient_tag_id;  /* endianed version of orientation tag ID */
+       guint   ret;            /* Return value */
+       guint   offset;         /* de-endianed offset in various situations */
+       guint   tags;           /* number of tags in current ifd */
+       guint   type;           /* de-endianed type of tag used as index into types[] */
+       guint   count;          /* de-endianed count of elements in a tag */
+        guint   tiff = 0;      /* offset to active tiff header */
+        guint   endian = 0;    /* detected endian of data */
+
+       jpeg_saved_marker_ptr exif_marker;  /* Location of the Exif APP1 marker */
+       jpeg_saved_marker_ptr cmarker;      /* Location to check for Exif APP1 marker */
+
+       /* check for Exif marker (also called the APP1 marker) */
+       exif_marker = NULL;
+       cmarker = cinfo->marker_list;
+       while (cmarker) {
+               if (cmarker->marker == EXIF_JPEG_MARKER) {
+                       /* The Exif APP1 marker should contain a unique
+                          identification string ("Exif\0\0"). Check for it. */
+                       if (!memcmp (cmarker->data, EXIF_IDENT_STRING, 6)) {
+                               exif_marker = cmarker;
+                               }
+                       }
+               cmarker = cmarker->next;
+       }
+         
+       /* Did we find the Exif APP1 marker? */
+       if (exif_marker == NULL)
+               return 0;
+
+       /* Do we have enough data? */
+       if (exif_marker->data_length < 32)
+               return 0;
+
+        /* Check for TIFF header and catch endianess */
+       i = 0;
+
+       /* Just skip data until TIFF header - it should be within 16 bytes from marker start.
+          Normal structure relative to APP1 marker -
+               0x0000: APP1 marker entry = 2 bytes
+               0x0002: APP1 length entry = 2 bytes
+               0x0004: Exif Identifier entry = 6 bytes
+               0x000A: Start of TIFF header (Byte order entry) - 4 bytes  
+                       - This is what we look for, to determine endianess.
+               0x000E: 0th IFD offset pointer - 4 bytes
+
+               exif_marker->data points to the first data after the APP1 marker
+               and length entries, which is the exif identification string.
+               The TIFF header should thus normally be found at i=6, below,
+               and the pointer to IFD0 will be at 6+4 = 10.
+       */
+                   
+       while (i < 16) {
+               /* Little endian TIFF header */
+               if (memcmp (&exif_marker->data[i], leth, 4) == 0){ 
+                       endian = G_LITTLE_ENDIAN;
+                }
+               /* Big endian TIFF header */
+               else if (memcmp (&exif_marker->data[i], beth, 4) == 0){ 
+                       endian = G_BIG_ENDIAN;
+                }
+               /* Keep looking through buffer */
+               else {
+                       i++;
+                       continue;
+               }
+               /* We have found either big or little endian TIFF header */
+               tiff = i;
+               break;
+        }
+
+       /* So did we find a TIFF header or did we just hit end of buffer? */
+       if (tiff == 0) 
+               return 0;
+        /* Endian the orientation tag ID, to locate it more easily */
+        orient_tag_id = ENDIAN16_IT(0x112);
+        /* Read out the offset pointer to IFD0 */
+        offset  = DE_ENDIAN32(*((unsigned long*) (&exif_marker->data[i] + 4)));
+       i       = i + offset;
+
+       /* Check that we still are within the buffer and can read the tag count */
+       if ((i + 2) > exif_marker->data_length)
+               return 0;
+
+       /* Find out how many tags we have in IFD0. As per the TIFF spec, the first
+          two bytes of the IFD contain a count of the number of tags. */
+       tags    = DE_ENDIAN16(*((unsigned short*) (&exif_marker->data[i])));
+       i       = i + 2;
+
+       /* Check that we still have enough data for all tags to check. The tags
+          are listed in consecutive 12-byte blocks. The tag ID, type, size, and
+          a pointer to the actual value, are packed into these 12 byte entries. */
+       if ((i + tags * 12) > exif_marker->data_length)
+               return 0;
+
+       /* Check through IFD0 for tags of interest */
+       while (tags--){
+               type   = DE_ENDIAN16(*((unsigned short*)(&exif_marker->data[i + 2])));
+               count  = DE_ENDIAN32(*((unsigned long*) (&exif_marker->data[i + 4])));
+
+               /* Is this the orientation tag? */
+               if (memcmp (&exif_marker->data[i], (char *) &orient_tag_id, 2) == 0){ 
+                       /* Check that type and count fields are OK. The orientation field 
+                          will consist of a single (count=1) 2-byte integer (type=3). */
+                       if (type != 3 || count != 1) return 0;
+
+                       /* Return the orientation value. Within the 12-byte block, the
+                          pointer to the actual data is at offset 8. */
+                       ret = DE_ENDIAN16(*((unsigned short*) (&exif_marker->data[i + 8])));
+                       return ret <= 8 ? ret : 0;
+               }
+               /* move the pointer to the next 12-byte tag field. */
+               i = i + 12;
+       }
+
+       return 0; /* No EXIF Orientation tag found */
+}
+
+
 /* Shared library entry point */
 static GdkPixbuf *
 gdk_pixbuf__jpeg_image_load (FILE *f, GError **error)
 {
-       gint i;
+       gint   i;
+       int     is_otag;
+       char   otag_str[5];
        GdkPixbuf * volatile pixbuf = NULL;
        guchar *dptr;
        guchar *lines[4]; /* Used to expand rows, via rec_outbuf_height, 
@@ -332,7 +482,12 @@ gdk_pixbuf__jpeg_image_load (FILE *f, GError **error)
        src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
        src->pub.next_input_byte = NULL; /* until buffer loaded */
 
+       jpeg_save_markers (&cinfo, EXIF_JPEG_MARKER, 0xffff);
        jpeg_read_header (&cinfo, TRUE);
+
+       /* check for orientation tag */
+       is_otag = get_orientation (&cinfo);
+       
        jpeg_start_decompress (&cinfo);
        cinfo.do_fancy_upsampling = FALSE;
        cinfo.do_block_smoothing = FALSE;
@@ -357,6 +512,13 @@ gdk_pixbuf__jpeg_image_load (FILE *f, GError **error)
                return NULL;
        }
 
+       /* if orientation tag was found set an option to remember its value */
+       if (is_otag) {
+               snprintf (otag_str, sizeof (otag_str), "%d", is_otag);
+               gdk_pixbuf_set_option (pixbuf, "orientation", otag_str);
+       }
+
+
        dptr = pixbuf->pixels;
 
        /* decompress all the lines, a few at a time */
@@ -626,14 +788,16 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data,
                                        GError **error)
 {
        JpegProgContext *context = (JpegProgContext *)data;
-       struct jpeg_decompress_struct *cinfo;
-       my_src_ptr  src;
-       guint       num_left, num_copy;
-       guint       last_bytes_left;
-       guint       spinguard;
-       gboolean    first;
-       const guchar *bufhd;
-       gint        width, height;
+       struct           jpeg_decompress_struct *cinfo;
+       my_src_ptr       src;
+       guint            num_left, num_copy;
+       guint            last_bytes_left;
+       guint            spinguard;
+       gboolean         first;
+       const guchar    *bufhd;
+       gint             width, height;
+        int              is_otag;
+       char             otag_str[5];
 
        g_return_val_if_fail (context != NULL, FALSE);
        g_return_val_if_fail (buf != NULL, FALSE);
@@ -707,7 +871,8 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data,
                /* try to load jpeg header */
                if (!context->got_header) {
                        int rc;
-                       
+               
+                       jpeg_save_markers (cinfo, EXIF_JPEG_MARKER, 0xffff);
                        rc = jpeg_read_header (cinfo, TRUE);
                        context->src_initialized = TRUE;
                        
@@ -715,7 +880,10 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data,
                                continue;
                        
                        context->got_header = TRUE;
-                       
+
+                       /* check for orientation tag */
+                       is_otag = get_orientation (cinfo);
+               
                        width = cinfo->image_width;
                        height = cinfo->image_height;
                        if (context->size_func) {
@@ -751,7 +919,13 @@ gdk_pixbuf__jpeg_image_load_increment (gpointer data,
                                              _("Couldn't allocate memory for loading JPEG file"));
                                 return FALSE;
                        }
-                       
+               
+                       /* if orientation tag was found set an option to remember its value */
+                       if (is_otag) {
+                               snprintf (otag_str, sizeof (otag_str), "%d", is_otag);
+                               gdk_pixbuf_set_option (context->pixbuf, "orientation", otag_str);
+                       }
+
                        /* Use pixbuf buffer to store decompressed data */
                        context->dptr = context->pixbuf->pixels;
                        
index 79e8ef2c60fac91f455e20b0bc0fd05105c72440..a9863e6cffb2fd8eb2a36c8896170e63fa51d3f6 100644 (file)
@@ -141,27 +141,14 @@ static void free_buffer (guchar *pixels, gpointer data)
        g_free (pixels);
 }
 
-#if TIFFLIB_VERSION >= 20031226
-static gboolean tifflibversion (int *major, int *minor, int *revision)
-{
-        if (sscanf (TIFFGetVersion(), 
-                    "LIBTIFF, Version %d.%d.%d", 
-                    major, minor, revision) < 3)
-                return FALSE;
-
-        return TRUE;
-}
-#endif
-
 static GdkPixbuf *
 tiff_image_parse (TIFF *tiff, TiffContext *context, GError **error)
 {
        guchar *pixels = NULL;
        gint width, height, rowstride, bytes;
        GdkPixbuf *pixbuf;
-#if TIFFLIB_VERSION >= 20031226
-        gint major, minor, revision;
-#endif
+       uint16 orientation = 0;
+       uint16 transform = 0;
 
         /* We're called with the lock held. */
         
@@ -238,95 +225,73 @@ tiff_image_parse (TIFF *tiff, TiffContext *context, GError **error)
                 return NULL;
         }
 
+       /* Set the "orientation" key associated with this image. libtiff 
+          orientation handling is odd, so further processing is required
+          by higher-level functions based on this tag. If the embedded
+          orientation tag is 1-4, libtiff flips/mirrors the image as
+          required, and no client processing is required - so we report 
+          no orientation. Orientations 5-8 require rotations which would 
+          swap the width and height of the image. libtiff does not do this. 
+          Instead it interprets orientations 5-8 the same as 1-4. 
+          See http://bugzilla.remotesensing.org/show_bug.cgi?id=1548.
+          To correct for this, the client must apply the transform normally
+          used for orientation 5 to both orientations 5 and 7, and apply
+          the transform normally used for orientation 7 for both
+          orientations 6 and 8. Then everythings works out OK! */
+       
+       TIFFGetField (tiff, TIFFTAG_ORIENTATION, &orientation);
+
+       switch (orientation) {
+               case 5:
+               case 7:
+                       transform = 5;
+                       break;
+               case 6:
+               case 8:
+                       transform = 7;
+                       break;
+               default:
+                       transform = 0;
+                       break;
+       }
+
+       if (transform > 0 ) {
+               gchar str[5];
+               snprintf (str, sizeof (str), "%d", transform);
+               gdk_pixbuf_set_option (pixbuf, "orientation", str);
+       }
+
        if (context && context->prepare_func)
                (* context->prepare_func) (pixbuf, NULL, context->user_data);
 
-#if TIFFLIB_VERSION >= 20031226
-        if (tifflibversion(&major, &minor, &revision) && major == 3 &&
-            (minor > 6 || (minor == 6 && revision > 0))) {                
-                if (!TIFFReadRGBAImageOriented (tiff, width, height, (uint32 *)pixels, ORIENTATION_TOPLEFT, 1) || global_error) 
-                {
-                        tiff_set_error (error,
-                                        GDK_PIXBUF_ERROR_FAILED,
-                                        _("Failed to load RGB data from TIFF file"));
-                        g_object_unref (pixbuf);
-                        return NULL;
-                }
+       if (!TIFFReadRGBAImageOriented (tiff, width, height, (uint32 *)pixels, ORIENTATION_TOPLEFT, 1) || global_error) {
+               tiff_set_error (error,
+                                GDK_PIXBUF_ERROR_FAILED,
+                                _("Failed to load RGB data from TIFF file"));
+               g_object_unref (pixbuf);
+               return NULL;
+       }
 
 #if G_BYTE_ORDER == G_BIG_ENDIAN
-                /* Turns out that the packing used by TIFFRGBAImage depends on 
-                 * the host byte order... 
-                 */ 
-                while (pixels < pixbuf->pixels + bytes) {
-                        uint32 pixel = *(uint32 *)pixels;
-                        int r = TIFFGetR(pixel);
-                        int g = TIFFGetG(pixel);
-                        int b = TIFFGetB(pixel);
-                        int a = TIFFGetA(pixel);
-                        *pixels++ = r;
-                        *pixels++ = g;
-                        *pixels++ = b;
-                        *pixels++ = a;
-                }
-#endif
-        }
-        else 
+       /* Turns out that the packing used by TIFFRGBAImage depends on 
+         * the host byte order... 
+         */ 
+       while (pixels < pixbuf->pixels + bytes) {
+               uint32 pixel = *(uint32 *)pixels;
+               int r = TIFFGetR(pixel);
+               int g = TIFFGetG(pixel);
+               int b = TIFFGetB(pixel);
+               int a = TIFFGetA(pixel);
+               *pixels++ = r;
+               *pixels++ = g;
+               *pixels++ = b;
+               *pixels++ = a;
+       }
 #endif
-              {
-                uint32 *rast, *tmp_rast;
-                gint x, y;
-                guchar *tmppix;
-
-                /* Yes, it needs to be _TIFFMalloc... */
-                rast = (uint32 *) _TIFFmalloc (width * height * sizeof (uint32));
-                if (!rast) {
-                        g_set_error (error,
-                                     GDK_PIXBUF_ERROR,
-                                     GDK_PIXBUF_ERROR_INSUFFICIENT_MEMORY,
-                                     _("Insufficient memory to open TIFF file"));
-                        g_object_unref (pixbuf);
-                        
-                        return NULL;
-                }
-                if (!TIFFReadRGBAImage (tiff, width, height, rast, 1) || global_error) {
-                        tiff_set_error (error,
-                                        GDK_PIXBUF_ERROR_FAILED,
-                                        _("Failed to load RGB data from TIFF file"));
-                        g_object_unref (pixbuf);
-                        _TIFFfree (rast);
-                        
-                        return NULL;
-                }
-                
-                pixels = gdk_pixbuf_get_pixels (pixbuf);
-                
-                g_assert (pixels);
-                
-                tmppix = pixels;
-                
-                for (y = 0; y < height; y++) {
-                        /* Unexplainable...are tiffs backwards? */
-                        /* Also looking at the GIMP plugin, this
-                         * whole reading thing can be a bit more
-                         * robust.
-                         */
-                        tmp_rast = rast + ((height - y - 1) * width);
-                        for (x = 0; x < width; 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);
-             }
 
        if (context && context->update_func)
                (* context->update_func) (pixbuf, 0, 0, width, height, context->user_data);
-        
+
         return pixbuf;
 }