Creating a BGE staging branch.
[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_utildefines.h"
45 #include "BLI_path_util.h"
46 #include "BLI_fileops.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 (BLI_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 #ifdef _MSC_VER
232 #define va_copy(dst, src) ((dst) = (src))
233 #endif
234
235 /* BLI_vsnprintf in ffmpeg_log_callback() causes invalid warning */
236 #ifdef __GNUC__
237 #  pragma GCC diagnostic push
238 #  pragma GCC diagnostic ignored "-Wmissing-format-attribute"
239 #endif
240
241 static char ffmpeg_last_error[1024];
242
243 static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_list arg)
244 {
245         if (ELEM(level, AV_LOG_FATAL, AV_LOG_ERROR)) {
246                 size_t n;
247                 va_list arg2;
248
249                 va_copy(arg2, arg);
250
251                 n = BLI_vsnprintf(ffmpeg_last_error, sizeof(ffmpeg_last_error), format, arg2);
252
253                 /* strip trailing \n */
254                 ffmpeg_last_error[n - 1] = '\0';
255         }
256
257         if (G.debug & G_DEBUG_FFMPEG) {
258                 /* call default logger to print all message to console */
259                 av_log_default_callback(ptr, level, format, arg);
260         }
261 }
262
263 #ifdef __GNUC__
264 #  pragma GCC diagnostic pop
265 #endif
266
267 void IMB_ffmpeg_init(void)
268 {
269         av_register_all();
270         avdevice_register_all();
271
272         ffmpeg_last_error[0] = '\0';
273
274         if (G.debug & G_DEBUG_FFMPEG)
275                 av_log_set_level(AV_LOG_DEBUG);
276
277         /* set own callback which could store last error to report to UI */
278         av_log_set_callback(ffmpeg_log_callback);
279 }
280
281 const char *IMB_ffmpeg_last_error(void)
282 {
283         return ffmpeg_last_error;
284 }
285
286 static int isffmpeg(const char *filename)
287 {
288         AVFormatContext *pFormatCtx = NULL;
289         unsigned int i;
290         int videoStream;
291         AVCodec *pCodec;
292         AVCodecContext *pCodecCtx;
293
294         if (BLI_testextensie(filename, ".swf") ||
295             BLI_testextensie(filename, ".jpg") ||
296             BLI_testextensie(filename, ".png") ||
297             BLI_testextensie(filename, ".dds") ||
298             BLI_testextensie(filename, ".tga") ||
299             BLI_testextensie(filename, ".bmp") ||
300             BLI_testextensie(filename, ".tif") ||
301             BLI_testextensie(filename, ".exr") ||
302             BLI_testextensie(filename, ".cin") ||
303             BLI_testextensie(filename, ".wav"))
304         {
305                 return 0;
306         }
307
308         if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) != 0) {
309                 if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_open_input_file failed\n");
310                 return 0;
311         }
312
313         if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
314                 if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: avformat_find_stream_info failed\n");
315                 av_close_input_file(pFormatCtx);
316                 return 0;
317         }
318
319         if (UTIL_DEBUG) av_dump_format(pFormatCtx, 0, filename, 0);
320
321
322         /* Find the first video stream */
323         videoStream = -1;
324         for (i = 0; i < pFormatCtx->nb_streams; i++)
325                 if (pFormatCtx->streams[i] &&
326                     pFormatCtx->streams[i]->codec &&
327                     (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO))
328                 {
329                         videoStream = i;
330                         break;
331                 }
332
333         if (videoStream == -1) {
334                 av_close_input_file(pFormatCtx);
335                 return 0;
336         }
337
338         pCodecCtx = pFormatCtx->streams[videoStream]->codec;
339
340         /* Find the decoder for the video stream */
341         pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
342         if (pCodec == NULL) {
343                 av_close_input_file(pFormatCtx);
344                 return 0;
345         }
346
347         if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
348                 av_close_input_file(pFormatCtx);
349                 return 0;
350         }
351
352         avcodec_close(pCodecCtx);
353         av_close_input_file(pFormatCtx);
354
355         return 1;
356 }
357 #endif
358
359 #ifdef WITH_REDCODE
360 static int isredcode(const char *filename)
361 {
362         struct redcode_handle *h = redcode_open(filename);
363         if (!h) {
364                 return 0;
365         }
366         redcode_close(h);
367         return 1;
368 }
369
370 #endif
371
372 int imb_get_anim_type(const char *name)
373 {
374         int type;
375         struct stat st;
376
377         if (UTIL_DEBUG) printf("in getanimtype: %s\n", name);
378
379 #ifndef _WIN32
380 #   ifdef WITH_QUICKTIME
381         if (isqtime(name)) return (ANIM_QTIME);
382 #   endif
383 #   ifdef WITH_FFMPEG
384         /* stat test below fails on large files > 4GB */
385         if (isffmpeg(name)) return (ANIM_FFMPEG);
386 #   endif
387         if (BLI_stat(name, &st) == -1) return(0);
388         if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
389
390         if (isavi(name)) return (ANIM_AVI);
391
392         if (ismovie(name)) return (ANIM_MOVIE);
393 #else
394         if (BLI_stat(name, &st) == -1) return(0);
395         if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
396
397         if (ismovie(name)) return (ANIM_MOVIE);
398 #   ifdef WITH_QUICKTIME
399         if (isqtime(name)) return (ANIM_QTIME);
400 #   endif
401 #   ifdef WITH_FFMPEG
402         if (isffmpeg(name)) return (ANIM_FFMPEG);
403 #   endif
404
405
406         if (isavi(name)) return (ANIM_AVI);
407 #endif
408 #ifdef WITH_REDCODE
409         if (isredcode(name)) return (ANIM_REDCODE);
410 #endif
411         type = IMB_ispic(name);
412         if (type) {
413                 return ANIM_SEQUENCE;
414         }
415
416         return ANIM_NONE;
417 }
418  
419 int IMB_isanim(const char *filename)
420 {
421         int type;
422         
423         if (U.uiflag & USER_FILTERFILEEXTS) {
424                 if (G.have_quicktime) {
425                         if (BLI_testextensie(filename, ".avi")   ||
426                             BLI_testextensie(filename, ".flc")   ||
427                             BLI_testextensie(filename, ".dv")    ||
428                             BLI_testextensie(filename, ".r3d")   ||
429                             BLI_testextensie(filename, ".mov")   ||
430                             BLI_testextensie(filename, ".movie") ||
431                             BLI_testextensie(filename, ".mv"))
432                         {
433                                 type = imb_get_anim_type(filename);
434                         }
435                         else {
436                                 return(FALSE);
437                         }
438                 }
439                 else { /* no quicktime */
440                         if (BLI_testextensie(filename, ".avi") ||
441                             BLI_testextensie(filename, ".dv")  ||
442                             BLI_testextensie(filename, ".r3d") ||
443                             BLI_testextensie(filename, ".mv"))
444                         {
445                                 type = imb_get_anim_type(filename);
446                         }
447                         else {
448                                 return(FALSE);
449                         }
450                 }
451         }
452         else { /* no FILTERFILEEXTS */
453                 type = imb_get_anim_type(filename);
454         }
455         
456         return (type && type != ANIM_SEQUENCE);
457 }