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