kmvc: Use bytestream2 functions to prevent buffer overreads.
[libav.git] / cmdutils.c
CommitLineData
01310af2
FB
1/*
2 * Various utilities for command line tools
3 * Copyright (c) 2000-2003 Fabrice Bellard
4 *
2912e87a 5 * This file is part of Libav.
b78e7197 6 *
2912e87a 7 * Libav is free software; you can redistribute it and/or
01310af2
FB
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
b78e7197 10 * version 2.1 of the License, or (at your option) any later version.
01310af2 11 *
2912e87a 12 * Libav is distributed in the hope that it will be useful,
01310af2
FB
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
2912e87a 18 * License along with Libav; if not, write to the Free Software
5509bffa 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
01310af2 20 */
364a9607 21
0f4e8165
RB
22#include <string.h>
23#include <stdlib.h>
24#include <errno.h>
7c84b8bc 25#include <math.h>
0f4e8165 26
2cd39dbf
DP
27/* Include only the enabled headers since some compilers (namely, Sun
28 Studio) will not omit unused inline functions and create undefined
29 references to libraries that are not being built. */
30
63d026b1 31#include "config.h"
245976da
DB
32#include "libavformat/avformat.h"
33#include "libavfilter/avfilter.h"
34#include "libavdevice/avdevice.h"
db6d50c7 35#include "libswscale/swscale.h"
1981deaf 36#include "libpostproc/postprocess.h"
245976da 37#include "libavutil/avstring.h"
85770d6e 38#include "libavutil/mathematics.h"
f6c7375a 39#include "libavutil/parseutils.h"
9cb5c760 40#include "libavutil/pixdesc.h"
25e25617 41#include "libavutil/eval.h"
9ba38229 42#include "libavutil/dict.h"
41d0eb1c 43#include "libavutil/opt.h"
01310af2 44#include "cmdutils.h"
86074ed1 45#include "version.h"
da2dc39e 46#if CONFIG_NETWORK
245976da 47#include "libavformat/network.h"
da2dc39e 48#endif
ffcc6e24
MR
49#if HAVE_SYS_RESOURCE_H
50#include <sys/resource.h>
51#endif
01310af2 52
85663ef3 53struct SwsContext *sws_opts;
8c8eab8b 54AVDictionary *format_opts, *codec_opts;
086ab001 55
3568853f 56static const int this_year = 2011;
ef4c0bb1 57
a5c33faa
RD
58void init_opts(void)
59{
be4876ea 60#if CONFIG_SWSCALE
cbaef7d1
AD
61 sws_opts = sws_getContext(16, 16, 0, 16, 16, 0, SWS_BICUBIC,
62 NULL, NULL, NULL);
be4876ea 63#endif
a5c33faa
RD
64}
65
66void uninit_opts(void)
67{
be4876ea 68#if CONFIG_SWSCALE
faf8d3dd
RB
69 sws_freeContext(sws_opts);
70 sws_opts = NULL;
be4876ea 71#endif
9ba38229 72 av_dict_free(&format_opts);
8c8eab8b 73 av_dict_free(&codec_opts);
a5c33faa
RD
74}
75
cbaef7d1 76void log_callback_help(void *ptr, int level, const char *fmt, va_list vl)
1790d3b3
SS
77{
78 vfprintf(stdout, fmt, vl);
79}
80
cbaef7d1
AD
81double parse_number_or_die(const char *context, const char *numstr, int type,
82 double min, double max)
086ab001
MN
83{
84 char *tail;
85 const char *error;
25e25617 86 double d = av_strtod(numstr, &tail);
086ab001 87 if (*tail)
cbaef7d1 88 error = "Expected number for %s but found: %s\n";
086ab001 89 else if (d < min || d > max)
cbaef7d1
AD
90 error = "The value for %s was %s which is not within %f - %f\n";
91 else if (type == OPT_INT64 && (int64_t)d != d)
92 error = "Expected int64 for %s but found %s\n";
3372ec32 93 else if (type == OPT_INT && (int)d != d)
cbaef7d1 94 error = "Expected int for %s but found %s\n";
086ab001
MN
95 else
96 return d;
1c5e9551 97 av_log(NULL, AV_LOG_FATAL, error, context, numstr, min, max);
dad09ff9
AK
98 exit_program(1);
99 return 0;
086ab001
MN
100}
101
cbaef7d1
AD
102int64_t parse_time_or_die(const char *context, const char *timestr,
103 int is_duration)
7542157d 104{
f6c7375a
SS
105 int64_t us;
106 if (av_parse_time(&us, timestr, is_duration) < 0) {
1c5e9551
AK
107 av_log(NULL, AV_LOG_FATAL, "Invalid %s specification for %s: %s\n",
108 is_duration ? "duration" : "date", context, timestr);
dad09ff9 109 exit_program(1);
7542157d
SS
110 }
111 return us;
112}
113
cbaef7d1
AD
114void show_help_options(const OptionDef *options, const char *msg, int mask,
115 int value)
01310af2
FB
116{
117 const OptionDef *po;
02d504a7 118 int first;
01310af2 119
02d504a7 120 first = 1;
cbaef7d1 121 for (po = options; po->name != NULL; po++) {
02d504a7
FB
122 char buf[64];
123 if ((po->flags & mask) == value) {
124 if (first) {
125 printf("%s", msg);
126 first = 0;
127 }
f7d78f36 128 av_strlcpy(buf, po->name, sizeof(buf));
02d504a7 129 if (po->flags & HAS_ARG) {
f7d78f36
MR
130 av_strlcat(buf, " ", sizeof(buf));
131 av_strlcat(buf, po->argname, sizeof(buf));
01310af2 132 }
02d504a7 133 printf("-%-17s %s\n", buf, po->help);
01310af2
FB
134 }
135 }
136}
137
7a6cd995
AK
138void show_help_children(const AVClass *class, int flags)
139{
140 const AVClass *child = NULL;
141 av_opt_show2(&class, NULL, flags, 0);
142 printf("\n");
143
144 while (child = av_opt_child_class_next(class, child))
145 show_help_children(child, flags);
146}
147
cbaef7d1
AD
148static const OptionDef *find_option(const OptionDef *po, const char *name)
149{
d70e5122
AK
150 const char *p = strchr(name, ':');
151 int len = p ? p - name : strlen(name);
152
8bbf6db9 153 while (po->name != NULL) {
d70e5122 154 if (!strncmp(name, po->name, len) && strlen(po->name) == len)
8bbf6db9
MN
155 break;
156 po++;
157 }
158 return po;
159}
160
b1ac139d 161#if defined(_WIN32) && !defined(__MINGW32CE__)
ba9327ea 162#include <windows.h>
b1ac139d
KG
163/* Will be leaked on exit */
164static char** win32_argv_utf8 = NULL;
165static int win32_argc = 0;
166
167/**
168 * Prepare command line arguments for executable.
169 * For Windows - perform wide-char to UTF-8 conversion.
170 * Input arguments should be main() function arguments.
171 * @param argc_ptr Arguments number (including executable)
172 * @param argv_ptr Arguments list.
173 */
174static void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
175{
176 char *argstr_flat;
177 wchar_t **argv_w;
178 int i, buffsize = 0, offset = 0;
179
180 if (win32_argv_utf8) {
181 *argc_ptr = win32_argc;
182 *argv_ptr = win32_argv_utf8;
183 return;
184 }
185
186 win32_argc = 0;
187 argv_w = CommandLineToArgvW(GetCommandLineW(), &win32_argc);
188 if (win32_argc <= 0 || !argv_w)
189 return;
190
191 /* determine the UTF-8 buffer size (including NULL-termination symbols) */
192 for (i = 0; i < win32_argc; i++)
193 buffsize += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
194 NULL, 0, NULL, NULL);
195
cbaef7d1
AD
196 win32_argv_utf8 = av_mallocz(sizeof(char *) * (win32_argc + 1) + buffsize);
197 argstr_flat = (char *)win32_argv_utf8 + sizeof(char *) * (win32_argc + 1);
b1ac139d
KG
198 if (win32_argv_utf8 == NULL) {
199 LocalFree(argv_w);
200 return;
201 }
202
203 for (i = 0; i < win32_argc; i++) {
204 win32_argv_utf8[i] = &argstr_flat[offset];
205 offset += WideCharToMultiByte(CP_UTF8, 0, argv_w[i], -1,
206 &argstr_flat[offset],
207 buffsize - offset, NULL, NULL);
208 }
209 win32_argv_utf8[i] = NULL;
210 LocalFree(argv_w);
211
212 *argc_ptr = win32_argc;
213 *argv_ptr = win32_argv_utf8;
214}
215#else
216static inline void prepare_app_arguments(int *argc_ptr, char ***argv_ptr)
217{
218 /* nothing to do */
219}
220#endif /* WIN32 && !__MINGW32CE__ */
221
cbaef7d1
AD
222int parse_option(void *optctx, const char *opt, const char *arg,
223 const OptionDef *options)
2f8e586d
AK
224{
225 const OptionDef *po;
226 int bool_val = 1;
6361c5e1 227 int *dstcount;
2f8e586d
AK
228 void *dst;
229
230 po = find_option(options, opt);
231 if (!po->name && opt[0] == 'n' && opt[1] == 'o') {
232 /* handle 'no' bool option */
233 po = find_option(options, opt + 2);
234 if (!(po->name && (po->flags & OPT_BOOL)))
235 goto unknown_opt;
236 bool_val = 0;
237 }
238 if (!po->name)
239 po = find_option(options, "default");
240 if (!po->name) {
241unknown_opt:
242 av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
243 return AVERROR(EINVAL);
244 }
245 if (po->flags & HAS_ARG && !arg) {
246 av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'\n", opt);
247 return AVERROR(EINVAL);
248 }
249
250 /* new-style options contain an offset into optctx, old-style address of
251 * a global var*/
cbaef7d1
AD
252 dst = po->flags & (OPT_OFFSET | OPT_SPEC) ? (uint8_t *)optctx + po->u.off
253 : po->u.dst_ptr;
6361c5e1
AK
254
255 if (po->flags & OPT_SPEC) {
256 SpecifierOpt **so = dst;
257 char *p = strchr(opt, ':');
258
cbaef7d1 259 dstcount = (int *)(so + 1);
6361c5e1
AK
260 *so = grow_array(*so, sizeof(**so), dstcount, *dstcount + 1);
261 (*so)[*dstcount - 1].specifier = av_strdup(p ? p + 1 : "");
262 dst = &(*so)[*dstcount - 1].u;
263 }
2f8e586d
AK
264
265 if (po->flags & OPT_STRING) {
266 char *str;
267 str = av_strdup(arg);
cbaef7d1 268 *(char **)dst = str;
2f8e586d 269 } else if (po->flags & OPT_BOOL) {
cbaef7d1 270 *(int *)dst = bool_val;
2f8e586d 271 } else if (po->flags & OPT_INT) {
cbaef7d1 272 *(int *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT_MIN, INT_MAX);
2f8e586d 273 } else if (po->flags & OPT_INT64) {
cbaef7d1 274 *(int64_t *)dst = parse_number_or_die(opt, arg, OPT_INT64, INT64_MIN, INT64_MAX);
6b779ccc 275 } else if (po->flags & OPT_TIME) {
cbaef7d1 276 *(int64_t *)dst = parse_time_or_die(opt, arg, 1);
2f8e586d 277 } else if (po->flags & OPT_FLOAT) {
cbaef7d1 278 *(float *)dst = parse_number_or_die(opt, arg, OPT_FLOAT, -INFINITY, INFINITY);
33f75d72 279 } else if (po->flags & OPT_DOUBLE) {
cbaef7d1 280 *(double *)dst = parse_number_or_die(opt, arg, OPT_DOUBLE, -INFINITY, INFINITY);
2f8e586d 281 } else if (po->u.func_arg) {
cbaef7d1
AD
282 int ret = po->flags & OPT_FUNC2 ? po->u.func2_arg(optctx, opt, arg)
283 : po->u.func_arg(opt, arg);
2f8e586d 284 if (ret < 0) {
cbaef7d1
AD
285 av_log(NULL, AV_LOG_ERROR,
286 "Failed to set value '%s' for option '%s'\n", arg, opt);
2f8e586d
AK
287 return ret;
288 }
289 }
290 if (po->flags & OPT_EXIT)
291 exit_program(0);
292 return !!(po->flags & HAS_ARG);
293}
294
7cc8d638 295void parse_options(void *optctx, int argc, char **argv, const OptionDef *options,
cbaef7d1 296 void (*parse_arg_function)(void *, const char*))
01310af2 297{
2f8e586d
AK
298 const char *opt;
299 int optindex, handleoptions = 1, ret;
01310af2 300
b1ac139d
KG
301 /* perform system-dependent conversions for arguments list */
302 prepare_app_arguments(&argc, &argv);
303
01310af2
FB
304 /* parse options */
305 optindex = 1;
306 while (optindex < argc) {
307 opt = argv[optindex++];
115329f1 308
84bf226b 309 if (handleoptions && opt[0] == '-' && opt[1] != '\0') {
3749076c
SS
310 if (opt[1] == '-' && opt[2] == '\0') {
311 handleoptions = 0;
312 continue;
313 }
c3c78324 314 opt++;
2f8e586d
AK
315
316 if ((ret = parse_option(optctx, opt, argv[optindex], options)) < 0)
dad09ff9 317 exit_program(1);
2f8e586d 318 optindex += ret;
01310af2 319 } else {
60a9966e 320 if (parse_arg_function)
7cc8d638 321 parse_arg_function(optctx, opt);
01310af2
FB
322 }
323 }
324}
325
182cbe43
AK
326/*
327 * Return index of option opt in argv or 0 if not found.
328 */
cbaef7d1
AD
329static int locate_option(int argc, char **argv, const OptionDef *options,
330 const char *optname)
182cbe43
AK
331{
332 const OptionDef *po;
333 int i;
334
335 for (i = 1; i < argc; i++) {
336 const char *cur_opt = argv[i];
337
338 if (*cur_opt++ != '-')
339 continue;
340
341 po = find_option(options, cur_opt);
342 if (!po->name && cur_opt[0] == 'n' && cur_opt[1] == 'o')
343 po = find_option(options, cur_opt + 2);
344
345 if ((!po->name && !strcmp(cur_opt, optname)) ||
346 (po->name && !strcmp(optname, po->name)))
347 return i;
348
349 if (!po || po->flags & HAS_ARG)
350 i++;
351 }
352 return 0;
353}
354
355void parse_loglevel(int argc, char **argv, const OptionDef *options)
356{
357 int idx = locate_option(argc, argv, options, "loglevel");
8124d8ad
MR
358 if (!idx)
359 idx = locate_option(argc, argv, options, "v");
182cbe43
AK
360 if (idx && argv[idx + 1])
361 opt_loglevel("loglevel", argv[idx + 1]);
362}
363
145f741e 364#define FLAGS (o->type == AV_OPT_TYPE_FLAGS) ? AV_DICT_APPEND : 0
35d2e4e5 365int opt_default(const char *opt, const char *arg)
9ba38229
AK
366{
367 const AVOption *o;
d4863fc1
AK
368 char opt_stripped[128];
369 const char *p;
20c21f8b 370 const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(), *sc = sws_get_class();
d4863fc1
AK
371
372 if (!(p = strchr(opt, ':')))
373 p = opt + strlen(opt);
374 av_strlcpy(opt_stripped, opt, FFMIN(sizeof(opt_stripped), p - opt + 1));
375
cbaef7d1
AD
376 if ((o = av_opt_find(&cc, opt_stripped, NULL, 0,
377 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)) ||
378 ((opt[0] == 'v' || opt[0] == 'a' || opt[0] == 's') &&
379 (o = av_opt_find(&cc, opt + 1, NULL, 0, AV_OPT_SEARCH_FAKE_OBJ))))
8c8eab8b 380 av_dict_set(&codec_opts, opt, arg, FLAGS);
cbaef7d1
AD
381 else if ((o = av_opt_find(&fc, opt, NULL, 0,
382 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ)))
9ba38229 383 av_dict_set(&format_opts, opt, arg, FLAGS);
cbaef7d1
AD
384 else if ((o = av_opt_find(&sc, opt, NULL, 0,
385 AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) {
9ba38229 386 // XXX we only support sws_flags, not arbitrary sws options
3b3ea346 387 int ret = av_opt_set(sws_opts, opt, arg, 0);
9ba38229
AK
388 if (ret < 0) {
389 av_log(NULL, AV_LOG_ERROR, "Error setting option %s.\n", opt);
390 return ret;
391 }
392 }
393
9ba38229
AK
394 if (o)
395 return 0;
1c5e9551 396 av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'\n", opt);
9ba38229
AK
397 return AVERROR_OPTION_NOT_FOUND;
398}
399
4c97a6fa
SS
400int opt_loglevel(const char *opt, const char *arg)
401{
da4c2dab 402 const struct { const char *name; int level; } log_levels[] = {
4c97a6fa
SS
403 { "quiet" , AV_LOG_QUIET },
404 { "panic" , AV_LOG_PANIC },
405 { "fatal" , AV_LOG_FATAL },
406 { "error" , AV_LOG_ERROR },
407 { "warning", AV_LOG_WARNING },
408 { "info" , AV_LOG_INFO },
409 { "verbose", AV_LOG_VERBOSE },
410 { "debug" , AV_LOG_DEBUG },
411 };
412 char *tail;
413 int level;
414 int i;
415
416 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++) {
417 if (!strcmp(log_levels[i].name, arg)) {
418 av_log_set_level(log_levels[i].level);
419 return 0;
420 }
421 }
422
423 level = strtol(arg, &tail, 10);
424 if (*tail) {
1c5e9551
AK
425 av_log(NULL, AV_LOG_FATAL, "Invalid loglevel \"%s\". "
426 "Possible levels are numbers or:\n", arg);
4c97a6fa 427 for (i = 0; i < FF_ARRAY_ELEMS(log_levels); i++)
1c5e9551 428 av_log(NULL, AV_LOG_FATAL, "\"%s\"\n", log_levels[i].name);
dad09ff9 429 exit_program(1);
4c97a6fa
SS
430 }
431 av_log_set_level(level);
432 return 0;
433}
434
ffcc6e24
MR
435int opt_timelimit(const char *opt, const char *arg)
436{
0104b608 437#if HAVE_SETRLIMIT
ffcc6e24
MR
438 int lim = parse_number_or_die(opt, arg, OPT_INT64, 0, INT_MAX);
439 struct rlimit rl = { lim, lim + 1 };
440 if (setrlimit(RLIMIT_CPU, &rl))
441 perror("setrlimit");
442#else
1c5e9551 443 av_log(NULL, AV_LOG_WARNING, "-%s not implemented on this OS\n", opt);
ffcc6e24
MR
444#endif
445 return 0;
446}
447
01310af2
FB
448void print_error(const char *filename, int err)
449{
7a5bdd79 450 char errbuf[128];
735ef67b 451 const char *errbuf_ptr = errbuf;
7a5bdd79 452
9e94bd3e
SS
453 if (av_strerror(err, errbuf, sizeof(errbuf)) < 0)
454 errbuf_ptr = strerror(AVUNERROR(err));
1c5e9551 455 av_log(NULL, AV_LOG_ERROR, "%s: %s\n", filename, errbuf_ptr);
01310af2 456}
f35917b2 457
d101e731
SS
458static int warned_cfg = 0;
459
208749a0
SS
460#define INDENT 1
461#define SHOW_VERSION 2
d101e731 462#define SHOW_CONFIG 4
208749a0 463
1c5e9551 464#define PRINT_LIB_INFO(libname, LIBNAME, flags, level) \
5116571d 465 if (CONFIG_##LIBNAME) { \
65dd2ded 466 const char *indent = flags & INDENT? " " : ""; \
208749a0 467 if (flags & SHOW_VERSION) { \
b6525b4b 468 unsigned int version = libname##_version(); \
1c5e9551
AK
469 av_log(NULL, level, "%slib%-9s %2d.%3d.%2d / %2d.%3d.%2d\n",\
470 indent, #libname, \
471 LIB##LIBNAME##_VERSION_MAJOR, \
472 LIB##LIBNAME##_VERSION_MINOR, \
473 LIB##LIBNAME##_VERSION_MICRO, \
474 version >> 16, version >> 8 & 0xff, version & 0xff); \
208749a0 475 } \
d101e731
SS
476 if (flags & SHOW_CONFIG) { \
477 const char *cfg = libname##_configuration(); \
29ba0911 478 if (strcmp(LIBAV_CONFIGURATION, cfg)) { \
d101e731 479 if (!warned_cfg) { \
1c5e9551 480 av_log(NULL, level, \
d101e731 481 "%sWARNING: library configuration mismatch\n", \
65dd2ded 482 indent); \
d101e731
SS
483 warned_cfg = 1; \
484 } \
1c5e9551 485 av_log(NULL, level, "%s%-11s configuration: %s\n", \
65dd2ded 486 indent, #libname, cfg); \
d101e731
SS
487 } \
488 } \
208749a0 489 } \
9a109272 490
1c5e9551 491static void print_all_libs_info(int flags, int level)
9a109272 492{
1c5e9551
AK
493 PRINT_LIB_INFO(avutil, AVUTIL, flags, level);
494 PRINT_LIB_INFO(avcodec, AVCODEC, flags, level);
495 PRINT_LIB_INFO(avformat, AVFORMAT, flags, level);
496 PRINT_LIB_INFO(avdevice, AVDEVICE, flags, level);
497 PRINT_LIB_INFO(avfilter, AVFILTER, flags, level);
498 PRINT_LIB_INFO(swscale, SWSCALE, flags, level);
499 PRINT_LIB_INFO(postproc, POSTPROC, flags, level);
9a109272
SS
500}
501
ea9c581f 502void show_banner(void)
86074ed1 503{
cbaef7d1
AD
504 av_log(NULL, AV_LOG_INFO,
505 "%s version " LIBAV_VERSION ", Copyright (c) %d-%d the Libav developers\n",
1c5e9551
AK
506 program_name, program_birth_year, this_year);
507 av_log(NULL, AV_LOG_INFO, " built on %s %s with %s %s\n",
508 __DATE__, __TIME__, CC_TYPE, CC_VERSION);
509 av_log(NULL, AV_LOG_VERBOSE, " configuration: " LIBAV_CONFIGURATION "\n");
510 print_all_libs_info(INDENT|SHOW_CONFIG, AV_LOG_VERBOSE);
511 print_all_libs_info(INDENT|SHOW_VERSION, AV_LOG_VERBOSE);
86074ed1
SS
512}
513
64555bd9 514void show_version(void) {
1c5e9551 515 av_log_set_callback(log_callback_help);
a03be6e1 516 printf("%s " LIBAV_VERSION "\n", program_name);
1c5e9551 517 print_all_libs_info(SHOW_VERSION, AV_LOG_INFO);
86074ed1
SS
518}
519
f35917b2
SS
520void show_license(void)
521{
7ead693b 522 printf(
3bf28f9d 523#if CONFIG_NONFREE
304ba23a
SS
524 "This version of %s has nonfree parts compiled in.\n"
525 "Therefore it is not legally redistributable.\n",
526 program_name
9cad0e4e
DB
527#elif CONFIG_GPLV3
528 "%s is free software; you can redistribute it and/or modify\n"
529 "it under the terms of the GNU General Public License as published by\n"
530 "the Free Software Foundation; either version 3 of the License, or\n"
531 "(at your option) any later version.\n"
532 "\n"
533 "%s is distributed in the hope that it will be useful,\n"
534 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
535 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
536 "GNU General Public License for more details.\n"
537 "\n"
538 "You should have received a copy of the GNU General Public License\n"
539 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
540 program_name, program_name, program_name
7ead693b 541#elif CONFIG_GPL
304ba23a 542 "%s is free software; you can redistribute it and/or modify\n"
f35917b2
SS
543 "it under the terms of the GNU General Public License as published by\n"
544 "the Free Software Foundation; either version 2 of the License, or\n"
545 "(at your option) any later version.\n"
546 "\n"
304ba23a 547 "%s is distributed in the hope that it will be useful,\n"
f35917b2
SS
548 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
549 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
550 "GNU General Public License for more details.\n"
551 "\n"
552 "You should have received a copy of the GNU General Public License\n"
304ba23a
SS
553 "along with %s; if not, write to the Free Software\n"
554 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
555 program_name, program_name, program_name
9cad0e4e
DB
556#elif CONFIG_LGPLV3
557 "%s is free software; you can redistribute it and/or modify\n"
558 "it under the terms of the GNU Lesser General Public License as published by\n"
559 "the Free Software Foundation; either version 3 of the License, or\n"
560 "(at your option) any later version.\n"
561 "\n"
562 "%s is distributed in the hope that it will be useful,\n"
563 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
564 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
565 "GNU Lesser General Public License for more details.\n"
566 "\n"
567 "You should have received a copy of the GNU Lesser General Public License\n"
568 "along with %s. If not, see <http://www.gnu.org/licenses/>.\n",
569 program_name, program_name, program_name
f35917b2 570#else
304ba23a 571 "%s is free software; you can redistribute it and/or\n"
f35917b2
SS
572 "modify it under the terms of the GNU Lesser General Public\n"
573 "License as published by the Free Software Foundation; either\n"
574 "version 2.1 of the License, or (at your option) any later version.\n"
575 "\n"
304ba23a 576 "%s is distributed in the hope that it will be useful,\n"
f35917b2
SS
577 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
578 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
579 "Lesser General Public License for more details.\n"
580 "\n"
581 "You should have received a copy of the GNU Lesser General Public\n"
304ba23a
SS
582 "License along with %s; if not, write to the Free Software\n"
583 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n",
584 program_name, program_name, program_name
f35917b2 585#endif
3bf28f9d 586 );
f35917b2 587}
ba9880c1
SS
588
589void show_formats(void)
590{
cbaef7d1
AD
591 AVInputFormat *ifmt = NULL;
592 AVOutputFormat *ofmt = NULL;
ba9880c1
SS
593 const char *last_name;
594
cbaef7d1
AD
595 printf("File formats:\n"
596 " D. = Demuxing supported\n"
597 " .E = Muxing supported\n"
598 " --\n");
599 last_name = "000";
600 for (;;) {
601 int decode = 0;
602 int encode = 0;
603 const char *name = NULL;
604 const char *long_name = NULL;
605
606 while ((ofmt = av_oformat_next(ofmt))) {
607 if ((name == NULL || strcmp(ofmt->name, name) < 0) &&
608 strcmp(ofmt->name, last_name) > 0) {
609 name = ofmt->name;
610 long_name = ofmt->long_name;
611 encode = 1;
ba9880c1
SS
612 }
613 }
cbaef7d1
AD
614 while ((ifmt = av_iformat_next(ifmt))) {
615 if ((name == NULL || strcmp(ifmt->name, name) < 0) &&
616 strcmp(ifmt->name, last_name) > 0) {
617 name = ifmt->name;
618 long_name = ifmt->long_name;
619 encode = 0;
ba9880c1 620 }
cbaef7d1
AD
621 if (name && strcmp(ifmt->name, name) == 0)
622 decode = 1;
ba9880c1 623 }
cbaef7d1 624 if (name == NULL)
ba9880c1 625 break;
cbaef7d1 626 last_name = name;
ba9880c1 627
cbaef7d1
AD
628 printf(" %s%s %-15s %s\n",
629 decode ? "D" : " ",
630 encode ? "E" : " ",
631 name,
ba9880c1
SS
632 long_name ? long_name:" ");
633 }
8447f0bd 634}
ba9880c1 635
8447f0bd
MN
636void show_codecs(void)
637{
cbaef7d1 638 AVCodec *p = NULL, *p2;
8447f0bd 639 const char *last_name;
cbaef7d1
AD
640 printf("Codecs:\n"
641 " D..... = Decoding supported\n"
642 " .E.... = Encoding supported\n"
643 " ..V... = Video codec\n"
644 " ..A... = Audio codec\n"
645 " ..S... = Subtitle codec\n"
646 " ...S.. = Supports draw_horiz_band\n"
647 " ....D. = Supports direct rendering method 1\n"
648 " .....T = Supports weird frame truncation\n"
649 " ------\n");
ba9880c1 650 last_name= "000";
cbaef7d1
AD
651 for (;;) {
652 int decode = 0;
653 int encode = 0;
654 int cap = 0;
ba9880c1
SS
655 const char *type_str;
656
cbaef7d1
AD
657 p2 = NULL;
658 while ((p = av_codec_next(p))) {
659 if ((p2 == NULL || strcmp(p->name, p2->name) < 0) &&
660 strcmp(p->name, last_name) > 0) {
661 p2 = p;
662 decode = encode = cap = 0;
ba9880c1 663 }
cbaef7d1
AD
664 if (p2 && strcmp(p->name, p2->name) == 0) {
665 if (p->decode)
666 decode = 1;
667 if (p->encode)
668 encode = 1;
ba9880c1
SS
669 cap |= p->capabilities;
670 }
671 }
cbaef7d1 672 if (p2 == NULL)
ba9880c1 673 break;
cbaef7d1 674 last_name = p2->name;
ba9880c1 675
cbaef7d1 676 switch (p2->type) {
72415b2a 677 case AVMEDIA_TYPE_VIDEO:
ba9880c1
SS
678 type_str = "V";
679 break;
72415b2a 680 case AVMEDIA_TYPE_AUDIO:
ba9880c1
SS
681 type_str = "A";
682 break;
72415b2a 683 case AVMEDIA_TYPE_SUBTITLE:
ba9880c1
SS
684 type_str = "S";
685 break;
686 default:
687 type_str = "?";
688 break;
689 }
cbaef7d1
AD
690 printf(" %s%s%s%s%s%s %-15s %s",
691 decode ? "D" : (/* p2->decoder ? "d" : */ " "),
692 encode ? "E" : " ",
693 type_str,
694 cap & CODEC_CAP_DRAW_HORIZ_BAND ? "S" : " ",
695 cap & CODEC_CAP_DR1 ? "D" : " ",
696 cap & CODEC_CAP_TRUNCATED ? "T" : " ",
697 p2->name,
698 p2->long_name ? p2->long_name : "");
699#if 0
700 if (p2->decoder && decode == 0)
701 printf(" use %s for decoding", p2->decoder->name);
702#endif
ba9880c1
SS
703 printf("\n");
704 }
705 printf("\n");
cbaef7d1
AD
706 printf("Note, the names of encoders and decoders do not always match, so there are\n"
707 "several cases where the above table shows encoder only or decoder only entries\n"
708 "even though both encoding and decoding are supported. For example, the h263\n"
709 "decoder corresponds to the h263 and h263p encoders, for file formats it is even\n"
710 "worse.\n");
8447f0bd
MN
711}
712
713void show_bsfs(void)
714{
cbaef7d1 715 AVBitStreamFilter *bsf = NULL;
ba9880c1
SS
716
717 printf("Bitstream filters:\n");
cbaef7d1 718 while ((bsf = av_bitstream_filter_next(bsf)))
2091b27b 719 printf("%s\n", bsf->name);
ba9880c1 720 printf("\n");
8447f0bd
MN
721}
722
723void show_protocols(void)
724{
cdc6a87f
AK
725 void *opaque = NULL;
726 const char *name;
ba9880c1 727
2ee5c789 728 printf("Supported file protocols:\n"
cdc6a87f
AK
729 "Input:\n");
730 while ((name = avio_enum_protocols(&opaque, 0)))
731 printf("%s\n", name);
732 printf("Output:\n");
733 while ((name = avio_enum_protocols(&opaque, 1)))
734 printf("%s\n", name);
ba9880c1 735}
090b61b2 736
62d75662
SS
737void show_filters(void)
738{
78638628 739 AVFilter av_unused(**filter) = NULL;
62d75662
SS
740
741 printf("Filters:\n");
663c2edf 742#if CONFIG_AVFILTER
62d75662
SS
743 while ((filter = av_filter_next(filter)) && *filter)
744 printf("%-16s %s\n", (*filter)->name, (*filter)->description);
663c2edf 745#endif
62d75662
SS
746}
747
3f7bb426
SS
748void show_pix_fmts(void)
749{
9cb5c760
SS
750 enum PixelFormat pix_fmt;
751
cbaef7d1
AD
752 printf("Pixel formats:\n"
753 "I.... = Supported Input format for conversion\n"
754 ".O... = Supported Output format for conversion\n"
755 "..H.. = Hardware accelerated format\n"
756 "...P. = Paletted format\n"
757 "....B = Bitstream format\n"
758 "FLAGS NAME NB_COMPONENTS BITS_PER_PIXEL\n"
759 "-----\n");
9cb5c760 760
e24db3e3
MR
761#if !CONFIG_SWSCALE
762# define sws_isSupportedInput(x) 0
763# define sws_isSupportedOutput(x) 0
764#endif
765
9cb5c760
SS
766 for (pix_fmt = 0; pix_fmt < PIX_FMT_NB; pix_fmt++) {
767 const AVPixFmtDescriptor *pix_desc = &av_pix_fmt_descriptors[pix_fmt];
768 printf("%c%c%c%c%c %-16s %d %2d\n",
769 sws_isSupportedInput (pix_fmt) ? 'I' : '.',
770 sws_isSupportedOutput(pix_fmt) ? 'O' : '.',
771 pix_desc->flags & PIX_FMT_HWACCEL ? 'H' : '.',
772 pix_desc->flags & PIX_FMT_PAL ? 'P' : '.',
773 pix_desc->flags & PIX_FMT_BITSTREAM ? 'B' : '.',
774 pix_desc->name,
775 pix_desc->nb_components,
776 av_get_bits_per_pixel(pix_desc));
777 }
3f7bb426
SS
778}
779
05bffc12
AK
780int show_sample_fmts(const char *opt, const char *arg)
781{
782 int i;
783 char fmt_str[128];
784 for (i = -1; i < AV_SAMPLE_FMT_NB; i++)
785 printf("%s\n", av_get_sample_fmt_string(fmt_str, sizeof(fmt_str), i));
786 return 0;
787}
788
090b61b2
SS
789int read_yesno(void)
790{
791 int c = getchar();
792 int yesno = (toupper(c) == 'Y');
793
794 while (c != '\n' && c != EOF)
795 c = getchar();
796
797 return yesno;
798}
458b062d 799
02170990 800int cmdutils_read_file(const char *filename, char **bufptr, size_t *size)
458b062d 801{
d94c577d 802 int ret;
c56e9e05 803 FILE *f = fopen(filename, "rb");
458b062d
SS
804
805 if (!f) {
cbaef7d1
AD
806 av_log(NULL, AV_LOG_ERROR, "Cannot read file '%s': %s\n", filename,
807 strerror(errno));
458b062d
SS
808 return AVERROR(errno);
809 }
810 fseek(f, 0, SEEK_END);
811 *size = ftell(f);
812 fseek(f, 0, SEEK_SET);
813 *bufptr = av_malloc(*size + 1);
814 if (!*bufptr) {
1c5e9551 815 av_log(NULL, AV_LOG_ERROR, "Could not allocate file buffer\n");
458b062d
SS
816 fclose(f);
817 return AVERROR(ENOMEM);
818 }
d94c577d
JG
819 ret = fread(*bufptr, 1, *size, f);
820 if (ret < *size) {
821 av_free(*bufptr);
822 if (ferror(f)) {
823 av_log(NULL, AV_LOG_ERROR, "Error while reading file '%s': %s\n",
824 filename, strerror(errno));
825 ret = AVERROR(errno);
826 } else
827 ret = AVERROR_EOF;
828 } else {
829 ret = 0;
830 (*bufptr)[*size++] = '\0';
831 }
458b062d
SS
832
833 fclose(f);
d94c577d 834 return ret;
458b062d 835}
7a8bfa5d
AS
836
837void init_pts_correction(PtsCorrectionContext *ctx)
838{
839 ctx->num_faulty_pts = ctx->num_faulty_dts = 0;
840 ctx->last_pts = ctx->last_dts = INT64_MIN;
841}
842
cbaef7d1
AD
843int64_t guess_correct_pts(PtsCorrectionContext *ctx, int64_t reordered_pts,
844 int64_t dts)
7a8bfa5d
AS
845{
846 int64_t pts = AV_NOPTS_VALUE;
847
848 if (dts != AV_NOPTS_VALUE) {
849 ctx->num_faulty_dts += dts <= ctx->last_dts;
850 ctx->last_dts = dts;
851 }
852 if (reordered_pts != AV_NOPTS_VALUE) {
853 ctx->num_faulty_pts += reordered_pts <= ctx->last_pts;
854 ctx->last_pts = reordered_pts;
855 }
01d46198 856 if ((ctx->num_faulty_pts<=ctx->num_faulty_dts || dts == AV_NOPTS_VALUE)
cbaef7d1 857 && reordered_pts != AV_NOPTS_VALUE)
7a8bfa5d
AS
858 pts = reordered_pts;
859 else
860 pts = dts;
861
862 return pts;
863}
f7ead94c 864
6e872935 865FILE *get_preset_file(char *filename, size_t filename_size,
cbaef7d1
AD
866 const char *preset_name, int is_path,
867 const char *codec_name)
6e872935
SS
868{
869 FILE *f = NULL;
870 int i;
cbaef7d1
AD
871 const char *base[3] = { getenv("AVCONV_DATADIR"),
872 getenv("HOME"),
873 AVCONV_DATADIR, };
6e872935
SS
874
875 if (is_path) {
876 av_strlcpy(filename, preset_name, filename_size);
877 f = fopen(filename, "r");
878 } else {
879 for (i = 0; i < 3 && !f; i++) {
880 if (!base[i])
881 continue;
cbaef7d1
AD
882 snprintf(filename, filename_size, "%s%s/%s.ffpreset", base[i],
883 i != 1 ? "" : "/.avconv", preset_name);
6e872935
SS
884 f = fopen(filename, "r");
885 if (!f && codec_name) {
886 snprintf(filename, filename_size,
cbaef7d1
AD
887 "%s%s/%s-%s.ffpreset",
888 base[i], i != 1 ? "" : "/.avconv", codec_name,
889 preset_name);
6e872935
SS
890 f = fopen(filename, "r");
891 }
892 }
893 }
894
895 return f;
896}
897
d4863fc1
AK
898int check_stream_specifier(AVFormatContext *s, AVStream *st, const char *spec)
899{
cbaef7d1 900 if (*spec <= '9' && *spec >= '0') /* opt:index */
d4863fc1 901 return strtol(spec, NULL, 0) == st->index;
cbaef7d1
AD
902 else if (*spec == 'v' || *spec == 'a' || *spec == 's' || *spec == 'd' ||
903 *spec == 't') { /* opt:[vasdt] */
d4863fc1
AK
904 enum AVMediaType type;
905
906 switch (*spec++) {
cbaef7d1
AD
907 case 'v': type = AVMEDIA_TYPE_VIDEO; break;
908 case 'a': type = AVMEDIA_TYPE_AUDIO; break;
909 case 's': type = AVMEDIA_TYPE_SUBTITLE; break;
910 case 'd': type = AVMEDIA_TYPE_DATA; break;
3ccd1580 911 case 't': type = AVMEDIA_TYPE_ATTACHMENT; break;
d4863fc1
AK
912 }
913 if (type != st->codec->codec_type)
914 return 0;
cbaef7d1 915 if (*spec++ == ':') { /* possibly followed by :index */
d4863fc1
AK
916 int i, index = strtol(spec, NULL, 0);
917 for (i = 0; i < s->nb_streams; i++)
918 if (s->streams[i]->codec->codec_type == type && index-- == 0)
919 return i == st->index;
920 return 0;
921 }
922 return 1;
2c474ddb
AK
923 } else if (*spec == 'p' && *(spec + 1) == ':') {
924 int prog_id, i, j;
925 char *endptr;
926 spec += 2;
927 prog_id = strtol(spec, &endptr, 0);
928 for (i = 0; i < s->nb_programs; i++) {
929 if (s->programs[i]->id != prog_id)
930 continue;
931
932 if (*endptr++ == ':') {
933 int stream_idx = strtol(endptr, NULL, 0);
d4b63054
DB
934 return stream_idx >= 0 &&
935 stream_idx < s->programs[i]->nb_stream_indexes &&
936 st->index == s->programs[i]->stream_index[stream_idx];
2c474ddb
AK
937 }
938
939 for (j = 0; j < s->programs[i]->nb_stream_indexes; j++)
940 if (st->index == s->programs[i]->stream_index[j])
941 return 1;
942 }
943 return 0;
d4863fc1
AK
944 } else if (!*spec) /* empty specifier, matches everything */
945 return 1;
946
947 av_log(s, AV_LOG_ERROR, "Invalid stream specifier: %s.\n", spec);
948 return AVERROR(EINVAL);
949}
950
cbaef7d1
AD
951AVDictionary *filter_codec_opts(AVDictionary *opts, enum CodecID codec_id,
952 AVFormatContext *s, AVStream *st)
8c8eab8b
AK
953{
954 AVDictionary *ret = NULL;
955 AVDictionaryEntry *t = NULL;
cbaef7d1
AD
956 AVCodec *codec = s->oformat ? avcodec_find_encoder(codec_id)
957 : avcodec_find_decoder(codec_id);
958 int flags = s->oformat ? AV_OPT_FLAG_ENCODING_PARAM
959 : AV_OPT_FLAG_DECODING_PARAM;
8c8eab8b 960 char prefix = 0;
20c21f8b 961 const AVClass *cc = avcodec_get_class();
8c8eab8b
AK
962
963 if (!codec)
964 return NULL;
965
966 switch (codec->type) {
cbaef7d1
AD
967 case AVMEDIA_TYPE_VIDEO:
968 prefix = 'v';
969 flags |= AV_OPT_FLAG_VIDEO_PARAM;
970 break;
971 case AVMEDIA_TYPE_AUDIO:
972 prefix = 'a';
973 flags |= AV_OPT_FLAG_AUDIO_PARAM;
974 break;
975 case AVMEDIA_TYPE_SUBTITLE:
976 prefix = 's';
977 flags |= AV_OPT_FLAG_SUBTITLE_PARAM;
978 break;
8c8eab8b
AK
979 }
980
981 while (t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX)) {
d4863fc1
AK
982 char *p = strchr(t->key, ':');
983
984 /* check stream specification in opt name */
985 if (p)
986 switch (check_stream_specifier(s, st, p + 1)) {
987 case 1: *p = 0; break;
988 case 0: continue;
989 default: return NULL;
990 }
991
20c21f8b 992 if (av_opt_find(&cc, t->key, NULL, flags, AV_OPT_SEARCH_FAKE_OBJ) ||
cbaef7d1
AD
993 (codec && codec->priv_class &&
994 av_opt_find(&codec->priv_class, t->key, NULL, flags,
995 AV_OPT_SEARCH_FAKE_OBJ)))
8c8eab8b 996 av_dict_set(&ret, t->key, t->value, 0);
cbaef7d1
AD
997 else if (t->key[0] == prefix &&
998 av_opt_find(&cc, t->key + 1, NULL, flags,
999 AV_OPT_SEARCH_FAKE_OBJ))
1000 av_dict_set(&ret, t->key + 1, t->value, 0);
d4863fc1
AK
1001
1002 if (p)
1003 *p = ':';
8c8eab8b
AK
1004 }
1005 return ret;
1006}
1007
cbaef7d1
AD
1008AVDictionary **setup_find_stream_info_opts(AVFormatContext *s,
1009 AVDictionary *codec_opts)
3009f521
AK
1010{
1011 int i;
1012 AVDictionary **opts;
1013
1014 if (!s->nb_streams)
1015 return NULL;
1016 opts = av_mallocz(s->nb_streams * sizeof(*opts));
1017 if (!opts) {
cbaef7d1
AD
1018 av_log(NULL, AV_LOG_ERROR,
1019 "Could not alloc memory for stream options.\n");
3009f521
AK
1020 return NULL;
1021 }
1022 for (i = 0; i < s->nb_streams; i++)
cbaef7d1
AD
1023 opts[i] = filter_codec_opts(codec_opts, s->streams[i]->codec->codec_id,
1024 s, s->streams[i]);
3009f521
AK
1025 return opts;
1026}
1027
f7ead94c
SS
1028#if CONFIG_AVFILTER
1029
1030static int ffsink_init(AVFilterContext *ctx, const char *args, void *opaque)
1031{
1032 FFSinkContext *priv = ctx->priv;
1033
1034 if (!opaque)
1035 return AVERROR(EINVAL);
1036 *priv = *(FFSinkContext *)opaque;
1037
1038 return 0;
1039}
1040
1041static void null_end_frame(AVFilterLink *inlink) { }
1042
1043static int ffsink_query_formats(AVFilterContext *ctx)
1044{
1045 FFSinkContext *priv = ctx->priv;
1046 enum PixelFormat pix_fmts[] = { priv->pix_fmt, PIX_FMT_NONE };
1047
1048 avfilter_set_common_formats(ctx, avfilter_make_format_list(pix_fmts));
1049 return 0;
1050}
1051
1052AVFilter ffsink = {
1053 .name = "ffsink",
1054 .priv_size = sizeof(FFSinkContext),
1055 .init = ffsink_init,
1056
1057 .query_formats = ffsink_query_formats,
1058
1059 .inputs = (AVFilterPad[]) {{ .name = "default",
1060 .type = AVMEDIA_TYPE_VIDEO,
1061 .end_frame = null_end_frame,
1062 .min_perms = AV_PERM_READ, },
1063 { .name = NULL }},
1064 .outputs = (AVFilterPad[]) {{ .name = NULL }},
1065};
1066
ff0652e5
SS
1067int get_filtered_video_frame(AVFilterContext *ctx, AVFrame *frame,
1068 AVFilterBufferRef **picref_ptr, AVRational *tb)
1069{
1070 int ret;
1071 AVFilterBufferRef *picref;
1072
1073 if ((ret = avfilter_request_frame(ctx->inputs[0])) < 0)
1074 return ret;
1075 if (!(picref = ctx->inputs[0]->cur_buf))
1076 return AVERROR(ENOENT);
1077 *picref_ptr = picref;
1078 ctx->inputs[0]->cur_buf = NULL;
1079 *tb = ctx->inputs[0]->time_base;
1080
1081 memcpy(frame->data, picref->data, sizeof(frame->data));
1082 memcpy(frame->linesize, picref->linesize, sizeof(frame->linesize));
cbaef7d1
AD
1083 frame->interlaced_frame = picref->video->interlaced;
1084 frame->top_field_first = picref->video->top_field_first;
1085 frame->key_frame = picref->video->key_frame;
1086 frame->pict_type = picref->video->pict_type;
b58dbb5b 1087 frame->sample_aspect_ratio = picref->video->pixel_aspect;
ff0652e5
SS
1088
1089 return 1;
1090}
1091
e1b10155
JG
1092#endif /* CONFIG_AVFILTER */
1093
cac651c8
AK
1094void *grow_array(void *array, int elem_size, int *size, int new_size)
1095{
1096 if (new_size >= INT_MAX / elem_size) {
1097 av_log(NULL, AV_LOG_ERROR, "Array too big.\n");
1098 exit_program(1);
1099 }
1100 if (*size < new_size) {
1101 uint8_t *tmp = av_realloc(array, new_size*elem_size);
1102 if (!tmp) {
1103 av_log(NULL, AV_LOG_ERROR, "Could not alloc buffer.\n");
1104 exit_program(1);
1105 }
1106 memset(tmp + *size*elem_size, 0, (new_size-*size) * elem_size);
1107 *size = new_size;
1108 return tmp;
1109 }
1110 return array;
1111}