From e12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Apr 2019 06:17:24 +0200 Subject: ClangFormat: apply to source, most of intern Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat --- source/blender/imbuf/intern/thumbs.c | 1129 +++++++++++++++++++--------------- 1 file changed, 620 insertions(+), 509 deletions(-) (limited to 'source/blender/imbuf/intern/thumbs.c') diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c index 6c71aa06583..fc5bfe42d60 100644 --- a/source/blender/imbuf/intern/thumbs.c +++ b/source/blender/imbuf/intern/thumbs.c @@ -36,7 +36,7 @@ #include "BLI_threads.h" #include BLI_SYSTEM_PID_H -#include "DNA_space_types.h" /* For FILE_MAX_LIBEXTRA */ +#include "DNA_space_types.h" /* For FILE_MAX_LIBEXTRA */ #include "BLO_readfile.h" @@ -53,13 +53,13 @@ #include #ifdef WIN32 - /* Need to include windows.h so _WIN32_IE is defined. */ +/* Need to include windows.h so _WIN32_IE is defined. */ # include # ifndef _WIN32_IE - /* Minimal requirements for SHGetSpecialFolderPath on MINGW MSVC has this defined already. */ +/* Minimal requirements for SHGetSpecialFolderPath on MINGW MSVC has this defined already. */ # define _WIN32_IE 0x0400 # endif - /* For SHGetSpecialFolderPath, has to be done before BLI_winstuff +/* For SHGetSpecialFolderPath, has to be done before BLI_winstuff * because 'near' is disabled through BLI_windstuff */ # include # include /* chdir */ @@ -68,7 +68,7 @@ #endif #if defined(WIN32) || defined(__APPLE__) - /* pass */ +/* pass */ #else # define USE_FREEDESKTOP #endif @@ -84,554 +84,665 @@ static bool get_thumb_dir(char *dir, ThumbSize size) { - char *s = dir; - const char *subdir; + char *s = dir; + const char *subdir; #ifdef WIN32 - wchar_t dir_16[MAX_PATH]; - /* yes, applications shouldn't store data there, but so does GIMP :)*/ - SHGetSpecialFolderPathW(0, dir_16, CSIDL_PROFILE, 0); - conv_utf_16_to_8(dir_16, dir, FILE_MAX); - s += strlen(dir); + wchar_t dir_16[MAX_PATH]; + /* yes, applications shouldn't store data there, but so does GIMP :)*/ + SHGetSpecialFolderPathW(0, dir_16, CSIDL_PROFILE, 0); + conv_utf_16_to_8(dir_16, dir, FILE_MAX); + s += strlen(dir); #else -#if defined(USE_FREEDESKTOP) - const char *home_cache = BLI_getenv("XDG_CACHE_HOME"); - const char *home = home_cache ? home_cache : BLI_getenv("HOME"); -#else - const char *home = BLI_getenv("HOME"); -#endif - if (!home) return 0; - s += BLI_strncpy_rlen(s, home, FILE_MAX); - -#ifdef USE_FREEDESKTOP - if (!home_cache) { - s += BLI_strncpy_rlen(s, "/.cache", FILE_MAX - (s - dir)); - } -#endif +# if defined(USE_FREEDESKTOP) + const char *home_cache = BLI_getenv("XDG_CACHE_HOME"); + const char *home = home_cache ? home_cache : BLI_getenv("HOME"); +# else + const char *home = BLI_getenv("HOME"); +# endif + if (!home) + return 0; + s += BLI_strncpy_rlen(s, home, FILE_MAX); + +# ifdef USE_FREEDESKTOP + if (!home_cache) { + s += BLI_strncpy_rlen(s, "/.cache", FILE_MAX - (s - dir)); + } +# endif #endif - switch (size) { - case THB_NORMAL: - subdir = "/" THUMBNAILS "/normal/"; - break; - case THB_LARGE: - subdir = "/" THUMBNAILS "/large/"; - break; - case THB_FAIL: - subdir = "/" THUMBNAILS "/fail/blender/"; - break; - default: - return 0; /* unknown size */ - } - - s += BLI_strncpy_rlen(s, subdir, FILE_MAX - (s - dir)); - (void)s; - - return 1; + switch (size) { + case THB_NORMAL: + subdir = "/" THUMBNAILS "/normal/"; + break; + case THB_LARGE: + subdir = "/" THUMBNAILS "/large/"; + break; + case THB_FAIL: + subdir = "/" THUMBNAILS "/fail/blender/"; + break; + default: + return 0; /* unknown size */ + } + + s += BLI_strncpy_rlen(s, subdir, FILE_MAX - (s - dir)); + (void)s; + + return 1; } #undef THUMBNAILS - /** ----- begin of adapted code from glib --- * The following code is adapted from function g_escape_uri_string from the gnome glib * Source: http://svn.gnome.org/viewcvs/glib/trunk/glib/gconvert.c?view=markup * released under the Gnu General Public License. */ typedef enum { - UNSAFE_ALL = 0x1, /* Escape all unsafe characters */ - UNSAFE_ALLOW_PLUS = 0x2, /* Allows '+' */ - UNSAFE_PATH = 0x8, /* Allows '/', '&', '=', ':', '@', '+', '$' and ',' */ - UNSAFE_HOST = 0x10, /* Allows '/' and ':' and '@' */ - UNSAFE_SLASHES = 0x20, /* Allows all characters except for '/' and '%' */ + UNSAFE_ALL = 0x1, /* Escape all unsafe characters */ + UNSAFE_ALLOW_PLUS = 0x2, /* Allows '+' */ + UNSAFE_PATH = 0x8, /* Allows '/', '&', '=', ':', '@', '+', '$' and ',' */ + UNSAFE_HOST = 0x10, /* Allows '/' and ':' and '@' */ + UNSAFE_SLASHES = 0x20, /* Allows all characters except for '/' and '%' */ } UnsafeCharacterSet; static const unsigned char acceptable[96] = { - /* A table of the ASCII chars from space (32) to DEL (127) */ - /* ! " # $ % & ' ( ) * + , - . / */ - 0x00,0x3F,0x20,0x20,0x28,0x00,0x2C,0x3F,0x3F,0x3F,0x3F,0x2A,0x28,0x3F,0x3F,0x1C, - /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ - 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x38,0x20,0x20,0x2C,0x20,0x20, - /* @ A B C D E F G H I J K L M N O */ - 0x38,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, - /* P Q R S T U V W X Y Z [ \ ] ^ _ */ - 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x20,0x3F, - /* ` a b c d e f g h i j k l m n o */ - 0x20,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, - /* p q r s t u v w x y z { | } ~ DEL */ - 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x3F,0x20, + /* A table of the ASCII chars from space (32) to DEL (127) */ + /* ! " # $ % & ' ( ) * + , - . / */ + 0x00, + 0x3F, + 0x20, + 0x20, + 0x28, + 0x00, + 0x2C, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x2A, + 0x28, + 0x3F, + 0x3F, + 0x1C, + /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */ + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x38, + 0x20, + 0x20, + 0x2C, + 0x20, + 0x20, + /* @ A B C D E F G H I J K L M N O */ + 0x38, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + /* P Q R S T U V W X Y Z [ \ ] ^ _ */ + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x20, + 0x20, + 0x20, + 0x20, + 0x3F, + /* ` a b c d e f g h i j k l m n o */ + 0x20, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + /* p q r s t u v w x y z { | } ~ DEL */ + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x3F, + 0x20, + 0x20, + 0x20, + 0x3F, + 0x20, }; static const char hex[17] = "0123456789abcdef"; /* Note: This escape function works on file: URIs, but if you want to * escape something else, please read RFC-2396 */ -static void escape_uri_string(const char *string, char *escaped_string, int escaped_string_size, UnsafeCharacterSet mask) +static void escape_uri_string(const char *string, + char *escaped_string, + int escaped_string_size, + UnsafeCharacterSet mask) { -#define ACCEPTABLE(a) ((a) >= 32 && (a) < 128 && (acceptable[(a) - 32] & use_mask)) - - const char *p; - char *q; - int c; - UnsafeCharacterSet use_mask; - use_mask = mask; - - BLI_assert(escaped_string_size > 0); - - /* space for \0 */ - escaped_string_size -= 1; - - for (q = escaped_string, p = string; (*p != '\0') && escaped_string_size; p++) { - c = (unsigned char) *p; - - if (!ACCEPTABLE(c)) { - if (escaped_string_size < 3) { - break; - } - - *q++ = '%'; /* means hex coming */ - *q++ = hex[c >> 4]; - *q++ = hex[c & 15]; - escaped_string_size -= 3; - } - else { - *q++ = *p; - escaped_string_size -= 1; - } - } - - *q = '\0'; +#define ACCEPTABLE(a) ((a) >= 32 && (a) < 128 && (acceptable[(a)-32] & use_mask)) + + const char *p; + char *q; + int c; + UnsafeCharacterSet use_mask; + use_mask = mask; + + BLI_assert(escaped_string_size > 0); + + /* space for \0 */ + escaped_string_size -= 1; + + for (q = escaped_string, p = string; (*p != '\0') && escaped_string_size; p++) { + c = (unsigned char)*p; + + if (!ACCEPTABLE(c)) { + if (escaped_string_size < 3) { + break; + } + + *q++ = '%'; /* means hex coming */ + *q++ = hex[c >> 4]; + *q++ = hex[c & 15]; + escaped_string_size -= 3; + } + else { + *q++ = *p; + escaped_string_size -= 1; + } + } + + *q = '\0'; } /** ----- end of adapted code from glib --- */ static bool thumbhash_from_path(const char *UNUSED(path), ThumbSource source, char *r_hash) { - switch (source) { - case THB_SOURCE_FONT: - return IMB_thumb_load_font_get_hash(r_hash); - default: - r_hash[0] = '\0'; - return false; - } + switch (source) { + case THB_SOURCE_FONT: + return IMB_thumb_load_font_get_hash(r_hash); + default: + r_hash[0] = '\0'; + return false; + } } static bool uri_from_filename(const char *path, char *uri) { - char orig_uri[URI_MAX]; - const char *dirstart = path; + char orig_uri[URI_MAX]; + const char *dirstart = path; #ifdef WIN32 - { - char vol[3]; - - BLI_strncpy(orig_uri, "file:///", FILE_MAX); - if (strlen(path) < 2 && path[1] != ':') { - /* not a correct absolute path */ - return 0; - } - /* on windows, using always uppercase drive/volume letter in uri */ - vol[0] = (unsigned char)toupper(path[0]); - vol[1] = ':'; - vol[2] = '\0'; - strcat(orig_uri, vol); - dirstart += 2; - } - strcat(orig_uri, dirstart); - BLI_str_replace_char(orig_uri, '\\', '/'); + { + char vol[3]; + + BLI_strncpy(orig_uri, "file:///", FILE_MAX); + if (strlen(path) < 2 && path[1] != ':') { + /* not a correct absolute path */ + return 0; + } + /* on windows, using always uppercase drive/volume letter in uri */ + vol[0] = (unsigned char)toupper(path[0]); + vol[1] = ':'; + vol[2] = '\0'; + strcat(orig_uri, vol); + dirstart += 2; + } + strcat(orig_uri, dirstart); + BLI_str_replace_char(orig_uri, '\\', '/'); #else - BLI_snprintf(orig_uri, URI_MAX, "file://%s", dirstart); + BLI_snprintf(orig_uri, URI_MAX, "file://%s", dirstart); #endif - escape_uri_string(orig_uri, uri, URI_MAX, UNSAFE_PATH); + escape_uri_string(orig_uri, uri, URI_MAX, UNSAFE_PATH); - return 1; + return 1; } static bool thumbpathname_from_uri( - const char *uri, char *r_path, const int path_len, char *r_name, int name_len, ThumbSize size) + const char *uri, char *r_path, const int path_len, char *r_name, int name_len, ThumbSize size) { - char name_buff[40]; - - if (r_path && !r_name) { - r_name = name_buff; - name_len = sizeof(name_buff); - } - - if (r_name) { - char hexdigest[33]; - unsigned char digest[16]; - BLI_hash_md5_buffer(uri, strlen(uri), digest); - hexdigest[0] = '\0'; - BLI_snprintf(r_name, name_len, "%s.png", BLI_hash_md5_to_hexdigest(digest, hexdigest)); -// printf("%s: '%s' --> '%s'\n", __func__, uri, r_name); - } - - if (r_path) { - char tmppath[FILE_MAX]; - - if (get_thumb_dir(tmppath, size)) { - BLI_snprintf(r_path, path_len, "%s%s", tmppath, r_name); -// printf("%s: '%s' --> '%s'\n", __func__, uri, r_path); - return true; - } - } - return false; + char name_buff[40]; + + if (r_path && !r_name) { + r_name = name_buff; + name_len = sizeof(name_buff); + } + + if (r_name) { + char hexdigest[33]; + unsigned char digest[16]; + BLI_hash_md5_buffer(uri, strlen(uri), digest); + hexdigest[0] = '\0'; + BLI_snprintf(r_name, name_len, "%s.png", BLI_hash_md5_to_hexdigest(digest, hexdigest)); + // printf("%s: '%s' --> '%s'\n", __func__, uri, r_name); + } + + if (r_path) { + char tmppath[FILE_MAX]; + + if (get_thumb_dir(tmppath, size)) { + BLI_snprintf(r_path, path_len, "%s%s", tmppath, r_name); + // printf("%s: '%s' --> '%s'\n", __func__, uri, r_path); + return true; + } + } + return false; } static void thumbname_from_uri(const char *uri, char *thumb, const int thumb_len) { - thumbpathname_from_uri(uri, NULL, 0, thumb, thumb_len, THB_FAIL); + thumbpathname_from_uri(uri, NULL, 0, thumb, thumb_len, THB_FAIL); } static bool thumbpath_from_uri(const char *uri, char *path, const int path_len, ThumbSize size) { - return thumbpathname_from_uri(uri, path, path_len, NULL, 0, size); + return thumbpathname_from_uri(uri, path, path_len, NULL, 0, size); } void IMB_thumb_makedirs(void) { - char tpath[FILE_MAX]; -#if 0 /* UNUSED */ - if (get_thumb_dir(tpath, THB_NORMAL)) { - BLI_dir_create_recursive(tpath); - } + char tpath[FILE_MAX]; +#if 0 /* UNUSED */ + if (get_thumb_dir(tpath, THB_NORMAL)) { + BLI_dir_create_recursive(tpath); + } #endif - if (get_thumb_dir(tpath, THB_LARGE)) { - BLI_dir_create_recursive(tpath); - } - if (get_thumb_dir(tpath, THB_FAIL)) { - BLI_dir_create_recursive(tpath); - } + if (get_thumb_dir(tpath, THB_LARGE)) { + BLI_dir_create_recursive(tpath); + } + if (get_thumb_dir(tpath, THB_FAIL)) { + BLI_dir_create_recursive(tpath); + } } /* create thumbnail for file and returns new imbuf for thumbnail */ -static ImBuf *thumb_create_ex( - const char *file_path, const char *uri, const char *thumb, const bool use_hash, const char *hash, - const char *blen_group, const char *blen_id, - ThumbSize size, ThumbSource source, ImBuf *img) +static ImBuf *thumb_create_ex(const char *file_path, + const char *uri, + const char *thumb, + const bool use_hash, + const char *hash, + const char *blen_group, + const char *blen_id, + ThumbSize size, + ThumbSource source, + ImBuf *img) { - char desc[URI_MAX + 22]; - char tpath[FILE_MAX]; - char tdir[FILE_MAX]; - char temp[FILE_MAX]; - char mtime[40] = "0"; /* in case we can't stat the file */ - char cwidth[40] = "0"; /* in case images have no data */ - char cheight[40] = "0"; - short tsize = 128; - short ex, ey; - float scaledx, scaledy; - BLI_stat_t info; - - switch (size) { - case THB_NORMAL: - tsize = PREVIEW_RENDER_DEFAULT_HEIGHT; - break; - case THB_LARGE: - tsize = PREVIEW_RENDER_DEFAULT_HEIGHT * 2; - break; - case THB_FAIL: - tsize = 1; - break; - default: - return NULL; /* unknown size */ - } - - /* exception, skip images over 100mb */ - if (source == THB_SOURCE_IMAGE) { - const size_t file_size = BLI_file_size(file_path); - if (file_size != -1 && file_size > THUMB_SIZE_MAX) { - // printf("file too big: %d, skipping %s\n", (int)size, file_path); - return NULL; - } - } - - if (get_thumb_dir(tdir, size)) { - BLI_snprintf(tpath, FILE_MAX, "%s%s", tdir, thumb); -// thumb[8] = '\0'; /* shorten for tempname, not needed anymore */ - BLI_snprintf(temp, FILE_MAX, "%sblender_%d_%s.png", tdir, abs(getpid()), thumb); - if (BLI_path_ncmp(file_path, tdir, sizeof(tdir)) == 0) { - return NULL; - } - if (size == THB_FAIL) { - img = IMB_allocImBuf(1, 1, 32, IB_rect | IB_metadata); - if (!img) return NULL; - } - else { - if (ELEM(source, THB_SOURCE_IMAGE, THB_SOURCE_BLEND, THB_SOURCE_FONT)) { - /* only load if we didn't give an image */ - if (img == NULL) { - switch (source) { - case THB_SOURCE_IMAGE: - img = IMB_loadiffname(file_path, IB_rect | IB_metadata, NULL); - break; - case THB_SOURCE_BLEND: - img = IMB_thumb_load_blend(file_path, blen_group, blen_id); - break; - case THB_SOURCE_FONT: - img = IMB_thumb_load_font(file_path, tsize, tsize); - break; - default: - BLI_assert(0); /* This should never happen */ - } - } - - if (img != NULL) { - if (BLI_stat(file_path, &info) != -1) { - BLI_snprintf(mtime, sizeof(mtime), "%ld", (long int)info.st_mtime); - } - BLI_snprintf(cwidth, sizeof(cwidth), "%d", img->x); - BLI_snprintf(cheight, sizeof(cheight), "%d", img->y); - } - } - else if (THB_SOURCE_MOVIE == source) { - struct anim *anim = NULL; - anim = IMB_open_anim(file_path, IB_rect | IB_metadata, 0, NULL); - if (anim != NULL) { - img = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE); - if (img == NULL) { - printf("not an anim; %s\n", file_path); - } - else { - IMB_freeImBuf(img); - img = IMB_anim_previewframe(anim); - } - IMB_free_anim(anim); - } - if (BLI_stat(file_path, &info) != -1) { - BLI_snprintf(mtime, sizeof(mtime), "%ld", (long int)info.st_mtime); - } - } - if (!img) return NULL; - - if (img->x > img->y) { - scaledx = (float)tsize; - scaledy = ( (float)img->y / (float)img->x) * tsize; - } - else { - scaledy = (float)tsize; - scaledx = ( (float)img->x / (float)img->y) * tsize; - } - ex = (short)scaledx; - ey = (short)scaledy; - - /* save some time by only scaling byte buf */ - if (img->rect_float) { - if (img->rect == NULL) { - IMB_rect_from_float(img); - } - - imb_freerectfloatImBuf(img); - } - - IMB_scaleImBuf(img, ex, ey); - } - BLI_snprintf(desc, sizeof(desc), "Thumbnail for %s", uri); - IMB_metadata_ensure(&img->metadata); - IMB_metadata_set_field(img->metadata, "Software", "Blender"); - IMB_metadata_set_field(img->metadata, "Thumb::URI", uri); - IMB_metadata_set_field(img->metadata, "Description", desc); - IMB_metadata_set_field(img->metadata, "Thumb::MTime", mtime); - if (use_hash) { - IMB_metadata_set_field(img->metadata, "X-Blender::Hash", hash); - } - if (ELEM(source, THB_SOURCE_IMAGE, THB_SOURCE_BLEND, THB_SOURCE_FONT)) { - IMB_metadata_set_field(img->metadata, "Thumb::Image::Width", cwidth); - IMB_metadata_set_field(img->metadata, "Thumb::Image::Height", cheight); - } - img->ftype = IMB_FTYPE_PNG; - img->planes = 32; - - /* If we generated from a 16bit PNG e.g., we have a float rect, not a byte one - fix this. */ - IMB_rect_from_float(img); - imb_freerectfloatImBuf(img); - - if (IMB_saveiff(img, temp, IB_rect | IB_metadata)) { + char desc[URI_MAX + 22]; + char tpath[FILE_MAX]; + char tdir[FILE_MAX]; + char temp[FILE_MAX]; + char mtime[40] = "0"; /* in case we can't stat the file */ + char cwidth[40] = "0"; /* in case images have no data */ + char cheight[40] = "0"; + short tsize = 128; + short ex, ey; + float scaledx, scaledy; + BLI_stat_t info; + + switch (size) { + case THB_NORMAL: + tsize = PREVIEW_RENDER_DEFAULT_HEIGHT; + break; + case THB_LARGE: + tsize = PREVIEW_RENDER_DEFAULT_HEIGHT * 2; + break; + case THB_FAIL: + tsize = 1; + break; + default: + return NULL; /* unknown size */ + } + + /* exception, skip images over 100mb */ + if (source == THB_SOURCE_IMAGE) { + const size_t file_size = BLI_file_size(file_path); + if (file_size != -1 && file_size > THUMB_SIZE_MAX) { + // printf("file too big: %d, skipping %s\n", (int)size, file_path); + return NULL; + } + } + + if (get_thumb_dir(tdir, size)) { + BLI_snprintf(tpath, FILE_MAX, "%s%s", tdir, thumb); + // thumb[8] = '\0'; /* shorten for tempname, not needed anymore */ + BLI_snprintf(temp, FILE_MAX, "%sblender_%d_%s.png", tdir, abs(getpid()), thumb); + if (BLI_path_ncmp(file_path, tdir, sizeof(tdir)) == 0) { + return NULL; + } + if (size == THB_FAIL) { + img = IMB_allocImBuf(1, 1, 32, IB_rect | IB_metadata); + if (!img) + return NULL; + } + else { + if (ELEM(source, THB_SOURCE_IMAGE, THB_SOURCE_BLEND, THB_SOURCE_FONT)) { + /* only load if we didn't give an image */ + if (img == NULL) { + switch (source) { + case THB_SOURCE_IMAGE: + img = IMB_loadiffname(file_path, IB_rect | IB_metadata, NULL); + break; + case THB_SOURCE_BLEND: + img = IMB_thumb_load_blend(file_path, blen_group, blen_id); + break; + case THB_SOURCE_FONT: + img = IMB_thumb_load_font(file_path, tsize, tsize); + break; + default: + BLI_assert(0); /* This should never happen */ + } + } + + if (img != NULL) { + if (BLI_stat(file_path, &info) != -1) { + BLI_snprintf(mtime, sizeof(mtime), "%ld", (long int)info.st_mtime); + } + BLI_snprintf(cwidth, sizeof(cwidth), "%d", img->x); + BLI_snprintf(cheight, sizeof(cheight), "%d", img->y); + } + } + else if (THB_SOURCE_MOVIE == source) { + struct anim *anim = NULL; + anim = IMB_open_anim(file_path, IB_rect | IB_metadata, 0, NULL); + if (anim != NULL) { + img = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE); + if (img == NULL) { + printf("not an anim; %s\n", file_path); + } + else { + IMB_freeImBuf(img); + img = IMB_anim_previewframe(anim); + } + IMB_free_anim(anim); + } + if (BLI_stat(file_path, &info) != -1) { + BLI_snprintf(mtime, sizeof(mtime), "%ld", (long int)info.st_mtime); + } + } + if (!img) + return NULL; + + if (img->x > img->y) { + scaledx = (float)tsize; + scaledy = ((float)img->y / (float)img->x) * tsize; + } + else { + scaledy = (float)tsize; + scaledx = ((float)img->x / (float)img->y) * tsize; + } + ex = (short)scaledx; + ey = (short)scaledy; + + /* save some time by only scaling byte buf */ + if (img->rect_float) { + if (img->rect == NULL) { + IMB_rect_from_float(img); + } + + imb_freerectfloatImBuf(img); + } + + IMB_scaleImBuf(img, ex, ey); + } + BLI_snprintf(desc, sizeof(desc), "Thumbnail for %s", uri); + IMB_metadata_ensure(&img->metadata); + IMB_metadata_set_field(img->metadata, "Software", "Blender"); + IMB_metadata_set_field(img->metadata, "Thumb::URI", uri); + IMB_metadata_set_field(img->metadata, "Description", desc); + IMB_metadata_set_field(img->metadata, "Thumb::MTime", mtime); + if (use_hash) { + IMB_metadata_set_field(img->metadata, "X-Blender::Hash", hash); + } + if (ELEM(source, THB_SOURCE_IMAGE, THB_SOURCE_BLEND, THB_SOURCE_FONT)) { + IMB_metadata_set_field(img->metadata, "Thumb::Image::Width", cwidth); + IMB_metadata_set_field(img->metadata, "Thumb::Image::Height", cheight); + } + img->ftype = IMB_FTYPE_PNG; + img->planes = 32; + + /* If we generated from a 16bit PNG e.g., we have a float rect, not a byte one - fix this. */ + IMB_rect_from_float(img); + imb_freerectfloatImBuf(img); + + if (IMB_saveiff(img, temp, IB_rect | IB_metadata)) { #ifndef WIN32 - chmod(temp, S_IRUSR | S_IWUSR); + chmod(temp, S_IRUSR | S_IWUSR); #endif - // printf("%s saving thumb: '%s'\n", __func__, tpath); + // printf("%s saving thumb: '%s'\n", __func__, tpath); - BLI_rename(temp, tpath); - } - } - return img; + BLI_rename(temp, tpath); + } + } + return img; } -static ImBuf *thumb_create_or_fail( - const char *file_path, const char *uri, const char *thumb, const bool use_hash, const char *hash, - const char *blen_group, const char *blen_id, ThumbSize size, ThumbSource source) +static ImBuf *thumb_create_or_fail(const char *file_path, + const char *uri, + const char *thumb, + const bool use_hash, + const char *hash, + const char *blen_group, + const char *blen_id, + ThumbSize size, + ThumbSource source) { - ImBuf *img = thumb_create_ex(file_path, uri, thumb, use_hash, hash, blen_group, blen_id, size, source, NULL); - - if (!img) { - /* thumb creation failed, write fail thumb */ - img = thumb_create_ex(file_path, uri, thumb, use_hash, hash, blen_group, blen_id, THB_FAIL, source, NULL); - if (img) { - /* we don't need failed thumb anymore */ - IMB_freeImBuf(img); - img = NULL; - } - } - - return img; + ImBuf *img = thumb_create_ex( + file_path, uri, thumb, use_hash, hash, blen_group, blen_id, size, source, NULL); + + if (!img) { + /* thumb creation failed, write fail thumb */ + img = thumb_create_ex( + file_path, uri, thumb, use_hash, hash, blen_group, blen_id, THB_FAIL, source, NULL); + if (img) { + /* we don't need failed thumb anymore */ + IMB_freeImBuf(img); + img = NULL; + } + } + + return img; } ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, ImBuf *img) { - char uri[URI_MAX] = ""; - char thumb_name[40]; + char uri[URI_MAX] = ""; + char thumb_name[40]; - if (!uri_from_filename(path, uri)) { - return NULL; - } - thumbname_from_uri(uri, thumb_name, sizeof(thumb_name)); + if (!uri_from_filename(path, uri)) { + return NULL; + } + thumbname_from_uri(uri, thumb_name, sizeof(thumb_name)); - return thumb_create_ex(path, uri, thumb_name, false, THUMB_DEFAULT_HASH, NULL, NULL, size, source, img); + return thumb_create_ex( + path, uri, thumb_name, false, THUMB_DEFAULT_HASH, NULL, NULL, size, source, img); } /* read thumbnail for file and returns new imbuf for thumbnail */ ImBuf *IMB_thumb_read(const char *path, ThumbSize size) { - char thumb[FILE_MAX]; - char uri[URI_MAX]; - ImBuf *img = NULL; - - if (!uri_from_filename(path, uri)) { - return NULL; - } - if (thumbpath_from_uri(uri, thumb, sizeof(thumb), size)) { - img = IMB_loadiffname(thumb, IB_rect | IB_metadata, NULL); - } - - return img; + char thumb[FILE_MAX]; + char uri[URI_MAX]; + ImBuf *img = NULL; + + if (!uri_from_filename(path, uri)) { + return NULL; + } + if (thumbpath_from_uri(uri, thumb, sizeof(thumb), size)) { + img = IMB_loadiffname(thumb, IB_rect | IB_metadata, NULL); + } + + return img; } /* delete all thumbs for the file */ void IMB_thumb_delete(const char *path, ThumbSize size) { - char thumb[FILE_MAX]; - char uri[URI_MAX]; - - if (!uri_from_filename(path, uri)) { - return; - } - if (thumbpath_from_uri(uri, thumb, sizeof(thumb), size)) { - if (BLI_path_ncmp(path, thumb, sizeof(thumb)) == 0) { - return; - } - if (BLI_exists(thumb)) { - BLI_delete(thumb, false, false); - } - } + char thumb[FILE_MAX]; + char uri[URI_MAX]; + + if (!uri_from_filename(path, uri)) { + return; + } + if (thumbpath_from_uri(uri, thumb, sizeof(thumb), size)) { + if (BLI_path_ncmp(path, thumb, sizeof(thumb)) == 0) { + return; + } + if (BLI_exists(thumb)) { + BLI_delete(thumb, false, false); + } + } } - /* create the thumb if necessary and manage failed and old thumbs */ ImBuf *IMB_thumb_manage(const char *org_path, ThumbSize size, ThumbSource source) { - char thumb_path[FILE_MAX]; - char thumb_name[40]; - char uri[URI_MAX]; - char path_buff[FILE_MAX_LIBEXTRA]; - const char *file_path; - const char *path; - BLI_stat_t st; - ImBuf *img = NULL; - char *blen_group = NULL, *blen_id = NULL; - - path = file_path = org_path; - if (source == THB_SOURCE_BLEND) { - if (BLO_library_path_explode(path, path_buff, &blen_group, &blen_id)) { - if (blen_group) { - if (!blen_id) { - /* No preview for blen groups */ - return NULL; - } - file_path = path_buff; /* path needs to be a valid file! */ - } - } - } - - if (BLI_stat(file_path, &st) == -1) { - return NULL; - } - if (!uri_from_filename(path, uri)) { - return NULL; - } - if (thumbpath_from_uri(uri, thumb_path, sizeof(thumb_path), THB_FAIL)) { - /* failure thumb exists, don't try recreating */ - if (BLI_exists(thumb_path)) { - /* clear out of date fail case (note for blen IDs we use blender file itself here) */ - if (BLI_file_older(thumb_path, file_path)) { - BLI_delete(thumb_path, false, false); - } - else { - return NULL; - } - } - } - - if (thumbpathname_from_uri(uri, thumb_path, sizeof(thumb_path), thumb_name, sizeof(thumb_name), size)) { - if (BLI_path_ncmp(path, thumb_path, sizeof(thumb_path)) == 0) { - img = IMB_loadiffname(path, IB_rect, NULL); - } - else { - img = IMB_loadiffname(thumb_path, IB_rect | IB_metadata, NULL); - if (img) { - bool regenerate = false; - - char mtime[40]; - char thumb_hash[33]; - char thumb_hash_curr[33]; - - const bool use_hash = thumbhash_from_path(file_path, source, thumb_hash); - - if (IMB_metadata_get_field(img->metadata, "Thumb::MTime", mtime, sizeof(mtime))) { - regenerate = (st.st_mtime != atol(mtime)); - } - else { - /* illegal thumb, regenerate it! */ - regenerate = true; - } - - if (use_hash && !regenerate) { - if (IMB_metadata_get_field(img->metadata, "X-Blender::Hash", thumb_hash_curr, sizeof(thumb_hash_curr))) { - regenerate = !STREQ(thumb_hash, thumb_hash_curr); - } - else { - regenerate = true; - } - } - - if (regenerate) { - /* recreate all thumbs */ - IMB_freeImBuf(img); - img = NULL; - IMB_thumb_delete(path, THB_NORMAL); - IMB_thumb_delete(path, THB_LARGE); - IMB_thumb_delete(path, THB_FAIL); - img = thumb_create_or_fail( - file_path, uri, thumb_name, use_hash, thumb_hash, blen_group, blen_id, size, source); - } - } - else { - char thumb_hash[33]; - const bool use_hash = thumbhash_from_path(file_path, source, thumb_hash); - - img = thumb_create_or_fail( - file_path, uri, thumb_name, use_hash, thumb_hash, blen_group, blen_id, size, source); - } - } - } - - /* Our imbuf **must** have a valid rect (i.e. 8-bits/channels) data, we rely on this in draw code. - * However, in some cases we may end loading 16bits PNGs, which generated float buffers. - * This should be taken care of in generation step, but add also a safeguard here! */ - if (img) { - IMB_rect_from_float(img); - imb_freerectfloatImBuf(img); - } - - return img; + char thumb_path[FILE_MAX]; + char thumb_name[40]; + char uri[URI_MAX]; + char path_buff[FILE_MAX_LIBEXTRA]; + const char *file_path; + const char *path; + BLI_stat_t st; + ImBuf *img = NULL; + char *blen_group = NULL, *blen_id = NULL; + + path = file_path = org_path; + if (source == THB_SOURCE_BLEND) { + if (BLO_library_path_explode(path, path_buff, &blen_group, &blen_id)) { + if (blen_group) { + if (!blen_id) { + /* No preview for blen groups */ + return NULL; + } + file_path = path_buff; /* path needs to be a valid file! */ + } + } + } + + if (BLI_stat(file_path, &st) == -1) { + return NULL; + } + if (!uri_from_filename(path, uri)) { + return NULL; + } + if (thumbpath_from_uri(uri, thumb_path, sizeof(thumb_path), THB_FAIL)) { + /* failure thumb exists, don't try recreating */ + if (BLI_exists(thumb_path)) { + /* clear out of date fail case (note for blen IDs we use blender file itself here) */ + if (BLI_file_older(thumb_path, file_path)) { + BLI_delete(thumb_path, false, false); + } + else { + return NULL; + } + } + } + + if (thumbpathname_from_uri( + uri, thumb_path, sizeof(thumb_path), thumb_name, sizeof(thumb_name), size)) { + if (BLI_path_ncmp(path, thumb_path, sizeof(thumb_path)) == 0) { + img = IMB_loadiffname(path, IB_rect, NULL); + } + else { + img = IMB_loadiffname(thumb_path, IB_rect | IB_metadata, NULL); + if (img) { + bool regenerate = false; + + char mtime[40]; + char thumb_hash[33]; + char thumb_hash_curr[33]; + + const bool use_hash = thumbhash_from_path(file_path, source, thumb_hash); + + if (IMB_metadata_get_field(img->metadata, "Thumb::MTime", mtime, sizeof(mtime))) { + regenerate = (st.st_mtime != atol(mtime)); + } + else { + /* illegal thumb, regenerate it! */ + regenerate = true; + } + + if (use_hash && !regenerate) { + if (IMB_metadata_get_field( + img->metadata, "X-Blender::Hash", thumb_hash_curr, sizeof(thumb_hash_curr))) { + regenerate = !STREQ(thumb_hash, thumb_hash_curr); + } + else { + regenerate = true; + } + } + + if (regenerate) { + /* recreate all thumbs */ + IMB_freeImBuf(img); + img = NULL; + IMB_thumb_delete(path, THB_NORMAL); + IMB_thumb_delete(path, THB_LARGE); + IMB_thumb_delete(path, THB_FAIL); + img = thumb_create_or_fail( + file_path, uri, thumb_name, use_hash, thumb_hash, blen_group, blen_id, size, source); + } + } + else { + char thumb_hash[33]; + const bool use_hash = thumbhash_from_path(file_path, source, thumb_hash); + + img = thumb_create_or_fail( + file_path, uri, thumb_name, use_hash, thumb_hash, blen_group, blen_id, size, source); + } + } + } + + /* Our imbuf **must** have a valid rect (i.e. 8-bits/channels) data, we rely on this in draw code. + * However, in some cases we may end loading 16bits PNGs, which generated float buffers. + * This should be taken care of in generation step, but add also a safeguard here! */ + if (img) { + IMB_rect_from_float(img); + imb_freerectfloatImBuf(img); + } + + return img; } /* ***** Threading ***** */ @@ -641,71 +752,71 @@ ImBuf *IMB_thumb_manage(const char *org_path, ThumbSize size, ThumbSource source */ static struct IMBThumbLocks { - GSet *locked_paths; - int lock_counter; - ThreadCondition cond; + GSet *locked_paths; + int lock_counter; + ThreadCondition cond; } thumb_locks = {0}; void IMB_thumb_locks_acquire(void) { - BLI_thread_lock(LOCK_IMAGE); - - if (thumb_locks.lock_counter == 0) { - BLI_assert(thumb_locks.locked_paths == NULL); - thumb_locks.locked_paths = BLI_gset_str_new(__func__); - BLI_condition_init(&thumb_locks.cond); - } - thumb_locks.lock_counter++; - - BLI_assert(thumb_locks.locked_paths != NULL); - BLI_assert(thumb_locks.lock_counter > 0); - BLI_thread_unlock(LOCK_IMAGE); + BLI_thread_lock(LOCK_IMAGE); + + if (thumb_locks.lock_counter == 0) { + BLI_assert(thumb_locks.locked_paths == NULL); + thumb_locks.locked_paths = BLI_gset_str_new(__func__); + BLI_condition_init(&thumb_locks.cond); + } + thumb_locks.lock_counter++; + + BLI_assert(thumb_locks.locked_paths != NULL); + BLI_assert(thumb_locks.lock_counter > 0); + BLI_thread_unlock(LOCK_IMAGE); } void IMB_thumb_locks_release(void) { - BLI_thread_lock(LOCK_IMAGE); - BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0)); + BLI_thread_lock(LOCK_IMAGE); + BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0)); - thumb_locks.lock_counter--; - if (thumb_locks.lock_counter == 0) { - BLI_gset_free(thumb_locks.locked_paths, MEM_freeN); - thumb_locks.locked_paths = NULL; - BLI_condition_end(&thumb_locks.cond); - } + thumb_locks.lock_counter--; + if (thumb_locks.lock_counter == 0) { + BLI_gset_free(thumb_locks.locked_paths, MEM_freeN); + thumb_locks.locked_paths = NULL; + BLI_condition_end(&thumb_locks.cond); + } - BLI_thread_unlock(LOCK_IMAGE); + BLI_thread_unlock(LOCK_IMAGE); } void IMB_thumb_path_lock(const char *path) { - void *key = BLI_strdup(path); + void *key = BLI_strdup(path); - BLI_thread_lock(LOCK_IMAGE); - BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0)); + BLI_thread_lock(LOCK_IMAGE); + BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0)); - if (thumb_locks.locked_paths) { - while (!BLI_gset_add(thumb_locks.locked_paths, key)) { - BLI_condition_wait_global_mutex(&thumb_locks.cond, LOCK_IMAGE); - } - } + if (thumb_locks.locked_paths) { + while (!BLI_gset_add(thumb_locks.locked_paths, key)) { + BLI_condition_wait_global_mutex(&thumb_locks.cond, LOCK_IMAGE); + } + } - BLI_thread_unlock(LOCK_IMAGE); + BLI_thread_unlock(LOCK_IMAGE); } void IMB_thumb_path_unlock(const char *path) { - const void *key = path; + const void *key = path; - BLI_thread_lock(LOCK_IMAGE); - BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0)); + BLI_thread_lock(LOCK_IMAGE); + BLI_assert((thumb_locks.locked_paths != NULL) && (thumb_locks.lock_counter > 0)); - if (thumb_locks.locked_paths) { - if (!BLI_gset_remove(thumb_locks.locked_paths, key, MEM_freeN)) { - BLI_assert(0); - } - BLI_condition_notify_all(&thumb_locks.cond); - } + if (thumb_locks.locked_paths) { + if (!BLI_gset_remove(thumb_locks.locked_paths, key, MEM_freeN)) { + BLI_assert(0); + } + BLI_condition_notify_all(&thumb_locks.cond); + } - BLI_thread_unlock(LOCK_IMAGE); + BLI_thread_unlock(LOCK_IMAGE); } -- cgit v1.2.3