|
Packit |
ed3af9 |
/* Convenience functions to read or write images from or to disk,
|
|
Packit |
ed3af9 |
* determining file type from the filename extension. */
|
|
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 <string.h>
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
#include "gd.h"
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
typedef gdImagePtr (BGD_STDCALL *ReadFn)(FILE *in);
|
|
Packit |
ed3af9 |
typedef void (BGD_STDCALL *WriteFn)(gdImagePtr im, FILE *out);
|
|
Packit |
ed3af9 |
typedef gdImagePtr (BGD_STDCALL *LoadFn)(char *filename);
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
#ifdef HAVE_LIBZ
|
|
Packit |
ed3af9 |
static void BGD_STDCALL writegd2(gdImagePtr im, FILE *out) {
|
|
Packit |
ed3af9 |
gdImageGd2(im, out, 0, GD2_FMT_COMPRESSED);
|
|
Packit |
ed3af9 |
}/* writegd*/
|
|
Packit |
ed3af9 |
#endif
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
#ifdef HAVE_LIBJPEG
|
|
Packit |
ed3af9 |
static void BGD_STDCALL writejpeg(gdImagePtr im, FILE *out) {
|
|
Packit |
ed3af9 |
gdImageJpeg(im, out, -1);
|
|
Packit |
ed3af9 |
}/* writejpeg*/
|
|
Packit |
ed3af9 |
#endif
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
static void BGD_STDCALL writewbmp(gdImagePtr im, FILE *out) {
|
|
Packit |
ed3af9 |
int fg = gdImageColorClosest(im, 0, 0, 0);
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
gdImageWBMP(im, fg, out);
|
|
Packit |
ed3af9 |
}/* writejpeg*/
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
static void BGD_STDCALL writebmp(gdImagePtr im, FILE *out) {
|
|
Packit |
ed3af9 |
gdImageBmp(im, out, GD_TRUE);
|
|
Packit |
ed3af9 |
}/* writejpeg*/
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
enum FType {UNKNOWN, PNG, JPG, GIF, TIFF, GD, GD2, WEBP};
|
|
Packit |
ed3af9 |
static struct FileType {
|
|
Packit |
ed3af9 |
const char *ext;
|
|
Packit |
ed3af9 |
ReadFn reader;
|
|
Packit |
ed3af9 |
WriteFn writer;
|
|
Packit |
ed3af9 |
LoadFn loader;
|
|
Packit |
ed3af9 |
} Types[] = {
|
|
Packit |
ed3af9 |
{".gif", gdImageCreateFromGif, gdImageGif, NULL},
|
|
Packit |
ed3af9 |
{".gd", gdImageCreateFromGd, gdImageGd, NULL},
|
|
Packit |
ed3af9 |
{".wbmp", gdImageCreateFromWBMP, writewbmp, NULL},
|
|
Packit |
ed3af9 |
{".bmp", gdImageCreateFromBmp, writebmp, NULL},
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
{".xbm", gdImageCreateFromXbm, NULL, NULL},
|
|
Packit |
ed3af9 |
{".tga", gdImageCreateFromTga, NULL, NULL},
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
#ifdef HAVE_LIBPNG
|
|
Packit |
ed3af9 |
{".png", gdImageCreateFromPng, gdImagePng, NULL},
|
|
Packit |
ed3af9 |
#endif
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
#ifdef HAVE_LIBJPEG
|
|
Packit |
ed3af9 |
{".jpg", gdImageCreateFromJpeg, writejpeg, NULL},
|
|
Packit |
ed3af9 |
{".jpeg", gdImageCreateFromJpeg, writejpeg, NULL},
|
|
Packit |
ed3af9 |
#endif
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
#ifdef HAVE_LIBTIFF
|
|
Packit |
ed3af9 |
{".tiff", gdImageCreateFromTiff, gdImageTiff, NULL},
|
|
Packit |
ed3af9 |
{".tif" , gdImageCreateFromTiff, gdImageTiff, NULL},
|
|
Packit |
ed3af9 |
#endif
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
#ifdef HAVE_LIBZ
|
|
Packit |
ed3af9 |
{".gd2", gdImageCreateFromGd2, writegd2, NULL},
|
|
Packit |
ed3af9 |
#endif
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
#ifdef HAVE_LIBWEBP
|
|
Packit |
ed3af9 |
{".webp", gdImageCreateFromWebp, gdImageWebp, NULL},
|
|
Packit |
ed3af9 |
#endif
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
#ifdef HAVE_LIBXPM
|
|
Packit |
ed3af9 |
{".xpm", NULL, NULL, gdImageCreateFromXpm},
|
|
Packit |
ed3af9 |
#endif
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
{NULL, NULL, NULL}
|
|
Packit |
ed3af9 |
};
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
struct FileType *
|
|
Packit |
ed3af9 |
ftype(const char *filename) {
|
|
Packit |
ed3af9 |
int n;
|
|
Packit |
ed3af9 |
char *ext;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
/* Find the file extension (i.e. the last period in the string. */
|
|
Packit |
ed3af9 |
ext = strrchr(filename, '.');
|
|
Packit |
ed3af9 |
if (!ext) return NULL;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
for (n = 0; Types[n].ext; n++) {
|
|
Packit |
ed3af9 |
if (strcasecmp(ext, Types[n].ext) == 0) {
|
|
Packit |
ed3af9 |
return &Types[n];
|
|
Packit |
ed3af9 |
}/* if */
|
|
Packit |
ed3af9 |
}/* for */
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
return NULL;
|
|
Packit |
ed3af9 |
}/* ftype*/
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
/*
|
|
Packit |
ed3af9 |
Function: gdSupportsFileType
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Tests if a given file type is supported by GD.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Given the name of an image file (which does not have to exist),
|
|
Packit |
ed3af9 |
returns 1 (i.e. TRUE) if <gdImageCreateFromFile> can read a file
|
|
Packit |
ed3af9 |
of that type. This is useful if you do not know which image types
|
|
Packit |
ed3af9 |
were enabled at compile time.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
If _writing_ is true, the result will be true only if
|
|
Packit |
ed3af9 |
<gdImageFile> can write a file of this type.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Note that filename parsing is done exactly the same as is done by
|
|
Packit |
ed3af9 |
<gdImageCreateFromFile> and <gdImageFile> and is subject to the
|
|
Packit |
ed3af9 |
same limitations.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Assuming LibGD is compiled with support for these image types, the
|
|
Packit |
ed3af9 |
following extensions are supported:
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
- .gif
|
|
Packit |
ed3af9 |
- .gd, .gd2
|
|
Packit |
ed3af9 |
- .wbmp
|
|
Packit |
ed3af9 |
- .bmp
|
|
Packit |
ed3af9 |
- .xbm
|
|
Packit |
ed3af9 |
- .tga
|
|
Packit |
ed3af9 |
- .png
|
|
Packit |
ed3af9 |
- .jpg, .jpeg
|
|
Packit |
ed3af9 |
- .tiff, .tif
|
|
Packit |
ed3af9 |
- .webp
|
|
Packit |
ed3af9 |
- .xpm
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Names are parsed case-insenstively.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Parameters:
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
filename - Filename with tested extension.
|
|
Packit |
ed3af9 |
writing - Flag: true tests if writing works
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Returns:
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
GD_TRUE (1) if the file type is supported, GD_FALSE (0) if not.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
*/
|
|
Packit |
ed3af9 |
BGD_DECLARE(int)
|
|
Packit |
ed3af9 |
gdSupportsFileType(const char *filename, int writing) {
|
|
Packit |
ed3af9 |
struct FileType *entry = ftype(filename);
|
|
Packit |
ed3af9 |
return !!entry && (!writing || !!entry->writer);
|
|
Packit |
ed3af9 |
}/* gdSupportsFileType*/
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
/*
|
|
Packit |
ed3af9 |
Function: gdImageCreateFromFile
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Read an image file of any supported.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Given the path to a file, <gdImageCreateFromFile> will open the
|
|
Packit |
ed3af9 |
file, read its contents with the appropriate _gdImageCreateFrom*_
|
|
Packit |
ed3af9 |
function and return it.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
File type is determined by the filename extension, so having an
|
|
Packit |
ed3af9 |
incorrect extension will probably not work. For example, renaming
|
|
Packit |
ed3af9 |
PNG image "foo.png" to "foo.gif" and then attempting to load it
|
|
Packit |
ed3af9 |
will fail even if GD supports both formats. See
|
|
Packit |
ed3af9 |
<gdSupportsFiletype> for more details.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
NULL is returned on error.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Parameters:
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
filename - the input file name
|
|
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 |
*/
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
BGD_DECLARE(gdImagePtr)
|
|
Packit |
ed3af9 |
gdImageCreateFromFile(const char *filename) {
|
|
Packit |
ed3af9 |
struct FileType *entry = ftype(filename);
|
|
Packit |
ed3af9 |
FILE *fh;
|
|
Packit |
ed3af9 |
gdImagePtr result;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
if (!entry) return NULL;
|
|
Packit |
ed3af9 |
if (entry->loader) return entry->loader((char *)filename);
|
|
Packit |
ed3af9 |
if (!entry->reader) return NULL;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
fh = fopen(filename, "rb");
|
|
Packit |
ed3af9 |
if (!fh) return NULL;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
result = entry->reader(fh);
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
fclose(fh);
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
return result;
|
|
Packit |
ed3af9 |
}/* gdImageCreateFromFile*/
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
/*
|
|
Packit |
ed3af9 |
Function: gdImageFile
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Writes an image to a file in the format indicated by the filename.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
File type is determined by the extension of the file name. See
|
|
Packit |
ed3af9 |
<gdSupportsFiletype> for an overview of the parsing.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
For file types that require extra arguments, <gdImageFile>
|
|
Packit |
ed3af9 |
attempts to use sane defaults:
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
<gdImageGd2> - chunk size = 0, compression is enabled.
|
|
Packit |
ed3af9 |
<gdImageJpeg> - quality = -1 (i.e. the reasonable default)
|
|
Packit |
ed3af9 |
<gdImageWBMP> - foreground is the darkest available color
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Everything else is called with the two-argument function and so
|
|
Packit |
ed3af9 |
will use the default values.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
<gdImageFile> has some rudimentary error detection and will return
|
|
Packit |
ed3af9 |
GD_FALSE (0) if a detectable error occurred. However, the image
|
|
Packit |
ed3af9 |
loaders do not normally return their error status so a result of
|
|
Packit |
ed3af9 |
GD_TRUE (1) does **not** mean the file was saved successfully.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Parameters:
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
im - The image to save.
|
|
Packit |
ed3af9 |
filename - The path to the file to which the image is saved.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
Returns:
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
GD_FALSE (0) if an error was detected, GD_TRUE (1) if not.
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
*/
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
BGD_DECLARE(int)
|
|
Packit |
ed3af9 |
gdImageFile(gdImagePtr im, const char *filename) {
|
|
Packit |
ed3af9 |
struct FileType *entry = ftype(filename);
|
|
Packit |
ed3af9 |
FILE *fh;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
if (!entry || !entry->writer) return GD_FALSE;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
fh = fopen(filename, "wb");
|
|
Packit |
ed3af9 |
if (!fh) return GD_FALSE;
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
entry->writer(im, fh);
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
fclose(fh);
|
|
Packit |
ed3af9 |
|
|
Packit |
ed3af9 |
return GD_TRUE;
|
|
Packit |
ed3af9 |
}/* gdImageFile*/
|
|
Packit |
ed3af9 |
|