summaryrefslogtreecommitdiff
path: root/gdk-pixbuf/io-xpm.c
diff options
context:
space:
mode:
authorMatthias Clasen <matthiasc@src.gnome.org>2001-09-21 21:39:42 +0000
committerMatthias Clasen <matthiasc@src.gnome.org>2001-09-21 21:39:42 +0000
commit9a9c682ac7590e2264a6c1ba9f190cdff7a4d5c9 (patch)
tree41e819aff53b2f809977222ee4c6becf94df0bf7 /gdk-pixbuf/io-xpm.c
parent01b8a81e30c045a5fdeb1072efa1cb06445607ba (diff)
downloadgdk-pixbuf-9a9c682ac7590e2264a6c1ba9f190cdff7a4d5c9.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.c128
1 files changed, 66 insertions, 62 deletions
diff --git a/gdk-pixbuf/io-xpm.c b/gdk-pixbuf/io-xpm.c
index 9784b68d0..2505ddba1 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 */