Cleanup: add trailing commas
[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 #endif
38
39 #include <stdlib.h>
40
41 #include "BLI_utildefines.h"
42 #include "BLI_path_util.h"
43 #include "BLI_fileops.h"
44 #include "BLI_string.h"
45
46 #include "imbuf.h"
47 #include "IMB_imbuf_types.h"
48 #include "IMB_imbuf.h"
49 #include "IMB_filetype.h"
50
51 #include "IMB_anim.h"
52
53 #ifdef WITH_FFMPEG
54 #include "BKE_global.h"  /* G.debug */
55 #include <libavcodec/avcodec.h>
56 #include <libavformat/avformat.h>
57 #include <libavdevice/avdevice.h>
58 #include <libavutil/log.h>
59
60 #include "ffmpeg_compat.h"
61
62 #endif
63
64 #define UTIL_DEBUG 0
65
66 const char *imb_ext_image[] = {
67         ".png",
68         ".tga",
69         ".bmp",
70         ".jpg", ".jpeg",
71         ".sgi", ".rgb", ".rgba",
72 #ifdef WITH_TIFF
73         ".tif", ".tiff", ".tx",
74 #endif
75 #ifdef WITH_OPENJPEG
76         ".jp2",
77         ".j2c",
78 #endif
79 #ifdef WITH_HDR
80         ".hdr",
81 #endif
82 #ifdef WITH_DDS
83         ".dds",
84 #endif
85 #ifdef WITH_CINEON
86         ".dpx",
87         ".cin",
88 #endif
89 #ifdef WITH_OPENEXR
90         ".exr",
91 #endif
92 #ifdef WITH_OPENIMAGEIO
93         ".psd", ".pdd", ".psb",
94 #endif
95         NULL,
96 };
97
98 const char *imb_ext_image_filepath_only[] = {
99 #ifdef WITH_OPENIMAGEIO
100         ".psd", ".pdd", ".psb",
101 #endif
102         NULL,
103 };
104
105 const char *imb_ext_movie[] = {
106         ".avi",
107         ".flc",
108         ".mov",
109         ".movie",
110         ".mp4",
111         ".m4v",
112         ".m2v",
113         ".m2t",
114         ".m2ts",
115         ".mts",
116         ".ts",
117         ".mv",
118         ".avs",
119         ".wmv",
120         ".ogv",
121         ".ogg",
122         ".r3d",
123         ".dv",
124         ".mpeg",
125         ".mpg",
126         ".mpg2",
127         ".vob",
128         ".mkv",
129         ".flv",
130         ".divx",
131         ".xvid",
132         ".mxf",
133         ".webm",
134         NULL,
135 };
136
137 /* sort of wrong being here... */
138 const char *imb_ext_audio[] = {
139         ".wav",
140         ".ogg",
141         ".oga",
142         ".mp3",
143         ".mp2",
144         ".ac3",
145         ".aac",
146         ".flac",
147         ".wma",
148         ".eac3",
149         ".aif",
150         ".aiff",
151         ".m4a",
152         ".mka",
153         NULL,
154 };
155
156 int IMB_ispic_type(const char *name)
157 {
158         /* increased from 32 to 64 because of the bitmaps header size */
159 #define HEADER_SIZE 64
160
161         unsigned char buf[HEADER_SIZE];
162         const ImFileType *type;
163         BLI_stat_t st;
164         int fp;
165
166         BLI_assert(!BLI_path_is_rel(name));
167
168         if (UTIL_DEBUG) printf("%s: loading %s\n", __func__, name);
169
170         if (BLI_stat(name, &st) == -1)
171                 return false;
172         if (((st.st_mode) & S_IFMT) != S_IFREG)
173                 return false;
174
175         if ((fp = BLI_open(name, O_BINARY | O_RDONLY, 0)) == -1)
176                 return false;
177
178         memset(buf, 0, sizeof(buf));
179         if (read(fp, buf, HEADER_SIZE) <= 0) {
180                 close(fp);
181                 return false;
182         }
183
184         close(fp);
185
186         /* XXX move this exception */
187         if ((BIG_LONG(((int *)buf)[0]) & 0xfffffff0) == 0xffd8ffe0)
188                 return IMB_FTYPE_JPG;
189
190         for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
191                 if (type->is_a) {
192                         if (type->is_a(buf)) {
193                                 return type->filetype;
194                         }
195                 }
196                 else if (type->is_a_filepath) {
197                         if (type->is_a_filepath(name)) {
198                                 return type->filetype;
199                         }
200                 }
201         }
202
203         return 0;
204
205 #undef HEADER_SIZE
206 }
207
208 bool IMB_ispic(const char *name)
209 {
210         return (IMB_ispic_type(name) != 0);
211 }
212
213 static int isavi(const char *name)
214 {
215 #ifdef WITH_AVI
216         return AVI_is_avi(name);
217 #else
218         (void)name;
219         return false;
220 #endif
221 }
222
223 #ifdef WITH_FFMPEG
224
225 /* BLI_vsnprintf in ffmpeg_log_callback() causes invalid warning */
226 #ifdef __GNUC__
227 #  pragma GCC diagnostic push
228 #  pragma GCC diagnostic ignored "-Wmissing-format-attribute"
229 #endif
230
231 static char ffmpeg_last_error[1024];
232
233 static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_list arg)
234 {
235         if (ELEM(level, AV_LOG_FATAL, AV_LOG_ERROR)) {
236                 size_t n;
237                 va_list args_cpy;
238
239                 va_copy(args_cpy, arg);
240                 n = BLI_vsnprintf(ffmpeg_last_error, sizeof(ffmpeg_last_error), format, args_cpy);
241                 va_end(args_cpy);
242
243                 /* strip trailing \n */
244                 ffmpeg_last_error[n - 1] = '\0';
245         }
246
247         if (G.debug & G_DEBUG_FFMPEG) {
248                 /* call default logger to print all message to console */
249                 av_log_default_callback(ptr, level, format, arg);
250         }
251 }
252
253 #ifdef __GNUC__
254 #  pragma GCC diagnostic pop
255 #endif
256
257 void IMB_ffmpeg_init(void)
258 {
259         av_register_all();
260         avdevice_register_all();
261
262         ffmpeg_last_error[0] = '\0';
263
264         if (G.debug & G_DEBUG_FFMPEG)
265                 av_log_set_level(AV_LOG_DEBUG);
266
267         /* set own callback which could store last error to report to UI */
268         av_log_set_callback(ffmpeg_log_callback);
269 }
270
271 const char *IMB_ffmpeg_last_error(void)
272 {
273         return ffmpeg_last_error;
274 }
275
276 static int isffmpeg(const char *filename)
277 {
278         AVFormatContext *pFormatCtx = NULL;
279         unsigned int i;
280         int videoStream;
281         AVCodec *pCodec;
282         AVCodecContext *pCodecCtx;
283
284         if (BLI_path_extension_check_n(
285                 filename,
286                 ".swf", ".jpg", ".png", ".dds", ".tga", ".bmp", ".tif", ".exr", ".cin", ".wav", NULL))
287         {
288                 return 0;
289         }
290
291         if (avformat_open_input(&pFormatCtx, filename, NULL, NULL) != 0) {
292                 if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_open_input_file failed\n");
293                 return 0;
294         }
295
296         if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {
297                 if (UTIL_DEBUG) fprintf(stderr, "isffmpeg: avformat_find_stream_info failed\n");
298                 avformat_close_input(&pFormatCtx);
299                 return 0;
300         }
301
302         if (UTIL_DEBUG) av_dump_format(pFormatCtx, 0, filename, 0);
303
304
305         /* Find the first video stream */
306         videoStream = -1;
307         for (i = 0; i < pFormatCtx->nb_streams; i++)
308                 if (pFormatCtx->streams[i] &&
309                     pFormatCtx->streams[i]->codec &&
310                     (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO))
311                 {
312                         videoStream = i;
313                         break;
314                 }
315
316         if (videoStream == -1) {
317                 avformat_close_input(&pFormatCtx);
318                 return 0;
319         }
320
321         pCodecCtx = pFormatCtx->streams[videoStream]->codec;
322
323         /* Find the decoder for the video stream */
324         pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
325         if (pCodec == NULL) {
326                 avformat_close_input(&pFormatCtx);
327                 return 0;
328         }
329
330         if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
331                 avformat_close_input(&pFormatCtx);
332                 return 0;
333         }
334
335         avcodec_close(pCodecCtx);
336         avformat_close_input(&pFormatCtx);
337
338         return 1;
339 }
340 #endif
341
342 int imb_get_anim_type(const char *name)
343 {
344         int type;
345         BLI_stat_t st;
346
347         BLI_assert(!BLI_path_is_rel(name));
348
349         if (UTIL_DEBUG) printf("%s: %s\n", __func__, name);
350
351 #ifndef _WIN32
352 #   ifdef WITH_FFMPEG
353         /* stat test below fails on large files > 4GB */
354         if (isffmpeg(name)) return (ANIM_FFMPEG);
355 #   endif
356         if (BLI_stat(name, &st) == -1) return(0);
357         if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
358
359         if (isavi(name)) return (ANIM_AVI);
360
361         if (ismovie(name)) return (ANIM_MOVIE);
362 #else
363         if (BLI_stat(name, &st) == -1) return(0);
364         if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
365
366         if (ismovie(name)) return (ANIM_MOVIE);
367 #   ifdef WITH_FFMPEG
368         if (isffmpeg(name)) return (ANIM_FFMPEG);
369 #   endif
370
371
372         if (isavi(name)) return (ANIM_AVI);
373 #endif
374         type = IMB_ispic(name);
375         if (type) {
376                 return ANIM_SEQUENCE;
377         }
378
379         return ANIM_NONE;
380 }
381
382 bool IMB_isanim(const char *filename)
383 {
384         int type;
385
386         type = imb_get_anim_type(filename);
387
388         return (type && type != ANIM_SEQUENCE);
389 }
390
391 bool IMB_isfloat(ImBuf *ibuf)
392 {
393         const ImFileType *type;
394
395         for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
396                 if (type->ftype(type, ibuf)) {
397                         return (type->flag & IM_FTYPE_FLOAT) != 0;
398                 }
399         }
400         return false;
401 }