Blender  V3.3
thumbs.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2007 Blender Foundation. All rights reserved. */
3 
8 #include <stdio.h>
9 #include <stdlib.h>
10 
11 #include "MEM_guardedalloc.h"
12 
13 #include "BLI_fileops.h"
14 #include "BLI_ghash.h"
15 #include "BLI_hash_md5.h"
16 #include "BLI_path_util.h"
17 #include "BLI_string.h"
18 #include "BLI_system.h"
19 #include "BLI_threads.h"
20 #include "BLI_utildefines.h"
21 #include BLI_SYSTEM_PID_H
22 
23 #include "DNA_space_types.h" /* For FILE_MAX_LIBEXTRA */
24 
25 #include "BLO_readfile.h"
26 
27 #include "IMB_imbuf.h"
28 #include "IMB_imbuf_types.h"
29 #include "IMB_metadata.h"
30 #include "IMB_thumbs.h"
31 
32 #include <ctype.h>
33 #include <string.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <time.h>
37 
38 #ifdef WIN32
39 /* Need to include windows.h so _WIN32_IE is defined. */
40 # include <windows.h>
41 # ifndef _WIN32_IE
42 /* Minimal requirements for SHGetSpecialFolderPath on MINGW MSVC has this defined already. */
43 # define _WIN32_IE 0x0400
44 # endif
45 /* For SHGetSpecialFolderPath, has to be done before BLI_winstuff
46  * because 'near' is disabled through BLI_windstuff */
47 # include "BLI_winstuff.h"
48 # include "utfconv.h"
49 # include <direct.h> /* #chdir */
50 # include <shlobj.h>
51 #endif
52 
53 #if defined(WIN32) || defined(__APPLE__)
54 /* pass */
55 #else
56 # define USE_FREEDESKTOP
57 #endif
58 
59 /* '$HOME/.cache/thumbnails' or '$HOME/.thumbnails' */
60 #ifdef USE_FREEDESKTOP
61 # define THUMBNAILS "thumbnails"
62 #else
63 # define THUMBNAILS ".thumbnails"
64 #endif
65 
66 #define URI_MAX (FILE_MAX * 3 + 8)
67 
68 static bool get_thumb_dir(char *dir, ThumbSize size)
69 {
70  char *s = dir;
71  const char *subdir;
72 #ifdef WIN32
73  wchar_t dir_16[MAX_PATH];
74  /* Yes, applications shouldn't store data there, but so does GIMP :). */
75  SHGetSpecialFolderPathW(0, dir_16, CSIDL_PROFILE, 0);
76  conv_utf_16_to_8(dir_16, dir, FILE_MAX);
77  s += strlen(dir);
78 #else
79 # if defined(USE_FREEDESKTOP)
80  const char *home_cache = BLI_getenv("XDG_CACHE_HOME");
81  const char *home = home_cache ? home_cache : BLI_getenv("HOME");
82 # else
83  const char *home = BLI_getenv("HOME");
84 # endif
85  if (!home) {
86  return 0;
87  }
88  s += BLI_strncpy_rlen(s, home, FILE_MAX);
89 
90 # ifdef USE_FREEDESKTOP
91  if (!home_cache) {
92  s += BLI_strncpy_rlen(s, "/.cache", FILE_MAX - (s - dir));
93  }
94 # endif
95 #endif
96  switch (size) {
97  case THB_NORMAL:
98  subdir = SEP_STR THUMBNAILS SEP_STR "normal" SEP_STR;
99  break;
100  case THB_LARGE:
101  subdir = SEP_STR THUMBNAILS SEP_STR "large" SEP_STR;
102  break;
103  case THB_FAIL:
104  subdir = SEP_STR THUMBNAILS SEP_STR "fail" SEP_STR "blender" SEP_STR;
105  break;
106  default:
107  return 0; /* unknown size */
108  }
109 
110  s += BLI_strncpy_rlen(s, subdir, FILE_MAX - (s - dir));
111  (void)s;
112 
113  return 1;
114 }
115 
116 #undef THUMBNAILS
117 
118 /* --- Begin of adapted code from glib. --- */
119 
120 /* -------------------------------------------------------------------- */
129 typedef enum {
130  UNSAFE_ALL = 0x1, /* Escape all unsafe characters. */
131  UNSAFE_ALLOW_PLUS = 0x2, /* Allows '+' */
132  UNSAFE_PATH = 0x8, /* Allows '/', '&', '=', ':', '@', '+', '$' and ',' */
133  UNSAFE_HOST = 0x10, /* Allows '/' and ':' and '@' */
134  UNSAFE_SLASHES = 0x20, /* Allows all characters except for '/' and '%' */
136 
137 /* Don't lose comment alignment. */
138 /* clang-format off */
139 static const unsigned char acceptable[96] = {
140  /* A table of the ASCII chars from space (32) to DEL (127) */
141  /* ! " # $ % & ' ( ) * + , - . / */
142  0x00,0x3F,0x20,0x20,0x28,0x00,0x2C,0x3F,0x3F,0x3F,0x3F,0x2A,0x28,0x3F,0x3F,0x1C,
143  /* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
144  0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x38,0x20,0x20,0x2C,0x20,0x20,
145  /* @ A B C D E F G H I J K L M N O */
146  0x38,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
147  /* P Q R S T U V W X Y Z [ \ ] ^ _ */
148  0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x20,0x3F,
149  /* ` a b c d e f g h i j k l m n o */
150  0x20,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
151  /* p q r s t u v w x y z { | } ~ DEL */
152  0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x3F,0x20,
153 };
154 /* clang-format on */
155 
156 static const char hex[17] = "0123456789abcdef";
157 
158 /* NOTE: This escape function works on file: URIs, but if you want to
159  * escape something else, please read RFC-2396 */
160 static void escape_uri_string(const char *string,
161  char *escaped_string,
162  int escaped_string_size,
164 {
165 #define ACCEPTABLE(a) ((a) >= 32 && (a) < 128 && (acceptable[(a)-32] & use_mask))
166 
167  const char *p;
168  char *q;
169  int c;
170  UnsafeCharacterSet use_mask;
171  use_mask = mask;
172 
173  BLI_assert(escaped_string_size > 0);
174 
175  /* space for \0 */
176  escaped_string_size -= 1;
177 
178  for (q = escaped_string, p = string; (*p != '\0') && escaped_string_size; p++) {
179  c = (unsigned char)*p;
180 
181  if (!ACCEPTABLE(c)) {
182  if (escaped_string_size < 3) {
183  break;
184  }
185 
186  *q++ = '%'; /* means hex coming */
187  *q++ = hex[c >> 4];
188  *q++ = hex[c & 15];
189  escaped_string_size -= 3;
190  }
191  else {
192  *q++ = *p;
193  escaped_string_size -= 1;
194  }
195  }
196 
197  *q = '\0';
198 }
199 
202 /* --- End of adapted code from glib. --- */
203 
204 static bool thumbhash_from_path(const char *UNUSED(path), ThumbSource source, char *r_hash)
205 {
206  switch (source) {
207  case THB_SOURCE_FONT:
208  return IMB_thumb_load_font_get_hash(r_hash);
209  default:
210  r_hash[0] = '\0';
211  return false;
212  }
213 }
214 
215 static bool uri_from_filename(const char *path, char *uri)
216 {
217  char orig_uri[URI_MAX];
218  const char *dirstart = path;
219 
220 #ifdef WIN32
221  {
222  char vol[3];
223 
224  BLI_strncpy(orig_uri, "file:///", FILE_MAX);
225  if (strlen(path) < 2 && path[1] != ':') {
226  /* not a correct absolute path */
227  return 0;
228  }
229  /* on windows, using always uppercase drive/volume letter in uri */
230  vol[0] = (unsigned char)toupper(path[0]);
231  vol[1] = ':';
232  vol[2] = '\0';
233  strcat(orig_uri, vol);
234  dirstart += 2;
235  }
236  strcat(orig_uri, dirstart);
237  BLI_str_replace_char(orig_uri, '\\', '/');
238 #else
239  BLI_snprintf(orig_uri, URI_MAX, "file://%s", dirstart);
240 #endif
241 
242  escape_uri_string(orig_uri, uri, URI_MAX, UNSAFE_PATH);
243 
244  return 1;
245 }
246 
248  const char *uri, char *r_path, const int path_len, char *r_name, int name_len, ThumbSize size)
249 {
250  char name_buff[40];
251 
252  if (r_path && !r_name) {
253  r_name = name_buff;
254  name_len = sizeof(name_buff);
255  }
256 
257  if (r_name) {
258  char hexdigest[33];
259  unsigned char digest[16];
260  BLI_hash_md5_buffer(uri, strlen(uri), digest);
261  hexdigest[0] = '\0';
262  BLI_snprintf(r_name, name_len, "%s.png", BLI_hash_md5_to_hexdigest(digest, hexdigest));
263  // printf("%s: '%s' --> '%s'\n", __func__, uri, r_name);
264  }
265 
266  if (r_path) {
267  char tmppath[FILE_MAX];
268 
269  if (get_thumb_dir(tmppath, size)) {
270  BLI_snprintf(r_path, path_len, "%s%s", tmppath, r_name);
271  // printf("%s: '%s' --> '%s'\n", __func__, uri, r_path);
272  return true;
273  }
274  }
275  return false;
276 }
277 
278 static void thumbname_from_uri(const char *uri, char *thumb, const int thumb_len)
279 {
280  thumbpathname_from_uri(uri, NULL, 0, thumb, thumb_len, THB_FAIL);
281 }
282 
283 static bool thumbpath_from_uri(const char *uri, char *path, const int path_len, ThumbSize size)
284 {
285  return thumbpathname_from_uri(uri, path, path_len, NULL, 0, size);
286 }
287 
289 {
290  char tpath[FILE_MAX];
291 #if 0 /* UNUSED */
292  if (get_thumb_dir(tpath, THB_NORMAL)) {
294  }
295 #endif
296  if (get_thumb_dir(tpath, THB_LARGE)) {
298  }
299  if (get_thumb_dir(tpath, THB_FAIL)) {
301  }
302 }
303 
304 /* create thumbnail for file and returns new imbuf for thumbnail */
305 static ImBuf *thumb_create_ex(const char *file_path,
306  const char *uri,
307  const char *thumb,
308  const bool use_hash,
309  const char *hash,
310  const char *blen_group,
311  const char *blen_id,
312  ThumbSize size,
313  ThumbSource source,
314  ImBuf *img)
315 {
316  char desc[URI_MAX + 22];
317  char tpath[FILE_MAX];
318  char tdir[FILE_MAX];
319  char temp[FILE_MAX];
320  char mtime[40] = "0"; /* in case we can't stat the file */
321  short tsize = 128;
322  BLI_stat_t info;
323 
324  switch (size) {
325  case THB_NORMAL:
327  break;
328  case THB_LARGE:
330  break;
331  case THB_FAIL:
332  tsize = 1;
333  break;
334  default:
335  return NULL; /* unknown size */
336  }
337 
338  if (get_thumb_dir(tdir, size)) {
339  BLI_snprintf(tpath, FILE_MAX, "%s%s", tdir, thumb);
340  // thumb[8] = '\0'; /* shorten for tempname, not needed anymore */
341  BLI_snprintf(temp, FILE_MAX, "%sblender_%d_%s.png", tdir, abs(getpid()), thumb);
342  if (BLI_path_ncmp(file_path, tdir, sizeof(tdir)) == 0) {
343  return NULL;
344  }
345  if (size == THB_FAIL) {
346  img = IMB_allocImBuf(1, 1, 32, IB_rect | IB_metadata);
347  if (!img) {
348  return NULL;
349  }
350  }
351  else {
353  /* only load if we didn't give an image */
354  if (img == NULL) {
355  switch (source) {
356  case THB_SOURCE_IMAGE:
357  img = IMB_thumb_load_image(file_path, tsize, NULL);
358  break;
359  case THB_SOURCE_BLEND:
360  img = IMB_thumb_load_blend(file_path, blen_group, blen_id);
361  break;
362  case THB_SOURCE_FONT:
363  img = IMB_thumb_load_font(file_path, tsize, tsize);
364  break;
365  default:
366  BLI_assert_unreachable(); /* This should never happen */
367  }
368  }
369 
370  if (img != NULL) {
371  if (BLI_stat(file_path, &info) != -1) {
372  BLI_snprintf(mtime, sizeof(mtime), "%ld", (long int)info.st_mtime);
373  }
374  }
375  }
376  else if (THB_SOURCE_MOVIE == source) {
377  struct anim *anim = NULL;
378  anim = IMB_open_anim(file_path, IB_rect | IB_metadata, 0, NULL);
379  if (anim != NULL) {
381  if (img == NULL) {
382  printf("not an anim; %s\n", file_path);
383  }
384  else {
385  IMB_freeImBuf(img);
387  }
389  }
390  if (BLI_stat(file_path, &info) != -1) {
391  BLI_snprintf(mtime, sizeof(mtime), "%ld", (long int)info.st_mtime);
392  }
393  }
394  if (!img) {
395  return NULL;
396  }
397 
398  if (img->x > tsize || img->y > tsize) {
399  float scale = MIN2((float)tsize / (float)img->x, (float)tsize / (float)img->y);
400  /* Scaling down must never assign zero width/height, see: T89868. */
401  short ex = MAX2(1, (short)(img->x * scale));
402  short ey = MAX2(1, (short)(img->y * scale));
403  /* Save some time by only scaling byte buf */
404  if (img->rect_float) {
405  if (img->rect == NULL) {
406  IMB_rect_from_float(img);
407  }
409  }
410  IMB_scaleImBuf(img, ex, ey);
411  }
412  }
413  BLI_snprintf(desc, sizeof(desc), "Thumbnail for %s", uri);
415  IMB_metadata_set_field(img->metadata, "Software", "Blender");
416  IMB_metadata_set_field(img->metadata, "Thumb::URI", uri);
417  IMB_metadata_set_field(img->metadata, "Description", desc);
418  IMB_metadata_set_field(img->metadata, "Thumb::MTime", mtime);
419  if (use_hash) {
420  IMB_metadata_set_field(img->metadata, "X-Blender::Hash", hash);
421  }
422  img->ftype = IMB_FTYPE_PNG;
423  img->planes = 32;
424 
425  /* If we generated from a 16bit PNG e.g., we have a float rect, not a byte one - fix this. */
426  IMB_rect_from_float(img);
428 
429  if (IMB_saveiff(img, temp, IB_rect | IB_metadata)) {
430 #ifndef WIN32
431  chmod(temp, S_IRUSR | S_IWUSR);
432 #endif
433  // printf("%s saving thumb: '%s'\n", __func__, tpath);
434 
435  BLI_rename(temp, tpath);
436  }
437  }
438  return img;
439 }
440 
441 static ImBuf *thumb_create_or_fail(const char *file_path,
442  const char *uri,
443  const char *thumb,
444  const bool use_hash,
445  const char *hash,
446  const char *blen_group,
447  const char *blen_id,
448  ThumbSize size,
449  ThumbSource source)
450 {
451  ImBuf *img = thumb_create_ex(
452  file_path, uri, thumb, use_hash, hash, blen_group, blen_id, size, source, NULL);
453 
454  if (!img) {
455  /* thumb creation failed, write fail thumb */
456  img = thumb_create_ex(
457  file_path, uri, thumb, use_hash, hash, blen_group, blen_id, THB_FAIL, source, NULL);
458  if (img) {
459  /* we don't need failed thumb anymore */
460  IMB_freeImBuf(img);
461  img = NULL;
462  }
463  }
464 
465  return img;
466 }
467 
468 ImBuf *IMB_thumb_create(const char *filepath, ThumbSize size, ThumbSource source, ImBuf *img)
469 {
470  char uri[URI_MAX] = "";
471  char thumb_name[40];
472 
473  if (!uri_from_filename(filepath, uri)) {
474  return NULL;
475  }
476  thumbname_from_uri(uri, thumb_name, sizeof(thumb_name));
477 
478  return thumb_create_ex(
479  filepath, uri, thumb_name, false, THUMB_DEFAULT_HASH, NULL, NULL, size, source, img);
480 }
481 
482 ImBuf *IMB_thumb_read(const char *filepath, ThumbSize size)
483 {
484  char thumb[FILE_MAX];
485  char uri[URI_MAX];
486  ImBuf *img = NULL;
487 
488  if (!uri_from_filename(filepath, uri)) {
489  return NULL;
490  }
491  if (thumbpath_from_uri(uri, thumb, sizeof(thumb), size)) {
492  img = IMB_loadiffname(thumb, IB_rect | IB_metadata, NULL);
493  }
494 
495  return img;
496 }
497 
498 void IMB_thumb_delete(const char *filepath, ThumbSize size)
499 {
500  char thumb[FILE_MAX];
501  char uri[URI_MAX];
502 
503  if (!uri_from_filename(filepath, uri)) {
504  return;
505  }
506  if (thumbpath_from_uri(uri, thumb, sizeof(thumb), size)) {
507  if (BLI_path_ncmp(filepath, thumb, sizeof(thumb)) == 0) {
508  return;
509  }
510  if (BLI_exists(thumb)) {
511  BLI_delete(thumb, false, false);
512  }
513  }
514 }
515 
516 ImBuf *IMB_thumb_manage(const char *filepath, ThumbSize size, ThumbSource source)
517 {
518  char thumb_path[FILE_MAX];
519  char thumb_name[40];
520  char uri[URI_MAX];
521  char path_buff[FILE_MAX_LIBEXTRA];
522  const char *file_path;
523  const char *path;
524  BLI_stat_t st;
525  ImBuf *img = NULL;
526  char *blen_group = NULL, *blen_id = NULL;
527 
528  path = file_path = filepath;
529  if (source == THB_SOURCE_BLEND) {
530  if (BLO_library_path_explode(path, path_buff, &blen_group, &blen_id)) {
531  if (blen_group) {
532  if (!blen_id) {
533  /* No preview for blen groups */
534  return NULL;
535  }
536  file_path = path_buff; /* path needs to be a valid file! */
537  }
538  }
539  }
540 
541  if (BLI_stat(file_path, &st) == -1) {
542  return NULL;
543  }
544  if (!uri_from_filename(path, uri)) {
545  return NULL;
546  }
547  if (thumbpath_from_uri(uri, thumb_path, sizeof(thumb_path), THB_FAIL)) {
548  /* failure thumb exists, don't try recreating */
549  if (BLI_exists(thumb_path)) {
550  /* clear out of date fail case (note for blen IDs we use blender file itself here) */
551  if (BLI_file_older(thumb_path, file_path)) {
552  BLI_delete(thumb_path, false, false);
553  }
554  else {
555  return NULL;
556  }
557  }
558  }
559 
561  uri, thumb_path, sizeof(thumb_path), thumb_name, sizeof(thumb_name), size)) {
562  if (BLI_path_ncmp(path, thumb_path, sizeof(thumb_path)) == 0) {
563  img = IMB_loadiffname(path, IB_rect, NULL);
564  }
565  else {
566  img = IMB_loadiffname(thumb_path, IB_rect | IB_metadata, NULL);
567  if (img) {
568  bool regenerate = false;
569 
570  char mtime[40];
571  char thumb_hash[33];
572  char thumb_hash_curr[33];
573 
574  const bool use_hash = thumbhash_from_path(file_path, source, thumb_hash);
575 
576  if (IMB_metadata_get_field(img->metadata, "Thumb::MTime", mtime, sizeof(mtime))) {
577  regenerate = (st.st_mtime != atol(mtime));
578  }
579  else {
580  /* illegal thumb, regenerate it! */
581  regenerate = true;
582  }
583 
584  if (use_hash && !regenerate) {
586  img->metadata, "X-Blender::Hash", thumb_hash_curr, sizeof(thumb_hash_curr))) {
587  regenerate = !STREQ(thumb_hash, thumb_hash_curr);
588  }
589  else {
590  regenerate = true;
591  }
592  }
593 
594  if (regenerate) {
595  /* recreate all thumbs */
596  IMB_freeImBuf(img);
597  img = NULL;
600  IMB_thumb_delete(path, THB_FAIL);
601  img = thumb_create_or_fail(
602  file_path, uri, thumb_name, use_hash, thumb_hash, blen_group, blen_id, size, source);
603  }
604  }
605  else {
606  char thumb_hash[33];
607  const bool use_hash = thumbhash_from_path(file_path, source, thumb_hash);
608 
609  img = thumb_create_or_fail(
610  file_path, uri, thumb_name, use_hash, thumb_hash, blen_group, blen_id, size, source);
611  }
612  }
613  }
614 
615  /* Our imbuf **must** have a valid rect (i.e. 8-bits/channels)
616  * data, we rely on this in draw code.
617  * However, in some cases we may end loading 16bits PNGs, which generated float buffers.
618  * This should be taken care of in generation step, but add also a safeguard here! */
619  if (img) {
620  IMB_rect_from_float(img);
622  }
623 
624  return img;
625 }
626 
627 /* ***** Threading ***** */
628 /* Thumbnail handling is not really threadsafe in itself.
629  * However, as long as we do not operate on the same file, we shall have no collision.
630  * So idea is to 'lock' a given source file path.
631  */
632 
633 static struct IMBThumbLocks {
637 } thumb_locks = {0};
638 
640 {
642 
643  if (thumb_locks.lock_counter == 0) {
647  }
649 
653 }
654 
656 {
659 
661  if (thumb_locks.lock_counter == 0) {
665  }
666 
668 }
669 
670 void IMB_thumb_path_lock(const char *path)
671 {
672  void *key = BLI_strdup(path);
673 
676 
678  while (!BLI_gset_add(thumb_locks.locked_paths, key)) {
680  }
681  }
682 
684 }
685 
686 void IMB_thumb_path_unlock(const char *path)
687 {
688  const void *key = path;
689 
692 
696  }
698  }
699 
701 }
#define BLI_assert_unreachable()
Definition: BLI_assert.h:93
#define BLI_assert(a)
Definition: BLI_assert.h:46
File and directory operations.
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: storage.c:314
bool BLI_file_older(const char *file1, const char *file2) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: storage.c:569
int BLI_stat(const char *path, BLI_stat_t *buffer) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
int BLI_delete(const char *file, bool dir, bool recursive) ATTR_NONNULL()
Definition: fileops.c:934
int BLI_rename(const char *from, const char *to) ATTR_NONNULL()
Definition: fileops.c:1268
struct stat BLI_stat_t
Definition: BLI_fileops.h:73
bool BLI_dir_create_recursive(const char *dir) ATTR_NONNULL()
Definition: fileops.c:1219
GSet * BLI_gset_str_new(const char *info)
struct GSet GSet
Definition: BLI_ghash.h:340
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1037
bool BLI_gset_add(GSet *gs, void *key)
Definition: BLI_ghash.c:969
bool BLI_gset_remove(GSet *gs, const void *key, GSetKeyFreeFP keyfreefp)
Definition: BLI_ghash.c:1002
void * BLI_hash_md5_buffer(const char *buffer, size_t len, void *resblock)
Definition: hash_md5.c:345
char * BLI_hash_md5_to_hexdigest(void *resblock, char r_hex_digest[33])
Definition: hash_md5.c:381
#define BLI_path_ncmp
#define FILE_MAX
const char * BLI_getenv(const char *env) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:1168
void BLI_str_replace_char(char *str, char src, char dst) ATTR_NONNULL()
Definition: string.c:503
size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: string.c:120
char * BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL() ATTR_MALLOC
Definition: string.c:42
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
Definition: string.c:64
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
void BLI_condition_notify_all(ThreadCondition *cond)
Definition: threads.cc:594
void BLI_thread_unlock(int type)
Definition: threads.cc:361
@ LOCK_IMAGE
Definition: BLI_threads.h:66
void BLI_thread_lock(int type)
Definition: threads.cc:356
void BLI_condition_wait_global_mutex(ThreadCondition *cond, int type)
Definition: threads.cc:584
pthread_cond_t ThreadCondition
Definition: BLI_threads.h:150
void BLI_condition_end(ThreadCondition *cond)
Definition: threads.cc:599
void BLI_condition_init(ThreadCondition *cond)
Definition: threads.cc:574
#define UNUSED(x)
#define MAX2(a, b)
#define ELEM(...)
#define MIN2(a, b)
#define STREQ(a, b)
Compatibility-like things for windows.
external readfile function prototypes.
bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, char **r_name)
Definition: readfile.c:1503
#define FILE_MAX_LIBEXTRA
void imb_freerectfloatImBuf(struct ImBuf *ibuf)
Definition: allocimbuf.c:80
bool IMB_scaleImBuf(struct ImBuf *ibuf, unsigned int newx, unsigned int newy)
Definition: scaling.c:1644
void IMB_free_anim(struct anim *anim)
Definition: anim_movie.c:193
struct ImBuf * IMB_allocImBuf(unsigned int x, unsigned int y, unsigned char planes, unsigned int flags)
Definition: allocimbuf.c:500
void IMB_rect_from_float(struct ImBuf *ibuf)
Definition: divers.c:696
@ IMB_PROXY_NONE
Definition: IMB_imbuf.h:341
struct anim * IMB_open_anim(const char *name, int ib_flags, int streamindex, char colorspace[IM_MAX_SPACE])
Definition: anim_movie.c:268
struct ImBuf * IMB_loadiffname(const char *filepath, int flags, char colorspace[IM_MAX_SPACE])
Definition: readimage.c:209
struct ImBuf * IMB_anim_previewframe(struct anim *anim)
Definition: anim_movie.c:1557
struct ImBuf * IMB_thumb_load_image(const char *filepath, const size_t max_thumb_size, char colorspace[IM_MAX_SPACE])
Definition: readimage.c:239
struct ImBuf * IMB_anim_absolute(struct anim *anim, int position, IMB_Timecode_Type tc, IMB_Proxy_Size preview_size)
Definition: anim_movie.c:1571
bool IMB_saveiff(struct ImBuf *ibuf, const char *filepath, int flags)
Definition: writeimage.c:22
@ IMB_TC_NONE
Definition: IMB_imbuf.h:318
Contains defines and structs used throughout the imbuf module.
@ IB_metadata
@ IB_rect
void IMB_metadata_set_field(struct IDProperty *metadata, const char *key, const char *value)
Definition: metadata.c:73
bool IMB_metadata_get_field(struct IDProperty *metadata, const char *key, char *value, size_t len)
Definition: metadata.c:44
void IMB_metadata_ensure(struct IDProperty **metadata)
Definition: metadata.c:25
struct ImBuf * IMB_thumb_load_blend(const char *blen_path, const char *blen_group, const char *blen_id)
Definition: thumbs_blend.c:67
#define PREVIEW_RENDER_DEFAULT_HEIGHT
Definition: IMB_thumbs.h:40
ThumbSize
Definition: IMB_thumbs.h:22
@ THB_FAIL
Definition: IMB_thumbs.h:25
@ THB_NORMAL
Definition: IMB_thumbs.h:23
@ THB_LARGE
Definition: IMB_thumbs.h:24
bool IMB_thumb_load_font_get_hash(char *r_hash)
Definition: thumbs_font.c:77
ThumbSource
Definition: IMB_thumbs.h:28
@ THB_SOURCE_IMAGE
Definition: IMB_thumbs.h:29
@ THB_SOURCE_FONT
Definition: IMB_thumbs.h:32
@ THB_SOURCE_BLEND
Definition: IMB_thumbs.h:31
@ THB_SOURCE_MOVIE
Definition: IMB_thumbs.h:30
#define PREVIEW_RENDER_LARGE_HEIGHT
Definition: IMB_thumbs.h:41
struct ImBuf * IMB_thumb_load_font(const char *filepath, unsigned int x, unsigned int y)
Definition: thumbs_font.c:44
#define THUMB_DEFAULT_HASH
Definition: IMB_thumbs.h:48
Read Guarded memory(de)allocation.
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
SyclQueue void void size_t num_bytes void
void IMB_freeImBuf(ImBuf *UNUSED(ibuf))
@ IMB_FTYPE_PNG
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
Definition: math_float4.h:513
static unsigned c
Definition: RandGen.cpp:83
T abs(const T &a)
static const pxr::TfToken st("st", pxr::TfToken::Immortal)
#define hash
Definition: noise.c:153
ThreadCondition cond
Definition: thumbs.c:636
int lock_counter
Definition: thumbs.c:635
GSet * locked_paths
Definition: thumbs.c:634
struct IDProperty * metadata
unsigned char planes
enum eImbFileType ftype
unsigned int * rect
float * rect_float
Definition: IMB_anim.h:71
ImBuf * IMB_thumb_manage(const char *filepath, ThumbSize size, ThumbSource source)
Definition: thumbs.c:516
void IMB_thumb_makedirs(void)
Definition: thumbs.c:288
UnsafeCharacterSet
Definition: thumbs.c:129
@ UNSAFE_HOST
Definition: thumbs.c:133
@ UNSAFE_ALLOW_PLUS
Definition: thumbs.c:131
@ UNSAFE_ALL
Definition: thumbs.c:130
@ UNSAFE_PATH
Definition: thumbs.c:132
@ UNSAFE_SLASHES
Definition: thumbs.c:134
ImBuf * IMB_thumb_create(const char *filepath, ThumbSize size, ThumbSource source, ImBuf *img)
Definition: thumbs.c:468
static void escape_uri_string(const char *string, char *escaped_string, int escaped_string_size, UnsafeCharacterSet mask)
Definition: thumbs.c:160
static bool thumbpathname_from_uri(const char *uri, char *r_path, const int path_len, char *r_name, int name_len, ThumbSize size)
Definition: thumbs.c:247
static bool uri_from_filename(const char *path, char *uri)
Definition: thumbs.c:215
static const unsigned char acceptable[96]
Definition: thumbs.c:139
void IMB_thumb_locks_release(void)
Definition: thumbs.c:655
void IMB_thumb_path_unlock(const char *path)
Definition: thumbs.c:686
ImBuf * IMB_thumb_read(const char *filepath, ThumbSize size)
Definition: thumbs.c:482
static void thumbname_from_uri(const char *uri, char *thumb, const int thumb_len)
Definition: thumbs.c:278
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)
Definition: thumbs.c:305
void IMB_thumb_delete(const char *filepath, ThumbSize size)
Definition: thumbs.c:498
void IMB_thumb_path_lock(const char *path)
Definition: thumbs.c:670
static bool thumbhash_from_path(const char *UNUSED(path), ThumbSource source, char *r_hash)
Definition: thumbs.c:204
#define URI_MAX
Definition: thumbs.c:66
static const char hex[17]
Definition: thumbs.c:156
#define THUMBNAILS
Definition: thumbs.c:61
#define ACCEPTABLE(a)
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)
Definition: thumbs.c:441
void IMB_thumb_locks_acquire(void)
Definition: thumbs.c:639
static struct IMBThumbLocks thumb_locks
static bool thumbpath_from_uri(const char *uri, char *path, const int path_len, ThumbSize size)
Definition: thumbs.c:283
static bool get_thumb_dir(char *dir, ThumbSize size)
Definition: thumbs.c:68
#define SEP_STR
Definition: unit.c:33
int conv_utf_16_to_8(const wchar_t *in16, char *out8, size_t size8)
Definition: utfconv.c:115