3 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
19 * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
20 * All rights reserved.
22 * The Original Code is: all of this file.
24 * Contributor(s): none yet.
26 * ***** END GPL LICENSE BLOCK *****
32 /** \file blender/imbuf/intern/util.c
44 #include "BLI_blenlib.h"
46 #include "DNA_userdef_types.h"
47 #include "BKE_global.h"
50 #include "IMB_imbuf_types.h"
51 #include "IMB_imbuf.h"
52 #include "IMB_filetype.h"
57 #include "quicktime_import.h"
61 #include <libavcodec/avcodec.h>
62 #include <libavformat/avformat.h>
63 #include <libavdevice/avdevice.h>
64 #include <libavutil/log.h>
66 #include "ffmpeg_compat.h"
72 const char *imb_ext_image[] = {
77 ".sgi", ".rgb", ".rgba",
79 ".tif", ".tiff", ".tx",
99 const char *imb_ext_image_qt[] = {
107 const char *imb_ext_movie[] = {
133 /* sort of wrong being here... */
134 const char *imb_ext_audio[] = {
147 static int IMB_ispic_name(const char *name)
153 if(UTIL_DEBUG) printf("IMB_ispic_name: loading %s\n", name);
155 if(stat(name,&st) == -1)
157 if(((st.st_mode) & S_IFMT) != S_IFREG)
160 if((fp = open(name,O_BINARY|O_RDONLY)) < 0)
163 if(read(fp, buf, 32) != 32) {
170 /* XXX move this exception */
171 if((BIG_LONG(buf[0]) & 0xfffffff0) == 0xffd8ffe0)
174 for(type=IMB_FILE_TYPES; type->is_a; type++)
175 if(type->is_a((uchar*)buf))
176 return type->filetype;
181 int IMB_ispic(const char *filename)
183 if(U.uiflag & USER_FILTERFILEEXTS) {
184 if( (BLI_testextensie_array(filename, imb_ext_image)) ||
185 (G.have_quicktime && BLI_testextensie_array(filename, imb_ext_image_qt))
187 return IMB_ispic_name(filename);
193 else { /* no FILTERFILEEXTS */
194 return IMB_ispic_name(filename);
200 static int isavi (const char *name) {
201 return AVI_is_avi (name);
204 #ifdef WITH_QUICKTIME
205 static int isqtime (const char *name) {
206 return anim_is_quicktime (name);
212 void silence_log_ffmpeg(int quiet)
216 av_log_set_level(AV_LOG_QUIET);
220 av_log_set_level(AV_LOG_INFO);
224 extern void do_init_ffmpeg(void);
225 void do_init_ffmpeg(void)
227 static int ffmpeg_init = 0;
231 avdevice_register_all();
233 if ((G.f & G_DEBUG) == 0)
235 silence_log_ffmpeg(1);
240 static int isffmpeg (const char *filename) {
241 AVFormatContext *pFormatCtx;
245 AVCodecContext *pCodecCtx;
249 if( BLI_testextensie(filename, ".swf") ||
250 BLI_testextensie(filename, ".jpg") ||
251 BLI_testextensie(filename, ".png") ||
252 BLI_testextensie(filename, ".dds") ||
253 BLI_testextensie(filename, ".tga") ||
254 BLI_testextensie(filename, ".bmp") ||
255 BLI_testextensie(filename, ".exr") ||
256 BLI_testextensie(filename, ".cin") ||
257 BLI_testextensie(filename, ".wav")) return 0;
259 if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0) {
260 if(UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_open_input_file failed\n");
264 if(av_find_stream_info(pFormatCtx)<0) {
265 if(UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_find_stream_info failed\n");
266 av_close_input_file(pFormatCtx);
270 if(UTIL_DEBUG) av_dump_format(pFormatCtx, 0, filename, 0);
273 /* Find the first video stream */
275 for(i=0; i<pFormatCtx->nb_streams; i++)
276 if(pFormatCtx->streams[i] &&
277 pFormatCtx->streams[i]->codec &&
278 (pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO))
284 if(videoStream==-1) {
285 av_close_input_file(pFormatCtx);
289 pCodecCtx = pFormatCtx->streams[videoStream]->codec;
291 /* Find the decoder for the video stream */
292 pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
294 av_close_input_file(pFormatCtx);
298 if(avcodec_open(pCodecCtx, pCodec)<0) {
299 av_close_input_file(pFormatCtx);
303 avcodec_close(pCodecCtx);
304 av_close_input_file(pFormatCtx);
311 static int isredcode(const char * filename)
313 struct redcode_handle * h = redcode_open(filename);
323 int imb_get_anim_type(const char * name) {
327 if(UTIL_DEBUG) printf("in getanimtype: %s\n", name);
330 # ifdef WITH_QUICKTIME
331 if (isqtime(name)) return (ANIM_QTIME);
334 /* stat test below fails on large files > 4GB */
335 if (isffmpeg(name)) return (ANIM_FFMPEG);
337 if (stat(name,&st) == -1) return(0);
338 if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
340 if (isavi(name)) return (ANIM_AVI);
342 if (ismovie(name)) return (ANIM_MOVIE);
344 if (stat(name,&st) == -1) return(0);
345 if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
347 if (ismovie(name)) return (ANIM_MOVIE);
348 # ifdef WITH_QUICKTIME
349 if (isqtime(name)) return (ANIM_QTIME);
352 if (isffmpeg(name)) return (ANIM_FFMPEG);
354 if (isavi(name)) return (ANIM_AVI);
357 if (isredcode(name)) return (ANIM_REDCODE);
359 type = IMB_ispic(name);
360 if (type) return(ANIM_SEQUENCE);
364 int IMB_isanim(const char *filename) {
367 if(U.uiflag & USER_FILTERFILEEXTS) {
368 if (G.have_quicktime){
369 if( BLI_testextensie(filename, ".avi")
370 || BLI_testextensie(filename, ".flc")
371 || BLI_testextensie(filename, ".dv")
372 || BLI_testextensie(filename, ".r3d")
373 || BLI_testextensie(filename, ".mov")
374 || BLI_testextensie(filename, ".movie")
375 || BLI_testextensie(filename, ".mv")) {
376 type = imb_get_anim_type(filename);
380 } else { // no quicktime
381 if( BLI_testextensie(filename, ".avi")
382 || BLI_testextensie(filename, ".dv")
383 || BLI_testextensie(filename, ".r3d")
384 || BLI_testextensie(filename, ".mv")) {
385 type = imb_get_anim_type(filename);
391 } else { // no FILTERFILEEXTS
392 type = imb_get_anim_type(filename);
395 return (type && type!=ANIM_SEQUENCE);