static GdkPixbuf * skin_get_thumbnail (const gchar * path) { gchar * thumbname = get_thumbnail_filename (path); GdkPixbuf * thumb = NULL; if (g_file_test (thumbname, G_FILE_TEST_EXISTS)) { thumb = gdk_pixbuf_new_from_file (thumbname, NULL); if (thumb) goto DONE; } thumb = skin_get_preview (path); if (! thumb) goto DONE; audgui_pixbuf_scale_within (& thumb, 128); if (thumb) gdk_pixbuf_save (thumb, thumbname, "png", NULL, NULL); DONE: g_free (thumbname); return thumb; }
/* * Load & display image */ void qiv_load_image(qiv_image *q) { /* Don't initialize most variables here, initialize them after load_next_image: */ struct stat st; const char *image_name; Imlib_Image *im; struct timeval load_before, load_after; char is_stat_ok; /* Used to omit slow disk operations if image_file doesn't exist or isn't * a file. */ char is_maybe_image_file; char is_first_error = 1; load_next_image: is_stat_ok = 0; is_maybe_image_file = 1; image_name = image_names[image_idx]; gettimeofday(&load_before, 0); if (imlib_context_get_image()) imlib_free_image(); q->real_w = q->real_h = -2; q->has_thumbnail = FALSE; if (!do_omit_load_stat) { is_stat_ok = 0 == stat(image_name, &st); is_maybe_image_file = is_stat_ok && S_ISREG(st.st_mode); } current_mtime = is_stat_ok ? st.st_mtime : 0; im = NULL; if (thumbnail && fullscreen && (is_stat_ok || maxpect)) { char *th_image_name = is_maybe_image_file ? get_thumbnail_filename(image_name, &is_maybe_image_file) : NULL; if (th_image_name) { im = imlib_load_image(th_image_name); if (im && maxpect) { get_image_dimensions(image_name, th_image_name, &q->real_w, &q->real_h); } free(th_image_name); th_image_name = NULL; } } if (im) { /* We have a dumb thumbnail in im. */ if (maxpect) { current_mtime = 0; q->has_thumbnail = TRUE; /* Now im still has the thumbnail image. Keep it. */ } else { /* Use the real, non-thumbnail image instead. */ imlib_context_set_image(im); imlib_free_image(); im = is_maybe_image_file ? imlib_load_image((char*)image_name) : NULL; } } else { im = is_maybe_image_file ? imlib_load_image((char*)image_name) : NULL; } if (!im) { /* error */ q->error = 1; q->orig_w = 400; q->orig_h = 300; if (to_root || to_root_t || to_root_s) { fprintf(stderr, "qiv: cannot load background_image\n"); qiv_exit(1); } /* Shortcut to speed up lots of subsequent load failures. */ if (is_first_error) { check_size(q, TRUE); if (first) { setup_win(q); first = 0; } gdk_window_set_background(q->win, &error_bg); gdk_beep(); is_first_error = 0; } /* TODO(pts): Avoid the slow loop of copying pointers around in update_image_on_error. */ update_image_on_error(q); /* This is a shortcut to avoid stack overflow in the recursion of * qiv_load_image -> update_image -> qiv_load_image -> update_image -> ... * if there are errors loading many subsequent images. */ goto load_next_image; } if (thumbnail && !q->has_thumbnail && q->real_w < 0 && is_maybe_image_file) { FILE *f = fopen(image_name, "rb"); if (f) { get_real_dimensions_fast(f, &q->real_w, &q->real_h); fclose(f); } } /* Retrieve image properties */ imlib_context_set_image(im); q->error = 0; q->orig_w = imlib_image_get_width(); q->orig_h = imlib_image_get_height(); if (q->orig_w >= (1 << 23) / q->orig_h) { /* Workaround for Imlib2 1.4.6 on Ubuntu Trusty: PNG images with an * alpha channel and pixel count >= (1 << 23) are displayed as black. * imlib_image_query_pixel returns the correct value, but * imlib_render_pixmaps_for_whole_image_at_size renders only black * pixels if unzoomed. */ Imlib_Color c; /* Without this call, imlib_image_set_has_alpha(0) is too early, and * it has no effect. */ imlib_image_query_pixel(0, 0, &c); imlib_image_set_has_alpha(0); } #ifdef HAVE_EXIF if (autorotate) { transform( q, orient( image_name)); } #endif check_size(q, TRUE); if (first) { setup_win(q); first = 0; } /* desktop-background -> exit */ if (to_root || to_root_t || to_root_s) { set_desktop_image(q); if(slide) return; else qiv_exit(0); } gdk_window_set_background(q->win, &image_bg); if (do_grab || (fullscreen && !disable_grab) ) { gdk_keyboard_grab(q->win, FALSE, CurrentTime); gdk_pointer_grab(q->win, FALSE, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK, NULL, NULL, CurrentTime); } gettimeofday(&load_after, 0); /* load_elapsed used by update_image. */ load_elapsed = ((load_after.tv_sec + load_after.tv_usec / 1.0e6) - (load_before.tv_sec + load_before.tv_usec / 1.0e6)); update_image(q, FULL_REDRAW); // if (magnify && !fullscreen) { // [lc] // setup_magnify(q, &magnify_img); // update_magnify(q, &magnify_img, FULL_REDRAW, 0, 0); // } }