Move the internal function declarations in avformat.h to internal.h.
[libav.git] / libavformat / cutils.c
CommitLineData
2302dd13
FB
1/*
2 * Various simple utilities for ffmpeg system
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
4 *
b78e7197
DB
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
2302dd13
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.
2302dd13 11 *
b78e7197 12 * FFmpeg is distributed in the hope that it will be useful,
2302dd13
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
b78e7197 18 * License along with FFmpeg; if not, write to the Free Software
5509bffa 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2302dd13
FB
20 */
21#include "avformat.h"
9a2cb05f 22#include "internal.h"
2302dd13 23
39f472c3 24/* add one element to a dynamic array */
2db5da97 25void ff_dynarray_add(intptr_t **tab_ptr, int *nb_ptr, intptr_t elem)
39f472c3
FB
26{
27 int nb, nb_alloc;
2db5da97 28 intptr_t *tab;
39f472c3
FB
29
30 nb = *nb_ptr;
31 tab = *tab_ptr;
32 if ((nb & (nb - 1)) == 0) {
33 if (nb == 0)
34 nb_alloc = 1;
35 else
36 nb_alloc = nb * 2;
2db5da97 37 tab = av_realloc(tab, nb_alloc * sizeof(intptr_t));
39f472c3
FB
38 *tab_ptr = tab;
39 }
40 tab[nb++] = elem;
41 *nb_ptr = nb;
42}
43
f71869a4
FB
44time_t mktimegm(struct tm *tm)
45{
46 time_t t;
47
48 int y = tm->tm_year + 1900, m = tm->tm_mon + 1, d = tm->tm_mday;
49
50 if (m < 3) {
51 m += 12;
52 y--;
53 }
54
115329f1 55 t = 86400 *
f71869a4
FB
56 (d + (153 * m - 457) / 5 + 365 * y + y / 4 - y / 100 + y / 400 - 719469);
57
58 t += 3600 * tm->tm_hour + 60 * tm->tm_min + tm->tm_sec;
59
60 return t;
61}
62
0c9fc6e1
RS
63#define ISLEAP(y) (((y) % 4 == 0) && (((y) % 100) != 0 || ((y) % 400) == 0))
64#define LEAPS_COUNT(y) ((y)/4 - (y)/100 + (y)/400)
65
34359cab 66/* This is our own gmtime_r. It differs from its POSIX counterpart in a
0c9fc6e1
RS
67 couple of places, though. */
68struct tm *brktimegm(time_t secs, struct tm *tm)
115329f1 69{
0c9fc6e1
RS
70 int days, y, ny, m;
71 int md[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
72
73 days = secs / 86400;
74 secs %= 86400;
75 tm->tm_hour = secs / 3600;
76 tm->tm_min = (secs % 3600) / 60;
77 tm->tm_sec = secs % 60;
78
79 /* oh well, may be someone some day will invent a formula for this stuff */
80 y = 1970; /* start "guessing" */
392f2273 81 while (days > 365) {
bb270c08
DB
82 ny = (y + days/366);
83 days -= (ny - y) * 365 + LEAPS_COUNT(ny - 1) - LEAPS_COUNT(y - 1);
84 y = ny;
0c9fc6e1 85 }
392f2273 86 if (days==365 && !ISLEAP(y)) { days=0; y++; }
0c9fc6e1
RS
87 md[1] = ISLEAP(y)?29:28;
88 for (m=0; days >= md[m]; m++)
bb270c08 89 days -= md[m];
0c9fc6e1
RS
90
91 tm->tm_year = y; /* unlike gmtime_r we store complete year here */
92 tm->tm_mon = m+1; /* unlike gmtime_r tm_mon is from 1 to 12 */
93 tm->tm_mday = days+1;
94
95 return tm;
96}
97
f71869a4
FB
98/* get a positive number between n_min and n_max, for a maximum length
99 of len_max. Return -1 if error. */
100static int date_get_num(const char **pp,
101 int n_min, int n_max, int len_max)
102{
103 int i, val, c;
104 const char *p;
105
106 p = *pp;
107 val = 0;
108 for(i = 0; i < len_max; i++) {
109 c = *p;
110 if (!isdigit(c))
111 break;
112 val = (val * 10) + c - '0';
113 p++;
114 }
115 /* no number read ? */
116 if (p == *pp)
117 return -1;
118 if (val < n_min || val > n_max)
119 return -1;
120 *pp = p;
121 return val;
122}
123
124/* small strptime for ffmpeg */
115329f1 125const char *small_strptime(const char *p, const char *fmt,
f71869a4
FB
126 struct tm *dt)
127{
128 int c, val;
129
130 for(;;) {
131 c = *fmt++;
132 if (c == '\0') {
133 return p;
134 } else if (c == '%') {
135 c = *fmt++;
136 switch(c) {
137 case 'H':
138 val = date_get_num(&p, 0, 23, 2);
139 if (val == -1)
140 return NULL;
141 dt->tm_hour = val;
142 break;
143 case 'M':
144 val = date_get_num(&p, 0, 59, 2);
145 if (val == -1)
146 return NULL;
147 dt->tm_min = val;
148 break;
149 case 'S':
150 val = date_get_num(&p, 0, 59, 2);
151 if (val == -1)
152 return NULL;
153 dt->tm_sec = val;
154 break;
155 case 'Y':
156 val = date_get_num(&p, 0, 9999, 4);
157 if (val == -1)
158 return NULL;
159 dt->tm_year = val - 1900;
160 break;
161 case 'm':
162 val = date_get_num(&p, 1, 12, 2);
163 if (val == -1)
164 return NULL;
165 dt->tm_mon = val - 1;
166 break;
167 case 'd':
168 val = date_get_num(&p, 1, 31, 2);
169 if (val == -1)
170 return NULL;
171 dt->tm_mday = val;
172 break;
173 case '%':
174 goto match;
175 default:
176 return NULL;
177 }
178 } else {
179 match:
180 if (c != *p)
181 return NULL;
182 p++;
183 }
184 }
185 return p;
186}
187