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