diff options
author | Matthias Clasen <matthiasc@src.gnome.org> | 2001-09-21 21:39:42 +0000 |
---|---|---|
committer | Matthias Clasen <matthiasc@src.gnome.org> | 2001-09-21 21:39:42 +0000 |
commit | f3a65f61a93e5eb72368afbaca1912b9c7f88dda (patch) | |
tree | a0536479c377ffb9a8baa4f32b9d7c895c59884a /gdk-pixbuf/io-xpm.c | |
parent | 293d78778377b034b9806d79cc060193fd890ee4 (diff) | |
download | gtk+-f3a65f61a93e5eb72368afbaca1912b9c7f88dda.tar.gz |
io-xpm.c (xpm_extract_color): Rewritten to handle
xpm colormap entries more thoroughly. (#59939)
Diffstat (limited to 'gdk-pixbuf/io-xpm.c')
-rw-r--r-- | gdk-pixbuf/io-xpm.c | 128 |
1 files changed, 66 insertions, 62 deletions
diff --git a/gdk-pixbuf/io-xpm.c b/gdk-pixbuf/io-xpm.c index 9784b68d01..2505ddba17 100644 --- a/gdk-pixbuf/io-xpm.c +++ b/gdk-pixbuf/io-xpm.c @@ -943,14 +943,14 @@ parse_color (const char *spec, char fmt[16]; int i, red, green, blue; - if ((i = strlen(spec+1))%3) { + if ((i = strlen (spec + 1)) % 3) { return FALSE; } i /= 3; g_snprintf (fmt, 16, "%%%dx%%%dx%%%dx", i, i, i); - if (sscanf(spec+1, fmt, &red, &green, &blue) != 3) { + if (sscanf (spec + 1, fmt, &red, &green, &blue) != 3) { return FALSE; } if (i == 4) { @@ -1092,74 +1092,78 @@ xpm_skip_string (const gchar *buffer) return &buffer[index]; } -/* Xlib crashed once at a color name lengths around 125 */ -#define MAX_COLOR_LEN 120 - static gchar * xpm_extract_color (const gchar *buffer) { - gint counter, numnames; - const gchar *ptr = NULL; - gchar ch, temp[128]; - gchar color[MAX_COLOR_LEN], *retcol; - gint space; - - counter = 0; - while (ptr == NULL) { - if ((buffer[counter] == 'c') || (buffer[counter] == 'g')) { - ch = buffer[counter + 1]; - if (ch == 0x20 || ch == 0x09) - ptr = &buffer[counter + 1]; - } else if (buffer[counter] == 0) - return NULL; - - counter++; - } - ptr = xpm_skip_whitespaces (ptr); - - if (ptr[0] == 0) - return NULL; - else if (ptr[0] == '#') { - counter = 1; - while (ptr[counter] != 0 && - ((ptr[counter] >= '0' && ptr[counter] <= '9') || - (ptr[counter] >= 'a' && ptr[counter] <= 'f') || - (ptr[counter] >= 'A' && ptr[counter] <= 'F'))) - counter++; - retcol = g_new (gchar, counter + 1); - strncpy (retcol, ptr, counter); - - retcol[counter] = 0; - - return retcol; - } - color[0] = 0; - numnames = 0; - - space = MAX_COLOR_LEN - 1; - while (space > 0) { - sscanf (ptr, "%127s", temp); - - if (((gint) ptr[0] == 0) || - (strcmp ("s", temp) == 0) || (strcmp ("m", temp) == 0) || - (strcmp ("g", temp) == 0) || (strcmp ("g4", temp) == 0)) - break; + gint new_key = 0; + gint key = 0; + gint current_key = 1; + gint space = 128; + gchar word[128], color[128], current_color[128]; + gchar *r, *p; + + p = &buffer[0]; + word[0] = '\0'; + color[0] = '\0'; + current_color[0] = '\0'; + while (1) { + /* skip whitespace */ + for (; *p != '\0' && g_ascii_isspace (*p); p++) { + } + /* copy word */ + for (r = word; *p != '\0' && !g_ascii_isspace (*p) && r - word < sizeof (word) - 1; p++, r++) { + *r = *p; + } + *r = '\0'; + if (*word == '\0') { + if (color[0] == '\0') /* incomplete colormap entry */ + return NULL; + else /* end of entry, still store the last color */ + new_key = 1; + } + else if (key > 0 && color[0] == '\0') /* next word must be a color name part */ + new_key = 0; else { - if (numnames > 0) { - space -= 1; + if (strcmp (word, "c") == 0) + new_key = 5; + else if (strcmp (word, "g") == 0) + new_key = 4; + else if (strcmp (word, "g4") == 0) + new_key = 3; + else if (strcmp (word, "m") == 0) + new_key = 2; + else if (strcmp (word, "s") == 0) + new_key = 1; + else + new_key = 0; + } + if (new_key == 0) { /* word is a color name part */ + if (key == 0) /* key expected */ + return NULL; + /* accumulate color name */ + if (color[0] != '\0') { strcat (color, " "); + space--; } - - strncat (color, temp, space); - space -= MIN (space, strlen (temp)); - ptr = xpm_skip_string (ptr); - ptr = xpm_skip_whitespaces (ptr); - numnames++; + strncat (color, word, space); + space -= MIN (space, strlen (word)); } + else { /* word is a key */ + if (key > current_key) { + current_key = key; + strcpy (current_color, color); + } + space = 128; + color[0] = '\0'; + key = new_key; + if (*p == '\0') break; + } + } - - retcol = g_strdup (color); - return retcol; + if (current_key > 1) + return g_strdup (current_color); + else + return NULL; } /* (almost) direct copy from gdkpixmap.c... loads an XPM from a file */ |