Statistics
| Branch: | Revision:

ffmpeg / libavfilter / parseutils.c @ d370e3e9

History | View | Annotate | Download (12.2 KB)

1
/*
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
 * @file
22
 * parsing utils
23
 */
24

    
25
#include <strings.h>
26
#include "libavutil/avutil.h"
27
#include "libavutil/avstring.h"
28
#include "libavutil/random_seed.h"
29
#include "parseutils.h"
30

    
31
typedef struct {
32
    const char *name;            ///< a string representing the name of the color
33
    uint8_t     rgb_color[3];    ///< RGB values for the color
34
} 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
    return strcasecmp(lhs, ((const ColorEntry *)rhs)->name);
182
}
183

    
184
#define ALPHA_SEP '@'
185

    
186
int av_parse_color(uint8_t *rgba_color, const char *color_string, void *log_ctx)
187
{
188
    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
        int rgba = av_get_random_seed();
197
        rgba_color[0] = rgba >> 24;
198
        rgba_color[1] = rgba >> 16;
199
        rgba_color[2] = rgba >> 8;
200
        rgba_color[3] = rgba;
201
    } else if (!strncmp(color_string2, "0x", 2)) {
202
        char *tail;
203
        int len = strlen(color_string2);
204
        unsigned int rgba = strtoul(color_string2, &tail, 16);
205

    
206
        if (*tail || (len != 8 && len != 10)) {
207
            av_log(log_ctx, AV_LOG_ERROR, "Invalid 0xRRGGBB[AA] color string: '%s'\n", color_string2);
208
            return AVERROR(EINVAL);
209
        }
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
        entry = bsearch(color_string2,
219
                        color_table,
220
                        FF_ARRAY_ELEMS(color_table),
221
                        sizeof(ColorEntry),
222
                        color_table_compare);
223
        if (!entry) {
224
            av_log(log_ctx, AV_LOG_ERROR, "Cannot find color '%s'\n", color_string2);
225
            return AVERROR(EINVAL);
226
        }
227
        memcpy(rgba_color, entry->rgb_color, 3);
228
    }
229

    
230
    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
    return 0;
252
}
253

    
254
#ifdef TEST
255

    
256
#undef printf
257

    
258
int main(void)
259
{
260
    int i;
261

    
262
    printf("\nTesting av_parse_color()\n");
263
    {
264
        uint8_t rgba[4];
265
        const char *color_names[] = {
266
            "bikeshed",
267
            "RaNdOm",
268
            "foo",
269
            "red",
270
            "Red ",
271
            "RED",
272
            "Violet",
273
            "Yellow",
274
            "Red",
275
            "0x000000",
276
            "0x0000000",
277
            "0xff000000",
278
            "0x3e34ff",
279
            "0x3e34ffaa",
280
            "0xffXXee",
281
            "0xfoobar",
282
            "0xffffeeeeeeee",
283
            "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
        };
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
    return 0;
309
}
310

    
311
#endif