style cleanup: trailing tabs & expand some non prefix tabs into spaces.
[blender.git] / source / blender / imbuf / intern / util.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  * util.c
27  *
28  */
29
30 /** \file blender/imbuf/intern/util.c
31  *  \ingroup imbuf
32  */
33
34
35 #ifdef _WIN32
36 #  include <io.h>
37 #  define open _open
38 #  define read _read
39 #  define close _close
40 #endif
41
42 #include <stdlib.h>
43
44 #include "BLI_path_util.h"
45 #include "BLI_fileops.h"
46 #include "BLI_utildefines.h"
47 #include "BLI_string.h"
48
49 #include "DNA_userdef_types.h"
50 #include "BKE_global.h"
51
52 #include "imbuf.h"
53 #include "IMB_imbuf_types.h"
54 #include "IMB_imbuf.h"
55 #include "IMB_filetype.h"
56
57 #include "IMB_anim.h"
58
59 #ifdef WITH_QUICKTIME
60 #include "quicktime_import.h"
61 #endif
62
63 #ifdef WITH_FFMPEG
64 #include <libavcodec/avcodec.h>
65 #include <libavformat/avformat.h>
66 #include <libavdevice/avdevice.h>
67 #include <libavutil/log.h>
68
69 #include "ffmpeg_compat.h"
70
71 #endif
72
73 #define UTIL_DEBUG 0
74
75 const char *imb_ext_image[] = {
76         ".png",
77         ".tga",
78         ".bmp",
79         ".jpg", ".jpeg",
80         ".sgi", ".rgb", ".rgba",
81 #ifdef WITH_TIFF
82         ".tif", ".tiff", ".tx",
83 #endif
84 #ifdef WITH_OPENJPEG
85         ".jp2",
86         ".j2c",
87 #endif
88 #ifdef WITH_HDR
89         ".hdr",
90 #endif
91 #ifdef WITH_DDS
92         ".dds",
93 #endif
94 #ifdef WITH_CINEON
95         ".dpx",
96         ".cin",
97 #endif
98 #ifdef WITH_OPENEXR
99         ".exr",
100 #endif
101         NULL
102 };
103
104 const char *imb_ext_image_qt[] = {
105         ".gif",
106         ".psd",
107         ".pct", ".pict",
108         ".pntg",
109         ".qtif",
110         NULL
111 };
112
113 const char *imb_ext_movie[] = {
114         ".avi",
115         ".flc",
116         ".mov",
117         ".movie",
118         ".mp4",
119         ".m4v",
120         ".m2v",
121         ".m2t",
122         ".m2ts",
123         ".mts",
124         ".mv",
125         ".avs",
126         ".wmv",
127         ".ogv",
128         ".dv",
129         ".mpeg",
130         ".mpg",
131         ".mpg2",
132         ".vob",
133         ".mkv",
134         ".flv",
135         ".divx",
136         ".xvid",
137         ".mxf",
138         NULL
139 };
140
141 /* sort of wrong being here... */
142 const char *imb_ext_audio[] = {
143         ".wav",
144         ".ogg",
145         ".oga",
146         ".mp3",
147         ".mp2",
148         ".ac3",
149         ".aac",
150         ".flac",
151         ".wma",
152         ".eac3",
153         ".aif",
154         ".aiff",
155         ".m4a",
156         NULL
157 };
158
159 static int IMB_ispic_name(const char *name)
160 {
161         ImFileType *type;
162         struct stat st;
163         int fp, buf[10];
164
165         if (UTIL_DEBUG) printf("IMB_ispic_name: loading %s\n", name);
166         
167         if (stat(name, &st) == -1)
168                 return FALSE;
169         if (((st.st_mode) & S_IFMT) != S_IFREG)
170                 return FALSE;
171
172         if ((fp = BLI_open(name, O_BINARY | O_RDONLY, 0)) < 0)
173                 return FALSE;
174
175         if (read(fp, buf, 32) != 32) {
176                 close(fp);
177                 return FALSE;
178         }
179
180         close(fp);
181
182         /* XXX move this exception */
183         if ((BIG_LONG(buf[0]) & 0xfffffff0) == 0xffd8ffe0)
184                 return JPG;
185
186         for (type = IMB_FILE_TYPES; type->is_a; type++)
187                 if (type->is_a((uchar *)buf))
188                         return type->filetype;
189
190         return FALSE;
191 }
192
193 int IMB_ispic(const char *filename)
194 {
195         if (U.uiflag & USER_FILTERFILEEXTS) {
196                 if ((BLI_testextensie_array(filename, imb_ext_image)) ||
197                     (G.have_quicktime && BLI_testextensie_array(filename, imb_ext_image_qt)))
198                 {
199                         return IMB_ispic_name(filename);
200                 }
201                 else {
202                         return FALSE;
203                 }
204         }
205         else { /* no FILTERFILEEXTS */
206                 return IMB_ispic_name(filename);
207         }
208 }
209
210
211
212 static int isavi(const char *name)
213 {
214 #ifdef WITH_AVI
215         return AVI_is_avi(name);
216 #else
217         (void)name;
218         return FALSE;
219 #endif
220 }
221
222 #ifdef WITH_QUICKTIME
223 static int isqtime(const char *name)
224 {
225         return anim_is_quicktime(name);
226 }
227 #endif
228
229 #ifdef WITH_FFMPEG
230
231 /* BLI_vsnprintf in ffmpeg_log_callback() causes invalid warning */
232 #pragma GCC diagnostic push
233 #pragma GCC diagnostic ignored "-Wmissing-format-attribute"
234
235 static char ffmpeg_last_error[1024];
236
237 static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_list arg)
238 {
239         if (ELEM(level, AV_LOG_FATAL, AV_LOG_ERROR)) {
240                 size_t n = BLI_vsnprintf(ffmpeg_last_error, sizeof(ffmpeg_last_error), format, arg);
241
242                 /* strip trailing \n */
243                 ffmpeg_last_error[n - 1] = '\0';
244         }
245
246         if (G.debug & G_DEBUG_FFMPEG) {
247                 /* call default logger to print all message to console */
248                 av_log_default_callback(ptr, level, format, arg);
249         }
250 }
251
252 #pragma GCC diagnostic pop
253
254 void IMB_ffmpeg_init(void)
255 {
256         av_register_all();
257         avdevice_register_all();
258
259         ffmpeg_last_error[0] = '\0';
260
261         /* set own callback which could store last error to report to UI */
262         av_log_set_callback(ffmpeg_log_callback);
263 }
264
265 const char *IMB_ffmpeg_last_error(void)
266 {
267         return ffmpeg_last_error;
268 }
269
270 static int isffmpeg(const char *filename)
271 {
272         AVFormatContext *pFormatCtx = NULL;
273         unsigned int i;
274         int videoStream;
275         AVCodec *pCodec;
276         AVCodecContext *pCodecCtx;
277
278         if (BLI_testextensie(filename, ".swf") ||
279             BLI_testextensie(filename, ".jpg") ||
280             BLI_testextensie(filename, ".png") ||
281             BLI_testextensie(filename, ".dds") ||
282             BLI_testextensie(filename, ".tga") ||
283             BLI_testextensie(filename, ".bmp") ||
284             BLI_testextensie(filename, ".exr") ||
285             BLI_testextensie(filename, ".cin") ||
286             BLI_testextensie(filename, ".wav"))
287         {
288                 return 0;
289         }
290
291         if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) != 0) {
292                 if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_open_input_file failed\n");
293                 return 0;
294         }
295
296         if (av_find_stream_info(pFormatCtx) < 0) {
297                 if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_find_stream_info failed\n");
298                 av_close_input_file(pFormatCtx);
299                 return 0;
300         }
301
302         if (UTIL_DEBUG) av_dump_format(pFormatCtx, 0, filename, 0);
303
304
305         /* Find the first video stream */
306         videoStream = -1;
307         for (i = 0; i < pFormatCtx->nb_streams; i++)
308                 if (pFormatCtx->streams[i] &&
309                     pFormatCtx->streams[i]->codec &&
310                     (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO))
311                 {
312                         videoStream = i;
313                         break;
314                 }
315
316         if (videoStream == -1) {
317                 av_close_input_file(pFormatCtx);
318                 return 0;
319         }
320
321         pCodecCtx = pFormatCtx->streams[videoStream]->codec;
322
323         /* Find the decoder for the video stream */
324         pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
325         if (pCodec == NULL) {
326                 av_close_input_file(pFormatCtx);
327                 return 0;
328         }
329
330         if (avcodec_open(pCodecCtx, pCodec) < 0) {
331                 av_close_input_file(pFormatCtx);
332                 return 0;
333         }
334
335         avcodec_close(pCodecCtx);
336         av_close_input_file(pFormatCtx);
337
338         return 1;
339 }
340 #endif
341
342 #ifdef WITH_REDCODE
343 static int isredcode(const char *filename)
344 {
345         struct redcode_handle *h = redcode_open(filename);
346         if (!h) {
347                 return 0;
348         }
349         redcode_close(h);
350         return 1;
351 }
352
353 #endif
354
355 int imb_get_anim_type(const char *name)
356 {
357         int type;
358         struct stat st;
359
360         if (UTIL_DEBUG) printf("in getanimtype: %s\n", name);
361
362 #ifndef _WIN32
363 #   ifdef WITH_QUICKTIME
364         if (isqtime(name)) return (ANIM_QTIME);
365 #   endif
366 #   ifdef WITH_FFMPEG
367         /* stat test below fails on large files > 4GB */
368         if (isffmpeg(name)) return (ANIM_FFMPEG);
369 #   endif
370         if (BLI_stat(name, &st) == -1) return(0);
371         if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
372
373         if (isavi(name)) return (ANIM_AVI);
374
375         if (ismovie(name)) return (ANIM_MOVIE);
376 #else
377         if (BLI_stat(name, &st) == -1) return(0);
378         if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
379
380         if (ismovie(name)) return (ANIM_MOVIE);
381 #   ifdef WITH_QUICKTIME
382         if (isqtime(name)) return (ANIM_QTIME);
383 #   endif
384 #   ifdef WITH_FFMPEG
385         if (isffmpeg(name)) return (ANIM_FFMPEG);
386 #   endif
387
388
389         if (isavi(name)) return (ANIM_AVI);
390 #endif
391 #ifdef WITH_REDCODE
392         if (isredcode(name)) return (ANIM_REDCODE);
393 #endif
394         type = IMB_ispic(name);
395         if (type) {
396                 return ANIM_SEQUENCE;
397         }
398
399         return ANIM_NONE;
400 }
401  
402 int IMB_isanim(const char *filename)
403 {
404         int type;
405         
406         if (U.uiflag & USER_FILTERFILEEXTS) {
407                 if (G.have_quicktime) {
408                         if (BLI_testextensie(filename, ".avi")   ||
409                             BLI_testextensie(filename, ".flc")   ||
410                             BLI_testextensie(filename, ".dv")    ||
411                             BLI_testextensie(filename, ".r3d")   ||
412                             BLI_testextensie(filename, ".mov")   ||
413                             BLI_testextensie(filename, ".movie") ||
414                             BLI_testextensie(filename, ".mv"))
415                         {
416                                 type = imb_get_anim_type(filename);
417                         }
418                         else {
419                                 return(FALSE);
420                         }
421                 }
422                 else { /* no quicktime */
423                         if (BLI_testextensie(filename, ".avi") ||
424                             BLI_testextensie(filename, ".dv")  ||
425                             BLI_testextensie(filename, ".r3d") ||
426                             BLI_testextensie(filename, ".mv"))
427                         {
428                                 type = imb_get_anim_type(filename);
429                         }
430                         else {
431                                 return(FALSE);
432                         }
433                 }
434         }
435         else { /* no FILTERFILEEXTS */
436                 type = imb_get_anim_type(filename);
437         }
438         
439         return (type && type != ANIM_SEQUENCE);
440 }