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