Add GBRAP12 pixel format support
[ffmpeg.git] / libavutil / parseutils.c
index 0ca179e..f424811 100644 (file)
 #include "eval.h"
 #include "log.h"
 #include "random_seed.h"
+#include "time_internal.h"
 #include "parseutils.h"
 
-typedef struct {
+typedef struct VideoSizeAbbr {
     const char *abbr;
     int width, height;
 } VideoSizeAbbr;
 
-typedef struct {
+typedef struct VideoRateAbbr {
     const char *abbr;
     AVRational rate;
 } VideoRateAbbr;
@@ -79,6 +80,10 @@ static const VideoSizeAbbr video_size_abbrs[] = {
     { "hd480",     852, 480 },
     { "hd720",    1280, 720 },
     { "hd1080",   1920,1080 },
+    { "2kdci",    2048,1080 },
+    { "4kdci",    4096,2160 },
+    { "uhd2160",  3840,2160 },
+    { "uhd4320",  7680,4320 },
 };
 
 static const VideoRateAbbr video_rate_abbrs[]= {
@@ -107,8 +112,7 @@ int av_parse_video_size(int *width_ptr, int *height_ptr, const char *str)
         }
     }
     if (i == n) {
-        p = str;
-        width = strtol(p, &p, 10);
+        width = strtol(str, &p, 10);
         if (*p)
             p++;
         height = strtol(p, &p, 10);
@@ -143,7 +147,7 @@ int av_parse_video_rate(AVRational *rate, const char *arg)
     return 0;
 }
 
-typedef struct {
+typedef struct ColorEntry {
     const char *name;            ///< a string representing the name of the color
     uint8_t     rgb_color[3];    ///< RGB values for the color
 } ColorEntry;
@@ -355,7 +359,7 @@ int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
     }
 
     if (tail) {
-        unsigned long int alpha;
+        double alpha;
         const char *alpha_string = tail;
         if (!strncmp(alpha_string, "0x", 2)) {
             alpha = strtoul(alpha_string, &tail, 16);
@@ -363,7 +367,7 @@ int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
             alpha = 255 * strtod(alpha_string, &tail);
         }
 
-        if (tail == alpha_string || *tail || alpha > 255) {
+        if (tail == alpha_string || *tail || alpha > 255 || alpha < 0) {
             av_log(log_ctx, AV_LOG_ERROR, "Invalid alpha value specifier '%s' in '%s'\n",
                    alpha_string, color_string);
             return AVERROR(EINVAL);
@@ -386,7 +390,7 @@ static int date_get_num(const char **pp,
     val = 0;
     for(i = 0; i < len_max; i++) {
         c = *p;
-        if (!isdigit(c))
+        if (!av_isdigit(c))
             break;
         val = (val * 10) + c - '0';
         p++;
@@ -400,65 +404,73 @@ static int date_get_num(const char **pp,
     return val;
 }
 
-static const char *small_strptime(const char *p, const char *fmt, struct tm *dt)
+const char *av_small_strptime(const char *p, const char *fmt, struct tm *dt)
 {
     int c, val;
 
-    for(;;) {
+    while((c = *fmt++)) {
+        if (c != '%') {
+            if (av_isspace(c))
+                for (; *p && av_isspace(*p); p++);
+            else if (*p != c)
+                return NULL;
+            else p++;
+            continue;
+        }
+
         c = *fmt++;
-        if (c == '\0') {
-            return p;
-        } else if (c == '%') {
-            c = *fmt++;
-            switch(c) {
-            case 'H':
-                val = date_get_num(&p, 0, 23, 2);
-                if (val == -1)
-                    return NULL;
-                dt->tm_hour = val;
-                break;
-            case 'M':
-                val = date_get_num(&p, 0, 59, 2);
-                if (val == -1)
-                    return NULL;
-                dt->tm_min = val;
-                break;
-            case 'S':
-                val = date_get_num(&p, 0, 59, 2);
-                if (val == -1)
-                    return NULL;
-                dt->tm_sec = val;
-                break;
-            case 'Y':
-                val = date_get_num(&p, 0, 9999, 4);
-                if (val == -1)
-                    return NULL;
-                dt->tm_year = val - 1900;
-                break;
-            case 'm':
-                val = date_get_num(&p, 1, 12, 2);
-                if (val == -1)
-                    return NULL;
-                dt->tm_mon = val - 1;
-                break;
-            case 'd':
-                val = date_get_num(&p, 1, 31, 2);
-                if (val == -1)
-                    return NULL;
-                dt->tm_mday = val;
-                break;
-            case '%':
-                goto match;
-            default:
+        switch(c) {
+        case 'H':
+            val = date_get_num(&p, 0, 23, 2);
+            if (val == -1)
                 return NULL;
-            }
-        } else {
-        match:
-            if (c != *p)
+            dt->tm_hour = val;
+            break;
+        case 'M':
+            val = date_get_num(&p, 0, 59, 2);
+            if (val == -1)
                 return NULL;
-            p++;
+            dt->tm_min = val;
+            break;
+        case 'S':
+            val = date_get_num(&p, 0, 59, 2);
+            if (val == -1)
+                return NULL;
+            dt->tm_sec = val;
+            break;
+        case 'Y':
+            val = date_get_num(&p, 0, 9999, 4);
+            if (val == -1)
+                return NULL;
+            dt->tm_year = val - 1900;
+            break;
+        case 'm':
+            val = date_get_num(&p, 1, 12, 2);
+            if (val == -1)
+                return NULL;
+            dt->tm_mon = val - 1;
+            break;
+        case 'd':
+            val = date_get_num(&p, 1, 31, 2);
+            if (val == -1)
+                return NULL;
+            dt->tm_mday = val;
+            break;
+        case 'T':
+            p = av_small_strptime(p, "%H:%M:%S", dt);
+            if (!p)
+                return NULL;
+            break;
+        case '%':
+            if (*p++ != '%')
+                return NULL;
+            break;
+        default:
+            return NULL;
         }
     }
+
+    return p;
 }
 
 time_t av_timegm(struct tm *tm)
@@ -484,7 +496,7 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
 {
     const char *p;
     int64_t t;
-    struct tm dt = { 0 };
+    struct tm dt = { 0 }, tmbuf;
     int i;
     static const char * const date_fmt[] = {
         "%Y-%m-%d",
@@ -499,7 +511,6 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
     char lastch;
     int negative = 0;
 
-#undef time
     time_t now = time(0);
 
     len = strlen(timestr);
@@ -519,7 +530,7 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
 
         /* parse the year-month-day part */
         for (i = 0; i < FF_ARRAY_ELEMS(date_fmt); i++) {
-            q = small_strptime(p, date_fmt[i], &dt);
+            q = av_small_strptime(p, date_fmt[i], &dt);
             if (q) {
                 break;
             }
@@ -529,9 +540,9 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
          * current year-month-day time */
         if (!q) {
             if (is_utc) {
-                dt = *gmtime(&now);
+                dt = *gmtime_r(&now, &tmbuf);
             } else {
-                dt = *localtime(&now);
+                dt = *localtime_r(&now, &tmbuf);
             }
             dt.tm_hour = dt.tm_min = dt.tm_sec = 0;
         } else {
@@ -543,7 +554,7 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
 
         /* parse the hour-minute-second part */
         for (i = 0; i < FF_ARRAY_ELEMS(time_fmt); i++) {
-            q = small_strptime(p, time_fmt[i], &dt);
+            q = av_small_strptime(p, time_fmt[i], &dt);
             if (q) {
                 break;
             }
@@ -555,17 +566,19 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
             ++p;
         }
         /* parse timestr as HH:MM:SS */
-        q = small_strptime(p, time_fmt[0], &dt);
+        q = av_small_strptime(p, time_fmt[0], &dt);
         if (!q) {
+            char *o;
             /* parse timestr as S+ */
-            dt.tm_sec = strtol(p, (char **)&q, 10);
-            if (q == p) {
+            dt.tm_sec = strtol(p, &o, 10);
+            if (o == p) {
                 /* the parsing didn't succeed */
                 *timeval = INT64_MIN;
                 return AVERROR(EINVAL);
             }
             dt.tm_min = 0;
             dt.tm_hour = 0;
+            q = o;
         }
     }
 
@@ -593,7 +606,7 @@ int av_parse_time(int64_t *timeval, const char *timestr, int duration)
         int val, n;
         q++;
         for (val = 0, n = 100000; n >= 1; n /= 10, q++) {
-            if (!isdigit(*q))
+            if (!av_isdigit(*q))
                 break;
             val += n * (*q - '0');
         }
@@ -641,103 +654,3 @@ int av_find_info_tag(char *arg, int arg_size, const char *tag1, const char *info
     }
     return 0;
 }
-
-#ifdef TEST
-
-#undef printf
-
-int main(void)
-{
-    printf("Testing av_parse_video_rate()\n");
-    {
-        int i;
-        const char *rates[] = {
-            "-inf",
-            "inf",
-            "nan",
-            "123/0",
-            "-123 / 0",
-            "",
-            "/",
-            " 123  /  321",
-            "foo/foo",
-            "foo/1",
-            "1/foo",
-            "0/0",
-            "/0",
-            "1/",
-            "1",
-            "0",
-            "-123/123",
-            "-foo",
-            "123.23",
-            ".23",
-            "-.23",
-            "-0.234",
-            "-0.0000001",
-            "  21332.2324   ",
-            " -21332.2324   ",
-        };
-
-        for (i = 0; i < FF_ARRAY_ELEMS(rates); i++) {
-            int ret;
-            AVRational q = (AVRational){0, 0};
-            ret = av_parse_video_rate(&q, rates[i]),
-            printf("'%s' -> %d/%d ret:%d\n",
-                   rates[i], q.num, q.den, ret);
-        }
-    }
-
-    printf("\nTesting av_parse_color()\n");
-    {
-        int i;
-        uint8_t rgba[4];
-        const char *color_names[] = {
-            "foo",
-            "red",
-            "Red ",
-            "RED",
-            "Violet",
-            "Yellow",
-            "Red",
-            "0x000000",
-            "0x0000000",
-            "0xff000000",
-            "0x3e34ff",
-            "0x3e34ffaa",
-            "0xffXXee",
-            "0xfoobar",
-            "0xffffeeeeeeee",
-            "#ff0000",
-            "#ffXX00",
-            "ff0000",
-            "ffXX00",
-            "red@foo",
-            "random@10",
-            "0xff0000@1.0",
-            "red@",
-            "red@0xfff",
-            "red@0xf",
-            "red@2",
-            "red@0.1",
-            "red@-1",
-            "red@0.5",
-            "red@1.0",
-            "red@256",
-            "red@10foo",
-            "red@-1.0",
-            "red@-0.0",
-        };
-
-        av_log_set_level(AV_LOG_DEBUG);
-
-        for (i = 0;  i < FF_ARRAY_ELEMS(color_names); i++) {
-            if (av_parse_color(rgba, color_names[i], -1, NULL) >= 0)
-                printf("%s -> R(%d) G(%d) B(%d) A(%d)\n", color_names[i], rgba[0], rgba[1], rgba[2], rgba[3]);
-        }
-    }
-
-    return 0;
-}
-
-#endif /* TEST */