void cache_sim_data_free(CacheData *cd) { if (!cd) return; g_free(cd->path); image_sim_free(cd->sim); g_free(cd); }
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; }
static gboolean cache_sim_read_similarity(FILE *f, gchar *buf, gint s, CacheData *cd) { if (!f || !buf || !cd) return FALSE; if (s < 11 || strncmp("Similarity", buf, 10) != 0) return FALSE; if (strncmp("Grid[32 x 32]", buf + 10, 13) != 0) return FALSE; if (fseek(f, - s, SEEK_CUR) == 0) { gchar b; guint8 pixel_buf[3]; ImageSimilarityData *sd; gint x, y; b = 'X'; while (b != '=') { if (fread(&b, sizeof(b), 1, f) != 1) return FALSE; } if (cd->sim) { /* use current sim that may already contain data we will not touch here */ sd = cd->sim; cd->sim = NULL; cd->similarity = FALSE; } else { sd = image_sim_new(); } for (y = 0; y < 32; y++) { gint s = y * 32; for (x = 0; x < 32; x++) { if (fread(&pixel_buf, sizeof(pixel_buf), 1, f) != 1) { image_sim_free(sd); return FALSE; } sd->avg_r[s + x] = pixel_buf[0]; sd->avg_g[s + x] = pixel_buf[1]; sd->avg_b[s + x] = pixel_buf[2]; } } if (fread(&b, sizeof(b), 1, f) == 1) { if (b != '\n') fseek(f, -1, SEEK_CUR); } cd->sim = sd; cd->sim->filled = TRUE; cd->similarity = TRUE; return TRUE; } return FALSE; }