static gint thumb_loader_std_setup(ThumbLoaderStd *tl, const gchar *path) { tl->il = image_loader_new(path); #if 0 /* this will speed up jpegs by up to 3x in some cases */ if (tl->requested_width <= THUMB_SIZE_NORMAL && tl->requested_height <= THUMB_SIZE_NORMAL) { image_loader_set_requested_size(tl->il, THUMB_SIZE_NORMAL, THUMB_SIZE_NORMAL); } else { image_loader_set_requested_size(tl->il, THUMB_SIZE_LARGE, THUMB_SIZE_LARGE); } #endif image_loader_set_error_func(tl->il, thumb_loader_std_error_cb, tl); if (tl->func_progress) { image_loader_set_percent_func(tl->il, thumb_loader_std_progress_cb, tl); } if (image_loader_start(tl->il, thumb_loader_std_done_cb, tl)) { return TRUE; } image_loader_free(tl->il); tl->il = NULL; return FALSE; }
static gint thumb_loader_std_next_source(ThumbLoaderStd *tl, gint remove_broken) { image_loader_free(tl->il); tl->il = NULL; if (tl->thumb_path) { if (!tl->thumb_path_local && remove_broken) { if (debug) printf("thumb broken, unlinking: %s\n", tl->thumb_path); unlink_file(tl->thumb_path); } g_free(tl->thumb_path); tl->thumb_path = NULL; if (!tl->thumb_path_local) { tl->thumb_path = thumb_loader_std_cache_path(tl, TRUE, NULL, FALSE); if (isfile(tl->thumb_path) && thumb_loader_std_setup(tl, tl->thumb_path)) { tl->thumb_path_local = TRUE; return TRUE; } g_free(tl->thumb_path); tl->thumb_path = NULL; } if (thumb_loader_std_setup(tl, tl->source_path)) return TRUE; } thumb_loader_std_save(tl, NULL); return FALSE; }
static void thumb_loader_std_reset(ThumbLoaderStd *tl) { if (tl->pixbuf) g_object_unref(tl->pixbuf); tl->pixbuf = NULL; image_loader_free(tl->il); tl->il = NULL; g_free(tl->source_path); tl->source_path = NULL; g_free(tl->thumb_path); tl->thumb_path = NULL; g_free(tl->thumb_uri); tl->thumb_uri = NULL; tl->local_uri = NULL; tl->thumb_path_local = FALSE; tl->cache_hit = FALSE; tl->source_mtime = 0; tl->source_size = 0; tl->source_mode = 0; tl->progress = 0.0; }
void thumb_loader_free (ThumbLoader * tl) { if (!tl) return; if (tl->pixbuf) gdk_pixbuf_unref (tl->pixbuf); image_loader_free (tl->il); g_free (tl->path); if (tl->idle_done_id != -1) gtk_idle_remove (tl->idle_done_id); g_free (tl); }
void cache_loader_free(CacheLoader *cl) { if (!cl) return; if (cl->idle_id) { g_source_remove(cl->idle_id); cl->idle_id = 0; } image_loader_free(cl->il); cache_sim_data_free(cl->cd); file_data_unref(cl->fd); g_free(cl); }
static void cb_thumb_loader_error (ImageLoader * il, gpointer data) { /* * at least some of the image must be available, go to cb_done * * the error handling should be settable to this or the #if 0 below, I guess */ cb_thumb_loader_done (il, data); #if 0 ThumbLoader *tl = data; image_loader_free (tl->il); tl->il = NULL; if (tl->func_error) tl->func_error (tl, tl->data_error); #endif }
gint thumb_loader_start (ThumbLoader * tl, void (*func_done) (ThumbLoader *, gpointer), gpointer data_done) { gchar *cache_path = NULL; if (!tl || !tl->path) return FALSE; tl->func_done = func_done; tl->data_done = data_done; if (conf.enable_thumb_caching) { cache_path = cache_find_location (CACHE_THUMBS, tl->path, PORNVIEW_CACHE_THUMB_EXT); if (cache_path) { if (filetime (cache_path) == filetime (tl->path)) { if (filesize (cache_path) == 0) { g_free (cache_path); return FALSE; } } else { g_free (cache_path); cache_path = NULL; } } } if (cache_path) { thumb_loader_setup (tl, cache_path); g_free (cache_path); tl->from_cache = TRUE; } else { thumb_loader_setup (tl, tl->path); } if (!image_loader_start (tl->il, cb_thumb_loader_done, tl)) { /* * try from original if cache attempt */ if (tl->from_cache) { tl->from_cache = FALSE; image_loader_free (tl->il); thumb_loader_setup (tl, tl->path); if (image_loader_start (tl->il, cb_thumb_loader_done, tl)) return TRUE; } /* * mark failed thumbnail in cache with 0 byte file */ if (conf.enable_thumb_caching) { thumb_loader_mark_failure (tl); } image_loader_free (tl->il); tl->il = NULL; return FALSE; } return TRUE; }
static void cb_thumb_loader_done (ImageLoader * il, gpointer data) { ThumbLoader *tl = data; GdkPixbuf *pixbuf; gint pw, ph; gint save; pixbuf = image_loader_get_pixbuf (tl->il); if (!pixbuf) { cb_thumb_loader_error (tl->il, tl); return; } pw = gdk_pixbuf_get_width (pixbuf); ph = gdk_pixbuf_get_height (pixbuf); if (tl->from_cache && pw != tl->max_w && ph != tl->max_h) { /* * requested thumbnail size may have changed, load original */ tl->from_cache = FALSE; image_loader_free (tl->il); thumb_loader_setup (tl, tl->path); if (!image_loader_start (tl->il, cb_thumb_loader_done, tl)) cb_thumb_loader_error (tl->il, tl); return; } gdk_pixbuf_ref (pixbuf); /* * scale ?? */ if (pw > tl->max_w || ph > tl->max_h) { gint w, h; if (((float) tl->max_w / pw) < ((float) tl->max_h / ph)) { w = tl->max_w; h = (float) w / pw * ph; if (h < 1) h = 1; } else { h = tl->max_h; w = (float) h / ph * pw; if (w < 1) w = 1; } tl->pixbuf = gdk_pixbuf_scale_simple (pixbuf, w, h, (GdkInterpType) conf.thumbnail_quality); save = TRUE; } else { tl->pixbuf = pixbuf; save = FALSE; } gdk_pixbuf_ref (tl->pixbuf); gdk_pixbuf_unref (pixbuf); /* * save it ? */ if (conf.enable_thumb_caching && save) { thumb_loader_save_to_cache (tl); } if (tl->func_done) tl->func_done (tl, tl->data_done); }
static gboolean cache_loader_process(CacheLoader *cl) { if (cl->todo_mask & CACHE_LOADER_SIMILARITY && !cl->cd->similarity) { GdkPixbuf *pixbuf; if (!cl->il && !cl->error) { cl->il = image_loader_new(cl->fd); g_signal_connect(G_OBJECT(cl->il), "error", (GCallback)cache_loader_error_cb, cl); g_signal_connect(G_OBJECT(cl->il), "done", (GCallback)cache_loader_done_cb, cl); if (image_loader_start(cl->il)) { return FALSE; } cl->error = TRUE; } pixbuf = image_loader_get_pixbuf(cl->il); if (pixbuf) { if (!cl->error) { ImageSimilarityData *sim; sim = image_sim_new_from_pixbuf(pixbuf); cache_sim_data_set_similarity(cl->cd, sim); image_sim_free(sim); cl->done_mask |= CACHE_LOADER_SIMILARITY; } /* we have the dimensions via pixbuf */ if (!cl->cd->dimensions) { cache_sim_data_set_dimensions(cl->cd, gdk_pixbuf_get_width(pixbuf), gdk_pixbuf_get_height(pixbuf)); if (cl->todo_mask & CACHE_LOADER_DIMENSIONS) { cl->todo_mask &= ~CACHE_LOADER_DIMENSIONS; cl->done_mask |= CACHE_LOADER_DIMENSIONS; } } } image_loader_free(cl->il); cl->il = NULL; cl->todo_mask &= ~CACHE_LOADER_SIMILARITY; } else if (cl->todo_mask & CACHE_LOADER_DIMENSIONS && !cl->cd->dimensions) { if (!cl->error && image_load_dimensions(cl->fd, &cl->cd->width, &cl->cd->height)) { cl->cd->dimensions = TRUE; cl->done_mask |= CACHE_LOADER_DIMENSIONS; } else { cl->error = TRUE; } cl->todo_mask &= ~CACHE_LOADER_DIMENSIONS; } else if (cl->todo_mask & CACHE_LOADER_MD5SUM && !cl->cd->have_md5sum) { if (md5_get_digest_from_file_utf8(cl->fd->path, cl->cd->md5sum)) { cl->cd->have_md5sum = TRUE; cl->done_mask |= CACHE_LOADER_MD5SUM; } else { cl->error = TRUE; } cl->todo_mask &= ~CACHE_LOADER_MD5SUM; } else if (cl->todo_mask & CACHE_LOADER_DATE && !cl->cd->have_date) { time_t date = -1; gchar *text; text = metadata_read_string(cl->fd, "formatted.DateTime", METADATA_FORMATTED); if (text) { struct tm t; memset(&t, 0, sizeof(t)); if (sscanf(text, "%d:%d:%d %d:%d:%d", &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &t.tm_sec) == 6) { t.tm_year -= 1900; t.tm_mon -= 1; t.tm_isdst = -1; date = mktime(&t); } g_free(text); } cl->cd->date = date; cl->cd->have_date = TRUE; cl->done_mask |= CACHE_LOADER_DATE; cl->todo_mask &= ~CACHE_LOADER_DATE; } else { /* done, save then call done function */ if (options->thumbnails.enable_caching && cl->done_mask != CACHE_LOADER_NONE) { gchar *base; mode_t mode = 0755; base = cache_get_location(CACHE_TYPE_SIM, cl->fd->path, FALSE, &mode); if (recursive_mkdir_if_not_exists(base, mode)) { g_free(cl->cd->path); cl->cd->path = cache_get_location(CACHE_TYPE_SIM, cl->fd->path, TRUE, NULL); if (cache_sim_data_save(cl->cd)) { filetime_set(cl->cd->path, filetime(cl->fd->path)); } } g_free(base); } cl->idle_id = 0; if (cl->done_func) { cl->done_func(cl, cl->error, cl->done_data); } return FALSE; } return TRUE; }