Blender  V2.93
util.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  * util.c
19  */
20 
25 #ifdef _WIN32
26 # include <io.h>
27 #endif
28 
29 #include <stdlib.h>
30 
31 #include "BLI_fileops.h"
32 #include "BLI_path_util.h"
33 #include "BLI_utildefines.h"
34 #ifdef _WIN32
35 # include "BLI_winstuff.h"
36 #endif
37 
38 #include "IMB_filetype.h"
39 #include "IMB_imbuf.h"
40 #include "IMB_imbuf_types.h"
41 #include "imbuf.h"
42 
43 #include "IMB_anim.h"
44 
45 #ifdef WITH_FFMPEG
46 # include "BLI_string.h" /* BLI_vsnprintf */
47 
48 # include "BKE_global.h" /* G.debug */
49 
50 # include <libavcodec/avcodec.h>
51 # include <libavdevice/avdevice.h>
52 # include <libavformat/avformat.h>
53 # include <libavutil/log.h>
54 
55 # include "ffmpeg_compat.h"
56 #endif
57 
58 #define UTIL_DEBUG 0
59 
60 const char *imb_ext_image[] = {
61  ".png", ".tga", ".bmp", ".jpg", ".jpeg", ".sgi", ".rgb", ".rgba",
62 #ifdef WITH_TIFF
63  ".tif", ".tiff", ".tx",
64 #endif
65 #ifdef WITH_OPENJPEG
66  ".jp2", ".j2c",
67 #endif
68 #ifdef WITH_HDR
69  ".hdr",
70 #endif
71 #ifdef WITH_DDS
72  ".dds",
73 #endif
74 #ifdef WITH_CINEON
75  ".dpx", ".cin",
76 #endif
77 #ifdef WITH_OPENEXR
78  ".exr",
79 #endif
80 #ifdef WITH_OPENIMAGEIO
81  ".psd", ".pdd", ".psb",
82 #endif
83  NULL,
84 };
85 
86 const char *imb_ext_image_filepath_only[] = {
87 #ifdef WITH_OPENIMAGEIO
88  ".psd",
89  ".pdd",
90  ".psb",
91 #endif
92  NULL,
93 };
94 
95 const char *imb_ext_movie[] = {
96  ".avi", ".flc", ".mov", ".movie", ".mp4", ".m4v", ".m2v", ".m2t", ".m2ts", ".mts",
97  ".ts", ".mv", ".avs", ".wmv", ".ogv", ".ogg", ".r3d", ".dv", ".mpeg", ".mpg",
98  ".mpg2", ".vob", ".mkv", ".flv", ".divx", ".xvid", ".mxf", ".webm", NULL,
99 };
100 
101 /* sort of wrong being here... */
102 const char *imb_ext_audio[] = {
103  ".wav",
104  ".ogg",
105  ".oga",
106  ".mp3",
107  ".mp2",
108  ".ac3",
109  ".aac",
110  ".flac",
111  ".wma",
112  ".eac3",
113  ".aif",
114  ".aiff",
115  ".m4a",
116  ".mka",
117  NULL,
118 };
119 
120 /* Increased from 32 to 64 because of the bitmaps header size. */
121 #define HEADER_SIZE 64
122 
123 static ssize_t imb_ispic_read_header_from_filepath(const char *filepath,
124  unsigned char buf[HEADER_SIZE])
125 {
126  BLI_stat_t st;
127  int fp;
128 
129  BLI_assert(!BLI_path_is_rel(filepath));
130 
131  if (UTIL_DEBUG) {
132  printf("%s: loading %s\n", __func__, filepath);
133  }
134 
135  if (BLI_stat(filepath, &st) == -1) {
136  return -1;
137  }
138  if (((st.st_mode) & S_IFMT) != S_IFREG) {
139  return -1;
140  }
141 
142  if ((fp = BLI_open(filepath, O_BINARY | O_RDONLY, 0)) == -1) {
143  return -1;
144  }
145 
146  const ssize_t size = read(fp, buf, HEADER_SIZE);
147 
148  close(fp);
149  return size;
150 }
151 
152 int IMB_ispic_type_from_memory(const unsigned char *buf, const size_t buf_size)
153 {
155  if (type->is_a != NULL) {
156  if (type->is_a(buf, buf_size)) {
157  return type->filetype;
158  }
159  }
160  }
161 
162  return IMB_FTYPE_NONE;
163 }
164 
165 int IMB_ispic_type(const char *filepath)
166 {
167  unsigned char buf[HEADER_SIZE];
168  const ssize_t buf_size = imb_ispic_read_header_from_filepath(filepath, buf);
169  if (buf_size <= 0) {
170  return IMB_FTYPE_NONE;
171  }
172  return IMB_ispic_type_from_memory(buf, (size_t)buf_size);
173 }
174 
175 bool IMB_ispic_type_matches(const char *filepath, int filetype)
176 {
177  unsigned char buf[HEADER_SIZE];
178  const ssize_t buf_size = imb_ispic_read_header_from_filepath(filepath, buf);
179  if (buf_size <= 0) {
180  return false;
181  }
182 
183  const ImFileType *type = IMB_file_type_from_ftype(filetype);
184  if (type != NULL) {
185  /* Requesting to load a type that can't check it's own header doesn't make sense.
186  * Keep the check for developers. */
187  BLI_assert(type->is_a != NULL);
188  if (type->is_a != NULL) {
189  return type->is_a(buf, (size_t)buf_size);
190  }
191  }
192  return false;
193 }
194 
195 #undef HEADER_SIZE
196 
197 bool IMB_ispic(const char *filepath)
198 {
199  return (IMB_ispic_type(filepath) != IMB_FTYPE_NONE);
200 }
201 
202 static bool isavi(const char *filepath)
203 {
204 #ifdef WITH_AVI
205  return AVI_is_avi(filepath);
206 #else
207  (void)filepath;
208  return false;
209 #endif
210 }
211 
212 #ifdef WITH_FFMPEG
213 
214 /* BLI_vsnprintf in ffmpeg_log_callback() causes invalid warning */
215 # ifdef __GNUC__
216 # pragma GCC diagnostic push
217 # pragma GCC diagnostic ignored "-Wmissing-format-attribute"
218 # endif
219 
220 static char ffmpeg_last_error[1024];
221 
222 static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_list arg)
223 {
224  if (ELEM(level, AV_LOG_FATAL, AV_LOG_ERROR)) {
225  size_t n;
226  va_list args_cpy;
227 
228  va_copy(args_cpy, arg);
229  n = BLI_vsnprintf(ffmpeg_last_error, sizeof(ffmpeg_last_error), format, args_cpy);
230  va_end(args_cpy);
231 
232  /* strip trailing \n */
233  ffmpeg_last_error[n - 1] = '\0';
234  }
235 
236  if (G.debug & G_DEBUG_FFMPEG) {
237  /* call default logger to print all message to console */
238  av_log_default_callback(ptr, level, format, arg);
239  }
240 }
241 
242 # ifdef __GNUC__
243 # pragma GCC diagnostic pop
244 # endif
245 
246 void IMB_ffmpeg_init(void)
247 {
248  avdevice_register_all();
249 
250  ffmpeg_last_error[0] = '\0';
251 
252  if (G.debug & G_DEBUG_FFMPEG) {
253  av_log_set_level(AV_LOG_DEBUG);
254  }
255 
256  /* set own callback which could store last error to report to UI */
257  av_log_set_callback(ffmpeg_log_callback);
258 }
259 
260 const char *IMB_ffmpeg_last_error(void)
261 {
262  return ffmpeg_last_error;
263 }
264 
265 static int isffmpeg(const char *filepath)
266 {
267  AVFormatContext *pFormatCtx = NULL;
268  unsigned int i;
269  int videoStream;
270  AVCodec *pCodec;
271 
272  if (BLI_path_extension_check_n(filepath,
273  ".swf",
274  ".jpg",
275  ".jp2",
276  ".j2c",
277  ".png",
278  ".dds",
279  ".tga",
280  ".bmp",
281  ".tif",
282  ".exr",
283  ".cin",
284  ".wav",
285  NULL)) {
286  return 0;
287  }
288 
289  if (avformat_open_input(&pFormatCtx, filepath, NULL, NULL) != 0) {
290  if (UTIL_DEBUG) {
291  fprintf(stderr, "isffmpeg: av_open_input_file failed\n");
292  }
293  return 0;
294  }
295 
296  if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
297  if (UTIL_DEBUG) {
298  fprintf(stderr, "isffmpeg: avformat_find_stream_info failed\n");
299  }
300  avformat_close_input(&pFormatCtx);
301  return 0;
302  }
303 
304  if (UTIL_DEBUG) {
305  av_dump_format(pFormatCtx, 0, filepath, 0);
306  }
307 
308  /* Find the first video stream */
309  videoStream = -1;
310  for (i = 0; i < pFormatCtx->nb_streams; i++) {
311  if (pFormatCtx->streams[i] && pFormatCtx->streams[i]->codecpar &&
312  (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)) {
313  videoStream = i;
314  break;
315  }
316  }
317 
318  if (videoStream == -1) {
319  avformat_close_input(&pFormatCtx);
320  return 0;
321  }
322 
323  AVCodecParameters *codec_par = pFormatCtx->streams[videoStream]->codecpar;
324 
325  /* Find the decoder for the video stream */
326  pCodec = avcodec_find_decoder(codec_par->codec_id);
327  if (pCodec == NULL) {
328  avformat_close_input(&pFormatCtx);
329  return 0;
330  }
331 
332  avformat_close_input(&pFormatCtx);
333 
334  return 1;
335 }
336 #endif
337 
338 int imb_get_anim_type(const char *filepath)
339 {
340  BLI_stat_t st;
341 
342  BLI_assert(!BLI_path_is_rel(filepath));
343 
344  if (UTIL_DEBUG) {
345  printf("%s: %s\n", __func__, filepath);
346  }
347 
348 #ifndef _WIN32
349 # ifdef WITH_FFMPEG
350  /* stat test below fails on large files > 4GB */
351  if (isffmpeg(filepath)) {
352  return ANIM_FFMPEG;
353  }
354 # endif
355  if (BLI_stat(filepath, &st) == -1) {
356  return 0;
357  }
358  if (((st.st_mode) & S_IFMT) != S_IFREG) {
359  return 0;
360  }
361 
362  if (isavi(filepath)) {
363  return ANIM_AVI;
364  }
365 
366  if (ismovie(filepath)) {
367  return ANIM_MOVIE;
368  }
369 #else /* !_WIN32 */
370  if (BLI_stat(filepath, &st) == -1) {
371  return 0;
372  }
373  if (((st.st_mode) & S_IFMT) != S_IFREG) {
374  return 0;
375  }
376 
377  if (ismovie(filepath)) {
378  return ANIM_MOVIE;
379  }
380 # ifdef WITH_FFMPEG
381  if (isffmpeg(filepath)) {
382  return ANIM_FFMPEG;
383  }
384 # endif
385 
386  if (isavi(filepath)) {
387  return ANIM_AVI;
388  }
389 #endif /* !_WIN32 */
390 
391  /* Assume a single image is part of an image sequence. */
392  if (IMB_ispic(filepath)) {
393  return ANIM_SEQUENCE;
394  }
395 
396  return ANIM_NONE;
397 }
398 
399 bool IMB_isanim(const char *filepath)
400 {
401  int type;
402 
403  type = imb_get_anim_type(filepath);
404 
405  return (type && type != ANIM_SEQUENCE);
406 }
407 
408 bool IMB_isfloat(const ImBuf *ibuf)
409 {
410  const ImFileType *type = IMB_file_type_from_ibuf(ibuf);
411  if (type != NULL) {
412  if (type->flag & IM_FTYPE_FLOAT) {
413  return true;
414  }
415  }
416  return false;
417 }
bool AVI_is_avi(const char *name)
Definition: avi.c:203
@ G_DEBUG_FFMPEG
Definition: BKE_global.h:134
#define BLI_assert(a)
Definition: BLI_assert.h:58
#define va_copy(a, b)
Definition: BLI_dynstr.c:45
File and directory operations.
int BLI_open(const char *filename, int oflag, int pmode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: fileops.c:1017
#define O_BINARY
Definition: BLI_fileops.h:182
int BLI_stat(const char *path, BLI_stat_t *buffer) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
struct stat BLI_stat_t
Definition: BLI_fileops.h:67
bool BLI_path_is_rel(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
Definition: path_util.c:411
bool BLI_path_extension_check_n(const char *str,...) ATTR_NONNULL(1) ATTR_SENTINEL(0)
Definition: path_util.c:1464
size_t BLI_vsnprintf(char *__restrict buffer, size_t maxncpy, const char *__restrict format, va_list arg) ATTR_PRINTF_FORMAT(3
#define ELEM(...)
Compatibility-like things for windows.
SSIZE_T ssize_t
Definition: BLI_winstuff.h:87
_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
#define ANIM_MOVIE
Definition: IMB_anim.h:77
#define ANIM_SEQUENCE
Definition: IMB_anim.h:76
#define ANIM_FFMPEG
Definition: IMB_anim.h:79
#define ANIM_AVI
Definition: IMB_anim.h:78
#define ANIM_NONE
Definition: IMB_anim.h:75
#define IM_FTYPE_FLOAT
Definition: IMB_filetype.h:29
void IMB_ffmpeg_init(void)
const char * IMB_ffmpeg_last_error(void)
int ismovie(const char *filepath)
Contains defines and structs used throughout the imbuf module.
#define IMB_FTYPE_NONE
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition: btDbvt.cpp:52
const ImFileType * IMB_file_type_from_ftype(int ftype)
Definition: filetype.c:219
const ImFileType IMB_FILE_TYPES[]
Definition: filetype.c:43
const ImFileType * IMB_file_type_from_ibuf(const ImBuf *ibuf)
Definition: filetype.c:229
const ImFileType * IMB_FILE_TYPES_LAST
Definition: filetype.c:217
format
Definition: logImageCore.h:47
const char * imb_ext_image_filepath_only[]
Definition: util.c:86
#define HEADER_SIZE
Definition: util.c:121
static bool isavi(const char *filepath)
Definition: util.c:202
int IMB_ispic_type_from_memory(const unsigned char *buf, const size_t buf_size)
Definition: util.c:152
const char * imb_ext_movie[]
Definition: util.c:95
int IMB_ispic_type(const char *filepath)
Definition: util.c:165
const char * imb_ext_audio[]
Definition: util.c:102
#define UTIL_DEBUG
Definition: util.c:58
bool IMB_isanim(const char *filepath)
Definition: util.c:399
static ssize_t imb_ispic_read_header_from_filepath(const char *filepath, unsigned char buf[HEADER_SIZE])
Definition: util.c:123
bool IMB_ispic_type_matches(const char *filepath, int filetype)
Definition: util.c:175
int imb_get_anim_type(const char *filepath)
Definition: util.c:338
bool IMB_ispic(const char *filepath)
Definition: util.c:197
const char * imb_ext_image[]
Definition: util.c:60
bool IMB_isfloat(const ImBuf *ibuf)
Definition: util.c:408
#define G(x, y, z)
PointerRNA * ptr
Definition: wm_files.c:3157