Statistics
| Branch: | Revision:

ffmpeg / libavfilter / parseutils.c @ d370e3e9

History | View | Annotate | Download (12.2 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 a3015225 Stefano Sabatini
typedef struct {
32
    const char *name;            ///< a string representing the name of the color
33 8e094dd6 Stefano Sabatini
    uint8_t     rgb_color[3];    ///< RGB values for the color
34 a3015225 Stefano Sabatini
} ColorEntry;
35
36
static ColorEntry color_table[] = {
37
    { "AliceBlue",            { 0xF0, 0xF8, 0xFF } },
38
    { "AntiqueWhite",         { 0xFA, 0xEB, 0xD7 } },
39
    { "Aqua",                 { 0x00, 0xFF, 0xFF } },
40
    { "Aquamarine",           { 0x7F, 0xFF, 0xD4 } },
41
    { "Azure",                { 0xF0, 0xFF, 0xFF } },
42
    { "Beige",                { 0xF5, 0xF5, 0xDC } },
43
    { "Bisque",               { 0xFF, 0xE4, 0xC4 } },
44
    { "Black",                { 0x00, 0x00, 0x00 } },
45
    { "BlanchedAlmond",       { 0xFF, 0xEB, 0xCD } },
46
    { "Blue",                 { 0x00, 0x00, 0xFF } },
47
    { "BlueViolet",           { 0x8A, 0x2B, 0xE2 } },
48
    { "Brown",                { 0xA5, 0x2A, 0x2A } },
49
    { "BurlyWood",            { 0xDE, 0xB8, 0x87 } },
50
    { "CadetBlue",            { 0x5F, 0x9E, 0xA0 } },
51
    { "Chartreuse",           { 0x7F, 0xFF, 0x00 } },
52
    { "Chocolate",            { 0xD2, 0x69, 0x1E } },
53
    { "Coral",                { 0xFF, 0x7F, 0x50 } },
54
    { "CornflowerBlue",       { 0x64, 0x95, 0xED } },
55
    { "Cornsilk",             { 0xFF, 0xF8, 0xDC } },
56
    { "Crimson",              { 0xDC, 0x14, 0x3C } },
57
    { "Cyan",                 { 0x00, 0xFF, 0xFF } },
58
    { "DarkBlue",             { 0x00, 0x00, 0x8B } },
59
    { "DarkCyan",             { 0x00, 0x8B, 0x8B } },
60
    { "DarkGoldenRod",        { 0xB8, 0x86, 0x0B } },
61
    { "DarkGray",             { 0xA9, 0xA9, 0xA9 } },
62
    { "DarkGreen",            { 0x00, 0x64, 0x00 } },
63
    { "DarkKhaki",            { 0xBD, 0xB7, 0x6B } },
64
    { "DarkMagenta",          { 0x8B, 0x00, 0x8B } },
65
    { "DarkOliveGreen",       { 0x55, 0x6B, 0x2F } },
66
    { "Darkorange",           { 0xFF, 0x8C, 0x00 } },
67
    { "DarkOrchid",           { 0x99, 0x32, 0xCC } },
68
    { "DarkRed",              { 0x8B, 0x00, 0x00 } },
69
    { "DarkSalmon",           { 0xE9, 0x96, 0x7A } },
70
    { "DarkSeaGreen",         { 0x8F, 0xBC, 0x8F } },
71
    { "DarkSlateBlue",        { 0x48, 0x3D, 0x8B } },
72
    { "DarkSlateGray",        { 0x2F, 0x4F, 0x4F } },
73
    { "DarkTurquoise",        { 0x00, 0xCE, 0xD1 } },
74
    { "DarkViolet",           { 0x94, 0x00, 0xD3 } },
75
    { "DeepPink",             { 0xFF, 0x14, 0x93 } },
76
    { "DeepSkyBlue",          { 0x00, 0xBF, 0xFF } },
77
    { "DimGray",              { 0x69, 0x69, 0x69 } },
78
    { "DodgerBlue",           { 0x1E, 0x90, 0xFF } },
79
    { "FireBrick",            { 0xB2, 0x22, 0x22 } },
80
    { "FloralWhite",          { 0xFF, 0xFA, 0xF0 } },
81
    { "ForestGreen",          { 0x22, 0x8B, 0x22 } },
82
    { "Fuchsia",              { 0xFF, 0x00, 0xFF } },
83
    { "Gainsboro",            { 0xDC, 0xDC, 0xDC } },
84
    { "GhostWhite",           { 0xF8, 0xF8, 0xFF } },
85
    { "Gold",                 { 0xFF, 0xD7, 0x00 } },
86
    { "GoldenRod",            { 0xDA, 0xA5, 0x20 } },
87
    { "Gray",                 { 0x80, 0x80, 0x80 } },
88
    { "Green",                { 0x00, 0x80, 0x00 } },
89
    { "GreenYellow",          { 0xAD, 0xFF, 0x2F } },
90
    { "HoneyDew",             { 0xF0, 0xFF, 0xF0 } },
91
    { "HotPink",              { 0xFF, 0x69, 0xB4 } },
92
    { "IndianRed",            { 0xCD, 0x5C, 0x5C } },
93
    { "Indigo",               { 0x4B, 0x00, 0x82 } },
94
    { "Ivory",                { 0xFF, 0xFF, 0xF0 } },
95
    { "Khaki",                { 0xF0, 0xE6, 0x8C } },
96
    { "Lavender",             { 0xE6, 0xE6, 0xFA } },
97
    { "LavenderBlush",        { 0xFF, 0xF0, 0xF5 } },
98
    { "LawnGreen",            { 0x7C, 0xFC, 0x00 } },
99
    { "LemonChiffon",         { 0xFF, 0xFA, 0xCD } },
100
    { "LightBlue",            { 0xAD, 0xD8, 0xE6 } },
101
    { "LightCoral",           { 0xF0, 0x80, 0x80 } },
102
    { "LightCyan",            { 0xE0, 0xFF, 0xFF } },
103
    { "LightGoldenRodYellow", { 0xFA, 0xFA, 0xD2 } },
104
    { "LightGrey",            { 0xD3, 0xD3, 0xD3 } },
105
    { "LightGreen",           { 0x90, 0xEE, 0x90 } },
106
    { "LightPink",            { 0xFF, 0xB6, 0xC1 } },
107
    { "LightSalmon",          { 0xFF, 0xA0, 0x7A } },
108
    { "LightSeaGreen",        { 0x20, 0xB2, 0xAA } },
109
    { "LightSkyBlue",         { 0x87, 0xCE, 0xFA } },
110
    { "LightSlateGray",       { 0x77, 0x88, 0x99 } },
111
    { "LightSteelBlue",       { 0xB0, 0xC4, 0xDE } },
112
    { "LightYellow",          { 0xFF, 0xFF, 0xE0 } },
113
    { "Lime",                 { 0x00, 0xFF, 0x00 } },
114
    { "LimeGreen",            { 0x32, 0xCD, 0x32 } },
115
    { "Linen",                { 0xFA, 0xF0, 0xE6 } },
116
    { "Magenta",              { 0xFF, 0x00, 0xFF } },
117
    { "Maroon",               { 0x80, 0x00, 0x00 } },
118
    { "MediumAquaMarine",     { 0x66, 0xCD, 0xAA } },
119
    { "MediumBlue",           { 0x00, 0x00, 0xCD } },
120
    { "MediumOrchid",         { 0xBA, 0x55, 0xD3 } },
121
    { "MediumPurple",         { 0x93, 0x70, 0xD8 } },
122
    { "MediumSeaGreen",       { 0x3C, 0xB3, 0x71 } },
123
    { "MediumSlateBlue",      { 0x7B, 0x68, 0xEE } },
124
    { "MediumSpringGreen",    { 0x00, 0xFA, 0x9A } },
125
    { "MediumTurquoise",      { 0x48, 0xD1, 0xCC } },
126
    { "MediumVioletRed",      { 0xC7, 0x15, 0x85 } },
127
    { "MidnightBlue",         { 0x19, 0x19, 0x70 } },
128
    { "MintCream",            { 0xF5, 0xFF, 0xFA } },
129
    { "MistyRose",            { 0xFF, 0xE4, 0xE1 } },
130
    { "Moccasin",             { 0xFF, 0xE4, 0xB5 } },
131
    { "NavajoWhite",          { 0xFF, 0xDE, 0xAD } },
132
    { "Navy",                 { 0x00, 0x00, 0x80 } },
133
    { "OldLace",              { 0xFD, 0xF5, 0xE6 } },
134
    { "Olive",                { 0x80, 0x80, 0x00 } },
135
    { "OliveDrab",            { 0x6B, 0x8E, 0x23 } },
136
    { "Orange",               { 0xFF, 0xA5, 0x00 } },
137
    { "OrangeRed",            { 0xFF, 0x45, 0x00 } },
138
    { "Orchid",               { 0xDA, 0x70, 0xD6 } },
139
    { "PaleGoldenRod",        { 0xEE, 0xE8, 0xAA } },
140
    { "PaleGreen",            { 0x98, 0xFB, 0x98 } },
141
    { "PaleTurquoise",        { 0xAF, 0xEE, 0xEE } },
142
    { "PaleVioletRed",        { 0xD8, 0x70, 0x93 } },
143
    { "PapayaWhip",           { 0xFF, 0xEF, 0xD5 } },
144
    { "PeachPuff",            { 0xFF, 0xDA, 0xB9 } },
145
    { "Peru",                 { 0xCD, 0x85, 0x3F } },
146
    { "Pink",                 { 0xFF, 0xC0, 0xCB } },
147
    { "Plum",                 { 0xDD, 0xA0, 0xDD } },
148
    { "PowderBlue",           { 0xB0, 0xE0, 0xE6 } },
149
    { "Purple",               { 0x80, 0x00, 0x80 } },
150
    { "Red",                  { 0xFF, 0x00, 0x00 } },
151
    { "RosyBrown",            { 0xBC, 0x8F, 0x8F } },
152
    { "RoyalBlue",            { 0x41, 0x69, 0xE1 } },
153
    { "SaddleBrown",          { 0x8B, 0x45, 0x13 } },
154
    { "Salmon",               { 0xFA, 0x80, 0x72 } },
155
    { "SandyBrown",           { 0xF4, 0xA4, 0x60 } },
156
    { "SeaGreen",             { 0x2E, 0x8B, 0x57 } },
157
    { "SeaShell",             { 0xFF, 0xF5, 0xEE } },
158
    { "Sienna",               { 0xA0, 0x52, 0x2D } },
159
    { "Silver",               { 0xC0, 0xC0, 0xC0 } },
160
    { "SkyBlue",              { 0x87, 0xCE, 0xEB } },
161
    { "SlateBlue",            { 0x6A, 0x5A, 0xCD } },
162
    { "SlateGray",            { 0x70, 0x80, 0x90 } },
163
    { "Snow",                 { 0xFF, 0xFA, 0xFA } },
164
    { "SpringGreen",          { 0x00, 0xFF, 0x7F } },
165
    { "SteelBlue",            { 0x46, 0x82, 0xB4 } },
166
    { "Tan",                  { 0xD2, 0xB4, 0x8C } },
167
    { "Teal",                 { 0x00, 0x80, 0x80 } },
168
    { "Thistle",              { 0xD8, 0xBF, 0xD8 } },
169
    { "Tomato",               { 0xFF, 0x63, 0x47 } },
170
    { "Turquoise",            { 0x40, 0xE0, 0xD0 } },
171
    { "Violet",               { 0xEE, 0x82, 0xEE } },
172
    { "Wheat",                { 0xF5, 0xDE, 0xB3 } },
173
    { "White",                { 0xFF, 0xFF, 0xFF } },
174
    { "WhiteSmoke",           { 0xF5, 0xF5, 0xF5 } },
175
    { "Yellow",               { 0xFF, 0xFF, 0x00 } },
176
    { "YellowGreen",          { 0x9A, 0xCD, 0x32 } },
177
};
178
179
static int color_table_compare(const void *lhs, const void *rhs)
180
{
181 b69b622c Stefano Sabatini
    return strcasecmp(lhs, ((const ColorEntry *)rhs)->name);
182 a3015225 Stefano Sabatini
}
183
184 a52e2c3a Stefano Sabatini
#define ALPHA_SEP '@'
185
186 a3015225 Stefano Sabatini
int av_parse_color(uint8_t *rgba_color, const char *color_string, void *log_ctx)
187
{
188 a52e2c3a Stefano Sabatini
    char *tail, color_string2[128];
189
    const ColorEntry *entry;
190
    av_strlcpy(color_string2, color_string, sizeof(color_string2));
191
    if ((tail = strchr(color_string2, ALPHA_SEP)))
192
        *tail++ = 0;
193
    rgba_color[3] = 255;
194
195
    if (!strcasecmp(color_string2, "random") || !strcasecmp(color_string2, "bikeshed")) {
196 576fb48e Martin Storsjö
        int rgba = av_get_random_seed();
197 4fa61d1e Ramiro Polla
        rgba_color[0] = rgba >> 24;
198
        rgba_color[1] = rgba >> 16;
199
        rgba_color[2] = rgba >> 8;
200
        rgba_color[3] = rgba;
201 9e74966b Stefano Sabatini
    } else if (!strncmp(color_string2, "0x", 2)) {
202 a3015225 Stefano Sabatini
        char *tail;
203 a52e2c3a Stefano Sabatini
        int len = strlen(color_string2);
204
        unsigned int rgba = strtoul(color_string2, &tail, 16);
205 a3015225 Stefano Sabatini
206
        if (*tail || (len != 8 && len != 10)) {
207 a52e2c3a Stefano Sabatini
            av_log(log_ctx, AV_LOG_ERROR, "Invalid 0xRRGGBB[AA] color string: '%s'\n", color_string2);
208 dc0eaef3 Stefano Sabatini
            return AVERROR(EINVAL);
209 a3015225 Stefano Sabatini
        }
210
        if (len == 10) {
211
            rgba_color[3] = rgba;
212
            rgba >>= 8;
213
        }
214
        rgba_color[0] = rgba >> 16;
215
        rgba_color[1] = rgba >> 8;
216
        rgba_color[2] = rgba;
217
    } else {
218 a52e2c3a Stefano Sabatini
        entry = bsearch(color_string2,
219 4cf0b43a Stefano Sabatini
                        color_table,
220
                        FF_ARRAY_ELEMS(color_table),
221
                        sizeof(ColorEntry),
222
                        color_table_compare);
223 a3015225 Stefano Sabatini
        if (!entry) {
224 a52e2c3a Stefano Sabatini
            av_log(log_ctx, AV_LOG_ERROR, "Cannot find color '%s'\n", color_string2);
225 dc0eaef3 Stefano Sabatini
            return AVERROR(EINVAL);
226 a3015225 Stefano Sabatini
        }
227 8e094dd6 Stefano Sabatini
        memcpy(rgba_color, entry->rgb_color, 3);
228 a3015225 Stefano Sabatini
    }
229
230 a52e2c3a Stefano Sabatini
    if (tail) {
231
        unsigned long int alpha;
232
        const char *alpha_string = tail;
233
        if (!strncmp(alpha_string, "0x", 2)) {
234
            alpha = strtoul(alpha_string, &tail, 16);
235
        } else {
236
            alpha = strtoul(alpha_string, &tail, 10);
237
            if (*tail) {
238
                double d = strtod(alpha_string, &tail);
239
                alpha = d * 255;
240
            }
241
        }
242
243
        if (tail == alpha_string || *tail || alpha > 255) {
244
            av_log(log_ctx, AV_LOG_ERROR, "Invalid alpha value specifier '%s' in '%s'\n",
245
                   alpha_string, color_string);
246
            return AVERROR(EINVAL);
247
        }
248
        rgba_color[3] = alpha;
249
    }
250
251 a3015225 Stefano Sabatini
    return 0;
252
}
253
254 d11dbf09 Michael Niedermayer
#ifdef TEST
255
256
#undef printf
257
258 2e032b32 Stefano Sabatini
int main(void)
259 d11dbf09 Michael Niedermayer
{
260
    int i;
261
262 a3015225 Stefano Sabatini
    printf("\nTesting av_parse_color()\n");
263
    {
264
        uint8_t rgba[4];
265
        const char *color_names[] = {
266 4fa61d1e Ramiro Polla
            "bikeshed",
267 3d3bd64d Stefano Sabatini
            "RaNdOm",
268 a3015225 Stefano Sabatini
            "foo",
269
            "red",
270
            "Red ",
271
            "RED",
272
            "Violet",
273
            "Yellow",
274
            "Red",
275
            "0x000000",
276
            "0x0000000",
277 7d132c54 Stefano Sabatini
            "0xff000000",
278 a3015225 Stefano Sabatini
            "0x3e34ff",
279
            "0x3e34ffaa",
280
            "0xffXXee",
281
            "0xfoobar",
282
            "0xffffeeeeeeee",
283 a52e2c3a Stefano Sabatini
            "red@foo",
284
            "random@10",
285
            "0xff0000@1.0",
286
            "red@",
287
            "red@0xfff",
288
            "red@0xf",
289
            "red@2",
290
            "red@0.1",
291
            "red@-1",
292
            "red@0.5",
293
            "red@1.0",
294
            "red@256",
295
            "red@10foo",
296
            "red@-1.0",
297
            "red@-0.0",
298 a3015225 Stefano Sabatini
        };
299
300
        av_log_set_level(AV_LOG_DEBUG);
301
302
        for (int i = 0;  i < FF_ARRAY_ELEMS(color_names); i++) {
303
            if (av_parse_color(rgba, color_names[i], NULL) >= 0)
304
                printf("%s -> R(%d) G(%d) B(%d) A(%d)\n", color_names[i], rgba[0], rgba[1], rgba[2], rgba[3]);
305
        }
306
    }
307
308 d11dbf09 Michael Niedermayer
    return 0;
309
}
310
311
#endif