Blender  V2.93
image_sequence.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) 2001-2002 by NaN Holding BV.
17  * All rights reserved.
18  */
19 
24 #include <string.h>
25 
26 #include "MEM_guardedalloc.h"
27 
28 #include "BLI_fileops.h"
29 #include "BLI_fileops_types.h"
30 #include "BLI_listbase.h"
31 #include "BLI_math_base.h"
32 #include "BLI_path_util.h"
33 #include "BLI_string.h"
34 #include "BLI_utildefines.h"
35 
36 #include "DNA_image_types.h"
38 
39 #include "RNA_access.h"
40 
41 #include "BKE_image.h"
42 #include "BKE_main.h"
43 
44 #include "ED_image.h"
45 
46 typedef struct ImageFrame {
47  struct ImageFrame *next, *prev;
48  int framenr;
50 
59 {
60  char dir[FILE_MAXDIR];
61  const bool do_frame_range = RNA_boolean_get(op->ptr, "use_sequence_detection");
62  ImageFrameRange *range = NULL;
63  int range_first_frame = 0;
64  /* Track when a new series of files are found that aren't compatible with the previous file. */
65  char base_head[FILE_MAX], base_tail[FILE_MAX];
66 
67  RNA_string_get(op->ptr, "directory", dir);
68  RNA_BEGIN (op->ptr, itemptr, "files") {
69  char head[FILE_MAX], tail[FILE_MAX];
70  ushort digits;
71  char *filename = RNA_string_get_alloc(&itemptr, "name", NULL, 0);
72  ImageFrame *frame = MEM_callocN(sizeof(ImageFrame), "image_frame");
73 
74  /* use the first file in the list as base filename */
75  frame->framenr = BLI_path_sequence_decode(filename, head, tail, &digits);
76 
77  /* still in the same sequence */
78  if (do_frame_range && (range != NULL) && (STREQLEN(base_head, head, FILE_MAX)) &&
79  (STREQLEN(base_tail, tail, FILE_MAX))) {
80  /* Set filepath to first frame in the range. */
81  if (frame->framenr < range_first_frame) {
82  BLI_join_dirfile(range->filepath, sizeof(range->filepath), dir, filename);
83  range_first_frame = frame->framenr;
84  }
85  }
86  else {
87  /* start a new frame range */
88  range = MEM_callocN(sizeof(*range), __func__);
89  BLI_join_dirfile(range->filepath, sizeof(range->filepath), dir, filename);
90  BLI_addtail(ranges, range);
91 
92  BLI_strncpy(base_head, head, sizeof(base_head));
93  BLI_strncpy(base_tail, tail, sizeof(base_tail));
94 
95  range_first_frame = frame->framenr;
96  }
97 
98  BLI_addtail(&range->frames, frame);
99  MEM_freeN(filename);
100  }
101  RNA_END;
102 }
103 
104 static int image_cmp_frame(const void *a, const void *b)
105 {
106  const ImageFrame *frame_a = a;
107  const ImageFrame *frame_b = b;
108 
109  if (frame_a->framenr < frame_b->framenr) {
110  return -1;
111  }
112  if (frame_a->framenr > frame_b->framenr) {
113  return 1;
114  }
115  return 0;
116 }
117 
118 /*
119  * Checks whether the given filepath refers to a UDIM texture.
120  * If yes, the range from 1001 to the highest tile is returned, otherwise 0.
121  *
122  * If the result is positive, the filepath will be overwritten with that of
123  * the 1001 tile.
124  *
125  * udim_tiles may get filled even if the result ultimately is false!
126  */
127 static int image_get_udim(char *filepath, ListBase *udim_tiles)
128 {
129  char filename[FILE_MAX], dirname[FILE_MAXDIR];
130  BLI_split_dirfile(filepath, dirname, filename, sizeof(dirname), sizeof(filename));
131 
132  ushort digits;
133  char base_head[FILE_MAX], base_tail[FILE_MAX];
134  int id = BLI_path_sequence_decode(filename, base_head, base_tail, &digits);
135 
136  if (id < 1001 || id >= IMA_UDIM_MAX) {
137  return 0;
138  }
139 
140  bool is_udim = true;
141  bool has_primary = false;
142  int max_udim = 0;
143 
144  struct direntry *dir;
145  uint totfile = BLI_filelist_dir_contents(dirname, &dir);
146  for (int i = 0; i < totfile; i++) {
147  if (!(dir[i].type & S_IFREG)) {
148  continue;
149  }
150  char head[FILE_MAX], tail[FILE_MAX];
151  id = BLI_path_sequence_decode(dir[i].relname, head, tail, &digits);
152 
153  if (digits > 4 || !(STREQLEN(base_head, head, FILE_MAX)) ||
154  !(STREQLEN(base_tail, tail, FILE_MAX))) {
155  continue;
156  }
157 
158  if (id < 1001 || id >= IMA_UDIM_MAX) {
159  is_udim = false;
160  break;
161  }
162  if (id == 1001) {
163  has_primary = true;
164  }
165 
167  max_udim = max_ii(max_udim, id);
168  }
169  BLI_filelist_free(dir, totfile);
170 
171  if (is_udim && has_primary) {
172  char primary_filename[FILE_MAX];
173  BLI_path_sequence_encode(primary_filename, base_head, base_tail, digits, 1001);
174  BLI_join_dirfile(filepath, FILE_MAX, dirname, primary_filename);
175  return max_udim - 1000;
176  }
177  return 0;
178 }
179 
184 static void image_detect_frame_range(ImageFrameRange *range, const bool detect_udim)
185 {
186  /* UDIM */
187  if (detect_udim) {
188  int len_udim = image_get_udim(range->filepath, &range->udim_tiles);
189 
190  if (len_udim > 0) {
191  range->offset = 1001;
192  range->length = len_udim;
193  return;
194  }
195  }
196 
197  /* Image Sequence */
199 
200  ImageFrame *frame = range->frames.first;
201  if (frame != NULL) {
202  int frame_curr = frame->framenr;
203  range->offset = frame_curr;
204 
205  while (frame != NULL && (frame->framenr == frame_curr)) {
206  frame_curr++;
207  frame = frame->next;
208  }
209 
210  range->length = frame_curr - range->offset;
211  }
212  else {
213  range->length = 1;
214  range->offset = 0;
215  }
216 }
217 
218 /* Used for both images and volume file loading. */
219 ListBase ED_image_filesel_detect_sequences(Main *bmain, wmOperator *op, const bool detect_udim)
220 {
221  ListBase ranges;
222  BLI_listbase_clear(&ranges);
223 
224  char filepath[FILE_MAX];
225  RNA_string_get(op->ptr, "filepath", filepath);
226 
227  /* File browser. */
228  if (RNA_struct_property_is_set(op->ptr, "directory") &&
229  RNA_struct_property_is_set(op->ptr, "files")) {
230  const bool was_relative = BLI_path_is_rel(filepath);
231 
232  image_sequence_get_frame_ranges(op, &ranges);
233  LISTBASE_FOREACH (ImageFrameRange *, range, &ranges) {
234  image_detect_frame_range(range, detect_udim);
235  BLI_freelistN(&range->frames);
236 
237  if (was_relative) {
238  BLI_path_rel(range->filepath, BKE_main_blendfile_path(bmain));
239  }
240  }
241  }
242  /* Filepath property for drag & drop etc. */
243  else {
244  ImageFrameRange *range = MEM_callocN(sizeof(*range), __func__);
245  BLI_addtail(&ranges, range);
246 
247  BLI_strncpy(range->filepath, filepath, FILE_MAX);
248  image_detect_frame_range(range, detect_udim);
249  }
250 
251  return ranges;
252 }
#define IMA_UDIM_MAX
Definition: BKE_image.h:48
const char * BKE_main_blendfile_path(const struct Main *bmain) ATTR_NONNULL()
File and directory operations.
void BLI_filelist_free(struct direntry *filelist, const unsigned int nrentries)
Definition: BLI_filelist.c:467
unsigned int BLI_filelist_dir_contents(const char *dir, struct direntry **r_filelist)
Definition: BLI_filelist.c:238
Some types for dealing with directories.
#define LISTBASE_FOREACH(type, var, list)
Definition: BLI_listbase.h:172
BLI_INLINE void BLI_listbase_clear(struct ListBase *lb)
Definition: BLI_listbase.h:128
struct LinkData * BLI_genericNodeN(void *data)
Definition: listbase.c:923
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
Definition: listbase.c:547
void void BLI_listbase_sort(struct ListBase *listbase, int(*cmp)(const void *, const void *)) ATTR_NONNULL(1
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
Definition: listbase.c:110
MINLINE int max_ii(int a, int b)
bool BLI_path_is_rel(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:411
#define FILE_MAX
int BLI_path_sequence_decode(const char *string, char *head, char *tail, unsigned short *r_num_len)
Definition: path_util.c:83
void BLI_join_dirfile(char *__restrict dst, const size_t maxlen, const char *__restrict dir, const char *__restrict file) ATTR_NONNULL()
Definition: path_util.c:1737
void BLI_path_sequence_encode(char *string, const char *head, const char *tail, unsigned short numlen, int pic)
Definition: path_util.c:154
void BLI_path_rel(char *file, const char *relfile) ATTR_NONNULL()
Definition: path_util.c:519
void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen)
Definition: path_util.c:1654
#define FILE_MAXDIR
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) ATTR_NONNULL()
Definition: string.c:108
unsigned int uint
Definition: BLI_sys_types.h:83
unsigned short ushort
Definition: BLI_sys_types.h:84
#define STREQLEN(a, b, n)
#define POINTER_FROM_INT(i)
const char * dirname(char *path)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
Read Guarded memory(de)allocation.
#define RNA_BEGIN(sptr, itemptr, propname)
Definition: RNA_access.h:1248
#define RNA_END
Definition: RNA_access.h:1255
static int image_get_udim(char *filepath, ListBase *udim_tiles)
static void image_detect_frame_range(ImageFrameRange *range, const bool detect_udim)
static void image_sequence_get_frame_ranges(wmOperator *op, ListBase *ranges)
ListBase ED_image_filesel_detect_sequences(Main *bmain, wmOperator *op, const bool detect_udim)
static int image_cmp_frame(const void *a, const void *b)
struct ImageFrame ImageFrame
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
static unsigned a[3]
Definition: RandGen.cpp:92
void RNA_string_get(PointerRNA *ptr, const char *name, char *value)
Definition: rna_access.c:6514
bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier)
Definition: rna_access.c:6685
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6261
char * RNA_string_get_alloc(PointerRNA *ptr, const char *name, char *fixedbuf, int fixedlen)
Definition: rna_access.c:6527
ListBase frames
Definition: ED_image.h:149
char filepath[FILE_MAX]
Definition: ED_image.h:141
ListBase udim_tiles
Definition: ED_image.h:146
struct ImageFrame * next
struct ImageFrame * prev
void * first
Definition: DNA_listBase.h:47
Definition: BKE_main.h:116
const char * relname
struct PointerRNA * ptr