Statistics
| Branch: | Revision:

ffmpeg / libavfilter / parseutils.c @ 34017fd9

History | View | Annotate | Download (18.1 KB)

1 d11dbf09 Michael Niedermayer
/*
2
 * copyright (c) 2009 Stefano Sabatini
3
 * This file is part of FFmpeg.
4
 *
5
 * FFmpeg is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2.1 of the License, or (at your option) any later version.
9
 *
10
 * FFmpeg is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with FFmpeg; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
 */
19
20
/**
21 ba87f080 Diego Biurrun
 * @file
22 d11dbf09 Michael Niedermayer
 * parsing utils
23
 */
24
25 b69b622c Stefano Sabatini
#include <strings.h>
26 d11dbf09 Michael Niedermayer
#include "libavutil/avutil.h"
27 a52e2c3a Stefano Sabatini
#include "libavutil/avstring.h"
28 4fa61d1e Ramiro Polla
#include "libavutil/random_seed.h"
29 d11dbf09 Michael Niedermayer
#include "parseutils.h"
30
31
#define WHITESPACES " \n\t"
32
33
char *av_get_token(const char **buf, const char *term)
34
{
35
    char *out = av_malloc(strlen(*buf) + 1);
36
    char *ret= out, *end= out;
37
    const char *p = *buf;
38 5ba949fe Stefano Sabatini
    if (!out) return NULL;
39 d11dbf09 Michael Niedermayer
    p += strspn(p, WHITESPACES);
40
41
    while(*p && !strspn(p, term)) {
42
        char c = *p++;
43
        if(c == '\\' && *p){
44
            *out++ = *p++;
45
            end= out;
46
        }else if(c == '\''){
47
            while(*p && *p != '\'')
48
                *out++ = *p++;
49
            if(*p){
50
                p++;
51
                end= out;
52
            }
53
        }else{
54
            *out++ = c;
55
        }
56
    }
57
58
    do{
59
        *out-- = 0;
60
    }while(out >= end && strspn(out, WHITESPACES));
61
62
    *buf = p;
63
64
    return ret;
65
}
66
67 a3015225 Stefano Sabatini
typedef struct {
68
    const char *name;            ///< a string representing the name of the color
69 8e094dd6 Stefano Sabatini
    uint8_t     rgb_color[3];    ///< RGB values for the color
70 a3015225 Stefano Sabatini
} ColorEntry;
71
72
static ColorEntry color_table[] = {
73
    { "AliceBlue",            { 0xF0, 0xF8, 0xFF } },
74
    { "AntiqueWhite",         { 0xFA, 0xEB, 0xD7 } },
75
    { "Aqua",                 { 0x00, 0xFF, 0xFF } },
76
    { "Aquamarine",           { 0x7F, 0xFF, 0xD4 } },
77
    { "Azure",                { 0xF0, 0xFF, 0xFF } },
78
    { "Beige",                { 0xF5, 0xF5, 0xDC } },
79
    { "Bisque",               { 0xFF, 0xE4, 0xC4 } },
80
    { "Black",                { 0x00, 0x00, 0x00 } },
81
    { "BlanchedAlmond",       { 0xFF, 0xEB, 0xCD } },
82
    { "Blue",                 { 0x00, 0x00, 0xFF } },
83
    { "BlueViolet",           { 0x8A, 0x2B, 0xE2 } },
84
    { "Brown",                { 0xA5, 0x2A, 0x2A } },
85
    { "BurlyWood",            { 0xDE, 0xB8, 0x87 } },
86
    { "CadetBlue",            { 0x5F, 0x9E, 0xA0 } },
87
    { "Chartreuse",           { 0x7F, 0xFF, 0x00 } },
88
    { "Chocolate",            { 0xD2, 0x69, 0x1E } },
89
    { "Coral",                { 0xFF, 0x7F, 0x50 } },
90
    { "CornflowerBlue",       { 0x64, 0x95, 0xED } },
91
    { "Cornsilk",             { 0xFF, 0xF8, 0xDC } },
92
    { "Crimson",              { 0xDC, 0x14, 0x3C } },
93
    { "Cyan",                 { 0x00, 0xFF, 0xFF } },
94
    { "DarkBlue",             { 0x00, 0x00, 0x8B } },
95
    { "DarkCyan",             { 0x00, 0x8B, 0x8B } },
96
    { "DarkGoldenRod",        { 0xB8, 0x86, 0x0B } },
97
    { "DarkGray",             { 0xA9, 0xA9, 0xA9 } },
98
    { "DarkGreen",            { 0x00, 0x64, 0x00 } },
99
    { "DarkKhaki",            { 0xBD, 0xB7, 0x6B } },
100
    { "DarkMagenta",          { 0x8B, 0x00, 0x8B } },
101
    { "DarkOliveGreen",       { 0x55, 0x6B, 0x2F } },
102
    { "Darkorange",           { 0xFF, 0x8C, 0x00 } },
103
    { "DarkOrchid",           { 0x99, 0x32, 0xCC } },
104
    { "DarkRed",              { 0x8B, 0x00, 0x00 } },
105
    { "DarkSalmon",           { 0xE9, 0x96, 0x7A } },
106
    { "DarkSeaGreen",         { 0x8F, 0xBC, 0x8F } },
107
    { "DarkSlateBlue",        { 0x48, 0x3D, 0x8B } },
108
    { "DarkSlateGray",        { 0x2F, 0x4F, 0x4F } },
109
    { "DarkTurquoise",        { 0x00, 0xCE, 0xD1 } },
110
    { "DarkViolet",           { 0x94, 0x00, 0xD3 } },
111
    { "DeepPink",             { 0xFF, 0x14, 0x93 } },
112
    { "DeepSkyBlue",          { 0x00, 0xBF, 0xFF } },
113
    { "DimGray",              { 0x69, 0x69, 0x69 } },
114
    { "DodgerBlue",           { 0x1E, 0x90, 0xFF } },
115
    { "FireBrick",            { 0xB2, 0x22, 0x22 } },
116
    { "FloralWhite",          { 0xFF, 0xFA, 0xF0 } },
117
    { "ForestGreen",          { 0x22, 0x8B, 0x22 } },
118
    { "Fuchsia",              { 0xFF, 0x00, 0xFF } },
119
    { "Gainsboro",            { 0xDC, 0xDC, 0xDC } },
120
    { "GhostWhite",           { 0xF8, 0xF8, 0xFF } },
121
    { "Gold",                 { 0xFF, 0xD7, 0x00 } },
122
    { "GoldenRod",            { 0xDA, 0xA5, 0x20 } },
123
    { "Gray",                 { 0x80, 0x80, 0x80 } },
124
    { "Green",                { 0x00, 0x80, 0x00 } },
125
    { "GreenYellow",          { 0xAD, 0xFF, 0x2F } },
126
    { "HoneyDew",             { 0xF0, 0xFF, 0xF0 } },
127
    { "HotPink",              { 0xFF, 0x69, 0xB4 } },
128
    { "IndianRed",            { 0xCD, 0x5C, 0x5C } },
129
    { "Indigo",               { 0x4B, 0x00, 0x82 } },
130
    { "Ivory",                { 0xFF, 0xFF, 0xF0 } },
131
    { "Khaki",                { 0xF0, 0xE6, 0x8C } },
132
    { "Lavender",             { 0xE6, 0xE6, 0xFA } },
133
    { "LavenderBlush",        { 0xFF, 0xF0, 0xF5 } },
134
    { "LawnGreen",            { 0x7C, 0xFC, 0x00 } },
135
    { "LemonChiffon",         { 0xFF, 0xFA, 0xCD } },
136
    { "LightBlue",            { 0xAD, 0xD8, 0xE6 } },
137
    { "LightCoral",           { 0xF0, 0x80, 0x80 } },
138
    { "LightCyan",            { 0xE0, 0xFF, 0xFF } },
139
    { "LightGoldenRodYellow", { 0xFA, 0xFA, 0xD2 } },
140
    { "LightGrey",            { 0xD3, 0xD3, 0xD3 } },
141
    { "LightGreen",           { 0x90, 0xEE, 0x90 } },
142
    { "LightPink",            { 0xFF, 0xB6, 0xC1 } },
143
    { "LightSalmon",          { 0xFF, 0xA0, 0x7A } },
144
    { "LightSeaGreen",        { 0x20, 0xB2, 0xAA } },
145
    { "LightSkyBlue",         { 0x87, 0xCE, 0xFA } },
146
    { "LightSlateGray",       { 0x77, 0x88, 0x99 } },
147
    { "LightSteelBlue",       { 0xB0, 0xC4, 0xDE } },
148
    { "LightYellow",          { 0xFF, 0xFF, 0xE0 } },
149
    { "Lime",                 { 0x00, 0xFF, 0x00 } },
150
    { "LimeGreen",            { 0x32, 0xCD, 0x32 } },
151
    { "Linen",                { 0xFA, 0xF0, 0xE6 } },
152
    { "Magenta",              { 0xFF, 0x00, 0xFF } },
153
    { "Maroon",               { 0x80, 0x00, 0x00 } },
154
    { "MediumAquaMarine",     { 0x66, 0xCD, 0xAA } },
155
    { "MediumBlue",           { 0x00, 0x00, 0xCD } },
156
    { "MediumOrchid",         { 0xBA, 0x55, 0xD3 } },
157
    { "MediumPurple",         { 0x93, 0x70, 0xD8 } },
158
    { "MediumSeaGreen",       { 0x3C, 0xB3, 0x71 } },
159
    { "MediumSlateBlue",      { 0x7B, 0x68, 0xEE } },
160
    { "MediumSpringGreen",    { 0x00, 0xFA, 0x9A } },
161
    { "MediumTurquoise",      { 0x48, 0xD1, 0xCC } },
162
    { "MediumVioletRed",      { 0xC7, 0x15, 0x85 } },
163
    { "MidnightBlue",         { 0x19, 0x19, 0x70 } },
164
    { "MintCream",            { 0xF5, 0xFF, 0xFA } },
165
    { "MistyRose",            { 0xFF, 0xE4, 0xE1 } },
166
    { "Moccasin",             { 0xFF, 0xE4, 0xB5 } },
167
    { "NavajoWhite",          { 0xFF, 0xDE, 0xAD } },
168
    { "Navy",                 { 0x00, 0x00, 0x80 } },
169
    { "OldLace",              { 0xFD, 0xF5, 0xE6 } },
170
    { "Olive",                { 0x80, 0x80, 0x00 } },
171
    { "OliveDrab",            { 0x6B, 0x8E, 0x23 } },
172
    { "Orange",               { 0xFF, 0xA5, 0x00 } },
173
    { "OrangeRed",            { 0xFF, 0x45, 0x00 } },
174
    { "Orchid",               { 0xDA, 0x70, 0xD6 } },
175
    { "PaleGoldenRod",        { 0xEE, 0xE8, 0xAA } },
176
    { "PaleGreen",            { 0x98, 0xFB, 0x98 } },
177
    { "PaleTurquoise",        { 0xAF, 0xEE, 0xEE } },
178
    { "PaleVioletRed",        { 0xD8, 0x70, 0x93 } },
179
    { "PapayaWhip",           { 0xFF, 0xEF, 0xD5 } },
180
    { "PeachPuff",            { 0xFF, 0xDA, 0xB9 } },
181
    { "Peru",                 { 0xCD, 0x85, 0x3F } },
182
    { "Pink",                 { 0xFF, 0xC0, 0xCB } },
183
    { "Plum",                 { 0xDD, 0xA0, 0xDD } },
184
    { "PowderBlue",           { 0xB0, 0xE0, 0xE6 } },
185
    { "Purple",               { 0x80, 0x00, 0x80 } },
186
    { "Red",                  { 0xFF, 0x00, 0x00 } },
187
    { "RosyBrown",            { 0xBC, 0x8F, 0x8F } },
188
    { "RoyalBlue",            { 0x41, 0x69, 0xE1 } },
189
    { "SaddleBrown",          { 0x8B, 0x45, 0x13 } },
190
    { "Salmon",               { 0xFA, 0x80, 0x72 } },
191
    { "SandyBrown",           { 0xF4, 0xA4, 0x60 } },
192
    { "SeaGreen",             { 0x2E, 0x8B, 0x57 } },
193
    { "SeaShell",             { 0xFF, 0xF5, 0xEE } },
194
    { "Sienna",               { 0xA0, 0x52, 0x2D } },
195
    { "Silver",               { 0xC0, 0xC0, 0xC0 } },
196
    { "SkyBlue",              { 0x87, 0xCE, 0xEB } },
197
    { "SlateBlue",            { 0x6A, 0x5A, 0xCD } },
198
    { "SlateGray",            { 0x70, 0x80, 0x90 } },
199
    { "Snow",                 { 0xFF, 0xFA, 0xFA } },
200
    { "SpringGreen",          { 0x00, 0xFF, 0x7F } },
201
    { "SteelBlue",            { 0x46, 0x82, 0xB4 } },
202
    { "Tan",                  { 0xD2, 0xB4, 0x8C } },
203
    { "Teal",                 { 0x00, 0x80, 0x80 } },
204
    { "Thistle",              { 0xD8, 0xBF, 0xD8 } },
205
    { "Tomato",               { 0xFF, 0x63, 0x47 } },
206
    { "Turquoise",            { 0x40, 0xE0, 0xD0 } },
207
    { "Violet",               { 0xEE, 0x82, 0xEE } },
208
    { "Wheat",                { 0xF5, 0xDE, 0xB3 } },
209
    { "White",                { 0xFF, 0xFF, 0xFF } },
210
    { "WhiteSmoke",           { 0xF5, 0xF5, 0xF5 } },
211
    { "Yellow",               { 0xFF, 0xFF, 0x00 } },
212
    { "YellowGreen",          { 0x9A, 0xCD, 0x32 } },
213
};
214
215
static int color_table_compare(const void *lhs, const void *rhs)
216
{
217 b69b622c Stefano Sabatini
    return strcasecmp(lhs, ((const ColorEntry *)rhs)->name);
218 a3015225 Stefano Sabatini
}
219
220 a52e2c3a Stefano Sabatini
#define ALPHA_SEP '@'
221
222 a3015225 Stefano Sabatini
int av_parse_color(uint8_t *rgba_color, const char *color_string, void *log_ctx)
223
{
224 a52e2c3a Stefano Sabatini
    char *tail, color_string2[128];
225
    const ColorEntry *entry;
226
    av_strlcpy(color_string2, color_string, sizeof(color_string2));
227
    if ((tail = strchr(color_string2, ALPHA_SEP)))
228
        *tail++ = 0;
229
    rgba_color[3] = 255;
230
231
    if (!strcasecmp(color_string2, "random") || !strcasecmp(color_string2, "bikeshed")) {
232 576fb48e Martin Storsjö
        int rgba = av_get_random_seed();
233 4fa61d1e Ramiro Polla
        rgba_color[0] = rgba >> 24;
234
        rgba_color[1] = rgba >> 16;
235
        rgba_color[2] = rgba >> 8;
236
        rgba_color[3] = rgba;
237 9e74966b Stefano Sabatini
    } else if (!strncmp(color_string2, "0x", 2)) {
238 a3015225 Stefano Sabatini
        char *tail;
239 a52e2c3a Stefano Sabatini
        int len = strlen(color_string2);
240
        unsigned int rgba = strtoul(color_string2, &tail, 16);
241 a3015225 Stefano Sabatini
242
        if (*tail || (len != 8 && len != 10)) {
243 a52e2c3a Stefano Sabatini
            av_log(log_ctx, AV_LOG_ERROR, "Invalid 0xRRGGBB[AA] color string: '%s'\n", color_string2);
244 dc0eaef3 Stefano Sabatini
            return AVERROR(EINVAL);
245 a3015225 Stefano Sabatini
        }
246
        if (len == 10) {
247
            rgba_color[3] = rgba;
248
            rgba >>= 8;
249
        }
250
        rgba_color[0] = rgba >> 16;
251
        rgba_color[1] = rgba >> 8;
252
        rgba_color[2] = rgba;
253
    } else {
254 a52e2c3a Stefano Sabatini
        entry = bsearch(color_string2,
255 4cf0b43a Stefano Sabatini
                        color_table,
256
                        FF_ARRAY_ELEMS(color_table),
257
                        sizeof(ColorEntry),
258
                        color_table_compare);
259 a3015225 Stefano Sabatini
        if (!entry) {
260 a52e2c3a Stefano Sabatini
            av_log(log_ctx, AV_LOG_ERROR, "Cannot find color '%s'\n", color_string2);
261 dc0eaef3 Stefano Sabatini
            return AVERROR(EINVAL);
262 a3015225 Stefano Sabatini
        }
263 8e094dd6 Stefano Sabatini
        memcpy(rgba_color, entry->rgb_color, 3);
264 a3015225 Stefano Sabatini
    }
265
266 a52e2c3a Stefano Sabatini
    if (tail) {
267
        unsigned long int alpha;
268
        const char *alpha_string = tail;
269
        if (!strncmp(alpha_string, "0x", 2)) {
270
            alpha = strtoul(alpha_string, &tail, 16);
271
        } else {
272
            alpha = strtoul(alpha_string, &tail, 10);
273
            if (*tail) {
274
                double d = strtod(alpha_string, &tail);
275
                alpha = d * 255;
276
            }
277
        }
278
279
        if (tail == alpha_string || *tail || alpha > 255) {
280
            av_log(log_ctx, AV_LOG_ERROR, "Invalid alpha value specifier '%s' in '%s'\n",
281
                   alpha_string, color_string);
282
            return AVERROR(EINVAL);
283
        }
284
        rgba_color[3] = alpha;
285
    }
286
287 a3015225 Stefano Sabatini
    return 0;
288
}
289
290 c1ec75b5 Stefano Sabatini
/**
291 49bd8e4b Måns Rullgård
 * Store the value in the field in ctx that is named like key.
292 c1ec75b5 Stefano Sabatini
 * ctx must be an AVClass context, storing is done using AVOptions.
293
 *
294
 * @param buf the string to parse, buf will be updated to point at the
295
 * separator just after the parsed key/value pair
296
 * @param key_val_sep a 0-terminated list of characters used to
297
 * separate key from value
298
 * @param pairs_sep a 0-terminated list of characters used to separate
299
 * two pairs from each other
300
 * @return 0 if the key/value pair has been successfully parsed and
301
 * set, or a negative value corresponding to an AVERROR code in case
302
 * of error:
303
 * AVERROR(EINVAL) if the key/value pair cannot be parsed,
304
 * the error code issued by av_set_string3() if the key/value pair
305
 * cannot be set
306
 */
307
static int parse_key_value_pair(void *ctx, const char **buf,
308
                                const char *key_val_sep, const char *pairs_sep)
309
{
310
    char *key = av_get_token(buf, key_val_sep);
311
    char *val;
312
    int ret;
313
314
    if (*key && strspn(*buf, key_val_sep)) {
315
        (*buf)++;
316
        val = av_get_token(buf, pairs_sep);
317
    } else {
318
        av_log(ctx, AV_LOG_ERROR, "Missing key or no key/value separator found after key '%s'\n", key);
319
        av_free(key);
320
        return AVERROR(EINVAL);
321
    }
322
323
    av_log(ctx, AV_LOG_DEBUG, "Setting value '%s' for key '%s'\n", val, key);
324
325
    ret = av_set_string3(ctx, key, val, 1, NULL);
326 62096b99 Stefano Sabatini
    if (ret == AVERROR(ENOENT))
327
        av_log(ctx, AV_LOG_ERROR, "Key '%s' not found.\n", key);
328 c1ec75b5 Stefano Sabatini
329
    av_free(key);
330
    av_free(val);
331
    return ret;
332
}
333
334
int av_set_options_string(void *ctx, const char *opts,
335
                          const char *key_val_sep, const char *pairs_sep)
336
{
337
    int ret, count = 0;
338
339
    while (*opts) {
340
        if ((ret = parse_key_value_pair(ctx, &opts, key_val_sep, pairs_sep)) < 0)
341
            return ret;
342
        count++;
343
344
        if (*opts)
345
            opts++;
346
    }
347
348
    return count;
349
}
350
351 d11dbf09 Michael Niedermayer
#ifdef TEST
352
353
#undef printf
354
355 c1ec75b5 Stefano Sabatini
typedef struct TestContext
356
{
357
    const AVClass *class;
358
    int num;
359
    int toggle;
360
    char *string;
361
    int flags;
362
    AVRational rational;
363
} TestContext;
364
365
#define OFFSET(x) offsetof(TestContext, x)
366
367
#define TEST_FLAG_COOL 01
368
#define TEST_FLAG_LAME 02
369
#define TEST_FLAG_MU   04
370
371
static const AVOption test_options[]= {
372
{"num",      "set num",        OFFSET(num),      FF_OPT_TYPE_INT,      0,              0,        100                 },
373
{"toggle",   "set toggle",     OFFSET(toggle),   FF_OPT_TYPE_INT,      0,              0,        1                   },
374
{"rational", "set rational",   OFFSET(rational), FF_OPT_TYPE_RATIONAL, 0,              0,        10                  },
375
{"string",   "set string",     OFFSET(string),   FF_OPT_TYPE_STRING,   0,              CHAR_MIN, CHAR_MAX            },
376
{"flags",    "set flags",      OFFSET(flags),    FF_OPT_TYPE_FLAGS,    0,              0,        INT_MAX, 0, "flags" },
377
{"cool",     "set cool flag ", 0,                FF_OPT_TYPE_CONST,    TEST_FLAG_COOL, INT_MIN,  INT_MAX, 0, "flags" },
378
{"lame",     "set lame flag ", 0,                FF_OPT_TYPE_CONST,    TEST_FLAG_LAME, INT_MIN,  INT_MAX, 0, "flags" },
379
{"mu",       "set mu flag ",   0,                FF_OPT_TYPE_CONST,    TEST_FLAG_MU,   INT_MIN,  INT_MAX, 0, "flags" },
380
{NULL},
381
};
382
383
static const char *test_get_name(void *ctx)
384
{
385
    return "test";
386
}
387
388
static const AVClass test_class = {
389
    "TestContext",
390
    test_get_name,
391
    test_options
392
};
393
394 2e032b32 Stefano Sabatini
int main(void)
395 d11dbf09 Michael Niedermayer
{
396
    int i;
397
398
    const char *strings[] = {
399
        "''",
400
        "",
401
        ":",
402
        "\\",
403
        "'",
404
        "    ''    :",
405
        "    ''  ''  :",
406
        "foo   '' :",
407
        "'foo'",
408
        "foo     ",
409
        "foo\\",
410
        "foo':  blah:blah",
411
        "foo\\:  blah:blah",
412
        "foo\'",
413
        "'foo :  '  :blahblah",
414
        "\\ :blah",
415
        "     foo",
416
        "      foo       ",
417
        "      foo     \\ ",
418
        "foo ':blah",
419
        " foo   bar    :   blahblah",
420
        "\\f\\o\\o",
421
        "'foo : \\ \\  '   : blahblah",
422
        "'\\fo\\o:': blahblah",
423
        "\\'fo\\o\\:':  foo  '  :blahblah"
424
    };
425
426
    for (i=0; i < FF_ARRAY_ELEMS(strings); i++) {
427
        const char *p= strings[i];
428
        printf("|%s|", p);
429
        printf(" -> |%s|", av_get_token(&p, ":"));
430
        printf(" + |%s|\n", p);
431
    }
432
433 a3015225 Stefano Sabatini
    printf("\nTesting av_parse_color()\n");
434
    {
435
        uint8_t rgba[4];
436
        const char *color_names[] = {
437 4fa61d1e Ramiro Polla
            "bikeshed",
438 3d3bd64d Stefano Sabatini
            "RaNdOm",
439 a3015225 Stefano Sabatini
            "foo",
440
            "red",
441
            "Red ",
442
            "RED",
443
            "Violet",
444
            "Yellow",
445
            "Red",
446
            "0x000000",
447
            "0x0000000",
448 7d132c54 Stefano Sabatini
            "0xff000000",
449 a3015225 Stefano Sabatini
            "0x3e34ff",
450
            "0x3e34ffaa",
451
            "0xffXXee",
452
            "0xfoobar",
453
            "0xffffeeeeeeee",
454 a52e2c3a Stefano Sabatini
            "red@foo",
455
            "random@10",
456
            "0xff0000@1.0",
457
            "red@",
458
            "red@0xfff",
459
            "red@0xf",
460
            "red@2",
461
            "red@0.1",
462
            "red@-1",
463
            "red@0.5",
464
            "red@1.0",
465
            "red@256",
466
            "red@10foo",
467
            "red@-1.0",
468
            "red@-0.0",
469 a3015225 Stefano Sabatini
        };
470
471
        av_log_set_level(AV_LOG_DEBUG);
472
473
        for (int i = 0;  i < FF_ARRAY_ELEMS(color_names); i++) {
474
            if (av_parse_color(rgba, color_names[i], NULL) >= 0)
475
                printf("%s -> R(%d) G(%d) B(%d) A(%d)\n", color_names[i], rgba[0], rgba[1], rgba[2], rgba[3]);
476
        }
477
    }
478
479 c1ec75b5 Stefano Sabatini
    printf("\nTesting av_set_options_string()\n");
480
    {
481
        TestContext test_ctx;
482
        const char *options[] = {
483
            "",
484
            ":",
485
            "=",
486
            "foo=:",
487
            ":=foo",
488
            "=foo",
489
            "foo=",
490
            "foo",
491
            "foo=val",
492
            "foo==val",
493
            "toggle=:",
494
            "string=:",
495
            "toggle=1 : foo",
496
            "toggle=100",
497
            "toggle==1",
498
            "flags=+mu-lame : num=42: toggle=0",
499
            "num=42 : string=blahblah",
500
            "rational=0 : rational=1/2 : rational=1/-1",
501
            "rational=-1/0",
502
        };
503
504
        test_ctx.class = &test_class;
505
        av_opt_set_defaults2(&test_ctx, 0, 0);
506
        test_ctx.string = av_strdup("default");
507
508
        av_log_set_level(AV_LOG_DEBUG);
509
510
        for (i=0; i < FF_ARRAY_ELEMS(options); i++) {
511
            av_log(&test_ctx, AV_LOG_DEBUG, "Setting options string '%s'\n", options[i]);
512
            if (av_set_options_string(&test_ctx, options[i], "=", ":") < 0)
513
                av_log(&test_ctx, AV_LOG_ERROR, "Error setting options string: '%s'\n", options[i]);
514
            printf("\n");
515
        }
516
    }
517
518 d11dbf09 Michael Niedermayer
    return 0;
519
}
520
521
#endif