1 /*
2 Copyright (C) 2008 Annodex Association
3
4 Based on anx_time.c from libannodex, Copyright (C) 2003 Commonwealth
5 Scientific and Industrial Research Organisation (CSIRO) Australia
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 - Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13
14 - Redistributions in binary form must reproduce the above copyright
15 notice, this list of conditions and the following disclaimer in the
16 documentation and/or other materials provided with the distribution.
17
18 - Neither the name of CSIRO Australia nor the names of its
19 contributors may be used to endorse or promote products derived from
20 this software without specific prior written permission.
21
22 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE ORGANISATION OR
26 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #include "config.h"
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <math.h>
41
42 static double
parse_npt(const char * str)43 parse_npt (const char *str)
44 {
45 int h=0,m=0, n;
46 float s;
47 double result;
48
49 n = sscanf (str, "%d:%d:%f", &h, &m, &s);
50 if (n == 3) {
51 goto done;
52 }
53
54 n = sscanf (str, "%d:%f", &m, &s);
55 if (n == 2) {
56 h = 0;
57 goto done;
58 }
59
60 n = sscanf (str, "%f", &s);
61 if (n == 1) {
62 h = 0; m = 0;
63 goto sec_only;
64 }
65
66 return -1.0;
67
68 done:
69
70 /* check valid time specs */
71 if (h < 0) return -1;
72 if (m > 59 || m < 0) return -1;
73 if (s >= 60.0 || s < 0) return -1;
74
75 sec_only:
76
77 result = ((h * 3600.0) + (m * 60.0) + s);
78
79 return result;
80 }
81
82 /* parse_smpte: parse a smpte-string */
83 static double
parse_smpte(const char * str,double framerate)84 parse_smpte(const char *str, double framerate)
85 {
86 int h = 0, m = 0, s = 0, n;
87 float frames;
88 double result;
89
90 n = sscanf (str, "%d:%d:%d:%f", &h, &m, &s, &frames);
91 if (n == 4) {
92 goto done;
93 }
94
95 n = sscanf (str, "%d:%d:%f", &m, &s, &frames);
96 if (n == 3) {
97 h = 0;
98 goto done;
99 }
100
101 return -1.0;
102
103 done:
104
105 /* check valid time specs */
106 if (h < 0) return -1;
107 if (m > 59 || m < 0) return -1;
108 if (s > 59 || s < 0) return -1;
109 if (frames > (float)ceil(framerate) || frames < 0) return -1;
110
111 result = ((h * 3600.0) + (m * 60.0) + s) + (frames/framerate);
112
113 return result;
114 }
115
116 double
parse_timespec(const char * str)117 parse_timespec (const char * str)
118 {
119 char timespec[16];
120
121 if (str == NULL) return -1.0;
122
123 if (sscanf (str, "npt:%16s", timespec) == 1) {
124 return parse_npt (timespec);
125 }
126
127 if (sscanf (str, "smpte-24:%16s", timespec) == 1) {
128 return parse_smpte (timespec, 24.0);
129 }
130
131 if (sscanf (str, "smpte-24-drop:%16s", timespec) == 1) {
132 return parse_smpte (timespec, 23.976);
133 }
134
135 if (sscanf (str, "smpte-25:%16s", timespec) == 1) {
136 return parse_smpte (timespec, 25.0);
137 }
138
139 if (sscanf (str, "smpte-30:%16s", timespec) == 1) {
140 return parse_smpte (timespec, 30.0);
141 }
142
143 if (sscanf (str, "smpte-30-drop:%16s", timespec) == 1) {
144 return parse_smpte (timespec, 29.97);
145 }
146
147 if (sscanf (str, "smpte-50:%16s", timespec) == 1) {
148 return parse_smpte (timespec, 50.0);
149 }
150
151 if (sscanf (str, "smpte-60:%16s", timespec) == 1) {
152 return parse_smpte (timespec, 60);
153 }
154
155 if (sscanf (str, "smpte-60-drop:%16s", timespec) == 1) {
156 return parse_smpte (timespec, 59.94);
157 }
158
159 return parse_npt(str);
160 }
161