| File: | thumbnailer/lector-thumbnailer.c |
| Warning: | line 248, column 3 This statement is never executed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 17 | */ |
| 18 | |
| 19 | #include <config.h> |
| 20 | |
| 21 | #include <lector-document.h> |
| 22 | |
| 23 | #include <gio/gio.h> |
| 24 | |
| 25 | #include <stdlib.h> |
| 26 | #include <string.h> |
| 27 | |
| 28 | #define THUMBNAIL_SIZE128 128 |
| 29 | #define DEFAULT_SLEEP_TIME(15 * 1000000) (15 * G_USEC_PER_SEC1000000) /* 15 seconds */ |
| 30 | |
| 31 | static gboolean finished = TRUE(!(0)); |
| 32 | |
| 33 | static gint size = THUMBNAIL_SIZE128; |
| 34 | static gboolean time_limit = TRUE(!(0)); |
| 35 | static char **file_arguments = NULL((void*)0); |
| 36 | |
| 37 | static const GOptionEntry goption_options[] = { |
| 38 | { "size", 's', 0, G_OPTION_ARG_INT, &size, NULL((void*)0), "SIZE" }, |
| 39 | { "no-limit", 'l', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &time_limit, "Don't limit the thumbnailing time to 15 seconds", NULL((void*)0) }, |
| 40 | { G_OPTION_REMAINING"", 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &file_arguments, NULL((void*)0), "<input> <ouput>" }, |
| 41 | { NULL((void*)0) } |
| 42 | }; |
| 43 | |
| 44 | struct AsyncData { |
| 45 | EvDocument *document; |
| 46 | const gchar *output; |
| 47 | gint size; |
| 48 | gboolean success; |
| 49 | }; |
| 50 | |
| 51 | /* Time monitor: copied from totem */ |
| 52 | G_GNUC_NORETURN__attribute__ ((__noreturn__)) static gpointer |
| 53 | time_monitor (gpointer data) |
| 54 | { |
| 55 | const gchar *app_name; |
| 56 | |
| 57 | g_usleep (DEFAULT_SLEEP_TIME(15 * 1000000)); |
| 58 | |
| 59 | if (finished) |
| 60 | g_thread_exit (NULL((void*)0)); |
| 61 | |
| 62 | app_name = g_get_application_name (); |
| 63 | if (app_name == NULL((void*)0)) |
| 64 | app_name = g_get_prgname (); |
| 65 | g_printerr ("%s couldn't process file: '%s'\n" |
| 66 | "Reason: Took too much time to process.\n", |
| 67 | app_name, |
| 68 | (const char *) data); |
| 69 | |
| 70 | exit (0); |
| 71 | } |
| 72 | |
| 73 | static void |
| 74 | time_monitor_start (const char *input) |
| 75 | { |
| 76 | finished = FALSE(0); |
| 77 | g_thread_new ("EvThumbnailerTimer", time_monitor, (gpointer) input); |
| 78 | } |
| 79 | |
| 80 | static void |
| 81 | time_monitor_stop (void) |
| 82 | { |
| 83 | finished = TRUE(!(0)); |
| 84 | } |
| 85 | |
| 86 | static void |
| 87 | delete_temp_file (GFile *file) |
| 88 | { |
| 89 | ev_tmp_file_unlink (file); |
| 90 | g_object_unref (file); |
| 91 | } |
| 92 | |
| 93 | static EvDocument * |
| 94 | lector_thumbnailer_get_document (GFile *file) |
| 95 | { |
| 96 | EvDocument *document = NULL((void*)0); |
| 97 | gchar *uri; |
| 98 | GFile *tmp_file = NULL((void*)0); |
| 99 | GError *error = NULL((void*)0); |
| 100 | |
| 101 | if (!g_file_is_native (file)) { |
| 102 | gchar *base_name, *template; |
| 103 | |
| 104 | base_name = g_file_get_basename (file); |
| 105 | template = g_strdup_printf ("document.XXXXXX-%s", base_name); |
| 106 | g_free (base_name); |
| 107 | |
| 108 | tmp_file = ev_mkstemp_file (template, &error); |
| 109 | g_free (template); |
| 110 | if (!tmp_file) { |
| 111 | g_printerr ("Error loading remote document: %s\n", error->message); |
| 112 | g_error_free (error); |
| 113 | |
| 114 | return NULL((void*)0); |
| 115 | } |
| 116 | |
| 117 | g_file_copy (file, tmp_file, G_FILE_COPY_OVERWRITE, |
| 118 | NULL((void*)0), NULL((void*)0), NULL((void*)0), &error); |
| 119 | if (error) { |
| 120 | g_printerr ("Error loading remote document: %s\n", error->message); |
| 121 | g_error_free (error); |
| 122 | g_object_unref (tmp_file); |
| 123 | |
| 124 | return NULL((void*)0); |
| 125 | } |
| 126 | uri = g_file_get_uri (tmp_file); |
| 127 | } else { |
| 128 | uri = g_file_get_uri (file); |
| 129 | } |
| 130 | |
| 131 | document = ev_document_factory_get_document (uri, &error); |
| 132 | if (tmp_file) { |
| 133 | if (document) { |
| 134 | g_object_weak_ref (G_OBJECT (document)((((GObject*) (void *) g_type_check_instance_cast ((GTypeInstance *) ((document)), (((GType) ((20) << (2)))))))), |
| 135 | (GWeakNotify)delete_temp_file, |
| 136 | tmp_file); |
| 137 | } else { |
| 138 | ev_tmp_file_unlink (tmp_file); |
| 139 | g_object_unref (tmp_file); |
| 140 | } |
| 141 | } |
| 142 | g_free (uri); |
| 143 | if (error) { |
| 144 | if (error->domain == EV_DOCUMENT_ERRORev_document_error_quark () && |
| 145 | error->code == EV_DOCUMENT_ERROR_ENCRYPTED) { |
| 146 | /* FIXME: Create a thumb for cryp docs */ |
| 147 | g_error_free (error); |
| 148 | return NULL((void*)0); |
| 149 | } |
| 150 | g_printerr ("Error loading document: %s\n", error->message); |
| 151 | g_error_free (error); |
| 152 | return NULL((void*)0); |
| 153 | } |
| 154 | |
| 155 | return document; |
| 156 | } |
| 157 | |
| 158 | static gboolean |
| 159 | lector_thumbnail_pngenc_get (EvDocument *document, const char *thumbnail, int size) |
| 160 | { |
| 161 | EvRenderContext *rc; |
| 162 | double width, height; |
| 163 | GdkPixbuf *pixbuf; |
| 164 | EvPage *page; |
| 165 | |
| 166 | page = ev_document_get_page (document, 0); |
| 167 | |
| 168 | ev_document_get_page_size (document, 0, &width, &height); |
| 169 | |
| 170 | rc = ev_render_context_new (page, 0, size / width); |
| 171 | pixbuf = ev_document_thumbnails_get_thumbnail (EV_DOCUMENT_THUMBNAILS (document)((((EvDocumentThumbnails*) (void *) g_type_check_instance_cast ((GTypeInstance*) ((document)), ((ev_document_thumbnails_get_type ())))))), |
| 172 | rc, FALSE(0)); |
| 173 | g_object_unref (rc); |
| 174 | g_object_unref (page); |
| 175 | |
| 176 | if (pixbuf != NULL((void*)0)) { |
| 177 | if (gdk_pixbuf_save (pixbuf, thumbnail, "png", NULL((void*)0), NULL((void*)0))) { |
| 178 | g_object_unref (pixbuf); |
| 179 | return TRUE(!(0)); |
| 180 | } |
| 181 | |
| 182 | g_object_unref (pixbuf); |
| 183 | } |
| 184 | |
| 185 | return FALSE(0); |
| 186 | } |
| 187 | |
| 188 | static gpointer |
| 189 | lector_thumbnail_pngenc_get_async (struct AsyncData *data) |
| 190 | { |
| 191 | ev_document_doc_mutex_lock (); |
| 192 | data->success = lector_thumbnail_pngenc_get (data->document, |
| 193 | data->output, |
| 194 | data->size); |
| 195 | ev_document_doc_mutex_unlock (); |
| 196 | |
| 197 | g_idle_add ((GSourceFunc)ctk_main_quit, NULL((void*)0)); |
| 198 | |
| 199 | return NULL((void*)0); |
| 200 | } |
| 201 | |
| 202 | static void |
| 203 | print_usage (GOptionContext *context) |
| 204 | { |
| 205 | gchar *help; |
| 206 | |
| 207 | help = g_option_context_get_help (context, TRUE(!(0)), NULL((void*)0)); |
| 208 | g_print ("%s", help); |
| 209 | g_free (help); |
| 210 | } |
| 211 | |
| 212 | int |
| 213 | main (int argc, char *argv[]) |
| 214 | { |
| 215 | EvDocument *document; |
| 216 | GOptionContext *context; |
| 217 | const char *input; |
| 218 | const char *output; |
| 219 | GFile *file; |
| 220 | GError *error = NULL((void*)0); |
| 221 | |
| 222 | context = g_option_context_new ("- CAFE Document Thumbnailer"); |
| 223 | g_option_context_add_main_entries (context, goption_options, NULL((void*)0)); |
| 224 | |
| 225 | if (!g_option_context_parse (context, &argc, &argv, &error)) { |
| 226 | g_printerr ("%s\n", error->message); |
| 227 | g_error_free (error); |
| 228 | print_usage (context); |
| 229 | g_option_context_free (context); |
| 230 | if (file_arguments) |
| 231 | g_strfreev (file_arguments); |
| 232 | |
| 233 | return -1; |
| 234 | } |
| 235 | |
| 236 | if (file_arguments == NULL((void*)0) || g_strv_length (file_arguments) != 2) { |
| 237 | print_usage (context); |
| 238 | g_option_context_free (context); |
| 239 | if (file_arguments) |
| 240 | g_strfreev (file_arguments); |
| 241 | |
| 242 | return -1; |
| 243 | } |
| 244 | |
| 245 | g_option_context_free (context); |
| 246 | |
| 247 | if (size < 1) { |
| 248 | g_printerr ("Size cannot be smaller than 1 pixel\n"); |
This statement is never executed | |
| 249 | g_strfreev (file_arguments); |
| 250 | |
| 251 | return -1; |
| 252 | } |
| 253 | |
| 254 | input = file_arguments[0]; |
| 255 | output = file_arguments[1]; |
| 256 | |
| 257 | if (!ev_init ()) { |
| 258 | g_strfreev (file_arguments); |
| 259 | return -1; |
| 260 | } |
| 261 | |
| 262 | file = g_file_new_for_commandline_arg (input); |
| 263 | document = lector_thumbnailer_get_document (file); |
| 264 | g_object_unref (file); |
| 265 | |
| 266 | if (!document) { |
| 267 | ev_shutdown (); |
| 268 | g_strfreev (file_arguments); |
| 269 | |
| 270 | return -2; |
| 271 | } |
| 272 | |
| 273 | if (!EV_IS_DOCUMENT_THUMBNAILS (document)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (document)); GType __t = ((ev_document_thumbnails_get_type () )); gboolean __r; if (!__inst) __r = (0); else if (__inst-> g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) { |
| 274 | g_object_unref (document); |
| 275 | ev_shutdown (); |
| 276 | g_strfreev (file_arguments); |
| 277 | |
| 278 | return -2; |
| 279 | } |
| 280 | |
| 281 | if (time_limit) |
| 282 | time_monitor_start (input); |
| 283 | |
| 284 | if (EV_IS_ASYNC_RENDERER (document)(((__extension__ ({ GTypeInstance *__inst = (GTypeInstance*) ( (document)); GType __t = ((ev_async_renderer_get_type ())); gboolean __r; if (!__inst) __r = (0); else if (__inst->g_class && __inst->g_class->g_type == __t) __r = (!(0)); else __r = g_type_check_instance_is_a (__inst, __t); __r; }))))) { |
| 285 | struct AsyncData data; |
| 286 | |
| 287 | ctk_init (&argc, &argv); |
| 288 | |
| 289 | data.document = document; |
| 290 | data.output = output; |
| 291 | data.size = size; |
| 292 | |
| 293 | g_thread_new ("EvThumbnailerAsyncRenderer", |
| 294 | (GThreadFunc) lector_thumbnail_pngenc_get_async, |
| 295 | &data); |
| 296 | |
| 297 | ctk_main (); |
| 298 | |
| 299 | g_object_unref (document); |
| 300 | ev_shutdown (); |
| 301 | g_strfreev (file_arguments); |
| 302 | |
| 303 | return data.success ? 0 : -2; |
| 304 | } |
| 305 | |
| 306 | if (!lector_thumbnail_pngenc_get (document, output, size)) { |
| 307 | g_object_unref (document); |
| 308 | ev_shutdown (); |
| 309 | g_strfreev (file_arguments); |
| 310 | |
| 311 | return -2; |
| 312 | } |
| 313 | |
| 314 | time_monitor_stop (); |
| 315 | g_object_unref (document); |
| 316 | ev_shutdown (); |
| 317 | g_strfreev (file_arguments); |
| 318 | |
| 319 | return 0; |
| 320 | } |