io-xpm.c (xpm_extract_color): Rewritten to handle

xpm colormap entries more thoroughly. (#59939)
This commit is contained in:
Matthias Clasen 2001-09-21 21:39:42 +00:00
parent 293d787783
commit f3a65f61a9
2 changed files with 73 additions and 64 deletions

View File

@ -1,3 +1,8 @@
2001-09-21 Matthias Clasen <matthiasc@poet.de>
* io-xpm.c (xpm_extract_color): Rewritten to handle
xpm colormap entries more thoroughly. (#59939)
2001-09-21 Hans Breuer <hans@breuer.org>
* gdk-pixbuf.def : updated externals

View File

@ -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;
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;
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;
else {
if (numnames > 0) {
space -= 1;
strcat (color, " ");
}
strncat (color, temp, space);
space -= MIN (space, strlen (temp));
ptr = xpm_skip_string (ptr);
ptr = xpm_skip_whitespaces (ptr);
numnames++;
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 (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, 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 */