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