/* * Read a rgb text file. It stores the rgb values (0->65535) * and the rgb mnemonics (malloc'ed) into the "rgbn" array. Returns the * number of entries stored. */ int xpmReadRgbNames(char *rgb_fname, xpmRgbName rgbn[]) { FILE *rgbf; int i, items, red, green, blue; char line[512], name[512], *rgbname, *n, *m; xpmRgbName *rgb; /* Open the rgb text file. Abort if error. */ if ((rgbf = fopen(rgb_fname, "r")) == NULL) return 0; /* Loop reading each line in the file. */ for (i = 0, rgb = rgbn; fgets(line, sizeof(line), rgbf); i++, rgb++) { /* Quit if rgb text file is too large. */ if (i == MAX_RGBNAMES) { /* Too many entries in rgb text file, give up here */ break; } /* Read the line. Skip silently if bad. */ items = sscanf(line, "%d %d %d %[^\n]\n", &red, &green, &blue, name); if (items != 4) { i--; continue; } /* * Make sure rgb values are within 0->255 range. Skip silently if * bad. */ if (red < 0 || red > 0xFF || green < 0 || green > 0xFF || blue < 0 || blue > 0xFF) { i--; continue; } /* Allocate memory for ascii name. If error give up here. */ if (!(rgbname = (char *) XpmMalloc(strlen(name) + 1))) break; /* Copy string to ascii name and lowercase it. */ for (n = name, m = rgbname; *n; n++) *m++ = tolower(*n); *m = '\0'; /* Save the rgb values and ascii name in the array. */ rgb->r = red * 257; /* 65535/255 = 257 */ rgb->g = green * 257; rgb->b = blue * 257; rgb->name = rgbname; } fclose(rgbf); /* Return the number of read rgb names. */ return i < 0 ? 0 : i; }
/* * Read a rgb text file. It stores the rgb values (0->65535) * and the rgb mnemonics (malloc'ed) into the "rgbn" array. Returns the * number of entries stored. */ int xpmReadRgbNames( char *rgb_fname, xpmRgbName rgbn[]) { FILE *rgbf; int n, items, red, green, blue; char line[512], name[512], *rgbname, *s1, *s2; xpmRgbName *rgb; /* Open the rgb text file. Abort if error. */ if ((rgbf = fopen(rgb_fname, "r")) == NULL) return 0; /* Loop reading each line in the file. */ n = 0; rgb = rgbn; /* Quit if rgb text file has too many entries. */ while (fgets(line, sizeof(line), rgbf) && n < MAX_RGBNAMES) { /* Skip silently if line is bad. */ items = sscanf(line, "%d %d %d %[^\n]\n", &red, &green, &blue, name); if (items != 4) continue; /* * Make sure rgb values are within 0->255 range. Skip silently if * bad. */ if (red < 0 || red > 0xFF || green < 0 || green > 0xFF || blue < 0 || blue > 0xFF) continue; /* Allocate memory for ascii name. If error give up here. */ if (!(rgbname = (char *) XpmMalloc(strlen(name) + 1))) break; /* Copy string to ascii name and lowercase it. */ for (s1 = name, s2 = rgbname; *s1; s1++) *s2++ = tolower(*s1); *s2 = '\0'; /* Save the rgb values and ascii name in the array. */ rgb->r = red * 257; /* 65535/255 = 257 */ rgb->g = green * 257; rgb->b = blue * 257; rgb->name = rgbname; rgb++; n++; } fclose(rgbf); /* Return the number of read rgb names. */ return n < 0 ? 0 : n; }
/* * in case strdup is not provided by the system here is one * which does the trick */ char * strdup(char *s1) { char *s2; int l = strlen(s1) + 1; if (s2 = (char *) XpmMalloc(l)) strncpy(s2, s1, l); return s2; }
/* * get the current comment line */ int xpmGetCmt(xpmData *mdata, char **cmt) { if (!mdata->type) *cmt = NULL; else if (mdata->CommentLength) { *cmt = (char *) XpmMalloc(mdata->CommentLength + 1); strncpy(*cmt, mdata->Comment, mdata->CommentLength); (*cmt)[mdata->CommentLength] = '\0'; mdata->CommentLength = 0; } else *cmt = NULL; return 0; }
/* * Create a colortable compatible with the old style colortable */ static int CreateOldColorTable(XpmColor *ct, int ncolors, XpmColor ***oldct) { XpmColor **colorTable, **color; int a; colorTable = (XpmColor **) XpmMalloc(ncolors * sizeof(XpmColor *)); if (!colorTable) { *oldct = NULL; return (XpmNoMemory); } for (a = 0, color = colorTable; a < ncolors; a++, color++, ct++) *color = ct; *oldct = colorTable; return (XpmSuccess); }
/* * get the current comment line */ int xpmGetCmt( xpmData *data, char **cmt) { if (!data->type) *cmt = NULL; else if (data->CommentLength != 0 && data->CommentLength < UINT_MAX - 1) { if( (*cmt = (char *) XpmMalloc(data->CommentLength + 1)) == NULL) return XpmNoMemory; strncpy(*cmt, data->Comment, data->CommentLength); (*cmt)[data->CommentLength] = '\0'; data->CommentLength = 0; } else *cmt = NULL; return 0; }
static int alloc_color(int index, int r, int g, int b, void *closure) { XpmImage *img = closure; XpmColor *c; if ( index < 0 || index >= (int)img->ncolors ) return GIF_INVALID; c = &img->colorTable[index]; if ( (c->c_color = XpmMalloc(8)) ) { sprintf(c->c_color, "#%02x%02x%02x", r, g, b); return GIF_OK; } return GIF_NOMEM; }
static int alloc_colortable(int ncolors, void *closure) { XpmImage *img = closure; if ( ncolors < 0 || ncolors > 256 ) return GIF_INVALID; img->ncolors = ncolors; img->colorTable = XpmMalloc(sizeof(XpmColor) * ncolors); if ( img->colorTable ) { memset(img->colorTable, 0, sizeof(XpmColor) * ncolors); return GIF_OK; } return GIF_NOMEM; }
static int WritePixels( FILE *file, unsigned int width, unsigned int height, unsigned int cpp, unsigned int *pixels, XpmColor *colors) { char *s, *p, *buf; unsigned int x, y, h; h = height - 1; if (cpp != 0 && width >= (UINT_MAX - 3)/cpp) return XpmNoMemory; p = buf = (char *) XpmMalloc(width * cpp + 3); if (!buf) return (XpmNoMemory); *buf = '"'; p++; for (y = 0; y < h; y++) { s = p; for (x = 0; x < width; x++, pixels++) { strncpy(s, colors[*pixels].string, cpp); s += cpp; } *s++ = '"'; *s = '\0'; fprintf(file, "%s,\n", buf); } /* duplicate some code to avoid a test in the loop */ s = p; for (x = 0; x < width; x++, pixels++) { strncpy(s, colors[*pixels].string, cpp); s += cpp; } *s++ = '"'; *s = '\0'; fprintf(file, "%s", buf); XpmFree(buf); return (XpmSuccess); }
/* * File / Buffer utilities */ int XpmReadFileToBuffer(char *filename, char **buffer_return) { int fd, fcheck, len; char *ptr; struct stat stats; FILE *fp; *buffer_return = NULL; fd = _wopen(wxWIDE_STRING(filename), O_RDONLY); if (fd < 0) return XpmOpenFailed; if (fstat(fd, &stats)) { close(fd); return XpmOpenFailed; } fp = fdopen(fd, "r"); if (!fp) { close(fd); return XpmOpenFailed; } len = (int) stats.st_size; ptr = (char *) XpmMalloc(len + 1); if (!ptr) { fclose(fp); return XpmNoMemory; } fcheck = fread(ptr, len, 1, fp); fclose(fp); if (fcheck != 1) { XpmFree(ptr); return XpmOpenFailed; } ptr[len] = '\0'; *buffer_return = ptr; return XpmSuccess; }
int XpmCreateBufferFromXpmImage( char **buffer_return, XpmImage *image, XpmInfo *info) { /* calculation variables */ int ErrorStatus; char buf[BUFSIZ]; unsigned int cmts, extensions, ext_size = 0; unsigned int l, cmt_size = 0; char *ptr = NULL, *p; unsigned int ptr_size, used_size, tmp; *buffer_return = NULL; cmts = info && (info->valuemask & XpmComments); extensions = info && (info->valuemask & XpmExtensions) && info->nextensions; /* compute the extensions and comments size */ if (extensions) ext_size = ExtensionsSize(info->extensions, info->nextensions); if (cmts) cmt_size = CommentsSize(info); /* write the header line */ #ifndef VOID_SPRINTF used_size = #endif sprintf(buf, "/* XPM */\nstatic char * image_name[] = {\n"); #ifdef VOID_SPRINTF used_size = strlen(buf); #endif ptr_size = used_size + ext_size + cmt_size + 1; /* ptr_size can't be 0 */ if(ptr_size <= used_size || ptr_size <= ext_size || ptr_size <= cmt_size) { return XpmNoMemory; } ptr = (char *) XpmMalloc(ptr_size); if (!ptr) return XpmNoMemory; strcpy(ptr, buf); /* write the values line */ if (cmts && info->hints_cmt) { #ifndef VOID_SPRINTF used_size += #endif snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->hints_cmt); #ifdef VOID_SPRINTF used_size += strlen(info->hints_cmt) + 5; #endif } #ifndef VOID_SPRINTF l = #endif sprintf(buf, "\"%d %d %d %d", image->width, image->height, image->ncolors, image->cpp); #ifdef VOID_SPRINTF l = strlen(buf); #endif if (info && (info->valuemask & XpmHotspot)) { #ifndef VOID_SPRINTF l += #endif snprintf(buf + l, sizeof(buf)-l, " %d %d", info->x_hotspot, info->y_hotspot); #ifdef VOID_SPRINTF l = strlen(buf); #endif } if (extensions) { #ifndef VOID_SPRINTF l += #endif sprintf(buf + l, " XPMEXT"); #ifdef VOID_SPRINTF l = strlen(buf); #endif } #ifndef VOID_SPRINTF l += #endif sprintf(buf + l, "\",\n"); #ifdef VOID_SPRINTF l = strlen(buf); #endif ptr_size += l; if(ptr_size <= l) RETURN(XpmNoMemory); p = (char *) XpmRealloc(ptr, ptr_size); if (!p) RETURN(XpmNoMemory); ptr = p; strcpy(ptr + used_size, buf); used_size += l; /* write colors */ if (cmts && info->colors_cmt) { #ifndef VOID_SPRINTF used_size += #endif snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->colors_cmt); #ifdef VOID_SPRINTF used_size += strlen(info->colors_cmt) + 5; #endif } ErrorStatus = WriteColors(&ptr, &ptr_size, &used_size, image->colorTable, image->ncolors, image->cpp); if (ErrorStatus != XpmSuccess) RETURN(ErrorStatus); /* * now we know the exact size we need, realloc the data * 4 = 1 (for '"') + 3 (for '",\n') * 1 = - 2 (because the last line does not end with ',\n') + 3 (for '};\n') */ if(image->width > UINT_MAX / image->cpp || (tmp = image->width * image->cpp + 4) <= 4 || image->height > UINT_MAX / tmp || (tmp = image->height * tmp + 1) <= 1 || (ptr_size += tmp) <= tmp) RETURN(XpmNoMemory); p = (char *) XpmRealloc(ptr, ptr_size); if (!p) RETURN(XpmNoMemory); ptr = p; /* print pixels */ if (cmts && info->pixels_cmt) { #ifndef VOID_SPRINTF used_size += #endif snprintf(ptr + used_size, ptr_size-used_size, "/*%s*/\n", info->pixels_cmt); #ifdef VOID_SPRINTF used_size += strlen(info->pixels_cmt) + 5; #endif } WritePixels(ptr + used_size, ptr_size - used_size, &used_size, image->width, image->height, image->cpp, image->data, image->colorTable); /* print extensions */ if (extensions) WriteExtensions(ptr + used_size, ptr_size-used_size, &used_size, info->extensions, info->nextensions); /* close the array */ strcpy(ptr + used_size, "};\n"); *buffer_return = ptr; return (XpmSuccess); /* exit point in case of error, free only locally allocated variables */ error: if (ptr) XpmFree(ptr); return (ErrorStatus); }
int XpmReadFileToBuffer( const char *filename, char **buffer_return) { int fd, fcheck; off_t len; char *ptr; struct stat stats; FILE *fp; *buffer_return = NULL; #ifndef VAX11C fd = open(filename, O_RDONLY); #else fd = open(filename, O_RDONLY, NULL); #endif if (fd < 0) return XpmOpenFailed; if (fstat(fd, &stats)) { close(fd); return XpmOpenFailed; } fp = fdopen(fd, "r"); if (!fp) { close(fd); return XpmOpenFailed; } len = stats.st_size; if (len < 0 || len >= SIZE_MAX) { close(fd); return XpmOpenFailed; } ptr = (char *) XpmMalloc(len + 1); if (!ptr) { fclose(fp); return XpmNoMemory; } fcheck = fread(ptr, 1, len, fp); fclose(fp); #ifdef VMS /* VMS often stores text files in a variable-length record format, where there are two bytes of size followed by the record. fread converts this so it looks like a record followed by a newline. Unfortunately, the size reported by fstat() (and fseek/ftell) counts the two bytes for the record terminator, while fread() counts only one. So, fread() sees fewer bytes in the file (size minus # of records) and thus when asked to read the amount returned by stat(), it fails. The best solution, suggested by DEC, seems to consider the length returned from fstat() as an upper bound and call fread() with a record length of 1. Then don't check the return value. We'll check for 0 for gross error that's all. */ len = fcheck; if (fcheck == 0) { #else if (fcheck != len) { #endif XpmFree(ptr); return XpmOpenFailed; } ptr[len] = '\0'; *buffer_return = ptr; return XpmSuccess; }
/* * return end of string - WARNING: malloc! */ int xpmGetString( xpmData *data, char **sptr, unsigned int *l) { unsigned int i, n = 0; int c; char *p = NULL, *q, buf[BUFSIZ]; if (!data->type || data->type == XPMBUFFER) { if (data->cptr) { char *start = data->cptr; while ((c = *data->cptr) && c != data->Eos) data->cptr++; n = data->cptr - start + 1; p = (char *) XpmMalloc(n); if (!p) return (XpmNoMemory); strncpy(p, start, n); if (data->type) /* XPMBUFFER */ p[n - 1] = '\0'; } } else { FILE *file = data->stream.file; if ((c = Getc(data, file)) == EOF) return (XpmFileInvalid); i = 0; q = buf; p = (char *) XpmMalloc(1); while (c != data->Eos && c != EOF) { if (i == BUFSIZ) { /* get to the end of the buffer */ /* malloc needed memory */ q = (char *) XpmRealloc(p, n + i); if (!q) { XpmFree(p); return (XpmNoMemory); } p = q; q += n; /* and copy what we already have */ strncpy(q, buf, i); n += i; i = 0; q = buf; } *q++ = c; i++; c = Getc(data, file); } if (c == EOF) { XpmFree(p); return (XpmFileInvalid); } if (n + i != 0) { /* malloc needed memory */ q = (char *) XpmRealloc(p, n + i + 1); if (!q) { XpmFree(p); return (XpmNoMemory); } p = q; q += n; /* and copy the buffer */ strncpy(q, buf, i); n += i; p[n++] = '\0'; } else { *p = '\0'; n = 1; } Ungetc(data, c, file); } *sptr = p; *l = n; return (XpmSuccess); }
/* * open the given file to be read as an xpmData which is returned. */ int xpmReadFile(char *filename, xpmData *mdata) { #ifdef ZPIPE char *compressfile, buf[BUFSIZ]; struct stat status; #endif if (!filename) { mdata->stream.file = (stdin); mdata->type = XPMFILE; } else { #ifdef ZPIPE if (((int) strlen(filename) > 2) && !strcmp(".Z", filename + (strlen(filename) - 2))) { mdata->type = XPMPIPE; sprintf(buf, "uncompress -c %s", filename); if (!(mdata->stream.file = popen(buf, "r"))) return (XpmOpenFailed); } else if (((int) strlen(filename) > 3) && !strcmp(".gz", filename + (strlen(filename) - 3))) { mdata->type = XPMPIPE; sprintf(buf, "gunzip -qc %s", filename); if (!(mdata->stream.file = popen(buf, "r"))) return (XpmOpenFailed); } else { if (!(compressfile = (char *) XpmMalloc(strlen(filename) + 4))) return (XpmNoMemory); strcpy(compressfile, filename); strcat(compressfile, ".Z"); if (!stat(compressfile, &status)) { sprintf(buf, "uncompress -c %s", compressfile); if (!(mdata->stream.file = popen(buf, "r"))) { XpmFree(compressfile); return (XpmOpenFailed); } mdata->type = XPMPIPE; } else { strcpy(compressfile, filename); strcat(compressfile, ".gz"); if (!stat(compressfile, &status)) { sprintf(buf, "gunzip -c %s", compressfile); if (!(mdata->stream.file = popen(buf, "r"))) { XpmFree(compressfile); return (XpmOpenFailed); } mdata->type = XPMPIPE; } else { #endif if (!(mdata->stream.file = fopen(filename, "r"))) { #ifdef ZPIPE XpmFree(compressfile); #endif return (XpmOpenFailed); } mdata->type = XPMFILE; #ifdef ZPIPE } } XpmFree(compressfile); } #endif } mdata->CommentLength = 0; return (XpmSuccess); }
/* * open the given file to be read as an xpmData which is returned. */ static int OpenReadFile( char *filename, xpmData *mdata) { if (!filename) { mdata->stream.file = (stdin); mdata->type = XPMFILE; } else { int fd = open(filename, O_RDONLY); #if defined(NO_ZPIPE) if ( fd < 0 ) return XpmOpenFailed; #else const char* ext = NULL; if ( fd >= 0 ) ext = strrchr(filename, '.'); #ifdef STAT_ZFILE /* searching for z-files if the given name not found */ else { size_t len = strlen(filename); char *compressfile = (char *) XpmMalloc(len + 4); if ( !compressfile ) return (XpmNoMemory); strcpy(compressfile, filename); strcpy(compressfile + len, ext = ".Z"); fd = open(compressfile, O_RDONLY); if ( fd < 0 ) { strcpy(compressfile + len, ext = ".gz"); fd = open(compressfile, O_RDONLY); if ( fd < 0 ) { XpmFree(compressfile); return XpmOpenFailed; } } XpmFree(compressfile); } #endif if ( ext && !strcmp(ext, ".Z") ) { mdata->type = XPMPIPE; mdata->stream.file = xpmPipeThrough(fd, "uncompress", "-c", "r"); } else if ( ext && !strcmp(ext, ".gz") ) { mdata->type = XPMPIPE; mdata->stream.file = xpmPipeThrough(fd, "gunzip", "-qc", "r"); } else #endif /* z-files */ { mdata->type = XPMFILE; mdata->stream.file = fdopen(fd, "r"); } if (!mdata->stream.file) { close(fd); return (XpmOpenFailed); } } mdata->CommentLength = 0; #ifdef CXPMPROG mdata->lineNum = 0; mdata->charNum = 0; #endif return (XpmSuccess); }