|
Packit |
ed3af9 |
/*
|
|
Packit |
ed3af9 |
* Add ability to load xpm files to gd, requires the xpm
|
|
Packit |
ed3af9 |
* library.
|
|
Packit |
ed3af9 |
* Caolan.McNamara@ul.ie
|
|
Packit |
ed3af9 |
* http://www.csn.ul.ie/~caolan
|
|
Packit |
ed3af9 |
*/
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
/**
|
|
Packit |
ed3af9 |
* File: XPM Input
|
|
Packit |
ed3af9 |
*
|
|
Packit |
ed3af9 |
* Read XPM images.
|
|
Packit |
ed3af9 |
*/
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
ed3af9 |
# include "config.h"
|
|
Packit |
ed3af9 |
#endif
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
#include <stdio.h>
|
|
Packit |
ed3af9 |
#include <stdlib.h>
|
|
Packit |
ed3af9 |
#include <string.h>
|
|
Packit |
ed3af9 |
#include "gd.h"
|
|
Packit |
ed3af9 |
#include "gdhelpers.h"
|
|
Packit |
ed3af9 |
#include "gd_color_map.h"
|
|
Packit |
ed3af9 |
#include "gd_errors.h"
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
#ifndef HAVE_LIBXPM
|
|
Packit |
ed3af9 |
BGD_DECLARE(gdImagePtr) gdImageCreateFromXpm(char *filename)
|
|
Packit |
ed3af9 |
{
|
|
Packit |
ed3af9 |
(void)filename;
|
|
Packit |
ed3af9 |
gd_error_ex(GD_ERROR, "libgd was not built with xpm support\n");
|
|
Packit |
ed3af9 |
return NULL;
|
|
Packit |
ed3af9 |
}
|
|
Packit |
ed3af9 |
#else
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
#include <X11/xpm.h>
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
/*
|
|
Packit |
ed3af9 |
Function: gdImageCreateFromXpm
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
<gdImageCreateFromXbm> is called to load images from XPM X Window
|
|
Packit |
ed3af9 |
System color bitmap format files. This function is available only
|
|
Packit |
ed3af9 |
if HAVE_XPM is selected in the Makefile and the Xpm library is
|
|
Packit |
ed3af9 |
linked with the application. Unlike most gd file functions, the
|
|
Packit |
ed3af9 |
Xpm functions *require filenames*, not file
|
|
Packit |
ed3af9 |
pointers. <gdImageCreateFromXpm> returns a <gdImagePtr> to the new
|
|
Packit |
ed3af9 |
image, or NULL if unable to load the image (most often because the
|
|
Packit |
ed3af9 |
file is corrupt or does not contain an XPM bitmap format
|
|
Packit |
ed3af9 |
image). You can inspect the sx and sy members of the image to
|
|
Packit |
ed3af9 |
determine its size. The image must eventually be destroyed using
|
|
Packit |
ed3af9 |
<gdImageDestroy>.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Parameters:
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
filename - The input filename (*not* FILE pointer)
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Returns:
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
A pointer to the new image or NULL if an error occurred.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Example:
|
|
Packit |
ed3af9 |
(start code)
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
gdImagePtr im;
|
|
Packit |
ed3af9 |
FILE *in;
|
|
Packit |
ed3af9 |
in = fopen("myxpm.xpm", "rb");
|
|
Packit |
ed3af9 |
im = gdImageCreateFromXpm(in);
|
|
Packit |
ed3af9 |
fclose(in);
|
|
Packit |
ed3af9 |
// ... Use the image ...
|
|
Packit |
ed3af9 |
gdImageDestroy(im);
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
(end code)
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
*/
|
|
Packit |
ed3af9 |
BGD_DECLARE(gdImagePtr) gdImageCreateFromXpm(char *filename)
|
|
Packit |
ed3af9 |
{
|
|
Packit |
ed3af9 |
XpmInfo info;
|
|
Packit |
ed3af9 |
XpmImage image;
|
|
Packit |
ed3af9 |
unsigned int i, j, k, number, len;
|
|
Packit |
ed3af9 |
char buf[5];
|
|
Packit |
ed3af9 |
gdImagePtr im = 0;
|
|
Packit |
ed3af9 |
int *pointer;
|
|
Packit |
ed3af9 |
int red = 0, green = 0, blue = 0;
|
|
Packit |
ed3af9 |
int *colors;
|
|
Packit |
ed3af9 |
int ret;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
ret = XpmReadFileToXpmImage(filename, &image, &info;;
|
|
Packit |
ed3af9 |
if(ret != XpmSuccess) {
|
|
Packit |
ed3af9 |
return 0;
|
|
Packit |
ed3af9 |
}
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
number = image.ncolors;
|
|
Packit |
ed3af9 |
if(overflow2(sizeof(int), number)) {
|
|
Packit |
ed3af9 |
goto done;
|
|
Packit |
ed3af9 |
}
|
|
Packit |
ed3af9 |
for(i = 0; i < number; i++) {
|
|
Packit |
ed3af9 |
/*
|
|
Packit |
ed3af9 |
avoid NULL pointer dereference
|
|
Packit |
ed3af9 |
TODO better fix need to manage monochrome/monovisual
|
|
Packit |
ed3af9 |
see m_color or g4_color or g_color
|
|
Packit |
ed3af9 |
*/
|
|
Packit |
ed3af9 |
if (!image.colorTable[i].c_color) {
|
|
Packit |
ed3af9 |
goto done;
|
|
Packit |
ed3af9 |
}
|
|
Packit |
ed3af9 |
}
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
colors = (int *)gdMalloc(sizeof(int) * number);
|
|
Packit |
ed3af9 |
if(colors == NULL) {
|
|
Packit |
ed3af9 |
goto done;
|
|
Packit |
ed3af9 |
}
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
if(!(im = gdImageCreate(image.width, image.height))) {
|
|
Packit |
ed3af9 |
gdFree(colors);
|
|
Packit |
ed3af9 |
goto done;
|
|
Packit |
ed3af9 |
}
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
for(i = 0; i < number; i++) {
|
|
Packit |
ed3af9 |
char *c_color = image.colorTable[i].c_color;
|
|
Packit |
ed3af9 |
if(strcmp(c_color, "None") == 0) {
|
|
Packit |
ed3af9 |
colors[i] = gdImageGetTransparent(im);
|
|
Packit |
ed3af9 |
if(colors[i] == -1) colors[i] = gdImageColorAllocate(im, 0, 0, 0);
|
|
Packit |
ed3af9 |
if(colors[i] != -1) gdImageColorTransparent(im, colors[i]);
|
|
Packit |
ed3af9 |
continue;
|
|
Packit |
ed3af9 |
}
|
|
Packit |
ed3af9 |
len = strlen(c_color);
|
|
Packit |
ed3af9 |
if(len < 1) continue;
|
|
Packit |
ed3af9 |
if(c_color[0] == '#') {
|
|
Packit |
ed3af9 |
switch(len) {
|
|
Packit |
ed3af9 |
case 4:
|
|
Packit |
ed3af9 |
buf[2] = '\0';
|
|
Packit |
ed3af9 |
buf[0] = buf[1] = c_color[1];
|
|
Packit |
ed3af9 |
red = strtol(buf, NULL, 16);
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
buf[0] = buf[1] = c_color[2];
|
|
Packit |
ed3af9 |
green = strtol(buf, NULL, 16);
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
buf[0] = buf[1] = c_color[3];
|
|
Packit |
ed3af9 |
blue = strtol(buf, NULL, 16);
|
|
Packit |
ed3af9 |
break;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
case 7:
|
|
Packit |
ed3af9 |
buf[2] = '\0';
|
|
Packit |
ed3af9 |
buf[0] = c_color[1];
|
|
Packit |
ed3af9 |
buf[1] = c_color[2];
|
|
Packit |
ed3af9 |
red = strtol(buf, NULL, 16);
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
buf[0] = c_color[3];
|
|
Packit |
ed3af9 |
buf[1] = c_color[4];
|
|
Packit |
ed3af9 |
green = strtol(buf, NULL, 16);
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
buf[0] = c_color[5];
|
|
Packit |
ed3af9 |
buf[1] = c_color[6];
|
|
Packit |
ed3af9 |
blue = strtol(buf, NULL, 16);
|
|
Packit |
ed3af9 |
break;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
case 10:
|
|
Packit |
ed3af9 |
buf[3] = '\0';
|
|
Packit |
ed3af9 |
buf[0] = c_color[1];
|
|
Packit |
ed3af9 |
buf[1] = c_color[2];
|
|
Packit |
ed3af9 |
buf[2] = c_color[3];
|
|
Packit |
ed3af9 |
red = strtol(buf, NULL, 16);
|
|
Packit |
ed3af9 |
red /= 64;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
buf[0] = c_color[4];
|
|
Packit |
ed3af9 |
buf[1] = c_color[5];
|
|
Packit |
ed3af9 |
buf[2] = c_color[6];
|
|
Packit |
ed3af9 |
green = strtol(buf, NULL, 16);
|
|
Packit |
ed3af9 |
green /= 64;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
buf[0] = c_color[7];
|
|
Packit |
ed3af9 |
buf[1] = c_color[8];
|
|
Packit |
ed3af9 |
buf[2] = c_color[9];
|
|
Packit |
ed3af9 |
blue = strtol(buf, NULL, 16);
|
|
Packit |
ed3af9 |
blue /= 64;
|
|
Packit |
ed3af9 |
break;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
case 13:
|
|
Packit |
ed3af9 |
buf[4] = '\0';
|
|
Packit |
ed3af9 |
buf[0] = c_color[1];
|
|
Packit |
ed3af9 |
buf[1] = c_color[2];
|
|
Packit |
ed3af9 |
buf[2] = c_color[3];
|
|
Packit |
ed3af9 |
buf[3] = c_color[4];
|
|
Packit |
ed3af9 |
red = strtol(buf, NULL, 16);
|
|
Packit |
ed3af9 |
red /= 256;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
buf[0] = c_color[5];
|
|
Packit |
ed3af9 |
buf[1] = c_color[6];
|
|
Packit |
ed3af9 |
buf[2] = c_color[7];
|
|
Packit |
ed3af9 |
buf[3] = c_color[8];
|
|
Packit |
ed3af9 |
green = strtol(buf, NULL, 16);
|
|
Packit |
ed3af9 |
green /= 256;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
buf[0] = c_color[9];
|
|
Packit |
ed3af9 |
buf[1] = c_color[10];
|
|
Packit |
ed3af9 |
buf[2] = c_color[11];
|
|
Packit |
ed3af9 |
buf[3] = c_color[12];
|
|
Packit |
ed3af9 |
blue = strtol(buf, NULL, 16);
|
|
Packit |
ed3af9 |
blue /= 256;
|
|
Packit |
ed3af9 |
break;
|
|
Packit |
ed3af9 |
}
|
|
Packit |
ed3af9 |
} else if(!gdColorMapLookup(GD_COLOR_MAP_X11, c_color, &red, &green, &blue)) {
|
|
Packit |
ed3af9 |
continue;
|
|
Packit |
ed3af9 |
}
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
colors[i] = gdImageColorResolve(im, red, green, blue);
|
|
Packit |
ed3af9 |
}
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
pointer = (int *)image.data;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
for(i = 0; i < image.height; i++) {
|
|
Packit |
ed3af9 |
for(j = 0; j < image.width; j++) {
|
|
Packit |
ed3af9 |
k = *pointer++;
|
|
Packit |
ed3af9 |
gdImageSetPixel(im, j, i, colors[k]);
|
|
Packit |
ed3af9 |
}
|
|
Packit |
ed3af9 |
}
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
gdFree(colors);
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
done:
|
|
Packit |
ed3af9 |
XpmFreeXpmImage(&image);
|
|
Packit |
ed3af9 |
XpmFreeXpmInfo(&info;;
|
|
Packit |
ed3af9 |
return im;
|
|
Packit |
ed3af9 |
}
|
|
Packit |
ed3af9 |
#endif /* HAVE_LIBXPM */
|