libextractor  1.11
About: GNU libextractor is a library used to extract meta-data from files of arbitrary type.
  Fossies Dox: libextractor-1.11.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

thumbnailgtk_extractor.c
Go to the documentation of this file.
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
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",
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",
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
202 {
204 }
205 
206 
207 /**
208  * Initialize glib and load magic file.
209  */
210 void __attribute__ ((constructor))
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))
229 {
230  if (NULL != magic)
231  {
232  magic_close (magic);
233  magic = NULL;
234  }
235 }
236 
237 
238 /* end of thumbnailgtk_extractor.c */
@ EXTRACTOR_METAFORMAT_BINARY
Definition: extractor.h:107
@ EXTRACTOR_METAFORMAT_UTF8
Definition: extractor.h:102
#define NULL
Definition: getopt1.c:60
@ EXTRACTOR_METATYPE_THUMBNAIL
Definition: extractor.h:259
@ EXTRACTOR_METATYPE_IMAGE_DIMENSIONS
Definition: extractor.h:257
plaform specifics
uint64_t(* get_size)(void *cls)
Definition: extractor.h:520
EXTRACTOR_MetaDataProcessor proc
Definition: extractor.h:525
ssize_t(* read)(void *cls, void **data, size_t size)
Definition: extractor.h:494
void EXTRACTOR_thumbnail_extract_method(struct EXTRACTOR_ExtractContext *ec)
#define THUMBSIZE
void thumbnailgtk_ltdl_fini()
void thumbnailgtk_gobject_init()
#define MAX_IMAGE_SIZE
static magic_t magic
void EXTRACTOR_thumbnailgtk_extract_method(struct EXTRACTOR_ExtractContext *ec)