]> www.fi.muni.cz Git - evince.git/blob - thumbnailer/evince-thumbnailer.c
d55067427bb292e9ae50f12ac7da95c268e72136
[evince.git] / thumbnailer / evince-thumbnailer.c
1 /*
2    Copyright (C) 2005 Fernando Herrera <fherrera@onirica.com>
3
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation; either version 2 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 #include <libgnomevfs/gnome-vfs-mime-utils.h>
20 #include <libgnomevfs/gnome-vfs-uri.h>
21 #include <libgnomevfs/gnome-vfs-utils.h>
22 #include <libgnomevfs/gnome-vfs-init.h>
23 #include <libgnomevfs/gnome-vfs-ops.h>
24
25 #include <ev-document.h>
26 #include <ev-document-thumbnails.h>
27 #include <ev-async-renderer.h>
28 #include <ev-document-factory.h>
29 #include <ev-backends-manager.h>
30
31 #include <stdlib.h>
32 #include <string.h>
33
34 #define THUMBNAIL_SIZE 128
35
36 struct AsyncData {
37         EvDocument  *document;
38         const gchar *output;
39         gint         size;
40         gboolean     success;
41 };
42
43 static EvDocument *
44 evince_thumbnailer_get_document (const gchar *uri)
45 {
46         EvDocument *document = NULL;
47         GError     *error = NULL;
48
49         document = ev_document_factory_get_document  (uri, &error);
50         if (error) {
51                 if (error->domain == EV_DOCUMENT_ERROR &&
52                     error->code == EV_DOCUMENT_ERROR_ENCRYPTED) {
53                         /* FIXME: Create a thumb for cryp docs */
54                         g_error_free (error);
55                         return NULL;
56                 }
57                 g_error_free (error);
58                 return NULL;
59         }
60         
61         return document;
62 }
63
64 static gboolean
65 evince_thumbnail_pngenc_get (EvDocument *document, const char *thumbnail, int size)
66 {
67         EvRenderContext *rc;
68         double width, height;
69         GdkPixbuf *pixbuf;
70
71         ev_document_get_page_size (document, 0, &width, &height);
72
73         rc = ev_render_context_new (0, 0, size / width);
74         pixbuf = ev_document_thumbnails_get_thumbnail (EV_DOCUMENT_THUMBNAILS (document),
75                                                        rc, FALSE);
76         g_object_unref (rc);
77         
78         if (pixbuf != NULL) {
79                 const char *overlaid_icon_name = NULL;
80
81                 if (overlaid_icon_name) {
82                         GdkPixbuf *overlaid_pixbuf;
83
84                         gchar *overlaid_icon_path = g_strdup_printf ("%s/%s", DATADIR, overlaid_icon_name);
85                         overlaid_pixbuf = gdk_pixbuf_new_from_file (overlaid_icon_path, NULL);
86                         g_free (overlaid_icon_path);
87                         if (overlaid_pixbuf != NULL) {
88                                 int delta_height, delta_width;
89                                 
90                                 delta_width = gdk_pixbuf_get_width (pixbuf) -
91                                         gdk_pixbuf_get_width (overlaid_pixbuf);
92                                 delta_height = gdk_pixbuf_get_height (pixbuf) -
93                                         gdk_pixbuf_get_height (overlaid_pixbuf);
94                                 
95                                 gdk_pixbuf_composite (overlaid_pixbuf, pixbuf,
96                                                       delta_width, delta_height,
97                                                       gdk_pixbuf_get_width (overlaid_pixbuf),
98                                                       gdk_pixbuf_get_height (overlaid_pixbuf),
99                                                       delta_width, delta_height,
100                                                       1, 1,
101                                                       GDK_INTERP_NEAREST, 100);
102                                 
103                                 g_object_unref  (overlaid_pixbuf);
104                         }
105                 }
106                 
107                 if (gdk_pixbuf_save (pixbuf, thumbnail, "png", NULL, NULL)) {
108                         g_object_unref  (pixbuf);
109                         return TRUE;
110                 }
111
112                 g_object_unref  (pixbuf);
113         }
114         
115         return FALSE;
116 }
117
118 static gpointer
119 evince_thumbnail_pngenc_get_async (struct AsyncData *data)
120 {
121         ev_document_doc_mutex_lock ();
122         data->success = evince_thumbnail_pngenc_get (data->document,
123                                                      data->output,
124                                                      data->size);
125         ev_document_doc_mutex_unlock ();
126         
127         g_idle_add ((GSourceFunc)gtk_main_quit, NULL);
128         
129         return NULL;
130 }
131
132 int
133 main (int argc, char *argv[])
134 {
135         EvDocument *document;
136         const char *input;
137         const char *output;
138         int         size;
139         char       *uri;
140
141         if (argc <= 2 || argc > 5 || strcmp (argv[1], "-h") == 0 ||
142             strcmp (argv[1], "--help") == 0) {
143                 g_print ("Usage: %s [-s <size>] <input> <output>\n", argv[0]);
144                 return -1;
145         }
146
147         if (!strcmp (argv[1], "-s")) {
148                 input = argv[3];
149                 output = argv[4];
150                 size = atoi (argv[2]);
151         } else {
152                 input = argv[1];
153                 output = argv[2];
154                 size = THUMBNAIL_SIZE;
155         }
156
157         if (size < 40) {
158                 g_print ("Size cannot be smaller than 40 pixels\n");
159                 return -1;
160         }
161
162         if (!g_thread_supported ())
163                 g_thread_init (NULL);
164         
165         gnome_vfs_init ();
166
167         ev_backends_manager_init ();
168
169         uri = gnome_vfs_make_uri_from_shell_arg (input);
170         document = evince_thumbnailer_get_document (uri);
171         g_free (uri);
172
173         if (!document) {
174                 ev_backends_manager_shutdown ();
175                 return -2;
176         }
177
178         if (!EV_IS_DOCUMENT_THUMBNAILS (document)) {
179                 g_object_unref (document);
180                 ev_backends_manager_shutdown ();
181                 return -2;
182         }
183
184         if (EV_IS_ASYNC_RENDERER (document)) {
185                 struct AsyncData data;
186
187                 gtk_init (&argc, &argv);
188                 
189                 data.document = document;
190                 data.output = output;
191                 data.size = size;
192
193                 g_thread_create ((GThreadFunc) evince_thumbnail_pngenc_get_async,
194                                  &data, FALSE, NULL);
195                 
196                 gtk_main ();
197
198                 g_object_unref (document);
199                 ev_backends_manager_shutdown ();
200
201                 return data.success ? 0 : -2;
202         }
203
204         if (!evince_thumbnail_pngenc_get (document, output, size)) {
205                 g_object_unref (document);
206                 ev_backends_manager_shutdown ();
207                 return -2;
208         }
209
210         g_object_unref (document);
211         ev_backends_manager_shutdown ();
212
213         return 0;
214 }