You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

539 lines
9.7 KiB

#define _GNU_SOURCE
#include <config.h>
#include <glib.h>
#include "gdk_imlib.h"
#define id _gdk_imlib_data
#include "gdk_imlib_private.h"
#include <setjmp.h>
/* 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;
}