X-Git-Url: https://repo.or.cz/w/wmaker-crm.git/blobdiff_plain/59fc927dc9f183802621138534fa6eaafe5593ba..688a56e8ab67b56550e2874d9d7423f0d435bfd9:/wrlib/load.c diff --git a/wrlib/load.c b/wrlib/load.c dissimilarity index 73% index 320b4361..bfd46b94 100644 --- a/wrlib/load.c +++ b/wrlib/load.c @@ -1,371 +1,347 @@ -/* load.c - load image from file - * - * Raster graphics library - * - * Copyright (c) 1997-2003 Alfredo K. Kojima - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef USE_PNG -#include -#endif - -#include "wraster.h" - -/* Silly hack for Windows systems with cygwin */ -#ifndef O_BINARY -# define O_BINARY 0 -#endif - -typedef struct RCachedImage { - RImage *image; - char *file; - time_t last_modif; /* last time file was modified */ - time_t last_use; /* last time image was used */ -} RCachedImage; - - -/* - * Size of image cache - */ -static int RImageCacheSize = -1; - -/* - * Max. size of image to store in cache - */ -static int RImageCacheMaxImage = -1; /* 0 = any size */ - -#define IMAGE_CACHE_SIZE 8 - -#define IMAGE_CACHE_MAX_IMAGE 64*64 - -static RCachedImage *RImageCache; - - - - - -#define IM_ERROR -1 -#define IM_UNKNOWN 0 -#define IM_XPM 1 -#define IM_TIFF 2 -#define IM_PNG 3 -#define IM_PPM 4 -#define IM_JPEG 5 -#define IM_GIF 6 -/* How many image types do we have. */ -/* Increase this when adding new image types! */ -#define IM_TYPES 6 - - -static int identFile(char *path); - -extern RImage *RLoadPPM(RContext *context, char *file_name, int index); - -extern RImage *RLoadXPM(RContext *context, char *file, int index); - - -#ifdef USE_TIFF -extern RImage *RLoadTIFF(RContext *context, char *file, int index); -#endif -#ifdef USE_PNG -extern RImage *RLoadPNG(RContext *context, char *file, int index); -#endif -#ifdef USE_JPEG -extern RImage *RLoadJPEG(RContext *context, char *file_name, int index); -#endif -#ifdef USE_GIF -extern RImage *RLoadGIF(RContext *context, char *file_name, int index); -#endif - - -char** -RSupportedFileFormats(void) -{ - static char *tmp[IM_TYPES+1]; - int i = 0; - - /* built-in */ - tmp[i++] = "XPM"; - /* built-in */ - tmp[i++] = "PPM"; -#ifdef USE_TIFF - tmp[i++] = "TIFF"; -#endif -#ifdef USE_PNG - tmp[i++] = "PNG"; -#endif -#ifdef USE_JPEG - tmp[i++] = "JPEG"; -#endif -#ifdef USE_GIF - tmp[i++] = "GIF"; -#endif - tmp[i] = NULL; - - return tmp; -} - - -static void -init_cache() -{ - char *tmp; - - tmp = getenv("RIMAGE_CACHE"); - if (!tmp || sscanf(tmp, "%i", &RImageCacheSize)!=1) { - RImageCacheSize = IMAGE_CACHE_SIZE; - } - if (RImageCacheSize<0) - RImageCacheSize = 0; - - tmp = getenv("RIMAGE_CACHE_SIZE"); - if (!tmp || sscanf(tmp, "%i", &RImageCacheMaxImage)!=1) { - RImageCacheMaxImage = IMAGE_CACHE_MAX_IMAGE; - } - - if (RImageCacheSize>0) { - RImageCache = malloc(sizeof(RCachedImage)*RImageCacheSize); - if (RImageCache==NULL) { - printf("wrlib: out of memory for image cache\n"); - return; - } - memset(RImageCache, 0, sizeof(RCachedImage)*RImageCacheSize); - } -} - - -RImage* -RLoadImage(RContext *context, char *file, int index) -{ - RImage *image = NULL; - int i; - struct stat st; - - assert(file!=NULL); - - if (RImageCacheSize<0) { - init_cache(); - } - - if (RImageCacheSize>0) { - - for (i=0; i0 && image && - (RImageCacheMaxImage==0 - || RImageCacheMaxImage >= image->width*image->height)) { - time_t oldest=time(NULL); - int oldest_idx = 0; - int done = 0; - - for (i=0; i RImageCache[i].last_use) { - oldest = RImageCache[i].last_use; - oldest_idx = i; - } - } - } - - /* if no slot available, dump least recently used one */ - if (!done) { - free(RImageCache[oldest_idx].file); - RReleaseImage(RImageCache[oldest_idx].image); - RImageCache[oldest_idx].file = malloc(strlen(file)+1); - strcpy(RImageCache[oldest_idx].file, file); - RImageCache[oldest_idx].image = RCloneImage(image); - RImageCache[oldest_idx].last_modif = st.st_mtime; - RImageCache[oldest_idx].last_use = time(NULL); - } - } - - return image; -} - - -char* -RGetImageFileFormat(char *file) -{ - switch (identFile(file)) { - case IM_XPM: - return "XPM"; - -#ifdef USE_TIFF - case IM_TIFF: - return "TIFF"; -#endif /* USE_TIFF */ - -#ifdef USE_PNG - case IM_PNG: - return "PNG"; -#endif /* USE_PNG */ - -#ifdef USE_JPEG - case IM_JPEG: - return "JPEG"; -#endif /* USE_JPEG */ - -#ifdef USE_GIF - case IM_GIF: - return "GIF"; -#endif /* USE_GIF */ - - case IM_PPM: - return "PPM"; - - default: - return NULL; - } -} - - -static int -identFile(char *path) -{ - int fd; - unsigned char buffer[32]; - - assert(path!=NULL); - - fd = open(path, O_RDONLY|O_BINARY); - if (fd < 0) { - RErrorCode = RERR_OPEN; - return IM_ERROR; - } - if (read(fd, buffer, 32)<1) { - close(fd); - RErrorCode = RERR_READ; - return IM_ERROR; - } - close(fd); - - /* check for XPM */ - if (strncmp((char*)buffer, "/* XPM */", 9)==0) - return IM_XPM; - - /* check for TIFF */ - if ((buffer[0]=='I' && buffer[1]=='I' && buffer[2]=='*' && buffer[3]==0) - ||(buffer[0]=='M' && buffer[1]=='M' && buffer[2]==0 && buffer[3]=='*')) - return IM_TIFF; - -#ifdef USE_PNG - /* check for PNG */ - if (png_check_sig(buffer, 8)) - return IM_PNG; -#endif - - /* check for raw PPM or PGM */ - if (buffer[0]=='P' && (buffer[1]=='5' || buffer[1]=='6')) - return IM_PPM; - - /* check for JPEG */ - if (buffer[0] == 0xff && buffer[1] == 0xd8) - return IM_JPEG; - - /* check for GIF */ - if (buffer[0] == 'G' && buffer[1] == 'I' && buffer[2] == 'F') - return IM_GIF; - - return IM_UNKNOWN; -} - - - +/* load.c - load image from file + * + * Raster graphics library + * + * Copyright (c) 1997-2003 Alfredo K. Kojima + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef USE_PNG +#include +#endif + +#include "wraster.h" + +/* Silly hack for Windows systems with cygwin */ +#ifndef O_BINARY +# define O_BINARY 0 +#endif + +typedef struct RCachedImage { + RImage *image; + char *file; + time_t last_modif; /* last time file was modified */ + time_t last_use; /* last time image was used */ +} RCachedImage; + +/* + * Size of image cache + */ +static int RImageCacheSize = -1; + +/* + * Max. size of image to store in cache + */ +static int RImageCacheMaxImage = -1; /* 0 = any size */ + +#define IMAGE_CACHE_SIZE 8 + +#define IMAGE_CACHE_MAX_IMAGE 64*64 + +static RCachedImage *RImageCache; + +#define IM_ERROR -1 +#define IM_UNKNOWN 0 +#define IM_XPM 1 +#define IM_TIFF 2 +#define IM_PNG 3 +#define IM_PPM 4 +#define IM_JPEG 5 +#define IM_GIF 6 +/* How many image types do we have. */ +/* Increase this when adding new image types! */ +#define IM_TYPES 6 + +static int identFile(char *path); + +extern RImage *RLoadPPM(RContext * context, char *file_name, int index); + +extern RImage *RLoadXPM(RContext * context, char *file, int index); + +#ifdef USE_TIFF +extern RImage *RLoadTIFF(RContext * context, char *file, int index); +#endif +#ifdef USE_PNG +extern RImage *RLoadPNG(RContext * context, char *file, int index); +#endif +#ifdef USE_JPEG +extern RImage *RLoadJPEG(RContext * context, char *file_name, int index); +#endif +#ifdef USE_GIF +extern RImage *RLoadGIF(RContext * context, char *file_name, int index); +#endif + +char **RSupportedFileFormats(void) +{ + static char *tmp[IM_TYPES + 1]; + int i = 0; + + /* built-in */ + tmp[i++] = "XPM"; + /* built-in */ + tmp[i++] = "PPM"; +#ifdef USE_TIFF + tmp[i++] = "TIFF"; +#endif +#ifdef USE_PNG + tmp[i++] = "PNG"; +#endif +#ifdef USE_JPEG + tmp[i++] = "JPEG"; +#endif +#ifdef USE_GIF + tmp[i++] = "GIF"; +#endif + tmp[i] = NULL; + + return tmp; +} + +static void init_cache() +{ + char *tmp; + + tmp = getenv("RIMAGE_CACHE"); + if (!tmp || sscanf(tmp, "%i", &RImageCacheSize) != 1) { + RImageCacheSize = IMAGE_CACHE_SIZE; + } + if (RImageCacheSize < 0) + RImageCacheSize = 0; + + tmp = getenv("RIMAGE_CACHE_SIZE"); + if (!tmp || sscanf(tmp, "%i", &RImageCacheMaxImage) != 1) { + RImageCacheMaxImage = IMAGE_CACHE_MAX_IMAGE; + } + + if (RImageCacheSize > 0) { + RImageCache = malloc(sizeof(RCachedImage) * RImageCacheSize); + if (RImageCache == NULL) { + printf("wrlib: out of memory for image cache\n"); + return; + } + memset(RImageCache, 0, sizeof(RCachedImage) * RImageCacheSize); + } +} + +RImage *RLoadImage(RContext * context, char *file, int index) +{ + RImage *image = NULL; + int i; + struct stat st; + + assert(file != NULL); + + if (RImageCacheSize < 0) { + init_cache(); + } + + if (RImageCacheSize > 0) { + + for (i = 0; i < RImageCacheSize; i++) { + if (RImageCache[i].file && strcmp(file, RImageCache[i].file) == 0) { + + if (stat(file, &st) == 0 && st.st_mtime == RImageCache[i].last_modif) { + RImageCache[i].last_use = time(NULL); + + return RCloneImage(RImageCache[i].image); + + } else { + free(RImageCache[i].file); + RImageCache[i].file = NULL; + RReleaseImage(RImageCache[i].image); + } + } + } + } + + switch (identFile(file)) { + case IM_ERROR: + return NULL; + + case IM_UNKNOWN: + RErrorCode = RERR_BADFORMAT; + return NULL; + + case IM_XPM: + image = RLoadXPM(context, file, index); + break; + +#ifdef USE_TIFF + case IM_TIFF: + image = RLoadTIFF(context, file, index); + break; +#endif /* USE_TIFF */ + +#ifdef USE_PNG + case IM_PNG: + image = RLoadPNG(context, file, index); + break; +#endif /* USE_PNG */ + +#ifdef USE_JPEG + case IM_JPEG: + image = RLoadJPEG(context, file, index); + break; +#endif /* USE_JPEG */ + +#ifdef USE_GIF + case IM_GIF: + image = RLoadGIF(context, file, index); + break; +#endif /* USE_GIF */ + + case IM_PPM: + image = RLoadPPM(context, file, index); + break; + + default: + RErrorCode = RERR_BADFORMAT; + return NULL; + } + + /* store image in cache */ + if (RImageCacheSize > 0 && image && + (RImageCacheMaxImage == 0 || RImageCacheMaxImage >= image->width * image->height)) { + time_t oldest = time(NULL); + int oldest_idx = 0; + int done = 0; + + for (i = 0; i < RImageCacheSize; i++) { + if (!RImageCache[i].file) { + RImageCache[i].file = malloc(strlen(file) + 1); + strcpy(RImageCache[i].file, file); + RImageCache[i].image = RCloneImage(image); + RImageCache[i].last_modif = st.st_mtime; + RImageCache[i].last_use = time(NULL); + done = 1; + break; + } else { + if (oldest > RImageCache[i].last_use) { + oldest = RImageCache[i].last_use; + oldest_idx = i; + } + } + } + + /* if no slot available, dump least recently used one */ + if (!done) { + free(RImageCache[oldest_idx].file); + RReleaseImage(RImageCache[oldest_idx].image); + RImageCache[oldest_idx].file = malloc(strlen(file) + 1); + strcpy(RImageCache[oldest_idx].file, file); + RImageCache[oldest_idx].image = RCloneImage(image); + RImageCache[oldest_idx].last_modif = st.st_mtime; + RImageCache[oldest_idx].last_use = time(NULL); + } + } + + return image; +} + +char *RGetImageFileFormat(char *file) +{ + switch (identFile(file)) { + case IM_XPM: + return "XPM"; + +#ifdef USE_TIFF + case IM_TIFF: + return "TIFF"; +#endif /* USE_TIFF */ + +#ifdef USE_PNG + case IM_PNG: + return "PNG"; +#endif /* USE_PNG */ + +#ifdef USE_JPEG + case IM_JPEG: + return "JPEG"; +#endif /* USE_JPEG */ + +#ifdef USE_GIF + case IM_GIF: + return "GIF"; +#endif /* USE_GIF */ + + case IM_PPM: + return "PPM"; + + default: + return NULL; + } +} + +static int identFile(char *path) +{ + int fd; + unsigned char buffer[32]; + + assert(path != NULL); + + fd = open(path, O_RDONLY | O_BINARY); + if (fd < 0) { + RErrorCode = RERR_OPEN; + return IM_ERROR; + } + if (read(fd, buffer, 32) < 1) { + close(fd); + RErrorCode = RERR_READ; + return IM_ERROR; + } + close(fd); + + /* check for XPM */ + if (strncmp((char *)buffer, "/* XPM */", 9) == 0) + return IM_XPM; + + /* check for TIFF */ + if ((buffer[0] == 'I' && buffer[1] == 'I' && buffer[2] == '*' && buffer[3] == 0) + || (buffer[0] == 'M' && buffer[1] == 'M' && buffer[2] == 0 && buffer[3] == '*')) + return IM_TIFF; + +#ifdef USE_PNG + /* check for PNG */ + if (png_check_sig(buffer, 8)) + return IM_PNG; +#endif + + /* check for raw PPM or PGM */ + if (buffer[0] == 'P' && (buffer[1] == '5' || buffer[1] == '6')) + return IM_PPM; + + /* check for JPEG */ + if (buffer[0] == 0xff && buffer[1] == 0xd8) + return IM_JPEG; + + /* check for GIF */ + if (buffer[0] == 'G' && buffer[1] == 'I' && buffer[2] == 'F') + return IM_GIF; + + return IM_UNKNOWN; +}