diff --git a/legacy/evas/src/modules/loaders/xpm/evas_image_load_xpm.c b/legacy/evas/src/modules/loaders/xpm/evas_image_load_xpm.c index 88b7dc1523..8646fade99 100644 --- a/legacy/evas/src/modules/loaders/xpm/evas_image_load_xpm.c +++ b/legacy/evas/src/modules/loaders/xpm/evas_image_load_xpm.c @@ -12,7 +12,7 @@ Evas_Image_Load_Func evas_image_load_xpm_func = }; -static FILE *rgb_txt = NULL; +static FILE *rgb_txt = NULL; static void xpm_parse_color(char *color, int *r, int *g, int *b) @@ -24,12 +24,12 @@ xpm_parse_color(char *color, int *r, int *g, int *b) { int len; char val[32]; - + len = strlen(color) - 1; if (len < 96) { int i; - + len /= 3; for (i = 0; i < len; i++) val[i] = color[1 + i + (0 * len)]; @@ -59,26 +59,29 @@ xpm_parse_color(char *color, int *r, int *g, int *b) return; } /* look in rgb txt database */ - if (!rgb_txt) - rgb_txt = fopen("/usr/X11/lib/X11/rgb.txt", "r"); - if (!rgb_txt) - return; + if (!rgb_txt) rgb_txt = fopen("/usr/lib/X11/rgb.txt", "r"); + if (!rgb_txt) rgb_txt = fopen("/usr/X11/lib/X11/rgb.txt", "r"); + if (!rgb_txt) rgb_txt = fopen("/usr/X11R6/lib/X11/rgb.txt", "r"); + if (!rgb_txt) return; fseek(rgb_txt, 0, SEEK_SET); - while (fgets(buf, 4000, rgb_txt)) + while (fgets(buf, sizeof(buf), rgb_txt)) { + buf[sizeof(buf) - 1] = 0; if (buf[0] != '!') { - int rr, gg, bb; - char name[4096]; - - sscanf(buf, "%i %i %i %[^\n]", &rr, &gg, &bb, name); - if (!strcasecmp(name, color)) - { - *r = rr; - *g = gg; - *b = bb; - return; - } + int rr, gg, bb; + char name[4096]; + + if (sscanf(buf, "%i %i %i %[^\n]", &rr, &gg, &bb, name) == 4) + { + if (!strcasecmp(name, color)) + { + *r = rr; + *g = gg; + *b = bb; + return; + } + } } } } @@ -86,8 +89,7 @@ xpm_parse_color(char *color, int *r, int *g, int *b) static void xpm_parse_done(void) { - if (rgb_txt) - fclose(rgb_txt); + if (rgb_txt) fclose(rgb_txt); rgb_txt = NULL; } @@ -100,23 +102,22 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int FILE *f; int pc, c, i, j, k, w, h, ncolors, cpp, comment, transp, - quote, context, len, done, r, g, b, backslash; - char *line, s[256], tok[128], col[256]; + quote, context, len, done, r, g, b, backslash, lu1, lu2; + char *line, s[256], tok[128], col[256], *tl; int lsz = 256; struct _cmap { - unsigned char str[6]; - unsigned char transp; - short r, g, b; + unsigned char str[6]; + unsigned char transp; + short r, g, b; } *cmap; short lookup[128 - 32][128 - 32]; - float per = 0.0, per_inc = 0.0; int count, pixels; if (!file) return 0; done = 0; // transp = -1; - transp = 0; + transp = 1; /* if immediate_load is 1, then dont delay image laoding as below, or */ /* already data in this image - dont load it again */ @@ -136,7 +137,7 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int xpm_parse_done(); return 0; } - + i = 0; j = 0; cmap = NULL; @@ -164,14 +165,13 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int { pc = c; c = fgetc(f); - if (c == EOF) - break; + if (c == EOF) break; if (!quote) { if ((pc == '/') && (c == '*')) - comment = 1; + comment = 1; else if ((pc == '*') && (c == '/') && (comment)) - comment = 0; + comment = 0; } if (!comment) { @@ -187,7 +187,15 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int if (context == 0) { /* Header */ - sscanf(line, "%i %i %i %i", &w, &h, &ncolors, &cpp); + if (sscanf(line, "%i %i %i %i", &w, &h, &ncolors, &cpp) != 4) + { + fprintf(stderr, + "XPM ERROR: XPM file malformed header\n"); + free(line); + fclose(f); + xpm_parse_done(); + return 0; + } if ((ncolors > 32766) || (ncolors < 1)) { fprintf(stderr, @@ -241,18 +249,16 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int im->image = evas_common_image_surface_new(im); if (!im->image) { - free(cmap); - free(line); - fclose(f); - xpm_parse_done(); - return 0; + free(cmap); + free(line); + fclose(f); + xpm_parse_done(); + return 0; } } im->image->w = w; im->image->h = h; - per_inc = 100.0 / (((float)w) * h); - j = 0; context++; } @@ -272,6 +278,11 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int len = strlen(line); strncpy(cmap[j].str, line, cpp); cmap[j].str[cpp] = 0; + for (slen = 0; slen < cpp; slen++) + { + /* fix the ascii of the color string - if its < 32 - just limit to 32 */ + if (cmap[j].str[slen] < 32) cmap[j].str[slen] = 0; + } cmap[j].r = -1; cmap[j].transp = 0; for (k = cpp; k < len; k++) @@ -279,28 +290,25 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int if (line[k] != ' ') { s[0] = 0; - sscanf(&line[k], "%65535s", s); + sscanf(&line[k], "%255s", s); slen = strlen(s); k += slen; - if (!strcmp(s, "c")) - iscolor = 1; + if (!strcmp(s, "c")) iscolor = 1; if ((!strcmp(s, "m")) || (!strcmp(s, "s")) - || (!strcmp(s, "g4")) - || (!strcmp(s, "g")) + || (!strcmp(s, "g4")) || (!strcmp(s, "g")) || (!strcmp(s, "c")) || (k >= len)) { if (k >= len) { if (col[0]) { - if (strlen(col) < ( sizeof(col) - 2)) + if (strlen(col) < (sizeof(col) - 2)) strcat(col, " "); else done = 1; } - if (strlen(col) + strlen(s) < - (sizeof(col) - 1)) - strcat(col, s); + if ((strlen(col) + strlen(s)) < (sizeof(col) - 1)) + strcat(col, s); } if (col[0]) { @@ -308,25 +316,20 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int { transp = 1; cmap[j].transp = 1; + cmap[j].r = 0; + cmap[j].g = 0; + cmap[j].b = 0; } else { - if ((((cmap[j].r < 0) || - (!strcmp(tok, "c"))) - && (!hascolor))) + if ((((cmap[j].r < 0) || (!strcmp(tok, "c"))) && (!hascolor))) { - r = 0; - g = 0; - b = 0; - xpm_parse_color(col, - &r, - &g, - &b); + r = g = b = 0; + xpm_parse_color(col, &r, &g, &b); cmap[j].r = r; cmap[j].g = g; cmap[j].b = b; - if (iscolor) - hascolor = 1; + if (iscolor) hascolor = 1; } } } @@ -342,8 +345,7 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int else done = 1; } - if (strlen(col) + strlen(s) < - (sizeof(col) - 1)) + if ((strlen(col) + strlen(s)) < (sizeof(col) - 1)) strcat(col, s); } } @@ -353,19 +355,24 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int if (j >= ncolors) { if (cpp == 1) - for (i = 0; i < ncolors; i++) - lookup[(int)cmap[i].str[0] - 32][0] = i; + { + for (i = 0; i < ncolors; i++) + lookup[(int)cmap[i].str[0] - 32][0] = i; + } if (cpp == 2) - for (i = 0; i < ncolors; i++) - lookup[(int)cmap[i].str[0] - - 32][(int)cmap[i].str[1] - 32] = i; + { + for (i = 0; i < ncolors; i++) + lookup[(int)cmap[i].str[0] - 32][(int)cmap[i].str[1] - 32] = i; + } context++; } -// if (transp >= 0) - im->flags |= RGBA_IMAGE_HAS_ALPHA; + if (transp) im->flags |= RGBA_IMAGE_HAS_ALPHA; + if (load_data) { + im->image->w = w; + im->image->h = h; evas_common_image_surface_alloc(im->image); if (!im->image->data) { @@ -397,7 +404,9 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int { /* Chars per pixel = 0? well u never know */ } - if (cpp == 1) + /* it's xpm - don't care about speed too much. still faster + * that most xpm loaders anyway */ + else if (cpp == 1) { if (transp) { @@ -405,39 +414,24 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int ((i < 65536) && (ptr < end) && (line[i])); i++) { - col[0] = line[i]; - if (cmap[lookup[(int)col[0] - 32][0]]. - transp) + lu1 = (int)line[i] - 32; + if (lu1 < 0) continue; + if (cmap[lookup[lu1][0]].transp) { - r = (unsigned char) - cmap[lookup[(int)col[0] - 32] - [0]].r; - g = (unsigned char) - cmap[lookup[(int)col[0] - 32] - [0]].g; - b = (unsigned char) - cmap[lookup[(int)col[0] - 32] - [0]].b; - *ptr++ = - 0x00ffffff & ((r << 16) | - (g << 8) | b); + r = (unsigned char)cmap[lookup[lu1][0]].r; + g = (unsigned char)cmap[lookup[lu1][0]].g; + b = (unsigned char)cmap[lookup[lu1][0]].b; + *ptr = (r << 16) | (g << 8) | b; + ptr++; count++; } else { - r = (unsigned char) - cmap[lookup[(int)col[0] - 32] - [0]].r; - g = (unsigned char) - cmap[lookup[(int)col[0] - 32] - [0]].g; - b = (unsigned char) - cmap[lookup[(int)col[0] - 32] - [0]].b; - *ptr++ = - (0xff << 24) | (r << 16) | (g << - 8) | - b; + r = (unsigned char)cmap[lookup[lu1][0]].r; + g = (unsigned char)cmap[lookup[lu1][0]].g; + b = (unsigned char)cmap[lookup[lu1][0]].b; + *ptr = (0xff << 24) | (r << 16) | (g << 8) | b; + ptr++; count++; } } @@ -448,17 +442,14 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int ((i < 65536) && (ptr < end) && (line[i])); i++) { - col[0] = line[i]; - r = (unsigned char) - cmap[lookup[(int)col[0] - 32][0]].r; - g = (unsigned char) - cmap[lookup[(int)col[0] - 32][0]].g; - b = (unsigned char) - cmap[lookup[(int)col[0] - 32][0]].b; - *ptr++ = - (0xff << 24) | (r << 16) | (g << 8) | - b; - count++; + lu1 = (int)line[i] - 32; + if (lu1 < 0) continue; + r = (unsigned char)cmap[lookup[lu1][0]].r; + g = (unsigned char)cmap[lookup[lu1][0]].g; + b = (unsigned char)cmap[lookup[lu1][0]].b; + *ptr = (0xff << 24) | (r << 16) | (g << 8) | b; + ptr++; + count++; } } } @@ -470,41 +461,27 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int ((i < 65536) && (ptr < end) && (line[i])); i++) { - col[0] = line[i++]; - col[1] = line[i]; - if (cmap - [lookup[(int)col[0] - 32] - [(int)col[1] - 32]].transp) + lu1 = (int)line[i] - 32; + i++; + lu2 = (int)line[i] - 32; + if (lu1 < 0) continue; + if (lu2 < 0) continue; + if (cmap[lookup[lu1][lu2]].transp) { - r = (unsigned char) - cmap[lookup[(int)col[0] - 32] - [(int)col[1] - 32]].r; - g = (unsigned char) - cmap[lookup[(int)col[0] - 32] - [(int)col[1] - 32]].g; - b = (unsigned char) - cmap[lookup[(int)col[0] - 32] - [(int)col[1] - 32]].b; - *ptr++ = - 0x00ffffff & ((r << 16) | - (g << 8) | b); + r = (unsigned char)cmap[lookup[lu1][lu2]].r; + g = (unsigned char)cmap[lookup[lu1][lu2]].g; + b = (unsigned char)cmap[lookup[lu1][lu2]].b; + *ptr = (r << 16) | (g << 8) | b; + ptr++; count++; } else { - r = (unsigned char) - cmap[lookup[(int)col[0] - 32] - [(int)col[1] - 32]].r; - g = (unsigned char) - cmap[lookup[(int)col[0] - 32] - [(int)col[1] - 32]].g; - b = (unsigned char) - cmap[lookup[(int)col[0] - 32] - [(int)col[1] - 32]].b; - *ptr++ = - (0xff << 24) | (r << 16) | (g << - 8) | - b; + r = (unsigned char)cmap[lookup[lu1][lu2]].r; + g = (unsigned char)cmap[lookup[lu1][lu2]].g; + b = (unsigned char)cmap[lookup[lu1][lu2]].b; + *ptr = (0xff << 24) | (r << 16) | (g << 8) | b; + ptr++; count++; } } @@ -515,21 +492,17 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int ((i < 65536) && (ptr < end) && (line[i])); i++) { - col[0] = line[i++]; - col[1] = line[i]; - r = (unsigned char) - cmap[lookup[(int)col[0] - 32] - [(int)col[1] - 32]].r; - g = (unsigned char) - cmap[lookup[(int)col[0] - 32] - [(int)col[1] - 32]].g; - b = (unsigned char) - cmap[lookup[(int)col[0] - 32] - [(int)col[1] - 32]].b; - *ptr++ = - (0xff << 24) | (r << 16) | (g << 8) | - b; - count++; + lu1 = (int)line[i] - 32; + i++; + lu2 = (int)line[i] - 32; + if (lu1 < 0) continue; + if (lu2 < 0) continue; + r = (unsigned char)cmap[lookup[lu1][lu2]].r; + g = (unsigned char)cmap[lookup[lu1][lu2]].g; + b = (unsigned char)cmap[lookup[lu1][lu2]].b; + *ptr = (0xff << 24) |ky (r << 16) | (g << 8) | b; + ptr++; + count++; } } } @@ -542,9 +515,10 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int i++) { for (j = 0; j < cpp; j++, i++) - { - col[j] = line[i]; - } + { + col[j] = line[i]; + if (col[j] < 32) col[j] = 32; + } col[j] = 0; i--; for (j = 0; j < ncolors; j++) @@ -553,40 +527,23 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int { if (cmap[j].transp) { - r = (unsigned char) - cmap[lookup - [(int)col[0] - - 32][0]].r; - g = (unsigned char) - cmap[lookup - [(int)col[0] - - 32][0]].g; - b = (unsigned char) - cmap[lookup - [(int)col[0] - - 32][0]].b; - *ptr++ = - 0x00ffffff & ((r << 16) - | (g << - 8) | - b); + r = (unsigned char)cmap[j].r; + g = (unsigned char)cmap[j].g; + b = (unsigned char)cmap[j].b; + *ptr = (r << 16) | (g << 8) | b; + ptr++; count++; } else { - r = (unsigned char)cmap[j]. - r; - g = (unsigned char)cmap[j]. - g; - b = (unsigned char)cmap[j]. - b; - *ptr++ = - (0xff << 24) | (r << - 16) | - (g << 8) | b; + r = (unsigned char)cmap[j].r; + g = (unsigned char)cmap[j].g; + b = (unsigned char)cmap[j].b; + *ptr = (0xff << 24) |ky (r << 16) | (g << 8) | b; + ptr++; count++; } - j = ncolors; + break; } } } @@ -610,58 +567,51 @@ evas_image_load_file_xpm(RGBA_Image *im, const char *file, const char *key, int r = (unsigned char)cmap[j].r; g = (unsigned char)cmap[j].g; b = (unsigned char)cmap[j].b; - *ptr++ = - (0xff << 24) | (r << 16) | - (g << 8) | b; - count++; - j = ncolors; + *ptr = (0xff << 24) |ky (r << 16) | (g << 8) | b; + ptr++; + count++; + break; } } } } } - per += per_inc; } } } /* Scan in line from XPM file */ if ((!comment) && (quote) && (c != '"')) { - if (c < 32) - c = 32; - else if (c > 127) - c = 127; - if ( c=='\\' ) { - if ( ++backslash<2 ) { - line[i++] = c; + if (c < 32) c = 32; + else if (c > 127) c = 127; + if (c =='\\') + { + if (++backslash < 2) + line[i++] = c; + else + backslash = 0; } - else { - backslash = 0; + else + { + backslash = 0; + line[i++] = c; } - } - else { - backslash = 0; - line[i++] = c; - } } if (i >= lsz) { lsz += 256; - line = realloc(line, lsz); - if (!line) - { - free(cmap); - fclose(f); - } + tl = realloc(line, lsz); + if (!tl) break; + line = tl; } if (((ptr) && ((ptr - im->image->data) >= (w * h * sizeof(DATA32)))) || ((context > 1) && (count >= pixels))) - done = 1; + break; } - free(cmap); - free(line); - fclose(f); + if (cmap) free(cmap); + if (line) free(line); + if (f) fclose(f); xpm_parse_done();