"Fossies" - the Fresh Open Source Software Archive

Member "libextractor-1.11/src/plugins/thumbnailgtk_extractor.c" (30 Jan 2021, 5877 Bytes) of package /linux/privat/libextractor-1.11.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "thumbnailgtk_extractor.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2      This file is part of libextractor.
    3      Copyright (C) 2005, 2009, 2012 Vidyut Samanta and Christian Grothoff
    4 
    5      libextractor is free software; you can redistribute it and/or modify
    6      it under the terms of the GNU General Public License as published
    7      by the Free Software Foundation; either version 3, or (at your
    8      option) any later version.
    9 
   10      libextractor is distributed in the hope that it will be useful, but
   11      WITHOUT ANY WARRANTY; without even the implied warranty of
   12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   13      General Public License for more details.
   14 
   15      You should have received a copy of the GNU General Public License
   16      along with libextractor; see the file COPYING.  If not, write to the
   17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   18      Boston, MA 02110-1301, USA.
   19  */
   20 /**
   21  * @file plugins/thumbnailgtk_extractor.c
   22  * @author Christian Grothoff
   23  * @brief this extractor produces a binary (!) encoded
   24  * thumbnail of images (using gdk pixbuf).  The bottom
   25  * of the file includes a decoder method that can be used
   26  * to reproduce the 128x128 PNG thumbnails.  We use
   27  * libmagic to test if the input data is actually an
   28  * image before trying to give it to gdk-pixbuf.
   29  */
   30 #include "platform.h"
   31 #include "extractor.h"
   32 #include <magic.h>
   33 #include <glib.h>
   34 #include <gdk-pixbuf/gdk-pixbuf.h>
   35 
   36 /**
   37  * Target size for the thumbnails (width and height).
   38  */
   39 #define THUMBSIZE 128
   40 
   41 /**
   42  * Maximum image size supported (to avoid unreasonable
   43  * allocations)
   44  */
   45 #define MAX_IMAGE_SIZE (32 * 1024 * 1024)
   46 
   47 
   48 /**
   49  * Global handle to MAGIC data.
   50  */
   51 static magic_t magic;
   52 
   53 
   54 /**
   55  * Main method for the gtk-thumbnailer plugin.
   56  *
   57  * @param ec extraction context
   58  */
   59 void
   60 EXTRACTOR_thumbnailgtk_extract_method (struct EXTRACTOR_ExtractContext *ec)
   61 {
   62   GdkPixbufLoader *loader;
   63   GdkPixbuf *in;
   64   GdkPixbuf *out;
   65   size_t length;
   66   char *thumb;
   67   unsigned long width;
   68   unsigned long height;
   69   char format[64];
   70   void *data;
   71   uint64_t size;
   72   size_t off;
   73   ssize_t iret;
   74   void *buf;
   75   const char *mime;
   76 
   77   if (-1 == (iret = ec->read (ec->cls,
   78                               &data,
   79                               16 * 1024)))
   80     return;
   81   if (NULL == (mime = magic_buffer (magic, data, iret)))
   82     return;
   83   if (0 != strncmp (mime,
   84                     "image/",
   85                     strlen ("image/")))
   86     return; /* not an image */
   87 
   88   /* read entire image into memory */
   89   size = ec->get_size (ec->cls);
   90   if (UINT64_MAX == size)
   91     size = MAX_IMAGE_SIZE; /* unknown size, cap at max */
   92   if (size > MAX_IMAGE_SIZE)
   93     return; /* FAR too big to be an image */
   94   if (NULL == (buf = malloc (size)))
   95     return; /* too big to fit into memory on this system */
   96 
   97   /* start with data already read */
   98   memcpy (buf, data, iret);
   99   off = iret;
  100   while (off < size)
  101   {
  102     iret = ec->read (ec->cls, &data, size - off);
  103     if (iret <= 0)
  104     {
  105       /* io error */
  106       free (buf);
  107       return;
  108     }
  109     memcpy (buf + off, data, iret);
  110     off += iret;
  111   }
  112 
  113   loader = gdk_pixbuf_loader_new ();
  114   gdk_pixbuf_loader_write (loader,
  115                            buf,
  116                            size, NULL);
  117   free (buf);
  118   in = gdk_pixbuf_loader_get_pixbuf (loader);
  119   gdk_pixbuf_loader_close (loader, NULL);
  120   if (NULL == in)
  121   {
  122     g_object_unref (loader);
  123     return;
  124   }
  125   g_object_ref (in);
  126   g_object_unref (loader);
  127   height = gdk_pixbuf_get_height (in);
  128   width = gdk_pixbuf_get_width (in);
  129   snprintf (format,
  130             sizeof (format),
  131             "%ux%u",
  132             (unsigned int) width,
  133             (unsigned int) height);
  134   if (0 != ec->proc (ec->cls,
  135                      "thumbnailgtk",
  136                      EXTRACTOR_METATYPE_IMAGE_DIMENSIONS,
  137                      EXTRACTOR_METAFORMAT_UTF8,
  138                      "text/plain",
  139                      format,
  140                      strlen (format) + 1))
  141   {
  142     g_object_unref (in);
  143     return;
  144   }
  145   if ((height <= THUMBSIZE) && (width <= THUMBSIZE))
  146   {
  147     g_object_unref (in);
  148     return;
  149   }
  150   if (height > THUMBSIZE)
  151   {
  152     width = width * THUMBSIZE / height;
  153     height = THUMBSIZE;
  154   }
  155   if (width > THUMBSIZE)
  156   {
  157     height = height * THUMBSIZE / width;
  158     width = THUMBSIZE;
  159   }
  160   if ( (0 == height) || (0 == width) )
  161   {
  162     g_object_unref (in);
  163     return;
  164   }
  165   out = gdk_pixbuf_scale_simple (in, width, height,
  166                                  GDK_INTERP_BILINEAR);
  167   g_object_unref (in);
  168   thumb = NULL;
  169   length = 0;
  170   if (NULL == out)
  171     return;
  172   if (! gdk_pixbuf_save_to_buffer (out, &thumb,
  173                                    &length,
  174                                    "png", NULL,
  175                                    "compression", "9",
  176                                    NULL))
  177   {
  178     g_object_unref (out);
  179     return;
  180   }
  181   g_object_unref (out);
  182   if (NULL == thumb)
  183     return;
  184   ec->proc (ec->cls,
  185             "thumbnailgtk",
  186             EXTRACTOR_METATYPE_THUMBNAIL,
  187             EXTRACTOR_METAFORMAT_BINARY,
  188             "image/png",
  189             thumb, length);
  190   free (thumb);
  191 }
  192 
  193 
  194 /**
  195  * This plugin sometimes is installed under the alias 'thumbnail'.
  196  * So we need to provide a second entry method.
  197  *
  198  * @param ec extraction context
  199  */
  200 void
  201 EXTRACTOR_thumbnail_extract_method (struct EXTRACTOR_ExtractContext *ec)
  202 {
  203   EXTRACTOR_thumbnailgtk_extract_method (ec);
  204 }
  205 
  206 
  207 /**
  208  * Initialize glib and load magic file.
  209  */
  210 void __attribute__ ((constructor))
  211 thumbnailgtk_gobject_init ()
  212 {
  213 #if ! GLIB_CHECK_VERSION (2, 35, 0)
  214   g_type_init ();
  215 #endif
  216   magic = magic_open (MAGIC_MIME_TYPE);
  217   if (0 != magic_load (magic, NULL))
  218   {
  219     /* FIXME: how to deal with errors? */
  220   }
  221 }
  222 
  223 
  224 /**
  225  * Destructor for the library, cleans up.
  226  */
  227 void __attribute__ ((destructor))
  228 thumbnailgtk_ltdl_fini ()
  229 {
  230   if (NULL != magic)
  231   {
  232     magic_close (magic);
  233     magic = NULL;
  234   }
  235 }
  236 
  237 
  238 /* end of thumbnailgtk_extractor.c */