]> git.sesse.net Git - ffmpeg/blobdiff - libavfilter/parseutils.c
Fix out of tree builds with vf_yadif and mmx
[ffmpeg] / libavfilter / parseutils.c
index 85effb06c118a33e3f3c76ca65f760336ab8a04e..b8923eda46800ed19e0d43ad06499189790b6fa4 100644 (file)
  */
 
 /**
- * @file libavfilter/parseutils.c
+ * @file
  * parsing utils
  */
 
 #include <strings.h>
 #include "libavutil/avutil.h"
+#include "libavutil/avstring.h"
 #include "libavutil/random_seed.h"
 #include "parseutils.h"
 
-#define WHITESPACES " \n\t"
-
-char *av_get_token(const char **buf, const char *term)
-{
-    char *out = av_malloc(strlen(*buf) + 1);
-    char *ret= out, *end= out;
-    const char *p = *buf;
-    p += strspn(p, WHITESPACES);
-
-    while(*p && !strspn(p, term)) {
-        char c = *p++;
-        if(c == '\\' && *p){
-            *out++ = *p++;
-            end= out;
-        }else if(c == '\''){
-            while(*p && *p != '\'')
-                *out++ = *p++;
-            if(*p){
-                p++;
-                end= out;
-            }
-        }else{
-            *out++ = c;
-        }
-    }
-
-    do{
-        *out-- = 0;
-    }while(out >= end && strspn(out, WHITESPACES));
-
-    *buf = p;
-
-    return ret;
-}
-
 typedef struct {
     const char *name;            ///< a string representing the name of the color
-    uint8_t     rgba_color[4];   ///< RGBA values for the color
+    uint8_t     rgb_color[3];    ///< RGB values for the color
 } ColorEntry;
 
 static ColorEntry color_table[] = {
@@ -215,23 +181,31 @@ static int color_table_compare(const void *lhs, const void *rhs)
     return strcasecmp(lhs, ((const ColorEntry *)rhs)->name);
 }
 
+#define ALPHA_SEP '@'
+
 int av_parse_color(uint8_t *rgba_color, const char *color_string, void *log_ctx)
 {
-    if (!strcasecmp(color_string, "random") || !strcasecmp(color_string, "bikeshed")) {
-        int rgba = ff_random_get_seed();
+    char *tail, color_string2[128];
+    const ColorEntry *entry;
+    av_strlcpy(color_string2, color_string, sizeof(color_string2));
+    if ((tail = strchr(color_string2, ALPHA_SEP)))
+        *tail++ = 0;
+    rgba_color[3] = 255;
+
+    if (!strcasecmp(color_string2, "random") || !strcasecmp(color_string2, "bikeshed")) {
+        int rgba = av_get_random_seed();
         rgba_color[0] = rgba >> 24;
         rgba_color[1] = rgba >> 16;
         rgba_color[2] = rgba >> 8;
         rgba_color[3] = rgba;
-    } else
-    if (!strncmp(color_string, "0x", 2)) {
+    } else if (!strncmp(color_string2, "0x", 2)) {
         char *tail;
-        int len = strlen(color_string);
-        int rgba = strtol(color_string, &tail, 16);
+        int len = strlen(color_string2);
+        unsigned int rgba = strtoul(color_string2, &tail, 16);
 
         if (*tail || (len != 8 && len != 10)) {
-            av_log(log_ctx, AV_LOG_ERROR, "Invalid 0xRRGGBB[AA] color string: '%s'\n", color_string);
-            return -1;
+            av_log(log_ctx, AV_LOG_ERROR, "Invalid 0xRRGGBB[AA] color string: '%s'\n", color_string2);
+            return AVERROR(EINVAL);
         }
         if (len == 10) {
             rgba_color[3] = rgba;
@@ -241,16 +215,37 @@ int av_parse_color(uint8_t *rgba_color, const char *color_string, void *log_ctx)
         rgba_color[1] = rgba >> 8;
         rgba_color[2] = rgba;
     } else {
-        const ColorEntry *entry = bsearch(color_string,
-                                          color_table,
-                                          FF_ARRAY_ELEMS(color_table),
-                                          sizeof(ColorEntry),
-                                          color_table_compare);
+        entry = bsearch(color_string2,
+                        color_table,
+                        FF_ARRAY_ELEMS(color_table),
+                        sizeof(ColorEntry),
+                        color_table_compare);
         if (!entry) {
-            av_log(log_ctx, AV_LOG_DEBUG, "Cannot find color '%s'\n", color_string);
-            return -1;
+            av_log(log_ctx, AV_LOG_ERROR, "Cannot find color '%s'\n", color_string2);
+            return AVERROR(EINVAL);
         }
-        memcpy(rgba_color, entry->rgba_color, 4);
+        memcpy(rgba_color, entry->rgb_color, 3);
+    }
+
+    if (tail) {
+        unsigned long int alpha;
+        const char *alpha_string = tail;
+        if (!strncmp(alpha_string, "0x", 2)) {
+            alpha = strtoul(alpha_string, &tail, 16);
+        } else {
+            alpha = strtoul(alpha_string, &tail, 10);
+            if (*tail) {
+                double d = strtod(alpha_string, &tail);
+                alpha = d * 255;
+            }
+        }
+
+        if (tail == alpha_string || *tail || alpha > 255) {
+            av_log(log_ctx, AV_LOG_ERROR, "Invalid alpha value specifier '%s' in '%s'\n",
+                   alpha_string, color_string);
+            return AVERROR(EINVAL);
+        }
+        rgba_color[3] = alpha;
     }
 
     return 0;
@@ -264,41 +259,6 @@ int main(void)
 {
     int i;
 
-    const char *strings[] = {
-        "''",
-        "",
-        ":",
-        "\\",
-        "'",
-        "    ''    :",
-        "    ''  ''  :",
-        "foo   '' :",
-        "'foo'",
-        "foo     ",
-        "foo\\",
-        "foo':  blah:blah",
-        "foo\\:  blah:blah",
-        "foo\'",
-        "'foo :  '  :blahblah",
-        "\\ :blah",
-        "     foo",
-        "      foo       ",
-        "      foo     \\ ",
-        "foo ':blah",
-        " foo   bar    :   blahblah",
-        "\\f\\o\\o",
-        "'foo : \\ \\  '   : blahblah",
-        "'\\fo\\o:': blahblah",
-        "\\'fo\\o\\:':  foo  '  :blahblah"
-    };
-
-    for (i=0; i < FF_ARRAY_ELEMS(strings); i++) {
-        const char *p= strings[i];
-        printf("|%s|", p);
-        printf(" -> |%s|", av_get_token(&p, ":"));
-        printf(" + |%s|\n", p);
-    }
-
     printf("\nTesting av_parse_color()\n");
     {
         uint8_t rgba[4];
@@ -314,11 +274,27 @@ int main(void)
             "Red",
             "0x000000",
             "0x0000000",
+            "0xff000000",
             "0x3e34ff",
             "0x3e34ffaa",
             "0xffXXee",
             "0xfoobar",
             "0xffffeeeeeeee",
+            "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);