#define _GNU_SOURCE #include #include #include "gdk_imlib.h" #define id _gdk_imlib_data #include "gdk_imlib_private.h" #include /* Split the ID - damages input */ static char * g_SplitID(char *file) { char *p = strrchr(file, ':'); if (p == NULL) return ""; else { *p++ = 0; return p; } } /* * Doesn't damage the input */ char * _gdk_imlib_GetExtension(char *file) { char *p = strrchr(file, '.'); if (p == NULL) return ""; else return p + 1; } int _gdk_imlib_ispnm(FILE *f) { char buf[8]; if (!f) return 0; fgets(buf, 8, f); rewind(f); if (!strcmp("P6\n", buf)) return 1; if (!strcmp("P5\n", buf)) return 1; if (!strcmp("P4\n", buf)) return 1; if (!strcmp("P3\n", buf)) return 1; if (!strcmp("P2\n", buf)) return 1; if (!strcmp("P1\n", buf)) return 1; return 0; } int _gdk_imlib_isjpeg(FILE *f) { unsigned char buf[8]; if (!f) return 0; fread(buf, 1, 2, f); rewind(f); if ((buf[0] == 0xff) && (buf[1] == 0xd8)) return 1; return 0; } int _gdk_imlib_ispng(FILE *f) { unsigned char buf[8]; if (!f) return 0; fread(buf, 1, 8, f); rewind(f); if (buf [0] != 0x89 || buf [1] != 'P' || buf [2] != 'N' || buf [3] != 'G' || buf [4] != 0x0d || buf [5] != 0x0a || buf [6] != 0x1a || buf [7] != 0x0a) return FALSE; return TRUE; } int _gdk_imlib_istiff(FILE *f) { char buf[8]; if (!f) return 0; fgets(buf, 5, f); rewind(f); if ((buf[0] == 'M') && (buf[1] == 'M') && (buf[2] == 0x00) && (buf[3] == 0x2a)) return 1; if ((buf[0] == 'I') && (buf[1] == 'I') && (buf[2] == 0x2a) && (buf[3] == 0x00)) return 1; return 0; } int _gdk_imlib_iseim(FILE *f) { char buf[8]; if (!f) return 0; fread(buf, 1, 4, f); rewind(f); if (!strncmp("EIM ", buf, 4)) return 1; return 0; } int _gdk_imlib_isgif(FILE *f) { char buf[8]; if (!f) return 0; fread(buf, 1, 4, f); rewind(f); buf[4] = 0; if (!strcmp("GIF8", buf)) return 1; return 0; } int _gdk_imlib_isxpm(FILE *f) { char buf[11]; if (!f) return 0; fread(buf, 1, 9, f); rewind(f); buf[9] = 0; if (!strcmp("/* XPM */", buf)) return 1; return 0; } int _gdk_imlib_isbmp(FILE *f) { char buf[3]; if (!f) return 0; fread(buf, 1, 2, f); rewind(f); buf[2] = 0; if (!strcmp("BM", buf)) return 1; return 0; } GdkImlibImage * gdk_imlib_load_image(char *file) { int w, h; unsigned char *data; GdkImlibImage *im; char *e; FILE *p; int eim; int fmt; int trans; eim = 0; fmt = 0; p = NULL; data = NULL; if (!file) return NULL; if (id->cache.on_image) if ((im = _gdk_imlib_find_image(file))) { if (im->rgb_width == 0 || im->rgb_height == 0) { gdk_imlib_destroy_image(im); return NULL; } else return im; } if (!strcmp(file,"-")) p = stdin; else p = fopen(file, "rb"); if (!p) return NULL; e = _gdk_imlib_GetExtension(file); if (_gdk_imlib_ispnm(p)) { fmt = 0; } else if (_gdk_imlib_isjpeg(p)) { fmt = 2; } else if (_gdk_imlib_istiff(p)) { fmt = 3; } else if (_gdk_imlib_iseim(p)) { eim = 1; fmt = 9999; } else if (_gdk_imlib_isxpm(p)) { fmt = 5; } else if (_gdk_imlib_ispng(p)) { fmt = 1; } else if (_gdk_imlib_isgif(p)) { fmt = 4; } else if (_gdk_imlib_isbmp(p)) { fmt = 6; } trans = 0; if (!eim && !data) { switch (fmt) { case 6: if (p) data = (*_gdk_imlib_LoadBMP)(p, &w, &h, &trans); break; case 5: if (p) data = (*_gdk_imlib_LoadXPM)(p, &w, &h, &trans); break; case 4: if (p) data = (*_gdk_imlib_LoadGIF)(p, &w, &h, &trans); break; case 3: if (p) data = (*_gdk_imlib_LoadTIFF)(p, file, &w, &h, &trans); break; case 2: if (p) data = (*_gdk_imlib_LoadJPEG)(p, &w, &h, &trans); break; case 1: if (p) data = (*_gdk_imlib_LoadPNG)(p, &w, &h, &trans); break; case 0: if (p) data = (*_gdk_imlib_LoadPPM)(p, &w, &h, &trans); break; } } if (p != stdin) fclose(p); if (!eim && !data) { fprintf(stderr, "gdk_imlib ERROR: Cannot load image: %s\n" "All fallbacks failed.\n", file); return NULL; } if (w == 0 || h == 0) { if (data) free(data); return NULL; } im = (GdkImlibImage *) malloc(sizeof(GdkImlibImage)); if (!im) { fprintf(stderr, "gdk_imlib ERROR: Cannot allocate RAM for image data\n"); if (data) free(data); return NULL; } im->alpha_data = NULL; im->map = NULL; if (trans) { im->shape_color.r = 255; im->shape_color.g = 0; im->shape_color.b = 255; } else { im->shape_color.r = -1; im->shape_color.g = -1; im->shape_color.b = -1; } im->border.left = 0; im->border.right = 0; im->border.top = 0; im->border.bottom = 0; im->cache = 1; im->rgb_data = data; im->rgb_width = w; im->rgb_height = h; im->pixmap = NULL; im->shape_mask = NULL; #if THIS_CODE_IS_BROKEN_WITH_REGARD_TO_FILENAMES_WITH_COLONS /* * The code here depends on the filenames not having a ':', * which is not the case for a lot of my files. */ if (eim) { char s1[256], s2[256]; char s[4096]; int num, size; int r, g, b; int br, bl, bt, bb; /* Load Native-as-can-be EIM format (Enlightenment IMlib format) */ if (!strcmp(file,"-")) p = stdin; else p = fopen(file, "r"); if (!p) { free(im); return NULL; } fgets(s, sizeof (s), p); if ((s[0] != 'E') && (s[1] != 'I') && (s[2] != 'M') && (s[3] != ' ')) { fclose(p); free(im); return NULL; } sscanf(s, "%256s %i", s1, &num); if (num <= 0) { fclose(p); free(im); return NULL; } while (fgets(s, sizeof (s), p)) { sscanf(s, "%256s", s1); if (!strcmp("IMAGE", s1)) { sscanf(s, "%256s %i %256s %i %i %i %i %i %i %i %i %i", s1, &size, s2, &w, &h, &r, &g, &b, &bl, &br, &bt, &bb); if (!iden[0]) break; else if (!strcmp(iden, s2)) break; if (size > 0) fseek(p, size, SEEK_CUR); } } im->rgb_data = _gdk_malloc_image(w, h); if (!im->rgb_data) { fclose(p); free(im); return NULL; } im->shape_color.r = r; im->shape_color.g = g; im->shape_color.b = b; im->rgb_width = w; im->rgb_height = h; im->border.left = bl; im->border.right = br; im->border.top = bt; im->border.bottom = bb; fread(im->rgb_data, 1, w * h * 3, p); fclose(p); } #endif im->mod.gamma = id->mod.gamma; im->mod.brightness = id->mod.brightness; im->mod.contrast = id->mod.contrast; im->rmod.gamma = id->rmod.gamma; im->rmod.brightness = id->rmod.brightness; im->rmod.contrast = id->rmod.contrast; im->gmod.gamma = id->gmod.gamma; im->gmod.brightness = id->gmod.brightness; im->gmod.contrast = id->gmod.contrast; im->bmod.gamma = id->bmod.gamma; im->bmod.brightness = id->bmod.brightness; im->bmod.contrast = id->bmod.contrast; im->filename = malloc(strlen(file) + 1); if (im->filename) strcpy(im->filename, file); if ((id->cache.on_image && im)) _gdk_imlib_add_image(im, file); _gdk_imlib_calc_map_tables(im); return im; } gint gdk_imlib_save_image_to_eim(GdkImlibImage * im, char *file) { char fil[4096]; char *iden; FILE *f; int size; if ((!id) || (!im) || (!file)) return 0; strncpy(fil, file, sizeof(fil)); iden = g_SplitID(fil); if (!iden[0]) iden = "default"; f = fopen(fil, "w"); if (!f) return 0; size = im->rgb_width * im->rgb_height * 3; fprintf(f, "EIM 1\n"); fprintf(f, "IMAGE %i %s %i %i %i %i %i %i %i %i %i\n", size, iden, im->rgb_width, im->rgb_height, im->shape_color.r, im->shape_color.g, im->shape_color.b, im->border.left, im->border.right, im->border.top, im->border.bottom); if (fwrite(im->rgb_data, size, 1, f) != 1) { fclose(f); return 0; } fclose(f); return 1; } gint gdk_imlib_add_image_to_eim(GdkImlibImage * im, char *file) { char fil[4096]; char *iden; FILE *f; int size; if ((!id) || (!im) || (!file)) return 0; strncpy(fil, file, sizeof(fil)); iden = g_SplitID(file); if (!iden[0]) strcpy(iden, "default"); f = fopen(fil, "a"); if (!f) return 0; size = im->rgb_width * im->rgb_height * 3; fprintf(f, "IMAGE %i %s %i %i %i %i %i %i %i %i %i\n", size, iden, im->rgb_width, im->rgb_height, im->shape_color.r, im->shape_color.g, im->shape_color.b, im->border.left, im->border.right, im->border.top, im->border.bottom); if (fwrite(im->rgb_data, size, 1, f) != 1) { fclose(f); return 0; } fclose(f); return 1; } gint gdk_imlib_save_image_to_ppm(GdkImlibImage * im, char *file) { FILE *f; if ((!id) || (!im) || (!file)) return 0; f = fopen(file, "w"); if (!f) return 0; fprintf(f, "P6\n"); fprintf(f, "%i %i\n255\n", im->rgb_width, im->rgb_height); if (fwrite(im->rgb_data, im->rgb_width * im->rgb_height * 3, 1, f) != 1) { fclose(f); return 0; } fclose(f); return 1; }