- sync to 2.0.1

master
pierre 2006-04-05 15:42:56 +00:00
parent ff50323cfa
commit 1cdea7482e
38 changed files with 25851 additions and 24257 deletions

4165
src/gd.c

File diff suppressed because it is too large Load Diff

View File

@ -75,7 +75,7 @@ typedef struct gdImageStruct {
int sx;
int sy;
/* These are valid in palette images only. See also
/* 'alpha', which appears later in the structure to
'alpha', which appears later in the structure to
preserve binary backwards compatibility */
int colorsTotal;
int red[gdMaxColors];
@ -372,13 +372,27 @@ void* gdImageGdPtr(gdImagePtr im, int *size);
void* gdImageGd2Ptr(gdImagePtr im, int cs, int fmt, int *size);
void gdImageEllipse(gdImagePtr im, int cx, int cy, int w, int h, int color);
void gdImageArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color);
#define gdPie 0
/* Style is a bitwise OR ( | operator ) of these.
gdArc and gdChord are mutually exclusive;
gdChord just connects the starting and ending
angles with a straight line, while gdArc produces
a rounded edge. gdPie is a synonym for gdArc.
gdNoFill indicates that the arc or chord should be
outlined, not filled. gdEdged, used together with
gdNoFill, indicates that the beginning and ending
angles should be connected to the center; this is
a good way to outline (rather than fill) a
'pie slice'. */
#define gdArc 0
#define gdPie gdArc
#define gdChord 1
#define gdNoFill 2
#define gdEdged 4
void gdImageFilledEllipse(gdImagePtr im, int cx, int cy, int w, int h, int color, int style);
void gdImageFilledArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color, int style);
void gdImageArc(gdImagePtr im, int cx, int cy, int w, int h, int s, int e, int color);
void gdImageFilledEllipse(gdImagePtr im, int cx, int cy, int w, int h, int color);
void gdImageFillToBorder(gdImagePtr im, int x, int y, int border, int color);
void gdImageFill(gdImagePtr im, int x, int y, int color);
void gdImageCopy(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h);

View File

@ -1,57 +1,64 @@
#include <stdio.h>
#include "gd.h"
/* A short program which converts a .png file into a .gd file, for
your convenience in creating images on the fly from a
basis image that must be loaded quickly. The .gd format
is not intended to be a general-purpose format. */
your convenience in creating images on the fly from a
basis image that must be loaded quickly. The .gd format
is not intended to be a general-purpose format. */
int main(int argc, char **argv)
int
main (int argc, char **argv)
{
gdImagePtr im;
gdImagePtr pal;
FILE *in, *out;
if (argc != 3) {
fprintf(stderr, "Usage: gd2copypal palettefile.gd2 filename.gd2\n");
exit(1);
}
in = fopen(argv[1], "rb");
if (!in) {
fprintf(stderr, "Palette file does not exist!\n");
exit(1);
}
pal = gdImageCreateFromGd2(in);
fclose(in);
if (!pal) {
fprintf(stderr, "Palette is not in GD2 format!\n");
exit(1);
}
in = fopen(argv[2], "rb");
if (!in) {
fprintf(stderr, "Input file does not exist!\n");
exit(1);
}
im = gdImageCreateFromGd2(in);
fclose(in);
if (!im) {
fprintf(stderr, "Input is not in GD2 format!\n");
exit(1);
}
gdImagePtr im;
gdImagePtr pal;
FILE *in, *out;
if (argc != 3)
{
fprintf (stderr, "Usage: gd2copypal palettefile.gd2 filename.gd2\n");
exit (1);
}
in = fopen (argv[1], "rb");
if (!in)
{
fprintf (stderr, "Palette file does not exist!\n");
exit (1);
}
pal = gdImageCreateFromGd2 (in);
fclose (in);
if (!pal)
{
fprintf (stderr, "Palette is not in GD2 format!\n");
exit (1);
}
gdImagePaletteCopy(im, pal);
out = fopen(argv[2], "wb");
if (!out) {
fprintf(stderr, "Output file cannot be written to!\n");
gdImageDestroy(im);
exit(1);
}
gdImageGd2(im, out, 128, 2);
fclose(out);
gdImageDestroy(pal);
gdImageDestroy(im);
in = fopen (argv[2], "rb");
if (!in)
{
fprintf (stderr, "Input file does not exist!\n");
exit (1);
}
im = gdImageCreateFromGd2 (in);
fclose (in);
if (!im)
{
fprintf (stderr, "Input is not in GD2 format!\n");
exit (1);
}
return 0;
gdImagePaletteCopy (im, pal);
out = fopen (argv[2], "wb");
if (!out)
{
fprintf (stderr, "Output file cannot be written to!\n");
gdImageDestroy (im);
exit (1);
}
gdImageGd2 (im, out, 128, 2);
fclose (out);
gdImageDestroy (pal);
gdImageDestroy (im);
return 0;
}

View File

@ -1,55 +1,60 @@
#include <stdio.h>
#include <stdlib.h> /* for atoi */
#include <time.h> /* For time */
#include <stdlib.h> /* for atoi */
#include <time.h> /* For time */
#include "gd.h"
/* A short program which converts a .png file into a .gd file, for
your convenience in creating images on the fly from a
basis image that must be loaded quickly. The .gd format
is not intended to be a general-purpose format. */
your convenience in creating images on the fly from a
basis image that must be loaded quickly. The .gd format
is not intended to be a general-purpose format. */
int main(int argc, char **argv)
int
main (int argc, char **argv)
{
gdImagePtr im;
FILE *in;
int x, y, w, h;
int c;
int i;
int t0;
gdImagePtr im;
FILE *in;
int x, y, w, h;
int c;
int i;
int t0;
if (argc != 7) {
fprintf(stderr, "Usage: gd2time filename.gd count x y w h\n");
exit(1);
if (argc != 7)
{
fprintf (stderr, "Usage: gd2time filename.gd count x y w h\n");
exit (1);
}
c = atoi (argv[2]);
x = atoi (argv[3]);
y = atoi (argv[4]);
w = atoi (argv[5]);
h = atoi (argv[6]);
printf ("Extracting %d times from (%d, %d), size is %dx%d\n", c, x, y, w, h);
t0 = time (0);
for (i = 0; i < c; i++)
{
in = fopen (argv[1], "rb");
if (!in)
{
fprintf (stderr, "Input file does not exist!\n");
exit (1);
}
c = atoi(argv[2]);
x = atoi(argv[3]);
y = atoi(argv[4]);
w = atoi(argv[5]);
h = atoi(argv[6]);
im = gdImageCreateFromGd2Part (in, x, y, w, h);
fclose (in);
printf("Extracting %d times from (%d, %d), size is %dx%d\n", c, x, y, w, h);
if (!im)
{
fprintf (stderr, "Error reading source file!\n");
exit (1);
}
gdImageDestroy (im);
};
t0 = time (0) - t0;
printf ("%d seconds to extract (& destroy) %d times\n", t0, c);
t0 = time(0);
for (i=0; i < c; i++) {
in = fopen(argv[1], "rb");
if (!in) {
fprintf(stderr, "Input file does not exist!\n");
exit(1);
}
im = gdImageCreateFromGd2Part(in, x, y, w, h);
fclose(in);
if (!im) {
fprintf(stderr, "Error reading source file!\n");
exit(1);
}
gdImageDestroy(im);
};
t0 = time(0) - t0;
printf("%d seconds to extract (& destroy) %d times\n",t0, c);
return 0;
return 0;
}

View File

@ -1,40 +1,45 @@
#include <stdio.h>
#include "gd.h"
/* A short program which converts a .png file into a .gd file, for
your convenience in creating images on the fly from a
basis image that must be loaded quickly. The .gd format
is not intended to be a general-purpose format. */
your convenience in creating images on the fly from a
basis image that must be loaded quickly. The .gd format
is not intended to be a general-purpose format. */
int main(int argc, char **argv)
int
main (int argc, char **argv)
{
gdImagePtr im;
FILE *in, *out;
if (argc != 3) {
fprintf(stderr, "Usage: gd2topng filename.gd2 filename.png\n");
exit(1);
}
in = fopen(argv[1], "rb");
if (!in) {
fprintf(stderr, "Input file does not exist!\n");
exit(1);
}
im = gdImageCreateFromGd2(in);
fclose(in);
if (!im) {
fprintf(stderr, "Input is not in GD2 format!\n");
exit(1);
}
out = fopen(argv[2], "wb");
if (!out) {
fprintf(stderr, "Output file cannot be written to!\n");
gdImageDestroy(im);
exit(1);
}
gdImagePng(im, out);
fclose(out);
gdImageDestroy(im);
gdImagePtr im;
FILE *in, *out;
if (argc != 3)
{
fprintf (stderr, "Usage: gd2topng filename.gd2 filename.png\n");
exit (1);
}
in = fopen (argv[1], "rb");
if (!in)
{
fprintf (stderr, "Input file does not exist!\n");
exit (1);
}
im = gdImageCreateFromGd2 (in);
fclose (in);
if (!im)
{
fprintf (stderr, "Input is not in GD2 format!\n");
exit (1);
}
out = fopen (argv[2], "wb");
if (!out)
{
fprintf (stderr, "Output file cannot be written to!\n");
gdImageDestroy (im);
exit (1);
}
gdImagePng (im, out);
fclose (out);
gdImageDestroy (im);
return 0;
return 0;
}

View File

@ -1,3 +1,4 @@
#include <stdio.h>
#include <math.h>
#include <string.h>
@ -8,7 +9,7 @@
#define FALSE 0
/* Exported functions: */
extern void gdImageGd(gdImagePtr im, FILE *out);
extern void gdImageGd (gdImagePtr im, FILE * out);
/* Use this for commenting out debug-print statements. */
@ -19,60 +20,78 @@ extern void gdImageGd(gdImagePtr im, FILE *out);
/* */
/* Shared code to read color tables from gd file. */
/* */
int _gdGetColors(gdIOCtx *in, gdImagePtr im, int gd2xFlag)
int
_gdGetColors (gdIOCtx * in, gdImagePtr im, int gd2xFlag)
{
int i;
if (gd2xFlag) {
if (!gdGetByte(&im->trueColor, in)) {
goto fail1;
}
/* This should have been a word all along */
if (!im->trueColor) {
if (!gdGetWord(&im->colorsTotal, in)) {
goto fail1;
}
}
/* Int to accommodate truecolor single-color transparency */
if (!gdGetInt(&im->transparent, in)) {
goto fail1;
}
} else {
if (!gdGetByte(&im->colorsTotal, in)) {
goto fail1;
}
if (!gdGetWord(&im->transparent, in)) {
goto fail1;
}
if (im->transparent == 257) {
im->transparent = (-1);
}
int i;
if (gd2xFlag)
{
if (!gdGetByte (&im->trueColor, in))
{
goto fail1;
}
GD2_DBG(printf("Pallette had %d colours (T=%d)\n",im->colorsTotal, im->transparent));
/* This should have been a word all along */
if (!im->trueColor)
{
if (!gdGetWord (&im->colorsTotal, in))
{
goto fail1;
}
}
/* Int to accommodate truecolor single-color transparency */
if (!gdGetInt (&im->transparent, in))
{
goto fail1;
}
}
else
{
if (!gdGetByte (&im->colorsTotal, in))
{
goto fail1;
}
if (!gdGetWord (&im->transparent, in))
{
goto fail1;
}
if (im->transparent == 257)
{
im->transparent = (-1);
}
}
GD2_DBG (printf ("Pallette had %d colours (T=%d)\n", im->colorsTotal, im->transparent));
for (i=0; (i<gdMaxColors); i++) {
if (!gdGetByte(&im->red[i], in)) {
goto fail1;
}
if (!gdGetByte(&im->green[i], in)) {
goto fail1;
}
if (!gdGetByte(&im->blue[i], in)) {
goto fail1;
}
if (gd2xFlag) {
if (!gdGetByte(&im->alpha[i], in)) {
goto fail1;
}
}
}
for (i = 0; (i < gdMaxColors); i++)
{
if (!gdGetByte (&im->red[i], in))
{
goto fail1;
}
if (!gdGetByte (&im->green[i], in))
{
goto fail1;
}
if (!gdGetByte (&im->blue[i], in))
{
goto fail1;
}
if (gd2xFlag)
{
if (!gdGetByte (&im->alpha[i], in))
{
goto fail1;
}
}
}
for (i=0; (i < im->colorsTotal); i++) {
im->open[i] = 0;
};
for (i = 0; (i < im->colorsTotal); i++)
{
im->open[i] = 0;
};
return TRUE;
return TRUE;
fail1:
return FALSE;
return FALSE;
}
/* */
@ -80,151 +99,174 @@ fail1:
/* This is also called from _gd2CreateFromFile */
/* */
static
gdImagePtr _gdCreateFromFile(gdIOCtx *in, int *sx, int *sy)
gdImagePtr
_gdCreateFromFile (gdIOCtx * in, int *sx, int *sy)
{
gdImagePtr im;
int gd2xFlag = 0;
if (!gdGetWord(sx, in)) {
goto fail1;
}
if (*sx == 65535) {
/* This is a gd 2.0 .gd file */
gd2xFlag = 1;
if (!gdGetWord(sx, in)) {
goto fail1;
}
}
if (!gdGetWord(sy, in)) {
goto fail1;
}
GD2_DBG(printf("Image is %dx%d\n", *sx, *sy));
im = gdImageCreate(*sx, *sy);
if (!_gdGetColors(in, im, gd2xFlag)) {
goto fail2;
}
return im;
fail2:
gdImageDestroy(im);
fail1:
return 0;
}
gdImagePtr gdImageCreateFromGd(FILE *inFile)
{
gdImagePtr im;
gdIOCtx *in;
in = gdNewFileCtx(inFile);
im = gdImageCreateFromGdCtx(in);
in->free(in);
return im;
}
gdImagePtr gdImageCreateFromGdCtx(gdIOCtxPtr in)
{
int sx, sy;
int x, y;
gdImagePtr im;
/* Read the header */
im = _gdCreateFromFile(in, &sx, &sy);
if (im == NULL) {
goto fail1;
};
/* Then the data... */
for (y=0; (y<sy); y++) {
for (x=0; (x<sx); x++) {
int ch;
ch = gdGetC(in);
if (ch == EOF) {
goto fail2;
}
/* ROW-MAJOR IN GD 1.3 */
im->pixels[y][x] = ch;
}
gdImagePtr im;
int gd2xFlag = 0;
if (!gdGetWord (sx, in))
{
goto fail1;
}
if (*sx == 65535)
{
/* This is a gd 2.0 .gd file */
gd2xFlag = 1;
if (!gdGetWord (sx, in))
{
goto fail1;
}
}
if (!gdGetWord (sy, in))
{
goto fail1;
}
return im;
GD2_DBG (printf ("Image is %dx%d\n", *sx, *sy));
im = gdImageCreate (*sx, *sy);
if (!_gdGetColors (in, im, gd2xFlag))
{
goto fail2;
}
return im;
fail2:
gdImageDestroy (im);
fail1:
return 0;
}
gdImagePtr
gdImageCreateFromGd (FILE * inFile)
{
gdImagePtr im;
gdIOCtx *in;
in = gdNewFileCtx (inFile);
im = gdImageCreateFromGdCtx (in);
in->free (in);
return im;
}
gdImagePtr
gdImageCreateFromGdCtx (gdIOCtxPtr in)
{
int sx, sy;
int x, y;
gdImagePtr im;
/* Read the header */
im = _gdCreateFromFile (in, &sx, &sy);
if (im == NULL)
{
goto fail1;
};
/* Then the data... */
for (y = 0; (y < sy); y++)
{
for (x = 0; (x < sx); x++)
{
int ch;
ch = gdGetC (in);
if (ch == EOF)
{
goto fail2;
}
/* ROW-MAJOR IN GD 1.3 */
im->pixels[y][x] = ch;
}
}
return im;
fail2:
gdImageDestroy(im);
gdImageDestroy (im);
fail1:
return 0;
return 0;
}
void _gdPutColors(gdImagePtr im, gdIOCtx *out)
void
_gdPutColors (gdImagePtr im, gdIOCtx * out)
{
int i;
int trans;
int i;
int trans;
gdPutC(im->trueColor, out);
if (!im->trueColor) {
gdPutWord(im->colorsTotal, out);
}
gdPutInt(im->transparent, out);
if (!im->trueColor) {
for (i=0; (i<gdMaxColors); i++) {
gdPutC((unsigned char)im->red[i], out);
gdPutC((unsigned char)im->green[i], out);
gdPutC((unsigned char)im->blue[i], out);
gdPutC((unsigned char)im->alpha[i], out);
}
gdPutC (im->trueColor, out);
if (!im->trueColor)
{
gdPutWord (im->colorsTotal, out);
}
gdPutInt (im->transparent, out);
if (!im->trueColor)
{
for (i = 0; (i < gdMaxColors); i++)
{
gdPutC ((unsigned char) im->red[i], out);
gdPutC ((unsigned char) im->green[i], out);
gdPutC ((unsigned char) im->blue[i], out);
gdPutC ((unsigned char) im->alpha[i], out);
}
}
}
static
void _gdPutHeader(gdImagePtr im, gdIOCtx *out)
void
_gdPutHeader (gdImagePtr im, gdIOCtx * out)
{
/* 65535 indicates this is a gd 2.x .gd file. */
gdPutWord(65535, out);
gdPutWord(im->sx, out);
gdPutWord(im->sy, out);
/* 65535 indicates this is a gd 2.x .gd file. */
gdPutWord (65535, out);
gdPutWord (im->sx, out);
gdPutWord (im->sy, out);
_gdPutColors(im, out);
_gdPutColors (im, out);
}
static void _gdImageGd(gdImagePtr im, gdIOCtx *out)
static void
_gdImageGd (gdImagePtr im, gdIOCtx * out)
{
int x, y;
int x, y;
_gdPutHeader(im, out);
_gdPutHeader (im, out);
for (y=0; (y < im->sy); y++) {
for (x=0; (x < im->sx); x++) {
/* ROW-MAJOR IN GD 1.3 */
if (im->trueColor) {
gdPutInt(im->tpixels[y][x], out);
} else {
gdPutC((unsigned char)im->pixels[y][x], out);
}
}
for (y = 0; (y < im->sy); y++)
{
for (x = 0; (x < im->sx); x++)
{
/* ROW-MAJOR IN GD 1.3 */
if (im->trueColor)
{
gdPutInt (im->tpixels[y][x], out);
}
else
{
gdPutC ((unsigned char) im->pixels[y][x], out);
}
}
}
}
void gdImageGd(gdImagePtr im, FILE *outFile)
void
gdImageGd (gdImagePtr im, FILE * outFile)
{
gdIOCtx *out = gdNewFileCtx(outFile);
_gdImageGd(im, out);
out->free(out);
gdIOCtx *out = gdNewFileCtx (outFile);
_gdImageGd (im, out);
out->free (out);
}
void* gdImageGdPtr(gdImagePtr im, int *size)
void *
gdImageGdPtr (gdImagePtr im, int *size)
{
void *rv;
gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
_gdImageGd(im, out);
rv = gdDPExtractData(out,size);
out->free(out);
return rv;
void *rv;
gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
_gdImageGd (im, out);
rv = gdDPExtractData (out, size);
out->free (out);
return rv;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,16 @@
/*
* io.c
*
* Implements the imple I/O 'helper' routines.
*
* Not really essential, but these routines were used extensively in GD,
* so they were moved here. They also make IOCtx calls look better...
*
* Written (or, at least, moved) 1999, Philip Warner.
*
*/
* io.c
*
* Implements the imple I/O 'helper' routines.
*
* Not really essential, but these routines were used extensively in GD,
* so they were moved here. They also make IOCtx calls look better...
*
* Written (or, at least, moved) 1999, Philip Warner.
*
*/
#include <math.h>
#include <string.h>
@ -25,133 +27,149 @@
* Write out a word to the I/O context pointer
*/
void
Putword(int w, gdIOCtx *ctx)
Putword (int w, gdIOCtx * ctx)
{
unsigned char buf[2];
buf[0] = w & 0xff;
buf[1] = (w / 256) & 0xff;
(ctx->putBuf)( ctx, (char *) buf, 2);
(ctx->putBuf) (ctx, (char *) buf, 2);
}
void
Putchar(int c, gdIOCtx *ctx)
Putchar (int c, gdIOCtx * ctx)
{
(ctx->putC)( ctx, c & 0xff );
}
void gdPutC(const unsigned char c, gdIOCtx *ctx)
{
(ctx->putC)(ctx, c);
(ctx->putC) (ctx, c & 0xff);
}
void
gdPutWord(int w, gdIOCtx *ctx)
gdPutC (const unsigned char c, gdIOCtx * ctx)
{
IO_DBG(printf("Putting word...\n"));
(ctx->putC)(ctx, (unsigned char)(w >> 8));
(ctx->putC)(ctx, (unsigned char)(w & 0xFF));
IO_DBG(printf("put.\n"));
(ctx->putC) (ctx, c);
}
void gdPutInt(int w, gdIOCtx *ctx)
void
gdPutWord (int w, gdIOCtx * ctx)
{
IO_DBG(printf("Putting int...\n"));
(ctx->putC)(ctx, (unsigned char)(w >> 24));
(ctx->putC)(ctx, (unsigned char)((w >> 16) & 0xFF));
(ctx->putC)(ctx, (unsigned char)((w >> 8) & 0xFF));
(ctx->putC)(ctx, (unsigned char)(w & 0xFF));
IO_DBG(printf("put.\n"));
IO_DBG (printf ("Putting word...\n"));
(ctx->putC) (ctx, (unsigned char) (w >> 8));
(ctx->putC) (ctx, (unsigned char) (w & 0xFF));
IO_DBG (printf ("put.\n"));
}
int gdGetC(gdIOCtx *ctx)
void
gdPutInt (int w, gdIOCtx * ctx)
{
return ((ctx->getC)(ctx));
IO_DBG (printf ("Putting int...\n"));
(ctx->putC) (ctx, (unsigned char) (w >> 24));
(ctx->putC) (ctx, (unsigned char) ((w >> 16) & 0xFF));
(ctx->putC) (ctx, (unsigned char) ((w >> 8) & 0xFF));
(ctx->putC) (ctx, (unsigned char) (w & 0xFF));
IO_DBG (printf ("put.\n"));
}
int
gdGetC (gdIOCtx * ctx)
{
return ((ctx->getC) (ctx));
}
int gdGetByte(int *result, gdIOCtx *ctx)
int
gdGetByte (int *result, gdIOCtx * ctx)
{
int r;
r = (ctx->getC)(ctx);
if (r == EOF) {
return 0;
}
*result = r;
return 1;
int r;
r = (ctx->getC) (ctx);
if (r == EOF)
{
return 0;
}
*result = r;
return 1;
}
int gdGetWord(int *result, gdIOCtx *ctx)
int
gdGetWord (int *result, gdIOCtx * ctx)
{
int r;
r = (ctx->getC)(ctx);
if (r == EOF) {
return 0;
}
*result = r << 8;
r = (ctx->getC)(ctx);
if (r == EOF) {
return 0;
}
*result += r;
return 1;
int r;
r = (ctx->getC) (ctx);
if (r == EOF)
{
return 0;
}
*result = r << 8;
r = (ctx->getC) (ctx);
if (r == EOF)
{
return 0;
}
*result += r;
return 1;
}
int gdGetInt(int *result, gdIOCtx *ctx)
int
gdGetInt (int *result, gdIOCtx * ctx)
{
int r;
r = (ctx->getC)(ctx);
if (r == EOF) {
return 0;
}
*result = r << 24;
int r;
r = (ctx->getC) (ctx);
if (r == EOF)
{
return 0;
}
*result = r << 24;
r = (ctx->getC)(ctx);
if (r == EOF) {
return 0;
}
*result += r << 16;
r = (ctx->getC) (ctx);
if (r == EOF)
{
return 0;
}
*result += r << 16;
r = (ctx->getC)(ctx);
if (r == EOF) {
return 0;
}
*result += r << 8;
r = (ctx->getC) (ctx);
if (r == EOF)
{
return 0;
}
*result += r << 8;
r = (ctx->getC)(ctx);
if (r == EOF) {
return 0;
}
*result += r;
r = (ctx->getC) (ctx);
if (r == EOF)
{
return 0;
}
*result += r;
return 1;
return 1;
}
int gdPutBuf(const void *buf, int size, gdIOCtx* ctx)
int
gdPutBuf (const void *buf, int size, gdIOCtx * ctx)
{
IO_DBG(printf("Putting buf...\n"));
return (ctx->putBuf)(ctx, buf, size);
IO_DBG(printf("put.\n"));
IO_DBG (printf ("Putting buf...\n"));
return (ctx->putBuf) (ctx, buf, size);
IO_DBG (printf ("put.\n"));
}
int gdGetBuf(void *buf, int size, gdIOCtx* ctx)
int
gdGetBuf (void *buf, int size, gdIOCtx * ctx)
{
return (ctx->getBuf)(ctx, buf, size);
return (ctx->getBuf) (ctx, buf, size);
}
int gdSeek(gdIOCtx *ctx, const int pos)
int
gdSeek (gdIOCtx * ctx, const int pos)
{
IO_DBG(printf("Seeking...\n"));
return ((ctx->seek)(ctx, pos));
IO_DBG(printf("Done.\n"));
IO_DBG (printf ("Seeking...\n"));
return ((ctx->seek) (ctx, pos));
IO_DBG (printf ("Done.\n"));
}
long gdTell(gdIOCtx *ctx)
long
gdTell (gdIOCtx * ctx)
{
IO_DBG(printf("Telling...\n"));
return ((ctx->tell)(ctx));
IO_DBG(printf("told.\n"));
IO_DBG (printf ("Telling...\n"));
return ((ctx->tell) (ctx));
IO_DBG (printf ("told.\n"));
}

View File

@ -1,20 +1,21 @@
/*
* io_dp.c
*
* Implements the dynamic pointer interface.
*
* Based on GD.pm code by Lincoln Stein for interfacing to libgd.
* Added support for reading as well as support for 'tell' and 'seek'.
*
* As will all I/O modules, most functions are for local use only (called
* via function pointers in the I/O context).
*
* gdDPExtractData is the exception to this: it will return the pointer to
* the internal data, and reset the internal storage.
*
* Written/Modified 1999, Philip Warner.
*
*/
* io_dp.c
*
* Implements the dynamic pointer interface.
*
* Based on GD.pm code by Lincoln Stein for interfacing to libgd.
* Added support for reading as well as support for 'tell' and 'seek'.
*
* As will all I/O modules, most functions are for local use only (called
* via function pointers in the I/O context).
*
* gdDPExtractData is the exception to this: it will return the pointer to
* the internal data, and reset the internal storage.
*
* Written/Modified 1999, Philip Warner.
*
*/
#include <math.h>
#include <string.h>
@ -25,55 +26,63 @@
#define TRUE 1
#define FALSE 0
/* this is used for creating images in main memory*/
typedef struct dpStruct {
void* data;
int logicalSize;
int realSize;
int dataGood;
int pos;
} dynamicPtr;
/* this is used for creating images in main memory */
typedef struct dpStruct
{
void *data;
int logicalSize;
int realSize;
int dataGood;
int pos;
}
dynamicPtr;
typedef struct dpIOCtx {
gdIOCtx ctx;
dynamicPtr *dp;
} dpIOCtx;
typedef struct dpIOCtx
{
gdIOCtx ctx;
dynamicPtr *dp;
}
dpIOCtx;
typedef struct dpIOCtx *dpIOCtxPtr;
typedef struct dpIOCtx *dpIOCtxPtr;
/* these functions operate on in-memory dynamic pointers */
static int allocDynamic (dynamicPtr* dp,int initialSize, void *data);
static int appendDynamic (dynamicPtr* dp, const void* src, int size);
static int gdReallocDynamic (dynamicPtr* dp, int required);
static int trimDynamic (dynamicPtr* dp);
static void gdFreeDynamicCtx(struct gdIOCtx* ctx);
static dynamicPtr* newDynamic(int initialSize, void *data);
static int allocDynamic (dynamicPtr * dp, int initialSize, void *data);
static int appendDynamic (dynamicPtr * dp, const void *src, int size);
static int gdReallocDynamic (dynamicPtr * dp, int required);
static int trimDynamic (dynamicPtr * dp);
static void gdFreeDynamicCtx (struct gdIOCtx *ctx);
static dynamicPtr *newDynamic (int initialSize, void *data);
static int dynamicPutbuf( struct gdIOCtx*, const void *, int );
static void dynamicPutchar( struct gdIOCtx*, int a );
static int dynamicPutbuf (struct gdIOCtx *, const void *, int);
static void dynamicPutchar (struct gdIOCtx *, int a);
static int dynamicGetbuf( gdIOCtxPtr ctx, void *buf, int len);
static int dynamicGetchar( gdIOCtxPtr ctx );
static int dynamicGetbuf (gdIOCtxPtr ctx, void *buf, int len);
static int dynamicGetchar (gdIOCtxPtr ctx);
static int dynamicSeek(struct gdIOCtx*, const int);
static long dynamicTell(struct gdIOCtx*);
static int dynamicSeek (struct gdIOCtx *, const int);
static long dynamicTell (struct gdIOCtx *);
/* return data as a dynamic pointer */
gdIOCtx* gdNewDynamicCtx (int initialSize, void *data) {
dpIOCtx *ctx;
dynamicPtr* dp;
gdIOCtx *
gdNewDynamicCtx (int initialSize, void *data)
{
dpIOCtx *ctx;
dynamicPtr *dp;
ctx = (dpIOCtx*) gdMalloc(sizeof(dpIOCtx));
if (ctx == NULL) {
return NULL;
}
ctx = (dpIOCtx *) gdMalloc (sizeof (dpIOCtx));
if (ctx == NULL)
{
return NULL;
}
dp = newDynamic(initialSize, data);
if (!dp) {
gdFree(ctx);
return NULL;
};
dp = newDynamic (initialSize, data);
if (!dp)
{
gdFree (ctx);
return NULL;
};
ctx->dp = dp;
@ -88,96 +97,109 @@ gdIOCtx* gdNewDynamicCtx (int initialSize, void *data) {
ctx->ctx.free = gdFreeDynamicCtx;
return (gdIOCtx*)ctx;
return (gdIOCtx *) ctx;
}
void* gdDPExtractData(struct gdIOCtx* ctx, int *size)
void *
gdDPExtractData (struct gdIOCtx *ctx, int *size)
{
dynamicPtr *dp;
dpIOCtx *dctx;
void *data;
dynamicPtr *dp;
dpIOCtx *dctx;
void *data;
dctx = (dpIOCtx*) ctx;
dctx = (dpIOCtx *) ctx;
dp = dctx->dp;
/* clean up the data block and return it */
if (dp->dataGood) {
trimDynamic(dp);
*size = dp->logicalSize;
data = dp->data;
} else {
*size = 0;
data = NULL;
if (dp->data != NULL) {
gdFree(dp->data);
if (dp->dataGood)
{
trimDynamic (dp);
*size = dp->logicalSize;
data = dp->data;
}
else
{
*size = 0;
data = NULL;
if (dp->data != NULL)
{
gdFree (dp->data);
}
}
}
dp->data = NULL;
dp->realSize=0;
dp->logicalSize=0;
dp->realSize = 0;
dp->logicalSize = 0;
return data;
}
static
void gdFreeDynamicCtx(struct gdIOCtx* ctx)
void
gdFreeDynamicCtx (struct gdIOCtx *ctx)
{
dynamicPtr *dp;
dpIOCtx *dctx;
dynamicPtr *dp;
dpIOCtx *dctx;
dctx = (dpIOCtx*) ctx;
dctx = (dpIOCtx *) ctx;
dp = dctx->dp;
gdFree(ctx);
gdFree (ctx);
/* clean up the data block and return it */
if (dp->data != NULL) {
gdFree(dp->data);
dp->data = NULL;
}
if (dp->data != NULL)
{
gdFree (dp->data);
dp->data = NULL;
}
dp->realSize=0;
dp->logicalSize=0;
dp->realSize = 0;
dp->logicalSize = 0;
gdFree(dp);
gdFree (dp);
}
static long dynamicTell(struct gdIOCtx* ctx)
static long
dynamicTell (struct gdIOCtx *ctx)
{
dpIOCtx *dctx;
dpIOCtx *dctx;
dctx = (dpIOCtx*) ctx;
dctx = (dpIOCtx *) ctx;
return (dctx->dp->pos);
}
static int dynamicSeek(struct gdIOCtx* ctx, const int pos)
static int
dynamicSeek (struct gdIOCtx *ctx, const int pos)
{
int bytesNeeded;
dynamicPtr *dp;
dpIOCtx *dctx;
int bytesNeeded;
dynamicPtr *dp;
dpIOCtx *dctx;
dctx = (dpIOCtx*) ctx;
dctx = (dpIOCtx *) ctx;
dp = dctx->dp;
if (!dp->dataGood) return FALSE;
if (!dp->dataGood)
return FALSE;
bytesNeeded = pos;
if (bytesNeeded > dp->realSize) {
if (!gdReallocDynamic(dp,dp->realSize*2)) {
dp->dataGood = FALSE;
return FALSE;
if (bytesNeeded > dp->realSize)
{
if (!gdReallocDynamic (dp, dp->realSize * 2))
{
dp->dataGood = FALSE;
return FALSE;
}
}
}
/* if we get here, we can be sure that we have enough bytes
to copy safely */
/* Extend the logical size if we seek beyond EOF. */
if (pos > dp->logicalSize) {
dp->logicalSize = pos;
};
if (pos > dp->logicalSize)
{
dp->logicalSize = pos;
};
dp->pos = pos;
@ -185,14 +207,17 @@ static int dynamicSeek(struct gdIOCtx* ctx, const int pos)
}
/* return data as a dynamic pointer */
static dynamicPtr* newDynamic (int initialSize, void *data) {
dynamicPtr* dp;
dp = (dynamicPtr*) gdMalloc(sizeof(dynamicPtr));
if (dp == NULL) {
return NULL;
}
static dynamicPtr *
newDynamic (int initialSize, void *data)
{
dynamicPtr *dp;
dp = (dynamicPtr *) gdMalloc (sizeof (dynamicPtr));
if (dp == NULL)
{
return NULL;
}
if (!allocDynamic(dp,initialSize, data))
if (!allocDynamic (dp, initialSize, data))
return NULL;
dp->pos = 0;
@ -200,161 +225,186 @@ static dynamicPtr* newDynamic (int initialSize, void *data) {
return dp;
}
static int
dynamicPutbuf( struct gdIOCtx* ctx, const void *buf, int size )
static int
dynamicPutbuf (struct gdIOCtx *ctx, const void *buf, int size)
{
dpIOCtx *dctx;
dctx = (dpIOCtx*) ctx;
dpIOCtx *dctx;
dctx = (dpIOCtx *) ctx;
appendDynamic(dctx->dp,buf,size);
appendDynamic (dctx->dp, buf, size);
if (dctx->dp->dataGood) {
return size;
} else {
return -1;
};
if (dctx->dp->dataGood)
{
return size;
}
else
{
return -1;
};
}
static void
dynamicPutchar( struct gdIOCtx* ctx, int a )
dynamicPutchar (struct gdIOCtx *ctx, int a)
{
unsigned char b;
dpIOCtxPtr dctx;
dpIOCtxPtr dctx;
b = a;
dctx = (dpIOCtxPtr) ctx;
appendDynamic(dctx->dp,&b,1);
appendDynamic (dctx->dp, &b, 1);
}
static int
dynamicGetbuf( gdIOCtxPtr ctx, void *buf, int len)
dynamicGetbuf (gdIOCtxPtr ctx, void *buf, int len)
{
int rlen, remain;
dpIOCtxPtr dctx;
dynamicPtr* dp;
int rlen, remain;
dpIOCtxPtr dctx;
dynamicPtr *dp;
dctx = (dpIOCtxPtr) ctx;
dp = dctx->dp;
dctx = (dpIOCtxPtr) ctx;
dp = dctx->dp;
remain = dp->logicalSize - dp->pos;
if (remain >= len) {
rlen = len;
} else {
if (remain == 0) {
return EOF;
}
rlen = remain;
remain = dp->logicalSize - dp->pos;
if (remain >= len)
{
rlen = len;
}
else
{
if (remain == 0)
{
return EOF;
}
rlen = remain;
}
memcpy(buf, (void*)((char*)dp->data + dp->pos), rlen);
dp->pos += rlen;
memcpy (buf, (void *) ((char *) dp->data + dp->pos), rlen);
dp->pos += rlen;
return rlen;
return rlen;
}
static int
dynamicGetchar( gdIOCtxPtr ctx )
dynamicGetchar (gdIOCtxPtr ctx)
{
unsigned char b;
int rv;
unsigned char b;
int rv;
rv = dynamicGetbuf(ctx, &b, 1);
rv = dynamicGetbuf (ctx, &b, 1);
if (rv != 1) {
return EOF;
} else {
return b ;/* (b & 0xff); */
}
}
if (rv != 1)
{
return EOF;
}
else
{
return b; /* (b & 0xff); */
}
}
/* *********************************************************************
*
* InitDynamic - Return a dynamically resizable void*
*
* *********************************************************************
*/
static int
allocDynamic (dynamicPtr* dp,int initialSize, void *data) {
allocDynamic (dynamicPtr * dp, int initialSize, void *data)
{
if (data == NULL) {
if (data == NULL)
{
dp->logicalSize = 0;
dp->dataGood = FALSE;
dp->data = gdMalloc(initialSize);
} else {
dp->data = gdMalloc (initialSize);
}
else
{
dp->logicalSize = initialSize;
dp->dataGood = TRUE;
dp->data = data;
}
}
if (dp->data !=NULL) {
dp->realSize = initialSize;
dp->dataGood = TRUE;
dp->pos = 0;
return TRUE;
} else {
dp->realSize = 0;
return FALSE;
}
if (dp->data != NULL)
{
dp->realSize = initialSize;
dp->dataGood = TRUE;
dp->pos = 0;
return TRUE;
}
else
{
dp->realSize = 0;
return FALSE;
}
}
/* append bytes to the end of a dynamic pointer */
static int
appendDynamic (dynamicPtr* dp, const void* src, int size) {
appendDynamic (dynamicPtr * dp, const void *src, int size)
{
int bytesNeeded;
char* tmp;
char *tmp;
if (!dp->dataGood) return FALSE;
if (!dp->dataGood)
return FALSE;
/* bytesNeeded = dp->logicalSize + size; */
bytesNeeded = dp->pos + size;
if (bytesNeeded > dp->realSize) {
if (!gdReallocDynamic(dp,bytesNeeded*2)) {
dp->dataGood = FALSE;
return FALSE;
if (bytesNeeded > dp->realSize)
{
if (!gdReallocDynamic (dp, bytesNeeded * 2))
{
dp->dataGood = FALSE;
return FALSE;
}
}
}
/* if we get here, we can be sure that we have enough bytes
to copy safely */
/*printf("Mem OK Size: %d, Pos: %d\n", dp->realSize, dp->pos); */
tmp = (char*)dp->data;
memcpy((void*)(tmp+(dp->pos)),src,size);
tmp = (char *) dp->data;
memcpy ((void *) (tmp + (dp->pos)), src, size);
dp->pos += size;
if (dp->pos > dp->logicalSize) {
dp->logicalSize = dp->pos;
};
if (dp->pos > dp->logicalSize)
{
dp->logicalSize = dp->pos;
};
return TRUE;
}
/* grow (or shrink) dynamic pointer */
static int
gdReallocDynamic (dynamicPtr* dp, int required) {
void* newPtr;
gdReallocDynamic (dynamicPtr * dp, int required)
{
void *newPtr;
/* First try gdRealloc(). If that doesn't work, make a new
memory block and copy. */
if ( (newPtr = gdRealloc(dp->data,required)) ) {
dp->realSize = required;
dp->data = newPtr;
return TRUE;
}
if ((newPtr = gdRealloc (dp->data, required)))
{
dp->realSize = required;
dp->data = newPtr;
return TRUE;
}
/* create a new pointer */
newPtr = gdMalloc(required);
if (!newPtr) {
dp->dataGood = FALSE;
return FALSE;
}
newPtr = gdMalloc (required);
if (!newPtr)
{
dp->dataGood = FALSE;
return FALSE;
}
/* copy the old data into it */
memcpy(newPtr,dp->data,dp->logicalSize);
gdFree(dp->data);
memcpy (newPtr, dp->data, dp->logicalSize);
gdFree (dp->data);
dp->data = newPtr;
dp->realSize = required;
@ -363,7 +413,7 @@ gdReallocDynamic (dynamicPtr* dp, int required) {
/* trim pointer so that its real and logical sizes match */
static int
trimDynamic (dynamicPtr* dp) {
return gdReallocDynamic(dp,dp->logicalSize);
trimDynamic (dynamicPtr * dp)
{
return gdReallocDynamic (dp, dp->logicalSize);
}

View File

@ -1,19 +1,20 @@
/*
* io_file.c
*
* Implements the file interface.
*
* As will all I/O modules, most functions are for local use only (called
* via function pointers in the I/O context).
*
* Most functions are just 'wrappers' for standard file functions.
*
* Written/Modified 1999, Philip Warner.
*
*/
* io_file.c
*
* Implements the file interface.
*
* As will all I/O modules, most functions are for local use only (called
* via function pointers in the I/O context).
*
* Most functions are just 'wrappers' for standard file functions.
*
* Written/Modified 1999, Philip Warner.
*
*/
/* For platforms with incomplete ANSI defines. Fortunately,
SEEK_SET is defined to be zero by the standard. */
SEEK_SET is defined to be zero by the standard. */
#ifndef SEEK_SET
#define SEEK_SET 0
@ -25,34 +26,39 @@
#include "gd.h"
#include "gdhelpers.h"
/* this is used for creating images in main memory*/
/* this is used for creating images in main memory */
typedef struct fileIOCtx {
gdIOCtx ctx;
FILE *f;
} fileIOCtx;
typedef struct fileIOCtx
{
gdIOCtx ctx;
FILE *f;
}
fileIOCtx;
struct fileIOCtx *fileIOCtxPtr;
struct fileIOCtx *fileIOCtxPtr;
gdIOCtx* newFileCtx(FILE *f);
gdIOCtx *newFileCtx (FILE * f);
static int fileGetbuf( gdIOCtx*, void *, int );
static int filePutbuf( gdIOCtx*, const void *, int );
static void filePutchar( gdIOCtx*, int );
static int fileGetchar( gdIOCtx* ctx);
static int fileGetbuf (gdIOCtx *, void *, int);
static int filePutbuf (gdIOCtx *, const void *, int);
static void filePutchar (gdIOCtx *, int);
static int fileGetchar (gdIOCtx * ctx);
static int fileSeek(struct gdIOCtx*, const int);
static long fileTell(struct gdIOCtx*);
static void gdFreeFileCtx(gdIOCtx *ctx);
static int fileSeek (struct gdIOCtx *, const int);
static long fileTell (struct gdIOCtx *);
static void gdFreeFileCtx (gdIOCtx * ctx);
/* return data as a dynamic pointer */
gdIOCtx* gdNewFileCtx (FILE *f) {
fileIOCtx *ctx;
gdIOCtx *
gdNewFileCtx (FILE * f)
{
fileIOCtx *ctx;
ctx = (fileIOCtx*) gdMalloc(sizeof(fileIOCtx));
if (ctx == NULL) {
return NULL;
}
ctx = (fileIOCtx *) gdMalloc (sizeof (fileIOCtx));
if (ctx == NULL)
{
return NULL;
}
ctx->f = f;
@ -67,70 +73,73 @@ gdIOCtx* gdNewFileCtx (FILE *f) {
ctx->ctx.free = gdFreeFileCtx;
return (gdIOCtx*)ctx;
return (gdIOCtx *) ctx;
}
static
void gdFreeFileCtx(gdIOCtx *ctx)
static
void
gdFreeFileCtx (gdIOCtx * ctx)
{
gdFree(ctx);
gdFree (ctx);
}
static int
filePutbuf( gdIOCtx* ctx, const void *buf, int size )
static int
filePutbuf (gdIOCtx * ctx, const void *buf, int size)
{
fileIOCtx *fctx;
fctx = (fileIOCtx*) ctx;
fileIOCtx *fctx;
fctx = (fileIOCtx *) ctx;
return fwrite(buf, 1, size, fctx->f);
return fwrite (buf, 1, size, fctx->f);
}
static int
fileGetbuf( gdIOCtx* ctx, void *buf, int size )
fileGetbuf (gdIOCtx * ctx, void *buf, int size)
{
fileIOCtx *fctx;
fctx = (fileIOCtx*) ctx;
fileIOCtx *fctx;
fctx = (fileIOCtx *) ctx;
return (fread(buf, 1, size, fctx->f));
return (fread (buf, 1, size, fctx->f));
}
static void
filePutchar( gdIOCtx* ctx, int a )
filePutchar (gdIOCtx * ctx, int a)
{
unsigned char b;
fileIOCtx *fctx;
fctx = (fileIOCtx*) ctx;
fileIOCtx *fctx;
fctx = (fileIOCtx *) ctx;
b = a;
putc(b, fctx->f);
putc (b, fctx->f);
}
static int fileGetchar( gdIOCtx* ctx)
static int
fileGetchar (gdIOCtx * ctx)
{
fileIOCtx *fctx;
fctx = (fileIOCtx*) ctx;
fileIOCtx *fctx;
fctx = (fileIOCtx *) ctx;
return getc(fctx->f);
return getc (fctx->f);
}
static int fileSeek(struct gdIOCtx* ctx, const int pos)
static int
fileSeek (struct gdIOCtx *ctx, const int pos)
{
fileIOCtx *fctx;
fctx = (fileIOCtx*) ctx;
fileIOCtx *fctx;
fctx = (fileIOCtx *) ctx;
return (fseek(fctx->f, pos, SEEK_SET) == 0);
return (fseek (fctx->f, pos, SEEK_SET) == 0);
}
static long fileTell(struct gdIOCtx* ctx)
static long
fileTell (struct gdIOCtx *ctx)
{
fileIOCtx *fctx;
fctx = (fileIOCtx*) ctx;
fileIOCtx *fctx;
fctx = (fileIOCtx *) ctx;
return ftell(fctx->f);
return ftell (fctx->f);
}

View File

@ -1,24 +1,25 @@
/*
* io_ss.c
*
* Implements the Source/Sink interface.
*
* As will all I/O modules, most functions are for local use only (called
* via function pointers in the I/O context).
*
* The Source/Sink model is the primary 'user' interface for alternate data
* sources; the IOCtx interface is intended (at least in version 1.5) to be
* used internally until it settles down a bit.
*
* This module just layers the Source/Sink interface on top of the IOCtx; no
* support is provided for tell/seek, so GD2 writing is not possible, and
* retrieving parts of GD2 files is also not possible.
*
* A new SS context does not need to be created with both a Source and a Sink.
*
* Written/Modified 1999, Philip Warner.
*
*/
* io_ss.c
*
* Implements the Source/Sink interface.
*
* As will all I/O modules, most functions are for local use only (called
* via function pointers in the I/O context).
*
* The Source/Sink model is the primary 'user' interface for alternate data
* sources; the IOCtx interface is intended (at least in version 1.5) to be
* used internally until it settles down a bit.
*
* This module just layers the Source/Sink interface on top of the IOCtx; no
* support is provided for tell/seek, so GD2 writing is not possible, and
* retrieving parts of GD2 files is also not possible.
*
* A new SS context does not need to be created with both a Source and a Sink.
*
* Written/Modified 1999, Philip Warner.
*
*/
#include <math.h>
#include <string.h>
@ -26,32 +27,37 @@
#include "gd.h"
#include "gdhelpers.h"
/* this is used for creating images in main memory*/
/* this is used for creating images in main memory */
typedef struct ssIOCtx {
gdIOCtx ctx;
gdSourcePtr src;
gdSinkPtr snk;
} ssIOCtx;
typedef struct ssIOCtx
{
gdIOCtx ctx;
gdSourcePtr src;
gdSinkPtr snk;
}
ssIOCtx;
typedef struct ssIOCtx *ssIOCtxPtr;
typedef struct ssIOCtx *ssIOCtxPtr;
gdIOCtx* gdNewSSCtx(gdSourcePtr src, gdSinkPtr snk);
gdIOCtx *gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk);
static int sourceGetbuf( gdIOCtx*, void *, int );
static int sourceGetchar( gdIOCtx* ctx);
static int sinkPutbuf( gdIOCtx* ctx, const void *buf, int size );
static void sinkPutchar( gdIOCtx* ctx, int a );
static void gdFreeSsCtx(gdIOCtx *ctx);
static int sourceGetbuf (gdIOCtx *, void *, int);
static int sourceGetchar (gdIOCtx * ctx);
static int sinkPutbuf (gdIOCtx * ctx, const void *buf, int size);
static void sinkPutchar (gdIOCtx * ctx, int a);
static void gdFreeSsCtx (gdIOCtx * ctx);
/* return data as a dynamic pointer */
gdIOCtx* gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk) {
ssIOCtxPtr ctx;
gdIOCtx *
gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk)
{
ssIOCtxPtr ctx;
ctx = (ssIOCtxPtr) gdMalloc(sizeof(ssIOCtx));
if (ctx == NULL) {
return NULL;
}
ctx = (ssIOCtxPtr) gdMalloc (sizeof (ssIOCtx));
if (ctx == NULL)
{
return NULL;
}
ctx->src = src;
ctx->snk = snk;
@ -67,82 +73,93 @@ gdIOCtx* gdNewSSCtx (gdSourcePtr src, gdSinkPtr snk) {
ctx->ctx.free = gdFreeSsCtx;
return (gdIOCtx*)ctx;
return (gdIOCtx *) ctx;
}
static
void gdFreeSsCtx(gdIOCtx *ctx)
void
gdFreeSsCtx (gdIOCtx * ctx)
{
gdFree(ctx);
gdFree (ctx);
}
static int
sourceGetbuf( gdIOCtx* ctx, void *buf, int size )
sourceGetbuf (gdIOCtx * ctx, void *buf, int size)
{
ssIOCtx *lctx;
int res;
ssIOCtx *lctx;
int res;
lctx = (ssIOCtx*) ctx;
lctx = (ssIOCtx *) ctx;
res = ((lctx->src->source)(lctx->src->context, buf, size));
res = ((lctx->src->source) (lctx->src->context, buf, size));
/*
** Translate the return values from the Source object:
** 0 is EOF, -1 is error
*/
** Translate the return values from the Source object:
** 0 is EOF, -1 is error
*/
if (res == 0) {
return EOF;
} else if (res < 0) {
return 0;
} else {
return res;
};
if (res == 0)
{
return EOF;
}
else if (res < 0)
{
return 0;
}
else
{
return res;
};
}
static int sourceGetchar( gdIOCtx* ctx)
static int
sourceGetchar (gdIOCtx * ctx)
{
int res;
unsigned char buf;
res = sourceGetbuf(ctx, &buf, 1);
res = sourceGetbuf (ctx, &buf, 1);
if (res == 1) {
return buf;
} else {
return EOF;
};
if (res == 1)
{
return buf;
}
else
{
return EOF;
};
}
static int
sinkPutbuf( gdIOCtx* ctx, const void *buf, int size )
sinkPutbuf (gdIOCtx * ctx, const void *buf, int size)
{
ssIOCtxPtr lctx;
int res;
ssIOCtxPtr lctx;
int res;
lctx = (ssIOCtx*) ctx;
lctx = (ssIOCtx *) ctx;
res = (lctx->snk->sink)(lctx->snk->context, buf, size);
res = (lctx->snk->sink) (lctx->snk->context, buf, size);
if (res <= 0) {
return 0;
} else {
return res;
};
if (res <= 0)
{
return 0;
}
else
{
return res;
};
}
static void
sinkPutchar( gdIOCtx* ctx, int a )
sinkPutchar (gdIOCtx * ctx, int a)
{
unsigned char b;
unsigned char b;
b = a;
sinkPutbuf(ctx, &b, 1);
sinkPutbuf (ctx, &b, 1);
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -8,31 +8,31 @@
#define FALSE 0
/* Exported functions: */
extern void gdImagePngToSink(gdImagePtr im, gdSinkPtr out);
extern gdImagePtr gdImageCreateFromPngSource(gdSourcePtr inSource);
extern void gdImagePngToSink (gdImagePtr im, gdSinkPtr out);
extern gdImagePtr gdImageCreateFromPngSource (gdSourcePtr inSource);
/* Use this for commenting out debug-print statements. */
/* Just use the first '#define' to allow all the prints... */
/*#define GD_SS_DBG(s) (s) */
#define GD_SS_DBG(s)
void gdImagePngToSink(gdImagePtr im, gdSinkPtr outSink)
void
gdImagePngToSink (gdImagePtr im, gdSinkPtr outSink)
{
gdIOCtx *out = gdNewSSCtx(NULL,outSink);
gdImagePngCtx(im, out);
out->free(out);
gdIOCtx *out = gdNewSSCtx (NULL, outSink);
gdImagePngCtx (im, out);
out->free (out);
}
gdImagePtr gdImageCreateFromPngSource(gdSourcePtr inSource)
gdImagePtr
gdImageCreateFromPngSource (gdSourcePtr inSource)
{
gdIOCtx *in = gdNewSSCtx(inSource, NULL);
gdImagePtr im;
gdIOCtx *in = gdNewSSCtx (inSource, NULL);
gdImagePtr im;
im = gdImageCreateFromPngCtx(in);
im = gdImageCreateFromPngCtx (in);
in->free(in);
in->free (in);
return im;
return im;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,55 +1,57 @@
/*
WBMP: Wireless Bitmap Type 0: B/W, Uncompressed Bitmap
Specification of the WBMP format can be found in the file:
SPEC-WAESpec-19990524.pdf
You can download the WAP specification on: http://www.wapforum.com/
WBMP: Wireless Bitmap Type 0: B/W, Uncompressed Bitmap
Specification of the WBMP format can be found in the file:
SPEC-WAESpec-19990524.pdf
You can download the WAP specification on: http://www.wapforum.com/
gd_wbmp.c
gd_wbmp.c
Copyright (C) Johan Van den Brande (johan@vandenbrande.com)
Fixed: gdImageWBMPPtr, gdImageWBMP
Copyright (C) Johan Van den Brande (johan@vandenbrande.com)
Recoded: gdImageWBMPCtx for use with my wbmp library
(wbmp library included, but you can find the latest distribution
at http://www.vandenbrande.com/wbmp)
Fixed: gdImageWBMPPtr, gdImageWBMP
Implemented: gdImageCreateFromWBMPCtx, gdImageCreateFromWBMP
Recoded: gdImageWBMPCtx for use with my wbmp library
(wbmp library included, but you can find the latest distribution
at http://www.vandenbrande.com/wbmp)
---------------------------------------------------------------------------
Implemented: gdImageCreateFromWBMPCtx, gdImageCreateFromWBMP
Parts of this code are from Maurice Smurlo.
---------------------------------------------------------------------------
Parts of this code are from Maurice Smurlo.
** Copyright (C) Maurice Szmurlo --- T-SIT --- January 2000
** (Maurice.Szmurlo@info.unicaen.fr)
** Copyright (C) Maurice Szmurlo --- T-SIT --- January 2000
** (Maurice.Szmurlo@info.unicaen.fr)
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
---------------------------------------------------------------------------
Parts od this code are inspired by 'pbmtowbmp.c' and 'wbmptopbm.c' by
Terje Sannum <terje@looplab.com>.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
**
---------------------------------------------------------------------------
---------------------------------------------------------------------------
Parts od this code are inspired by 'pbmtowbmp.c' and 'wbmptopbm.c' by
Terje Sannum <terje@looplab.com>.
**
** Permission to use, copy, modify, and distribute this software and its
** documentation for any purpose and without fee is hereby granted, provided
** that the above copyright notice appear in all copies and that both that
** copyright notice and this permission notice appear in supporting
** documentation. This software is provided "as is" without express or
** implied warranty.
**
---------------------------------------------------------------------------
Todo:
Todo:
gdCreateFromWBMP function for reading WBMP files
gdCreateFromWBMP function for reading WBMP files
----------------------------------------------------------------------------
*/
----------------------------------------------------------------------------
*/
#include <gd.h>
#include <gdfonts.h>
@ -61,148 +63,156 @@
/* gd_putout
** ---------
** Wrapper around gdPutC for use with writewbmp
**
*/
void gd_putout( int i, void * out )
** ---------
** Wrapper around gdPutC for use with writewbmp
**
*/
void
gd_putout (int i, void *out)
{
gdPutC( i , (gdIOCtx *) out );
}
/* gd_getin
** --------
** Wrapper around gdGetC for use with readwbmp
**
*/
int gd_getin( void *in )
{
return( gdGetC( ( gdIOCtx *) in ) );
gdPutC (i, (gdIOCtx *) out);
}
/* gdImageWBMPCtx
** --------------
** Write the image as a wbmp file
** Parameters are:
** image: gd image structure;
** fg: the index of the foreground color. any other value will be
** considered as background and will not be written
** out: the stream where to write
*/
void gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out) {
int x, y, pos;
Wbmp *wbmp;
/* gd_getin
** --------
** Wrapper around gdGetC for use with readwbmp
**
*/
int
gd_getin (void *in)
{
return (gdGetC ((gdIOCtx *) in));
}
/* create the WBMP */
if ( (wbmp = createwbmp( gdImageSX(image), gdImageSY(image), WBMP_WHITE)) == NULL )
fprintf(stderr, "Could not create WBMP\n");
/* gdImageWBMPCtx
** --------------
** Write the image as a wbmp file
** Parameters are:
** image: gd image structure;
** fg: the index of the foreground color. any other value will be
** considered as background and will not be written
** out: the stream where to write
*/
void
gdImageWBMPCtx (gdImagePtr image, int fg, gdIOCtx * out)
{
/* fill up the WBMP structure */
pos = 0;
for(y=0; y<gdImageSY(image); y++)
int x, y, pos;
Wbmp *wbmp;
/* create the WBMP */
if ((wbmp = createwbmp (gdImageSX (image), gdImageSY (image), WBMP_WHITE)) == NULL)
fprintf (stderr, "Could not create WBMP\n");
/* fill up the WBMP structure */
pos = 0;
for (y = 0; y < gdImageSY (image); y++)
{
for (x = 0; x < gdImageSX (image); x++)
{
for(x=0; x<gdImageSX(image); x++)
{
if(gdImageGetPixel(image, x, y) == fg)
{
wbmp->bitmap[pos] = WBMP_BLACK;
}
pos++;
}
if (gdImageGetPixel (image, x, y) == fg)
{
wbmp->bitmap[pos] = WBMP_BLACK;
}
pos++;
}
}
/* write the WBMP to a gd file descriptor */
if ( writewbmp( wbmp, &gd_putout, out ) )
fprintf(stderr, "Could not save WBMP\n");
/* des submitted this bugfix: gdFree the memory. */
freewbmp(wbmp);
/* write the WBMP to a gd file descriptor */
if (writewbmp (wbmp, &gd_putout, out))
fprintf (stderr, "Could not save WBMP\n");
/* des submitted this bugfix: gdFree the memory. */
freewbmp (wbmp);
}
/* gdImageCreateFromWBMPCtx
** ------------------------
** Create a gdImage from a WBMP file input from an gdIOCtx
*/
gdImagePtr gdImageCreateFromWBMPCtx( gdIOCtx *infile )
** ------------------------
** Create a gdImage from a WBMP file input from an gdIOCtx
*/
gdImagePtr
gdImageCreateFromWBMPCtx (gdIOCtx * infile)
{
/* FILE *wbmp_file; */
Wbmp *wbmp;
gdImagePtr im = NULL;
int black, white;
int col, row, pos;
/* FILE *wbmp_file; */
Wbmp *wbmp;
gdImagePtr im = NULL;
int black, white;
int col, row, pos;
if ( readwbmp( &gd_getin, infile, &wbmp ) )
return (NULL);
if (readwbmp (&gd_getin, infile, &wbmp))
return (NULL);
if (!(im = gdImageCreate(wbmp->width, wbmp->height)))
if (!(im = gdImageCreate (wbmp->width, wbmp->height)))
{
freewbmp (wbmp);
return (NULL);
}
/* create the background color */
white = gdImageColorAllocate (im, 255, 255, 255);
/* create foreground color */
black = gdImageColorAllocate (im, 0, 0, 0);
/* fill in image (in a wbmp 1 = white/ 0 = black) */
pos = 0;
for (row = 0; row < wbmp->height; row++)
{
for (col = 0; col < wbmp->width; col++)
{
freewbmp( wbmp );
return (NULL);
if (wbmp->bitmap[pos++] == WBMP_WHITE)
{
gdImageSetPixel (im, col, row, white);
}
else
{
gdImageSetPixel (im, col, row, black);
}
}
}
/* create the background color */
white = gdImageColorAllocate(im, 255, 255, 255);
/* create foreground color */
black = gdImageColorAllocate(im, 0, 0, 0);
freewbmp (wbmp);
/* fill in image (in a wbmp 1 = white/ 0 = black) */
pos = 0;
for(row=0; row<wbmp->height; row++)
{
for(col=0; col<wbmp->width; col++)
{
if (wbmp->bitmap[pos++] == WBMP_WHITE)
{
gdImageSetPixel(im, col, row, white);
}
else
{
gdImageSetPixel(im, col, row, black);
}
}
}
freewbmp( wbmp );
return(im);
return (im);
}
/* gdImageCreateFromWBMP
** ---------------------
*/
gdImagePtr gdImageCreateFromWBMP( FILE *inFile )
** ---------------------
*/
gdImagePtr
gdImageCreateFromWBMP (FILE * inFile)
{
gdImagePtr im;
gdIOCtx *in = gdNewFileCtx( inFile );
im = gdImageCreateFromWBMPCtx( in );
in->free(in);
return (im);
gdImagePtr im;
gdIOCtx *in = gdNewFileCtx (inFile);
im = gdImageCreateFromWBMPCtx (in);
in->free (in);
return (im);
}
/* gdImageWBMP
** -----------
*/
void gdImageWBMP(gdImagePtr im, int fg, FILE *outFile)
** -----------
*/
void
gdImageWBMP (gdImagePtr im, int fg, FILE * outFile)
{
gdIOCtx *out = gdNewFileCtx(outFile);
gdImageWBMPCtx(im, fg, out);
out->free(out);
gdIOCtx *out = gdNewFileCtx (outFile);
gdImageWBMPCtx (im, fg, out);
out->free (out);
}
/* gdImageWBMPPtr
** --------------
*/
void *gdImageWBMPPtr(gdImagePtr im, int *size, int fg)
** --------------
*/
void *
gdImageWBMPPtr (gdImagePtr im, int *size, int fg)
{
void *rv;
gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
gdImageWBMPCtx(im, fg, out);
rv = gdDPExtractData(out, size);
out->free(out);
return rv;
void *rv;
gdIOCtx *out = gdNewDynamicCtx (2048, NULL);
gdImageWBMPCtx (im, fg, out);
rv = gdDPExtractData (out, size);
out->free (out);
return rv;
}

View File

@ -21,7 +21,7 @@
* John Ellson (ellson@lucent.com) Oct 31, 1997
*
* Test this with:
* gcc -o gdcache -g -Wall -DTEST gdcache.c
* gcc -o gdcache -g -Wall -DTEST gdcache.c
*
* The cache is implemented by a singly-linked list of elements
* each containing a pointer to a user struct that is being managed by
@ -31,10 +31,10 @@
* element, and elements are moved to this position in the list each
* time they are used. The head also contains pointers to three
* user defined functions:
* - a function to test if a cached userdata matches some keydata
* - a function to provide a new userdata struct to the cache
* - a function to test if a cached userdata matches some keydata
* - a function to provide a new userdata struct to the cache
* if there has been a cache miss.
* - a function to release a userdata struct when it is
* - a function to release a userdata struct when it is
* no longer being managed by the cache
*
* In the event of a cache miss the cache is allowed to grow up to
@ -58,80 +58,87 @@
/* create a new cache */
gdCache_head_t *
gdCacheCreate(
int size,
gdCacheTestFn_t gdCacheTest,
gdCacheFetchFn_t gdCacheFetch,
gdCacheReleaseFn_t gdCacheRelease )
gdCacheCreate (
int size,
gdCacheTestFn_t gdCacheTest,
gdCacheFetchFn_t gdCacheFetch,
gdCacheReleaseFn_t gdCacheRelease)
{
gdCache_head_t *head;
gdCache_head_t *head;
head = (gdCache_head_t *)gdMalloc(sizeof(gdCache_head_t));
head->mru = NULL;
head->size = size;
head->gdCacheTest = gdCacheTest;
head->gdCacheFetch = gdCacheFetch;
head->gdCacheRelease = gdCacheRelease;
return head;
head = (gdCache_head_t *) gdMalloc (sizeof (gdCache_head_t));
head->mru = NULL;
head->size = size;
head->gdCacheTest = gdCacheTest;
head->gdCacheFetch = gdCacheFetch;
head->gdCacheRelease = gdCacheRelease;
return head;
}
void
gdCacheDelete( gdCache_head_t *head )
gdCacheDelete (gdCache_head_t * head)
{
gdCache_element_t *elem, *prev;
gdCache_element_t *elem, *prev;
elem = head->mru;
while(elem) {
(*(head->gdCacheRelease))(elem->userdata);
prev = elem;
elem = elem->next;
gdFree((char *)prev);
}
gdFree((char *)head);
elem = head->mru;
while (elem)
{
(*(head->gdCacheRelease)) (elem->userdata);
prev = elem;
elem = elem->next;
gdFree ((char *) prev);
}
gdFree ((char *) head);
}
void *
gdCacheGet( gdCache_head_t *head, void *keydata )
gdCacheGet (gdCache_head_t * head, void *keydata)
{
int i=0;
gdCache_element_t *elem, *prev = NULL, *prevprev = NULL;
void *userdata;
int i = 0;
gdCache_element_t *elem, *prev = NULL, *prevprev = NULL;
void *userdata;
elem = head->mru;
while(elem) {
if ((*(head->gdCacheTest))(elem->userdata, keydata)) {
if (i) { /* if not already most-recently-used */
/* relink to top of list */
prev->next = elem->next;
elem->next = head->mru;
head->mru = elem;
}
return elem->userdata;
}
prevprev = prev;
prev = elem;
elem = elem->next;
i++;
elem = head->mru;
while (elem)
{
if ((*(head->gdCacheTest)) (elem->userdata, keydata))
{
if (i)
{ /* if not already most-recently-used */
/* relink to top of list */
prev->next = elem->next;
elem->next = head->mru;
head->mru = elem;
}
return elem->userdata;
}
userdata = (*(head->gdCacheFetch))(&(head->error), keydata);
if (! userdata) {
/* if there was an error in the fetch then don't cache */
return NULL;
}
if (i < head->size) { /* cache still growing - add new elem */
elem = (gdCache_element_t *)gdMalloc(sizeof(gdCache_element_t));
}
else { /* cache full - replace least-recently-used */
/* preveprev becomes new end of list */
prevprev->next = NULL;
elem = prev;
(*(head->gdCacheRelease))(elem->userdata);
}
/* relink to top of list */
elem->next = head->mru;
head->mru = elem;
elem->userdata = userdata;
return userdata;
prevprev = prev;
prev = elem;
elem = elem->next;
i++;
}
userdata = (*(head->gdCacheFetch)) (&(head->error), keydata);
if (!userdata)
{
/* if there was an error in the fetch then don't cache */
return NULL;
}
if (i < head->size)
{ /* cache still growing - add new elem */
elem = (gdCache_element_t *) gdMalloc (sizeof (gdCache_element_t));
}
else
{ /* cache full - replace least-recently-used */
/* preveprev becomes new end of list */
prevprev->next = NULL;
elem = prev;
(*(head->gdCacheRelease)) (elem->userdata);
}
/* relink to top of list */
elem->next = head->mru;
head->mru = elem;
elem->userdata = userdata;
return userdata;
}
@ -145,60 +152,62 @@ gdCacheGet( gdCache_head_t *head, void *keydata )
#include <stdio.h>
typedef struct {
int key;
int value;
} key_value_t;
typedef struct
{
int key;
int value;
}
key_value_t;
static int
cacheTest( void *map, void *key )
cacheTest (void *map, void *key)
{
return (((key_value_t *)map)->key == *(int *)key);
return (((key_value_t *) map)->key == *(int *) key);
}
static void *
cacheFetch( char **error, void *key )
cacheFetch (char **error, void *key)
{
key_value_t *map;
key_value_t *map;
map = (key_value_t *)gdMalloc(sizeof(key_value_t));
map->key = *(int *)key;
map->value = 3;
map = (key_value_t *) gdMalloc (sizeof (key_value_t));
map->key = *(int *) key;
map->value = 3;
*error = NULL;
return (void *)map;
*error = NULL;
return (void *) map;
}
static void
cacheRelease( void *map)
cacheRelease (void *map)
{
gdFree( (char *)map );
gdFree ((char *) map);
}
int
main(char *argv[], int argc)
main (char *argv[], int argc)
{
gdCache_head_t *cacheTable;
int elem, key;
gdCache_head_t *cacheTable;
int elem, key;
cacheTable = gdCacheCreate(3, cacheTest, cacheFetch, cacheRelease);
cacheTable = gdCacheCreate (3, cacheTest, cacheFetch, cacheRelease);
key = 20;
elem = *(int *)gdCacheGet(cacheTable, &key);
key = 30;
elem = *(int *)gdCacheGet(cacheTable, &key);
key = 40;
elem = *(int *)gdCacheGet(cacheTable, &key);
key = 50;
elem = *(int *)gdCacheGet(cacheTable, &key);
key = 30;
elem = *(int *)gdCacheGet(cacheTable, &key);
key = 30;
elem = *(int *)gdCacheGet(cacheTable, &key);
key = 20;
elem = *(int *) gdCacheGet (cacheTable, &key);
key = 30;
elem = *(int *) gdCacheGet (cacheTable, &key);
key = 40;
elem = *(int *) gdCacheGet (cacheTable, &key);
key = 50;
elem = *(int *) gdCacheGet (cacheTable, &key);
key = 30;
elem = *(int *) gdCacheGet (cacheTable, &key);
key = 30;
elem = *(int *) gdCacheGet (cacheTable, &key);
gdCacheDelete(cacheTable);
gdCacheDelete (cacheTable);
return 0;
return 0;
}
#endif /* TEST */

View File

@ -3,111 +3,116 @@
#include "gdfontg.h"
#include "gdfonts.h"
int main(void)
int
main (void)
{
/* Input and output files */
FILE *in;
FILE *out;
/* Input and output files */
FILE *in;
FILE *out;
/* Input and output images */
gdImagePtr im_in = 0, im_out = 0;
/* Input and output images */
gdImagePtr im_in = 0, im_out = 0;
/* Brush image */
gdImagePtr brush;
/* Brush image */
gdImagePtr brush;
/* Color indexes */
int white;
int blue;
int red;
int green;
/* Color indexes */
int white;
int blue;
int red;
int green;
/* Points for polygon */
gdPoint points[3];
/* Points for polygon */
gdPoint points[3];
/* Create output image, 256 by 256 pixels, true color. */
im_out = gdImageCreateTrueColor(256, 256);
/* First color allocated is background. */
white = gdImageColorAllocate(im_out, 255, 255, 255);
/* Create output image, 256 by 256 pixels, true color. */
im_out = gdImageCreateTrueColor (256, 256);
/* First color allocated is background. */
white = gdImageColorAllocate (im_out, 255, 255, 255);
/* Set transparent color. */
gdImageColorTransparent(im_out, white);
/* Set transparent color. */
gdImageColorTransparent (im_out, white);
/* Try to load demoin.png and paste part of it into the
output image. */
in = fopen("demoin.png", "rb");
if (!in) {
fprintf(stderr, "Can't load source image; this demo\n");
fprintf(stderr, "is much more impressive if demoin.png\n");
fprintf(stderr, "is available.\n");
im_in = 0;
} else {
im_in = gdImageCreateFromPng(in);
fclose(in);
/* Now copy, and magnify as we do so */
gdImageCopyResized(im_out, im_in,
32, 32, 0, 0, 192, 192, 255, 255);
}
red = gdImageColorAllocate(im_out, 255, 0, 0);
green = gdImageColorAllocate(im_out, 0, 255, 0);
blue = gdImageColorAllocate(im_out, 0, 0, 255);
/* Rectangle */
gdImageLine(im_out, 16, 16, 240, 16, green);
gdImageLine(im_out, 240, 16, 240, 240, green);
gdImageLine(im_out, 240, 240, 16, 240, green);
gdImageLine(im_out, 16, 240, 16, 16, green);
/* Circle */
gdImageArc(im_out, 128, 128, 60, 20, 0, 720, blue);
/* Arc */
gdImageArc(im_out, 128, 128, 40, 40, 90, 270, blue);
/* Flood fill: doesn't do much on a continuously
variable tone jpeg original. */
gdImageFill(im_out, 8, 8, blue);
/* Polygon */
points[0].x = 64;
points[0].y = 0;
points[1].x = 0;
points[1].y = 128;
points[2].x = 128;
points[2].y = 128;
gdImageFilledPolygon(im_out, points, 3, green);
/* Brush. A fairly wild example also involving a line style! */
if (im_in) {
int style[8];
brush = gdImageCreateTrueColor(16, 16);
gdImageCopyResized(brush, im_in,
0, 0, 0, 0,
gdImageSX(brush), gdImageSY(brush),
gdImageSX(im_in), gdImageSY(im_in));
gdImageSetBrush(im_out, brush);
/* With a style, so they won't overprint each other.
Normally, they would, yielding a fat-brush effect. */
style[0] = 0;
style[1] = 0;
style[2] = 0;
style[3] = 0;
style[4] = 0;
style[5] = 0;
style[6] = 0;
style[7] = 1;
gdImageSetStyle(im_out, style, 8);
/* Draw the styled, brushed line */
gdImageLine(im_out, 0, 255, 255, 0, gdStyledBrushed);
}
/* Text */
gdImageString(im_out, gdFontGiant, 32, 32,
(unsigned char *) "hi", red);
gdImageStringUp(im_out, gdFontSmall, 64, 64,
(unsigned char *) "hi", red);
/* Make output image interlaced (progressive, in the case of JPEG) */
gdImageInterlace(im_out, 1);
out = fopen("demoout.png", "wb");
/* Write PNG */
gdImagePng(im_out, out);
fclose(out);
gdImageDestroy(im_out);
if (im_in) {
gdImageDestroy(im_in);
}
return 0;
/* Try to load demoin.png and paste part of it into the
output image. */
in = fopen ("demoin.png", "rb");
if (!in)
{
fprintf (stderr, "Can't load source image; this demo\n");
fprintf (stderr, "is much more impressive if demoin.png\n");
fprintf (stderr, "is available.\n");
im_in = 0;
}
else
{
im_in = gdImageCreateFromPng (in);
fclose (in);
/* Now copy, and magnify as we do so */
gdImageCopyResized (im_out, im_in,
32, 32, 0, 0, 192, 192, 255, 255);
}
red = gdImageColorAllocate (im_out, 255, 0, 0);
green = gdImageColorAllocate (im_out, 0, 255, 0);
blue = gdImageColorAllocate (im_out, 0, 0, 255);
/* Rectangle */
gdImageLine (im_out, 16, 16, 240, 16, green);
gdImageLine (im_out, 240, 16, 240, 240, green);
gdImageLine (im_out, 240, 240, 16, 240, green);
gdImageLine (im_out, 16, 240, 16, 16, green);
/* Circle */
gdImageArc (im_out, 128, 128, 60, 20, 0, 720, blue);
/* Arc */
gdImageArc (im_out, 128, 128, 40, 40, 90, 270, blue);
/* Flood fill: doesn't do much on a continuously
variable tone jpeg original. */
gdImageFill (im_out, 8, 8, blue);
/* Polygon */
points[0].x = 64;
points[0].y = 0;
points[1].x = 0;
points[1].y = 128;
points[2].x = 128;
points[2].y = 128;
gdImageFilledPolygon (im_out, points, 3, green);
/* Brush. A fairly wild example also involving a line style! */
if (im_in)
{
int style[8];
brush = gdImageCreateTrueColor (16, 16);
gdImageCopyResized (brush, im_in,
0, 0, 0, 0,
gdImageSX (brush), gdImageSY (brush),
gdImageSX (im_in), gdImageSY (im_in));
gdImageSetBrush (im_out, brush);
/* With a style, so they won't overprint each other.
Normally, they would, yielding a fat-brush effect. */
style[0] = 0;
style[1] = 0;
style[2] = 0;
style[3] = 0;
style[4] = 0;
style[5] = 0;
style[6] = 0;
style[7] = 1;
gdImageSetStyle (im_out, style, 8);
/* Draw the styled, brushed line */
gdImageLine (im_out, 0, 255, 255, 0, gdStyledBrushed);
}
/* Text */
gdImageString (im_out, gdFontGiant, 32, 32,
(unsigned char *) "hi", red);
gdImageStringUp (im_out, gdFontSmall, 64, 64,
(unsigned char *) "hi", red);
/* Make output image interlaced (progressive, in the case of JPEG) */
gdImageInterlace (im_out, 1);
out = fopen ("demoout.png", "wb");
/* Write PNG */
gdImagePng (im_out, out);
fclose (out);
gdImageDestroy (im_out);
if (im_in)
{
gdImageDestroy (im_in);
}
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1312
src/gdft.c

File diff suppressed because it is too large Load Diff

View File

@ -6,74 +6,90 @@
#define SEP_TEST (separators[*((unsigned char *) s)])
char *gd_strtok_r(char *s, char *sep, char **state)
char *
gd_strtok_r (char *s, char *sep, char **state)
{
char separators[256];
char *start;
char *result = 0;
memset(separators, 0, sizeof(separators));
while (*sep) {
separators[*((unsigned char *) sep)] = 1;
sep++;
char separators[256];
char *start;
char *result = 0;
memset (separators, 0, sizeof (separators));
while (*sep)
{
separators[*((unsigned char *) sep)] = 1;
sep++;
}
if (!s)
{
/* Pick up where we left off */
s = *state;
}
start = s;
/* 1. EOS */
if (!(*s))
{
*state = s;
return 0;
}
/* 2. Leading separators, if any */
if (SEP_TEST)
{
do
{
s++;
}
if (!s) {
/* Pick up where we left off */
s = *state;
while (SEP_TEST);
/* 2a. EOS after separators only */
if (!(*s))
{
*state = s;
return 0;
}
start = s;
/* 1. EOS */
if (!(*s)) {
*state = s;
return 0;
}
/* 3. A token */
result = s;
do
{
/* 3a. Token at end of string */
if (!(*s))
{
*state = s;
return result;
}
/* 2. Leading separators, if any */
if (SEP_TEST) {
do {
s++;
} while (SEP_TEST);
/* 2a. EOS after separators only */
if (!(*s)) {
*state = s;
return 0;
}
}
/* 3. A token */
result = s;
do {
/* 3a. Token at end of string */
if (!(*s)) {
*state = s;
return result;
}
s++;
} while (!SEP_TEST);
/* 4. Terminate token and skip trailing separators */
*s = '\0';
do {
s++;
} while (SEP_TEST);
/* 5. Return token */
*state = s;
return result;
s++;
}
while (!SEP_TEST);
/* 4. Terminate token and skip trailing separators */
*s = '\0';
do
{
s++;
}
while (SEP_TEST);
/* 5. Return token */
*state = s;
return result;
}
void *gdCalloc(size_t nmemb, size_t size)
void *
gdCalloc (size_t nmemb, size_t size)
{
return calloc(nmemb, size);
return calloc (nmemb, size);
}
void *gdMalloc(size_t size)
void *
gdMalloc (size_t size)
{
return malloc(size);
return malloc (size);
}
void *gdRealloc(void *ptr, size_t size)
void *
gdRealloc (void *ptr, size_t size)
{
return realloc(ptr, size);
return realloc (ptr, size);
}
void gdFree(void *ptr)
void
gdFree (void *ptr)
{
free(ptr);
free (ptr);
}

View File

@ -1,5 +1,6 @@
/* gdkanji.c (Kanji code converter) */
/* written by Masahito Yamaga (yamaga@ipc.chiba-u.ac.jp) */
/* written by Masahito Yamaga (ma@yama-ga.com) */
#include <stdio.h>
#include <stdlib.h>
@ -54,162 +55,187 @@
#define ESC 27
#define SS2 142
static void debug(const char *format, ...)
static void
debug (const char *format,...)
{
#ifdef DEBUG
va_list args;
va_list args;
va_start(args, format);
fprintf(stdout, "%s: ", LIBNAME);
vfprintf(stdout, format, args);
fprintf(stdout, "\n");
va_end(args);
va_start (args, format);
fprintf (stdout, "%s: ", LIBNAME);
vfprintf (stdout, format, args);
fprintf (stdout, "\n");
va_end (args);
#endif
}
static void error(const char *format, ...)
static void
error (const char *format,...)
{
va_list args;
va_list args;
va_start(args, format);
fprintf(stderr, "%s: ", LIBNAME);
vfprintf(stderr, format, args);
fprintf(stderr, "\n");
va_end(args);
va_start (args, format);
fprintf (stderr, "%s: ", LIBNAME);
vfprintf (stderr, format, args);
fprintf (stderr, "\n");
va_end (args);
}
/* DetectKanjiCode() derived from DetectCodeType() by Ken Lunde. */
static int DetectKanjiCode(unsigned char *str)
static int
DetectKanjiCode (unsigned char *str)
{
static int whatcode;
int c, i;
char *lang = NULL;
static int whatcode = ASCII;
int oldcode = ASCII;
int c, i;
char *lang = NULL;
c = '\1';
i = 0;
c = '\1';
i = 0;
if (whatcode == 0) whatcode = ASCII;
while ((whatcode == EUCORSJIS || whatcode == ASCII) && c != '\0') {
if ((c = str[i++]) != '\0') {
if (c == ESC){
c = str[i++];
if (c == '$') {
c = str[i++];
if (c == 'B') whatcode = NEW;
else
if (c == '@') whatcode = OLD;
} else
if (c == '(') {
c = str[i++];
if (c == 'I') whatcode = ESCI;
} else
if (c == 'K') whatcode = NEC;
} else
if ((c >= 129 && c <= 141) || (c >= 143 && c <= 159))
whatcode = SJIS;
else
if (c == SS2) {
c = str[i++];
if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160) || (c >= 224 && c <= 252))
whatcode = SJIS;
else
if (c >= 161 && c <= 223)
whatcode = EUCORSJIS;
} else
if (c >= 161 && c <= 223) {
c = str[i++];
if (c >= 240 && c <= 254) whatcode = EUC;
else
if (c >= 161 && c <= 223) whatcode = EUCORSJIS;
else
if (c >= 224 && c <= 239) {
whatcode = EUCORSJIS;
while (c >= 64 && c != '\0' && whatcode == EUCORSJIS) {
if (c >= 129) {
if (c <= 141 || (c >= 143 && c <= 159))
whatcode = SJIS;
else
if (c >= 253 && c <= 254)
whatcode = EUC;
}
c = str[i++];
}
} else
if (c <= 159) whatcode = SJIS;
} else
if (c >= 240 && c <= 254) whatcode = EUC;
else
if (c >= 224 && c <= 239) {
c = str[i++];
if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160))
whatcode = SJIS;
else
if (c >= 253 && c >= 254) whatcode = EUC;
else
if (c >= 161 && c <= 252) whatcode = EUCORSJIS;
}
if (whatcode != EUCORSJIS && whatcode != ASCII)
{
oldcode = whatcode;
whatcode = ASCII;
}
while ((whatcode == EUCORSJIS || whatcode == ASCII) && c != '\0')
{
if ((c = str[i++]) != '\0')
{
if (c == ESC)
{
c = str[i++];
if (c == '$')
{
c = str[i++];
if (c == 'B')
whatcode = NEW;
else if (c == '@')
whatcode = OLD;
}
else if (c == '(')
{
c = str[i++];
if (c == 'I')
whatcode = ESCI;
}
else if (c == 'K')
whatcode = NEC;
}
else if ((c >= 129 && c <= 141) || (c >= 143 && c <= 159))
whatcode = SJIS;
else if (c == SS2)
{
c = str[i++];
if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160) || (c >= 224 && c <= 252))
whatcode = SJIS;
else if (c >= 161 && c <= 223)
whatcode = EUCORSJIS;
}
else if (c >= 161 && c <= 223)
{
c = str[i++];
if (c >= 240 && c <= 254)
whatcode = EUC;
else if (c >= 161 && c <= 223)
whatcode = EUCORSJIS;
else if (c >= 224 && c <= 239)
{
whatcode = EUCORSJIS;
while (c >= 64 && c != '\0' && whatcode == EUCORSJIS)
{
if (c >= 129)
{
if (c <= 141 || (c >= 143 && c <= 159))
whatcode = SJIS;
else if (c >= 253 && c <= 254)
whatcode = EUC;
}
c = str[i++];
}
}
else if (c <= 159)
whatcode = SJIS;
}
else if (c >= 240 && c <= 254)
whatcode = EUC;
else if (c >= 224 && c <= 239)
{
c = str[i++];
if ((c >= 64 && c <= 126) || (c >= 128 && c <= 160))
whatcode = SJIS;
else if (c >= 253 && c <= 254)
whatcode = EUC;
else if (c >= 161 && c <= 252)
whatcode = EUCORSJIS;
}
}
}
#ifdef DEBUG
if (whatcode == ASCII)
debug("Kanji code not included.");
else
if (whatcode == EUCORSJIS)
debug("Kanji code not detected.");
else
debug("Kanji code detected at %d byte.", i);
if (whatcode == ASCII)
debug ("Kanji code not included.");
else if (whatcode == EUCORSJIS)
debug ("Kanji code not detected.");
else
debug ("Kanji code detected at %d byte.", i);
#endif
if (whatcode == EUCORSJIS) {
if (getenv ("LC_ALL")) lang = getenv ("LC_ALL");
else
if (getenv ("LC_CTYPE")) lang = getenv ("LC_CTYPE");
else
if (getenv ("LANG")) lang = getenv ("LANG");
if (whatcode == EUCORSJIS && oldcode != ASCII)
whatcode = oldcode;
if (lang) {
if (strcmp (lang, "ja_JP.SJIS") == 0 ||
if (whatcode == EUCORSJIS)
{
if (getenv ("LC_ALL"))
lang = getenv ("LC_ALL");
else if (getenv ("LC_CTYPE"))
lang = getenv ("LC_CTYPE");
else if (getenv ("LANG"))
lang = getenv ("LANG");
if (lang)
{
if (strcmp (lang, "ja_JP.SJIS") == 0 ||
#ifdef hpux
strcmp (lang, "japanese") == 0 ||
strcmp (lang, "japanese") == 0 ||
#endif
strcmp (lang, "ja_JP.mscode") == 0 ||
strcmp (lang, "ja_JP.PCK") == 0)
whatcode = SJIS;
else
if (strncmp (lang, "ja", 2) == 0)
strcmp (lang, "ja_JP.mscode") == 0 ||
strcmp (lang, "ja_JP.PCK") == 0)
whatcode = SJIS;
else if (strncmp (lang, "ja", 2) == 0)
#ifdef SJISPRE
whatcode = SJIS;
whatcode = SJIS;
#else
whatcode = EUC;
whatcode = EUC;
#endif
}
}
}
if (whatcode == EUCORSJIS)
if (whatcode == EUCORSJIS)
#ifdef SJISPRE
whatcode = SJIS;
whatcode = SJIS;
#else
whatcode = EUC;
whatcode = EUC;
#endif
return whatcode;
return whatcode;
}
/* SJIStoJIS() is sjis2jis() by Ken Lunde. */
static void SJIStoJIS(int *p1, int *p2)
static void
SJIStoJIS (int *p1, int *p2)
{
register unsigned char c1 = *p1;
register unsigned char c2 = *p2;
register int adjust = c2 < 159;
register int rowOffset = c1 < 160 ? 112 : 176;
register int cellOffset = adjust ? (31 + (c2 > 127)) : 126;
register unsigned char c1 = *p1;
register unsigned char c2 = *p2;
register int adjust = c2 < 159;
register int rowOffset = c1 < 160 ? 112 : 176;
register int cellOffset = adjust ? (31 + (c2 > 127)) : 126;
*p1 = ((c1 - rowOffset) << 1) - adjust;
*p2 -= cellOffset;
*p1 = ((c1 - rowOffset) << 1) - adjust;
*p2 -= cellOffset;
}
/* han2zen() was derived from han2zen() written by Ken Lunde. */
@ -217,289 +243,384 @@ static void SJIStoJIS(int *p1, int *p2)
#define IS_DAKU(c) ((c >= 182 && c <= 196) || (c >= 202 && c <= 206) || (c == 179))
#define IS_HANDAKU(c) (c >= 202 && c <= 206)
static void han2zen(int *p1, int *p2)
static void
han2zen (int *p1, int *p2)
{
int c = *p1;
int daku = FALSE;
int handaku = FALSE;
int mtable[][2] = {
{129,66},{129,117},{129,118},{129,65},{129,69},
{131,146},
{131,64},{131,66},{131,68},{131,70},{131,72},
{131,131},{131,133},{131,135},
{131,98},{129,91},
{131,65},{131,67},{131,69},{131,71},{131,73},
{131,74},{131,76},{131,78},{131,80},{131,82},
{131,84},{131,86},{131,88},{131,90},{131,92},
{131,94},{131,96},{131,99},{131,101},{131,103},
{131,105},{131,106},{131,107},{131,108},{131,109},
{131,110},{131,113},{131,116},{131,119},{131,122},
{131,125},{131,126},{131,128},{131,129},{131,130},
{131,132},{131,134},{131,136},
{131,137},{131,138},{131,139},{131,140},{131,141},
{131,143},{131,147},
{129,74},{129,75}
};
int c = *p1;
int daku = FALSE;
int handaku = FALSE;
int mtable[][2] =
{
{129, 66},
{129, 117},
{129, 118},
{129, 65},
{129, 69},
{131, 146},
{131, 64},
{131, 66},
{131, 68},
{131, 70},
{131, 72},
{131, 131},
{131, 133},
{131, 135},
{131, 98},
{129, 91},
{131, 65},
{131, 67},
{131, 69},
{131, 71},
{131, 73},
{131, 74},
{131, 76},
{131, 78},
{131, 80},
{131, 82},
{131, 84},
{131, 86},
{131, 88},
{131, 90},
{131, 92},
{131, 94},
{131, 96},
{131, 99},
{131, 101},
{131, 103},
{131, 105},
{131, 106},
{131, 107},
{131, 108},
{131, 109},
{131, 110},
{131, 113},
{131, 116},
{131, 119},
{131, 122},
{131, 125},
{131, 126},
{131, 128},
{131, 129},
{131, 130},
{131, 132},
{131, 134},
{131, 136},
{131, 137},
{131, 138},
{131, 139},
{131, 140},
{131, 141},
{131, 143},
{131, 147},
{129, 74},
{129, 75}
};
if (*p2 == 222 && IS_DAKU(*p1)) daku = TRUE; /* Daku-ten */
else
if (*p2 == 223 && IS_HANDAKU(*p1)) handaku = TRUE; /* Han-daku-ten */
if (*p2 == 222 && IS_DAKU (*p1))
daku = TRUE; /* Daku-ten */
else if (*p2 == 223 && IS_HANDAKU (*p1))
handaku = TRUE; /* Han-daku-ten */
*p1 = mtable[c - 161][0];
*p2 = mtable[c - 161][1];
*p1 = mtable[c - 161][0];
*p2 = mtable[c - 161][1];
if (daku) {
if ((*p2 >= 74 && *p2 <= 103) || (*p2 >= 110 && *p2 <= 122))
(*p2)++;
else
if (*p2 == 131 && *p2 == 69) *p2 = 148;
} else
if (handaku && *p2 >= 110 && *p2 <= 122) (*p2) += 2;
if (daku)
{
if ((*p2 >= 74 && *p2 <= 103) || (*p2 >= 110 && *p2 <= 122))
(*p2)++;
else if (*p2 == 131 && *p2 == 69)
*p2 = 148;
}
else if (handaku && *p2 >= 110 && *p2 <= 122)
(*p2) += 2;
}
/* Recast strcpy to handle unsigned chars used below. */
#define ustrcpy(A,B) (strcpy((char*)(A),(const char*)(B)))
static void do_convert(unsigned char *to, unsigned char *from, const char *code)
static void
do_convert (unsigned char *to, unsigned char *from, const char *code)
{
#ifdef HAVE_ICONV
iconv_t cd;
size_t from_len, to_len;
iconv_t cd;
size_t from_len, to_len;
if ((cd = iconv_open(EUCSTR, code)) == (iconv_t)-1) {
error("iconv_open() error");
if ((cd = iconv_open (EUCSTR, code)) == (iconv_t) - 1)
{
error ("iconv_open() error");
#ifdef HAVE_ERRNO_H
if (errno == EINVAL)
error("invalid code specification: \"%s\" or \"%s\"",
EUCSTR, code);
if (errno == EINVAL)
error ("invalid code specification: \"%s\" or \"%s\"",
EUCSTR, code);
#endif
strcpy(to, from);
return;
}
strcpy ((char *) to, (const char *) from);
return;
}
from_len = strlen((const char *)from) +1;
to_len = BUFSIZ;
from_len = strlen ((const char *) from) + 1;
to_len = BUFSIZ;
if (iconv(cd, (const char **)&from, &from_len,
(char **)&to, &to_len) == -1) {
if (iconv (cd, (const char **) &from, &from_len,
(char **) &to, &to_len) == -1)
{
#ifdef HAVE_ERRNO_H
if (errno == EINVAL) error("invalid end of input string");
else
if (errno == EILSEQ) error("invalid code in input string");
else
if (errno == E2BIG) error("output buffer overflow at do_convert()");
else
if (errno == EINVAL)
error ("invalid end of input string");
else if (errno == EILSEQ)
error ("invalid code in input string");
else if (errno == E2BIG)
error ("output buffer overflow at do_convert()");
else
#endif
error("something happen");
strcpy(to, from);
return;
}
error ("something happen");
strcpy ((char *) to, (const char *) from);
return;
}
if (iconv_close(cd) != 0) {
error("iconv_close() error");
}
if (iconv_close (cd) != 0)
{
error ("iconv_close() error");
}
#else
int p1, p2, i, j;
int jisx0208 = FALSE;
int hankaku = FALSE;
int p1, p2, i, j;
int jisx0208 = FALSE;
int hankaku = FALSE;
j = 0;
if (strcmp(code, NEWJISSTR) == 0 || strcmp(code, OLDJISSTR) == 0){
for(i=0; from[i] != '\0' && j < BUFSIZ; i++){
if (from[i] == ESC) {
i++;
if (from[i] == '$') {
jisx0208 = TRUE;
hankaku = FALSE;
i++;
}else
if (from[i] == '(') {
jisx0208 = FALSE;
i++;
if (from[i] == 'I') /* Hankaku Kana */
hankaku = TRUE;
else
hankaku = FALSE;
}
} else {
if (jisx0208)
to[j++] = from[i] + 128;
else
if (hankaku) {
to[j++] = SS2;
to[j++] = from[i] + 128;
}
else
to[j++] = from[i];
}
j = 0;
if (strcmp (code, NEWJISSTR) == 0 || strcmp (code, OLDJISSTR) == 0)
{
for (i = 0; from[i] != '\0' && j < BUFSIZ; i++)
{
if (from[i] == ESC)
{
i++;
if (from[i] == '$')
{
jisx0208 = TRUE;
hankaku = FALSE;
i++;
}
} else
if (strcmp(code, SJISSTR) == 0) {
for(i=0; from[i] != '\0' && j < BUFSIZ; i++){
p1 = from[i];
if (p1 < 127) to[j++] = p1;
else
if ((p1 >= 161) && (p1 <= 223)) { /* Hankaku Kana */
to[j++] = SS2;
to[j++] = p1;
} else {
p2 = from[++i];
SJIStoJIS(&p1, &p2);
to[j++] = p1 + 128;
to[j++] = p2 + 128;
}
else if (from[i] == '(')
{
jisx0208 = FALSE;
i++;
if (from[i] == 'I') /* Hankaku Kana */
hankaku = TRUE;
else
hankaku = FALSE;
}
} else {
error("invalid code specification: \"%s\"", code);
return;
}
else
{
if (jisx0208)
to[j++] = from[i] + 128;
else if (hankaku)
{
to[j++] = SS2;
to[j++] = from[i] + 128;
}
else
to[j++] = from[i];
}
}
}
else if (strcmp (code, SJISSTR) == 0)
{
for (i = 0; from[i] != '\0' && j < BUFSIZ; i++)
{
p1 = from[i];
if (p1 < 127)
to[j++] = p1;
else if ((p1 >= 161) && (p1 <= 223))
{ /* Hankaku Kana */
to[j++] = SS2;
to[j++] = p1;
}
else
{
p2 = from[++i];
SJIStoJIS (&p1, &p2);
to[j++] = p1 + 128;
to[j++] = p2 + 128;
}
}
}
else
{
error ("invalid code specification: \"%s\"", code);
return;
}
if (j >= BUFSIZ) {
error("output buffer overflow at do_convert()");
ustrcpy(to, from);
} else
to[j] = '\0';
if (j >= BUFSIZ)
{
error ("output buffer overflow at do_convert()");
ustrcpy (to, from);
}
else
to[j] = '\0';
#endif /* HAVE_ICONV */
}
static int do_check_and_conv(unsigned char *to, unsigned char *from)
static int
do_check_and_conv (unsigned char *to, unsigned char *from)
{
static unsigned char tmp[BUFSIZ];
int p1, p2, i, j;
int kanji = TRUE;
static unsigned char tmp[BUFSIZ];
int p1, p2, i, j;
int kanji = TRUE;
switch (DetectKanjiCode(from)){
case NEW:
debug("Kanji code is New JIS.");
do_convert(tmp, from, NEWJISSTR);
break;
case OLD:
debug("Kanji code is Old JIS.");
do_convert(tmp, from, OLDJISSTR);
break;
case ESCI:
debug("This string includes Hankaku-Kana (jisx0201) escape sequence [ESC] + ( + I.");
do_convert(tmp, from, NEWJISSTR);
break;
case NEC:
debug("Kanji code is NEC Kanji.");
error("cannot convert NEC Kanji.");
ustrcpy(tmp, from);
kanji = FALSE;
break;
case EUC:
debug("Kanji code is EUC.");
ustrcpy(tmp, from);
break;
case SJIS:
debug("Kanji code is SJIS.");
do_convert(tmp, from, SJISSTR);
break;
case EUCORSJIS:
debug("Kanji code is EUC or SJIS.");
ustrcpy(tmp, from);
kanji = FALSE;
break;
case ASCII:
debug("This is ASCII string.");
ustrcpy(tmp, from);
kanji = FALSE;
break;
default:
debug("This string includes unknown code.");
ustrcpy(tmp, from);
kanji = FALSE;
break;
switch (DetectKanjiCode (from))
{
case NEW:
debug ("Kanji code is New JIS.");
do_convert (tmp, from, NEWJISSTR);
break;
case OLD:
debug ("Kanji code is Old JIS.");
do_convert (tmp, from, OLDJISSTR);
break;
case ESCI:
debug ("This string includes Hankaku-Kana (jisx0201) escape sequence [ESC] + ( + I.");
do_convert (tmp, from, NEWJISSTR);
break;
case NEC:
debug ("Kanji code is NEC Kanji.");
error ("cannot convert NEC Kanji.");
ustrcpy (tmp, from);
kanji = FALSE;
break;
case EUC:
debug ("Kanji code is EUC.");
ustrcpy (tmp, from);
break;
case SJIS:
debug ("Kanji code is SJIS.");
do_convert (tmp, from, SJISSTR);
break;
case EUCORSJIS:
debug ("Kanji code is EUC or SJIS.");
ustrcpy (tmp, from);
kanji = FALSE;
break;
case ASCII:
debug ("This is ASCII string.");
ustrcpy (tmp, from);
kanji = FALSE;
break;
default:
debug ("This string includes unknown code.");
ustrcpy (tmp, from);
kanji = FALSE;
break;
}
/* Hankaku Kana ---> Zenkaku Kana */
if (kanji)
{
j = 0;
for (i = 0; tmp[i] != '\0' && j < BUFSIZ; i++)
{
if (tmp[i] == SS2)
{
p1 = tmp[++i];
if (tmp[i + 1] == SS2)
{
p2 = tmp[i + 2];
if (p2 == 222 || p2 == 223)
i += 2;
else
p2 = 0;
}
else
p2 = 0;
han2zen (&p1, &p2);
SJIStoJIS (&p1, &p2);
to[j++] = p1 + 128;
to[j++] = p2 + 128;
}
else
to[j++] = tmp[i];
}
/* Hankaku Kana ---> Zenkaku Kana */
if (kanji) {
j = 0;
for(i = 0; tmp[i] != '\0'&& j < BUFSIZ; i++) {
if (tmp[i] == SS2) {
p1 = tmp[++i];
if (tmp[i+1] == SS2) {
p2 = tmp[i+2];
if (p2 == 222 || p2 == 223) i += 2;
else p2 = 0;
} else p2 = 0;
han2zen(&p1, &p2);
SJIStoJIS(&p1, &p2);
to[j++] = p1 + 128;
to[j++] = p2 + 128;
} else
to[j++] = tmp[i];
}
if (j >= BUFSIZ)
{
error ("output buffer overflow at Hankaku --> Zenkaku");
ustrcpy (to, tmp);
}
else
to[j] = '\0';
}
else
ustrcpy (to, tmp);
if (j >= BUFSIZ) {
error("output buffer overflow at Hankaku --> Zenkaku");
ustrcpy(to, tmp);
} else
to[j] = '\0';
} else
ustrcpy(to, tmp);
return kanji;
return kanji;
}
int any2eucjp(unsigned char *dest, unsigned char *src, unsigned int dest_max)
int
any2eucjp (unsigned char *dest, unsigned char *src, unsigned int dest_max)
{
static unsigned char tmp_dest[BUFSIZ];
int ret;
static unsigned char tmp_dest[BUFSIZ];
int ret;
if (strlen((const char *)src) >= BUFSIZ) {
error("input string too large");
return -1;
}
if (dest_max > BUFSIZ) {
error("invalid maximum size of destination\nit should be less than %d.", BUFSIZ);
return -1;
}
ret = do_check_and_conv(tmp_dest, src);
if (strlen((const char *)tmp_dest) >= dest_max) {
error("output buffer overflow");
ustrcpy(dest, src);
return -1;
}
ustrcpy(dest, tmp_dest);
return ret;
if (strlen ((const char *) src) >= BUFSIZ)
{
error ("input string too large");
return -1;
}
if (dest_max > BUFSIZ)
{
error ("invalid maximum size of destination\nit should be less than %d.", BUFSIZ);
return -1;
}
ret = do_check_and_conv (tmp_dest, src);
if (strlen ((const char *) tmp_dest) >= dest_max)
{
error ("output buffer overflow");
ustrcpy (dest, src);
return -1;
}
ustrcpy (dest, tmp_dest);
return ret;
}
#if 0
unsigned int strwidth(unsigned char *s)
unsigned int
strwidth (unsigned char *s)
{
unsigned char *t;
unsigned int i;
unsigned char *t;
unsigned int i;
t = (unsigned char *)gdMalloc(BUFSIZ);
any2eucjp(t, s, BUFSIZ);
i = strlen(t);
gdFree(t);
return i;
t = (unsigned char *) gdMalloc (BUFSIZ);
any2eucjp (t, s, BUFSIZ);
i = strlen (t);
gdFree (t);
return i;
}
#endif
#ifdef DEBUG
int main()
int
main ()
{
unsigned char input[BUFSIZ];
unsigned char *output;
unsigned char *str;
int c, i = 0;
unsigned char input[BUFSIZ];
unsigned char *output;
unsigned char *str;
int c, i = 0;
while ( (c = fgetc(stdin)) != '\n' && i < BUFSIZ ) input[i++] = c;
input[i] = '\0';
while ((c = fgetc (stdin)) != '\n' && i < BUFSIZ)
input[i++] = c;
input[i] = '\0';
printf("input : %d bytes\n", strlen(input));
printf("output: %d bytes\n", strwidth(input));
printf ("input : %d bytes\n", strlen ((const char *) input));
printf ("output: %d bytes\n", strwidth (input));
output = (unsigned char *)gdMalloc(BUFSIZ);
any2eucjp(output, input, BUFSIZ);
str = output;
while(*str != '\0') putchar(*(str++));
putchar('\n');
gdFree(output);
output = (unsigned char *) gdMalloc (BUFSIZ);
any2eucjp (output, input, BUFSIZ);
str = output;
while (*str != '\0')
putchar (*(str++));
putchar ('\n');
gdFree (output);
return 0;
return 0;
}
#endif
#endif

View File

@ -1,51 +1,55 @@
#include <stdio.h>
#include <stdlib.h> /* For atoi */
#include <stdlib.h> /* For atoi */
#include "gd.h"
/* A short program which converts a .png file into a .gd file, for
your convenience in creating images on the fly from a
basis image that must be loaded quickly. The .gd format
is not intended to be a general-purpose format. */
your convenience in creating images on the fly from a
basis image that must be loaded quickly. The .gd format
is not intended to be a general-purpose format. */
int main(int argc, char **argv)
int
main (int argc, char **argv)
{
gdImagePtr im;
FILE *in, *out;
int x, y, w, h;
gdImagePtr im;
FILE *in, *out;
int x, y, w, h;
if (argc != 7) {
fprintf(stderr, "Usage: gdparttopng filename.gd filename.png x y w h\n");
exit(1);
}
in = fopen(argv[1], "rb");
if (!in) {
fprintf(stderr, "Input file does not exist!\n");
exit(1);
}
if (argc != 7)
{
fprintf (stderr, "Usage: gdparttopng filename.gd filename.png x y w h\n");
exit (1);
}
in = fopen (argv[1], "rb");
if (!in)
{
fprintf (stderr, "Input file does not exist!\n");
exit (1);
}
x = atoi(argv[3]);
y = atoi(argv[4]);
w = atoi(argv[5]);
h = atoi(argv[6]);
x = atoi (argv[3]);
y = atoi (argv[4]);
w = atoi (argv[5]);
h = atoi (argv[6]);
printf("Extracting from (%d, %d), size is %dx%d\n", x, y, w, h);
printf ("Extracting from (%d, %d), size is %dx%d\n", x, y, w, h);
im = gdImageCreateFromGd2Part(in, x, y, w, h);
fclose(in);
if (!im) {
fprintf(stderr, "Input is not in PNG format!\n");
exit(1);
}
out = fopen(argv[2], "wb");
if (!out) {
fprintf(stderr, "Output file cannot be written to!\n");
gdImageDestroy(im);
exit(1);
}
gdImagePng(im, out);
fclose(out);
gdImageDestroy(im);
im = gdImageCreateFromGd2Part (in, x, y, w, h);
fclose (in);
if (!im)
{
fprintf (stderr, "Input is not in PNG format!\n");
exit (1);
}
out = fopen (argv[2], "wb");
if (!out)
{
fprintf (stderr, "Output file cannot be written to!\n");
gdImageDestroy (im);
exit (1);
}
gdImagePng (im, out);
fclose (out);
gdImageDestroy (im);
return 0;
return 0;
}

View File

@ -1,4 +1,6 @@
int gdCosT[] = {
int gdCosT[] =
{
1024,
1023,
1023,
@ -361,7 +363,8 @@ int gdCosT[] = {
1023
};
int gdSinT[] = {
int gdSinT[] =
{
0,
17,
35,

View File

@ -1,370 +1,409 @@
#include <stdio.h>
#ifdef _WIN32
#include <process.h>
int unlink(const char * filename) {
return _unlink(filename);
int
unlink (const char *filename)
{
return _unlink (filename);
}
#else
#include <unistd.h> /* for getpid(), unlink() */
#else
#include <unistd.h> /* for getpid(), unlink() */
#endif
#include "gd.h"
void CompareImages(char *msg, gdImagePtr im1, gdImagePtr im2);
void CompareImages (char *msg, gdImagePtr im1, gdImagePtr im2);
static int freadWrapper(void *context, char *buf, int len);
static int fwriteWrapper(void *context, const char *buffer, int len);
static int freadWrapper (void *context, char *buf, int len);
static int fwriteWrapper (void *context, const char *buffer, int len);
int main(int argc, char **argv)
int
main (int argc, char **argv)
{
gdImagePtr im, ref, im2, im3;
FILE *in, *out;
void *iptr;
int sz;
gdIOCtxPtr ctx;
char of[256];
int colRed, colBlu;
gdSource imgsrc;
gdSink imgsnk;
int foreground;
int i;
if (argc != 2) {
fprintf(stderr, "Usage: gdtest filename.png\n");
exit(1);
}
in = fopen(argv[1], "rb");
if (!in) {
fprintf(stderr, "Input file does not exist!\n");
exit(1);
}
im = gdImageCreateFromPng(in);
gdImagePtr im, ref, im2, im3;
FILE *in, *out;
void *iptr;
int sz;
gdIOCtxPtr ctx;
char of[256];
int colRed, colBlu;
gdSource imgsrc;
gdSink imgsnk;
int foreground;
int i;
if (argc != 2)
{
fprintf (stderr, "Usage: gdtest filename.png\n");
exit (1);
}
in = fopen (argv[1], "rb");
if (!in)
{
fprintf (stderr, "Input file does not exist!\n");
exit (1);
}
im = gdImageCreateFromPng (in);
rewind(in);
ref = gdImageCreateFromPng(in);
rewind (in);
ref = gdImageCreateFromPng (in);
fclose(in);
fclose (in);
printf("Reference File has %d Palette entries\n",ref->colorsTotal);
printf ("Reference File has %d Palette entries\n", ref->colorsTotal);
CompareImages("Initial Versions", ref, im);
CompareImages ("Initial Versions", ref, im);
/* */
/* Send to PNG File then Ptr */
/* */
sprintf(of, "%s.png", argv[1]);
out = fopen(of, "wb");
gdImagePng(im, out);
fclose(out);
/* */
/* Send to PNG File then Ptr */
/* */
sprintf (of, "%s.png", argv[1]);
out = fopen (of, "wb");
gdImagePng (im, out);
fclose (out);
in = fopen(of, "rb");
if (!in) {
fprintf(stderr, "PNG Output file does not exist!\n");
exit(1);
}
im2 = gdImageCreateFromPng(in);
fclose(in);
in = fopen (of, "rb");
if (!in)
{
fprintf (stderr, "PNG Output file does not exist!\n");
exit (1);
}
im2 = gdImageCreateFromPng (in);
fclose (in);
CompareImages("GD->PNG File->GD", ref, im2);
CompareImages ("GD->PNG File->GD", ref, im2);
unlink(of);
gdImageDestroy(im2);
unlink (of);
gdImageDestroy (im2);
iptr = gdImagePngPtr(im,&sz);
ctx = gdNewDynamicCtx(sz,iptr);
im2 = gdImageCreateFromPngCtx(ctx);
iptr = gdImagePngPtr (im, &sz);
ctx = gdNewDynamicCtx (sz, iptr);
im2 = gdImageCreateFromPngCtx (ctx);
CompareImages("GD->PNG ptr->GD", ref, im2);
CompareImages ("GD->PNG ptr->GD", ref, im2);
gdImageDestroy(im2);
ctx->free(ctx);
gdImageDestroy (im2);
ctx->free (ctx);
/* */
/* Send to GD2 File then Ptr */
/* */
sprintf(of, "%s.gd2", argv[1]);
out = fopen(of, "wb");
gdImageGd2(im, out, 128, 2);
fclose(out);
/* */
/* Send to GD2 File then Ptr */
/* */
sprintf (of, "%s.gd2", argv[1]);
out = fopen (of, "wb");
gdImageGd2 (im, out, 128, 2);
fclose (out);
in = fopen(of, "rb");
if (!in) {
fprintf(stderr, "GD2 Output file does not exist!\n");
exit(1);
}
im2 = gdImageCreateFromGd2(in);
fclose(in);
in = fopen (of, "rb");
if (!in)
{
fprintf (stderr, "GD2 Output file does not exist!\n");
exit (1);
}
im2 = gdImageCreateFromGd2 (in);
fclose (in);
CompareImages("GD->GD2 File->GD", ref, im2);
CompareImages ("GD->GD2 File->GD", ref, im2);
unlink(of);
gdImageDestroy(im2);
unlink (of);
gdImageDestroy (im2);
iptr = gdImageGd2Ptr(im,128,2,&sz);
/*printf("Got ptr %d (size %d)\n",iptr, sz); */
ctx = gdNewDynamicCtx(sz,iptr);
/*printf("Got ctx %d\n",ctx); */
im2 = gdImageCreateFromGd2Ctx(ctx);
/*printf("Got img2 %d\n",im2); */
iptr = gdImageGd2Ptr (im, 128, 2, &sz);
/*printf("Got ptr %d (size %d)\n",iptr, sz); */
ctx = gdNewDynamicCtx (sz, iptr);
/*printf("Got ctx %d\n",ctx); */
im2 = gdImageCreateFromGd2Ctx (ctx);
/*printf("Got img2 %d\n",im2); */
CompareImages("GD->GD2 ptr->GD", ref, im2);
CompareImages ("GD->GD2 ptr->GD", ref, im2);
gdImageDestroy(im2);
ctx->free(ctx);
gdImageDestroy (im2);
ctx->free (ctx);
/* */
/* Send to GD File then Ptr */
/* */
sprintf(of, "%s.gd", argv[1]);
out = fopen(of, "wb");
gdImageGd(im, out);
fclose(out);
/* */
/* Send to GD File then Ptr */
/* */
sprintf (of, "%s.gd", argv[1]);
out = fopen (of, "wb");
gdImageGd (im, out);
fclose (out);
in = fopen(of, "rb");
if (!in) {
fprintf(stderr, "GD Output file does not exist!\n");
exit(1);
}
im2 = gdImageCreateFromGd(in);
fclose(in);
in = fopen (of, "rb");
if (!in)
{
fprintf (stderr, "GD Output file does not exist!\n");
exit (1);
}
im2 = gdImageCreateFromGd (in);
fclose (in);
CompareImages("GD->GD File->GD", ref, im2);
CompareImages ("GD->GD File->GD", ref, im2);
unlink(of);
gdImageDestroy(im2);
unlink (of);
gdImageDestroy (im2);
iptr = gdImageGdPtr(im,&sz);
/*printf("Got ptr %d (size %d)\n",iptr, sz); */
ctx = gdNewDynamicCtx(sz,iptr);
/*printf("Got ctx %d\n",ctx); */
im2 = gdImageCreateFromGdCtx(ctx);
/*printf("Got img2 %d\n",im2); */
iptr = gdImageGdPtr (im, &sz);
/*printf("Got ptr %d (size %d)\n",iptr, sz); */
ctx = gdNewDynamicCtx (sz, iptr);
/*printf("Got ctx %d\n",ctx); */
im2 = gdImageCreateFromGdCtx (ctx);
/*printf("Got img2 %d\n",im2); */
CompareImages("GD->GD ptr->GD", ref, im2);
CompareImages ("GD->GD ptr->GD", ref, im2);
gdImageDestroy(im2);
ctx->free(ctx);
gdImageDestroy (im2);
ctx->free (ctx);
/*
** Test gdImageCreateFromPngSource'
**/
/*
** Test gdImageCreateFromPngSource'
* */
in = fopen(argv[1], "rb");
in = fopen (argv[1], "rb");
imgsrc.source = freadWrapper;
imgsrc.context = in;
im2 = gdImageCreateFromPngSource(&imgsrc);
fclose(in);
imgsrc.source = freadWrapper;
imgsrc.context = in;
im2 = gdImageCreateFromPngSource (&imgsrc);
fclose (in);
if (im2 == NULL) {
printf("GD Source: ERROR Null returned by gdImageCreateFromPngSource\n");
} else {
CompareImages("GD Source", ref, im2);
gdImageDestroy(im2);
};
if (im2 == NULL)
{
printf ("GD Source: ERROR Null returned by gdImageCreateFromPngSource\n");
}
else
{
CompareImages ("GD Source", ref, im2);
gdImageDestroy (im2);
};
/*
** Test gdImagePngToSink'
**/
/*
** Test gdImagePngToSink'
* */
sprintf(of, "%s.snk", argv[1]);
out = fopen(of, "wb");
imgsnk.sink = fwriteWrapper;
imgsnk.context = out;
gdImagePngToSink(im, &imgsnk);
fclose(out);
in = fopen(of, "rb");
if (!in) {
fprintf(stderr, "GD Sink: ERROR - GD Sink Output file does not exist!\n");
} else {
im2 = gdImageCreateFromPng(in);
fclose(in);
sprintf (of, "%s.snk", argv[1]);
out = fopen (of, "wb");
imgsnk.sink = fwriteWrapper;
imgsnk.context = out;
gdImagePngToSink (im, &imgsnk);
fclose (out);
in = fopen (of, "rb");
if (!in)
{
fprintf (stderr, "GD Sink: ERROR - GD Sink Output file does not exist!\n");
}
else
{
im2 = gdImageCreateFromPng (in);
fclose (in);
CompareImages("GD Sink", ref, im2);
gdImageDestroy(im2);
};
CompareImages ("GD Sink", ref, im2);
gdImageDestroy (im2);
};
unlink(of);
unlink (of);
/* */
/* Test Extraction */
/* */
in = fopen("test/gdtest_200_300_150_100.png", "rb");
if (!in) {
fprintf(stderr, "gdtest_200_300_150_100.png does not exist!\n");
exit(1);
}
im2 = gdImageCreateFromPng(in);
fclose(in);
/* */
/* Test Extraction */
/* */
in = fopen ("test/gdtest_200_300_150_100.png", "rb");
if (!in)
{
fprintf (stderr, "gdtest_200_300_150_100.png does not exist!\n");
exit (1);
}
im2 = gdImageCreateFromPng (in);
fclose (in);
in = fopen("test/gdtest.gd2", "rb");
if (!in) {
fprintf(stderr, "gdtest.gd2 does not exist!\n");
exit(1);
}
im3 = gdImageCreateFromGd2Part(in, 200, 300, 150, 100);
fclose(in);
in = fopen ("test/gdtest.gd2", "rb");
if (!in)
{
fprintf (stderr, "gdtest.gd2 does not exist!\n");
exit (1);
}
im3 = gdImageCreateFromGd2Part (in, 200, 300, 150, 100);
fclose (in);
CompareImages("GD2Part (gdtest_200_300_150_100.png, gdtest.gd2(part))", im2, im3);
CompareImages ("GD2Part (gdtest_200_300_150_100.png, gdtest.gd2(part))", im2, im3);
gdImageDestroy(im2);
gdImageDestroy(im3);
gdImageDestroy (im2);
gdImageDestroy (im3);
/* */
/* Copy Blend */
/* */
in = fopen("test/gdtest.png", "rb");
if (!in) {
fprintf(stderr, "gdtest.png does not exist!\n");
exit(1);
}
im2 = gdImageCreateFromPng(in);
fclose(in);
/* */
/* Copy Blend */
/* */
in = fopen ("test/gdtest.png", "rb");
if (!in)
{
fprintf (stderr, "gdtest.png does not exist!\n");
exit (1);
}
im2 = gdImageCreateFromPng (in);
fclose (in);
im3 = gdImageCreate(100, 60);
colRed = gdImageColorAllocate(im3, 255, 0, 0);
colBlu = gdImageColorAllocate(im3, 0, 0, 255);
gdImageFilledRectangle(im3, 0, 0, 49, 30, colRed);
gdImageFilledRectangle(im3, 50, 30, 99, 59, colBlu);
im3 = gdImageCreate (100, 60);
colRed = gdImageColorAllocate (im3, 255, 0, 0);
colBlu = gdImageColorAllocate (im3, 0, 0, 255);
gdImageFilledRectangle (im3, 0, 0, 49, 30, colRed);
gdImageFilledRectangle (im3, 50, 30, 99, 59, colBlu);
gdImageCopyMerge(im2, im3, 150, 200, 10, 10, 90, 50, 50);
gdImageCopyMerge(im2, im3, 180, 70, 10, 10, 90, 50, 50);
gdImageCopyMerge (im2, im3, 150, 200, 10, 10, 90, 50, 50);
gdImageCopyMerge (im2, im3, 180, 70, 10, 10, 90, 50, 50);
gdImageCopyMergeGray(im2, im3, 250, 160, 10, 10, 90, 50, 50);
gdImageCopyMergeGray(im2, im3, 80, 70, 10, 10, 90, 50, 50);
gdImageCopyMergeGray (im2, im3, 250, 160, 10, 10, 90, 50, 50);
gdImageCopyMergeGray (im2, im3, 80, 70, 10, 10, 90, 50, 50);
gdImageDestroy(im3);
gdImageDestroy (im3);
in = fopen("test/gdtest_merge.png", "rb");
if (!in) {
fprintf(stderr, "gdtest_merge.png does not exist!\n");
exit(1);
}
im3 = gdImageCreateFromPng(in);
fclose(in);
in = fopen ("test/gdtest_merge.png", "rb");
if (!in)
{
fprintf (stderr, "gdtest_merge.png does not exist!\n");
exit (1);
}
im3 = gdImageCreateFromPng (in);
fclose (in);
printf("[Merged Image has %d colours]\n",im2->colorsTotal);
CompareImages("Merged (gdtest.png, gdtest_merge.png)", im2, im3);
printf ("[Merged Image has %d colours]\n", im2->colorsTotal);
CompareImages ("Merged (gdtest.png, gdtest_merge.png)", im2, im3);
gdImageDestroy(im2);
gdImageDestroy(im3);
gdImageDestroy (im2);
gdImageDestroy (im3);
#ifdef HAVE_JPEG
out = fopen("test/gdtest.jpg", "wb");
if (!out) {
fprintf(stderr, "Can't create file test/gdtest.jpg.\n");
exit(1);
}
gdImageJpeg(im, out, -1);
fclose(out);
in = fopen("test/gdtest.jpg", "rb");
if (!in) {
fprintf(stderr, "Can't open file test/gdtest.jpg.\n");
exit(1);
}
im2 = gdImageCreateFromJpeg(in);
fclose(in);
if (!im2) {
fprintf(stderr, "gdImageCreateFromJpeg failed.\n");
exit(1);
}
gdImageDestroy(im2);
printf("Created test/gdtest.jpg successfully. Compare this image\n"
"to the input image manually. Some difference must be\n"
"expected as JPEG is a lossy file format.\n");
out = fopen ("test/gdtest.jpg", "wb");
if (!out)
{
fprintf (stderr, "Can't create file test/gdtest.jpg.\n");
exit (1);
}
gdImageJpeg (im, out, -1);
fclose (out);
in = fopen ("test/gdtest.jpg", "rb");
if (!in)
{
fprintf (stderr, "Can't open file test/gdtest.jpg.\n");
exit (1);
}
im2 = gdImageCreateFromJpeg (in);
fclose (in);
if (!im2)
{
fprintf (stderr, "gdImageCreateFromJpeg failed.\n");
exit (1);
}
gdImageDestroy (im2);
printf ("Created test/gdtest.jpg successfully. Compare this image\n"
"to the input image manually. Some difference must be\n"
"expected as JPEG is a lossy file format.\n");
#endif /* HAVE_JPEG */
/* Assume the color closest to black is the foreground
color for the B&W wbmp image. */
fprintf(stderr, "NOTE: the WBMP output image will NOT match the original unless the original\n"
"is also black and white. This is OK!\n");
foreground = gdImageColorClosest(im, 0, 0, 0);
fprintf(stderr, "Foreground index is %d\n", foreground);
if (foreground == -1) {
fprintf(stderr, "Source image has no colors, skipping wbmp test.\n");
} else {
out = fopen("test/gdtest.wbmp", "wb");
if (!out) {
fprintf(stderr, "Can't create file test/gdtest.wbmp.\n");
exit(1);
}
gdImageWBMP(im, foreground, out);
fclose(out);
in = fopen("test/gdtest.wbmp", "rb");
if (!in) {
fprintf(stderr, "Can't open file test/gdtest.wbmp.\n");
exit(1);
}
im2 = gdImageCreateFromWBMP(in);
fprintf(stderr, "WBMP has %d colors\n", gdImageColorsTotal(im2));
fprintf(stderr, "WBMP colors are:\n");
for (i = 0; (i < gdImageColorsTotal(im2)); i++) {
fprintf(stderr, "%02X%02X%02X\n",
gdImageRed(im2, i),
gdImageGreen(im2, i),
gdImageBlue(im2, i));
}
fclose(in);
if (!im2) {
fprintf(stderr, "gdImageCreateFromWBMP failed.\n");
exit(1);
}
CompareImages("WBMP test (gdtest.png, gdtest.wbmp)", ref, im2);
out = fopen("test/gdtest_wbmp_to_png.png", "wb");
if (!out) {
fprintf(stderr, "Can't create file test/gdtest_wbmp_to_png.png.\n");
exit(1);
}
gdImagePng(im2, out);
fclose(out);
gdImageDestroy(im2);
/* Assume the color closest to black is the foreground
color for the B&W wbmp image. */
fprintf (stderr, "NOTE: the WBMP output image will NOT match the original unless the original\n"
"is also black and white. This is OK!\n");
foreground = gdImageColorClosest (im, 0, 0, 0);
fprintf (stderr, "Foreground index is %d\n", foreground);
if (foreground == -1)
{
fprintf (stderr, "Source image has no colors, skipping wbmp test.\n");
}
else
{
out = fopen ("test/gdtest.wbmp", "wb");
if (!out)
{
fprintf (stderr, "Can't create file test/gdtest.wbmp.\n");
exit (1);
}
gdImageDestroy(im);
gdImageDestroy(ref);
gdImageWBMP (im, foreground, out);
fclose (out);
in = fopen ("test/gdtest.wbmp", "rb");
if (!in)
{
fprintf (stderr, "Can't open file test/gdtest.wbmp.\n");
exit (1);
}
im2 = gdImageCreateFromWBMP (in);
fprintf (stderr, "WBMP has %d colors\n", gdImageColorsTotal (im2));
fprintf (stderr, "WBMP colors are:\n");
for (i = 0; (i < gdImageColorsTotal (im2)); i++)
{
fprintf (stderr, "%02X%02X%02X\n",
gdImageRed (im2, i),
gdImageGreen (im2, i),
gdImageBlue (im2, i));
}
fclose (in);
if (!im2)
{
fprintf (stderr, "gdImageCreateFromWBMP failed.\n");
exit (1);
}
CompareImages ("WBMP test (gdtest.png, gdtest.wbmp)", ref, im2);
out = fopen ("test/gdtest_wbmp_to_png.png", "wb");
if (!out)
{
fprintf (stderr, "Can't create file test/gdtest_wbmp_to_png.png.\n");
exit (1);
}
gdImagePng (im2, out);
fclose (out);
gdImageDestroy (im2);
}
gdImageDestroy (im);
gdImageDestroy (ref);
return 0;
return 0;
}
void CompareImages(char *msg, gdImagePtr im1, gdImagePtr im2)
void
CompareImages (char *msg, gdImagePtr im1, gdImagePtr im2)
{
int cmpRes;
int cmpRes;
cmpRes = gdImageCompare(im1, im2);
cmpRes = gdImageCompare (im1, im2);
if (cmpRes & GD_CMP_IMAGE) {
printf("%%%s: ERROR images differ: BAD\n",msg);
} else if (cmpRes != 0) {
printf("%%%s: WARNING images differ: WARNING - Probably OK\n",msg);
} else {
printf("%%%s: OK\n",msg);
return;
}
if (cmpRes & GD_CMP_IMAGE)
{
printf ("%%%s: ERROR images differ: BAD\n", msg);
}
else if (cmpRes != 0)
{
printf ("%%%s: WARNING images differ: WARNING - Probably OK\n", msg);
}
else
{
printf ("%%%s: OK\n", msg);
return;
}
if (cmpRes & (GD_CMP_SIZE_X + GD_CMP_SIZE_Y)) {
printf("-%s: INFO image sizes differ\n",msg);
}
if (cmpRes & (GD_CMP_SIZE_X + GD_CMP_SIZE_Y))
{
printf ("-%s: INFO image sizes differ\n", msg);
}
if (cmpRes & GD_CMP_NUM_COLORS) {
printf("-%s: INFO number of pallette entries differ %d Vs. %d\n",msg,
im1->colorsTotal, im2->colorsTotal);
}
if (cmpRes & GD_CMP_NUM_COLORS)
{
printf ("-%s: INFO number of pallette entries differ %d Vs. %d\n", msg,
im1->colorsTotal, im2->colorsTotal);
}
if (cmpRes & GD_CMP_COLOR) {
printf("-%s: INFO actual colours of pixels differ\n",msg);
}
if (cmpRes & GD_CMP_COLOR)
{
printf ("-%s: INFO actual colours of pixels differ\n", msg);
}
}
static int freadWrapper(void *context, char *buf, int len)
static int
freadWrapper (void *context, char *buf, int len)
{
int got = fread(buf, 1, len, (FILE *) context);
return got;
int got = fread (buf, 1, len, (FILE *) context);
return got;
}
static int fwriteWrapper(void *context, const char *buffer, int len)
static int
fwriteWrapper (void *context, const char *buffer, int len)
{
return fwrite(buffer, 1, len, (FILE *) context);
return fwrite (buffer, 1, len, (FILE *) context);
}

View File

@ -1,3 +1,4 @@
#include "gd.h"
#include <string.h>
@ -17,81 +18,91 @@
#define MAXY(x) MAX4(x[1],x[3],x[5],x[7])
#define MINY(x) MIN4(x[1],x[3],x[5],x[7])
int main(int argc, char *argv[])
int
main (int argc, char *argv[])
{
#ifndef HAVE_LIBFREETYPE
fprintf(stderr, "gd was not compiled with HAVE_LIBFREETYPE defined.\n");
fprintf(stderr, "Install the FreeType library, including the\n");
fprintf(stderr, "header files. Then edit the gd Makefile, type\n");
fprintf(stderr, "make clean, and type make again.\n");
return 1;
fprintf (stderr, "gd was not compiled with HAVE_LIBFREETYPE defined.\n");
fprintf (stderr, "Install the FreeType library, including the\n");
fprintf (stderr, "header files. Then edit the gd Makefile, type\n");
fprintf (stderr, "make clean, and type make again.\n");
return 1;
#else
gdImagePtr im;
int black;
int white;
int brect[8];
int x, y;
char *err;
FILE *out;
gdImagePtr im;
int black;
int white;
int brect[8];
int x, y;
char *err;
FILE *out;
#ifdef JISX0208
char *s = "Hello. ‚±‚ñ‚É‚¿‚Í Qyjpqg,"; /* String to draw. */
char *s = "Hello. ‚±‚ñ‚É‚¿‚Í Qyjpqg,"; /* String to draw. */
#else
char *s = "Hello. Qyjpqg,"; /* String to draw. */
char *s = "Hello. Qyjpqg,"; /* String to draw. */
#endif
double sz = 40.;
double sz = 40.;
#if 0
double angle = 0.;
double angle = 0.;
#else
double angle = DEG2RAD(-90);
double angle = DEG2RAD (-90);
#endif
#ifdef JISX0208
char *f = "/usr/openwin/lib/locale/ja/X11/fonts/TT/HG-MinchoL.ttf"; /* UNICODE */
/* char *f = "/usr/local/lib/fonts/truetype/DynaFont/dfpop1.ttf"; */ /* SJIS */
char *f = "/usr/openwin/lib/locale/ja/X11/fonts/TT/HG-MinchoL.ttf"; /* UNICODE */
/* char *f = "/usr/local/lib/fonts/truetype/DynaFont/dfpop1.ttf"; *//* SJIS */
#else
char *f = "times"; /* TrueType font */
char *f = "times"; /* TrueType font */
#endif
/* obtain brect so that we can size the image */
err = gdImageStringFT((gdImagePtr)NULL,&brect[0],0,f,sz,angle,0,0,s);
if (err) {fprintf(stderr,err); return 1;}
/* create an image just big enough for the string */
x = MAXX(brect) - MINX(brect) + 6;
y = MAXY(brect) - MINY(brect) + 6;
/* obtain brect so that we can size the image */
err = gdImageStringFT ((gdImagePtr) NULL, &brect[0], 0, f, sz, angle, 0, 0, s);
if (err)
{
fprintf (stderr, err);
return 1;
}
/* create an image just big enough for the string */
x = MAXX (brect) - MINX (brect) + 6;
y = MAXY (brect) - MINY (brect) + 6;
#if 0
im = gdImageCreate(500,500);
im = gdImageCreate (500, 500);
#else
/* gd 2.0: true color images can use freetype too */
im = gdImageCreateTrueColor(x,y);
/* gd 2.0: true color images can use freetype too */
im = gdImageCreateTrueColor (x, y);
#endif
/* Background color. gd 2.0: fill the image with it; truecolor
images have a black background otherwise. */
white = gdImageColorResolve(im, 255, 255, 255);
gdImageFilledRectangle(im, 0, 0, x, y, white);
black = gdImageColorResolve(im, 0, 0, 0);
/* Background color. gd 2.0: fill the image with it; truecolor
images have a black background otherwise. */
white = gdImageColorResolve (im, 255, 255, 255);
gdImageFilledRectangle (im, 0, 0, x, y, white);
black = gdImageColorResolve (im, 0, 0, 0);
/* render the string, offset origin to center string*/
x = 0 - MINX(brect) + 3;
y = 0 - MINY(brect) + 3;
/* render the string, offset origin to center string */
x = 0 - MINX (brect) + 3;
y = 0 - MINY (brect) + 3;
err = gdImageStringFT(im,NULL,black,f,sz,angle,x,y,s);
if (err) {fprintf(stderr,err); return 1;}
/* TBB: Write img to test/fttest.png */
out = fopen("test/fttest.png", "wb");
if (!out) {
fprintf(stderr, "Can't create test/fttest.png\n");
exit(1);
}
gdImagePng(im, out);
fclose(out);
fprintf(stderr, "Test image written to test/fttest.png\n");
/* Destroy it */
gdImageDestroy(im);
err = gdImageStringFT (im, NULL, black, f, sz, angle, x, y, s);
if (err)
{
fprintf (stderr, err);
return 1;
}
/* TBB: Write img to test/fttest.png */
out = fopen ("test/fttest.png", "wb");
if (!out)
{
fprintf (stderr, "Can't create test/fttest.png\n");
exit (1);
}
gdImagePng (im, out);
fclose (out);
fprintf (stderr, "Test image written to test/fttest.png\n");
/* Destroy it */
gdImageDestroy (im);
return 0;
return 0;
#endif /* HAVE_FREETYPE */
}
}

View File

@ -2,39 +2,43 @@
#include "gd.h"
/* A short program which converts a .png file into a .gd file, for
your convenience in creating images on the fly from a
basis image that must be loaded quickly. The .gd format
is not intended to be a general-purpose format. */
your convenience in creating images on the fly from a
basis image that must be loaded quickly. The .gd format
is not intended to be a general-purpose format. */
int main(int argc, char **argv)
int
main (int argc, char **argv)
{
gdImagePtr im;
FILE *in, *out;
if (argc != 3) {
fprintf(stderr, "Usage: gdtopng filename.gd filename.png\n");
exit(1);
}
in = fopen(argv[1], "rb");
if (!in) {
fprintf(stderr, "Input file does not exist!\n");
exit(1);
}
im = gdImageCreateFromGd(in);
fclose(in);
if (!im) {
fprintf(stderr, "Input is not in PNG format!\n");
exit(1);
}
out = fopen(argv[2], "wb");
if (!out) {
fprintf(stderr, "Output file cannot be written to!\n");
gdImageDestroy(im);
exit(1);
}
gdImagePng(im, out);
fclose(out);
gdImageDestroy(im);
gdImagePtr im;
FILE *in, *out;
if (argc != 3)
{
fprintf (stderr, "Usage: gdtopng filename.gd filename.png\n");
exit (1);
}
in = fopen (argv[1], "rb");
if (!in)
{
fprintf (stderr, "Input file does not exist!\n");
exit (1);
}
im = gdImageCreateFromGd (in);
fclose (in);
if (!im)
{
fprintf (stderr, "Input is not in PNG format!\n");
exit (1);
}
out = fopen (argv[2], "wb");
if (!out)
{
fprintf (stderr, "Output file cannot be written to!\n");
gdImageDestroy (im);
exit (1);
}
gdImagePng (im, out);
fclose (out);
gdImageDestroy (im);
return 0;
return 0;
}

View File

@ -1,145 +1,148 @@
/*
add ability to load xpm files to gd, requires the xpm
library.
Caolan.McNamara@ul.ie
http://www.csn.ul.ie/~caolan
*/
add ability to load xpm files to gd, requires the xpm
library.
Caolan.McNamara@ul.ie
http://www.csn.ul.ie/~caolan
*/
#include <stdio.h>
#include <stdlib.h>
#include "gd.h"
#include "gdhelpers.h"
#ifndef HAVE_XPM
gdImagePtr gdImageCreateFromXpm(char *filename)
{
fprintf(stderr,"libgd was not built with xpm support\n");
return(NULL);
}
gdImagePtr
gdImageCreateFromXpm (char *filename)
{
fprintf (stderr, "libgd was not built with xpm support\n");
return (NULL);
}
#else
#include "xpm.h"
gdImagePtr gdImageCreateFromXpm(char *filename)
gdImagePtr
gdImageCreateFromXpm (char *filename)
{
XpmInfo info;
XpmImage image;
int i, j, k, number;
char buf[5];
gdImagePtr im = 0;
char *apixel;
int *pointer;
int red = 0, green = 0, blue = 0, color = 0;
int *colors;
int ret;
ret = XpmReadFileToXpmImage (filename, &image, &info);
if (ret != XpmSuccess)
return 0;
if (!(im = gdImageCreate (image.width, image.height)))
return 0;
number = image.ncolors;
colors = (int *) gdMalloc (sizeof (int) * number);
if (colors == NULL)
return (0);
for (i = 0; i < number; i++)
{
switch (strlen (image.colorTable[i].c_color))
{
XpmInfo info;
XpmImage image;
int i,j,k,number;
char buf[5];
gdImagePtr im = 0;
char *apixel;
int *pointer;
int red=0,green=0,blue=0,color=0;
int *colors;
int ret;
case 4:
buf[1] = '\0';
buf[0] = image.colorTable[i].c_color[1];
red = strtol (buf, NULL, 16);
ret = XpmReadFileToXpmImage(filename,&image,&info);
if (ret != XpmSuccess)
return 0;
buf[0] = image.colorTable[i].c_color[3];
green = strtol (buf, NULL, 16);
if (!(im = gdImageCreate(image.width, image.height)))
return 0;
buf[0] = image.colorTable[i].c_color[5];
blue = strtol (buf, NULL, 16);
break;
case 7:
buf[2] = '\0';
buf[0] = image.colorTable[i].c_color[1];
buf[1] = image.colorTable[i].c_color[2];
red = strtol (buf, NULL, 16);
number = image.ncolors;
colors = (int*)gdMalloc(sizeof(int) * number);
if (colors == NULL)
return(0);
for (i = 0; i < number; i++)
{
switch(strlen(image.colorTable[i].c_color))
{
case 4:
buf[1] = '\0';
buf[0] = image.colorTable[i].c_color[1];
red = strtol(buf,NULL,16);
buf[0] = image.colorTable[i].c_color[3];
buf[1] = image.colorTable[i].c_color[4];
green = strtol (buf, NULL, 16);
buf[0] = image.colorTable[i].c_color[3];
green = strtol(buf,NULL,16);
buf[0] = image.colorTable[i].c_color[5];
buf[1] = image.colorTable[i].c_color[6];
blue = strtol (buf, NULL, 16);
break;
case 10:
buf[3] = '\0';
buf[0] = image.colorTable[i].c_color[1];
buf[1] = image.colorTable[i].c_color[2];
buf[2] = image.colorTable[i].c_color[3];
red = strtol (buf, NULL, 16);
red /= 64;
buf[0] = image.colorTable[i].c_color[5];
blue = strtol(buf,NULL,16);
break;
case 7:
buf[2] = '\0';
buf[0] = image.colorTable[i].c_color[1];
buf[1] = image.colorTable[i].c_color[2];
red = strtol(buf,NULL,16);
buf[0] = image.colorTable[i].c_color[4];
buf[1] = image.colorTable[i].c_color[5];
buf[2] = image.colorTable[i].c_color[6];
green = strtol (buf, NULL, 16);
green /= 64;
buf[0] = image.colorTable[i].c_color[3];
buf[1] = image.colorTable[i].c_color[4];
green = strtol(buf,NULL,16);
buf[0] = image.colorTable[i].c_color[7];
buf[1] = image.colorTable[i].c_color[8];
buf[2] = image.colorTable[i].c_color[9];
blue = strtol (buf, NULL, 16);
blue /= 64;
break;
case 13:
buf[4] = '\0';
buf[0] = image.colorTable[i].c_color[1];
buf[1] = image.colorTable[i].c_color[2];
buf[2] = image.colorTable[i].c_color[3];
buf[3] = image.colorTable[i].c_color[4];
red = strtol (buf, NULL, 16);
red /= 256;
buf[0] = image.colorTable[i].c_color[5];
buf[1] = image.colorTable[i].c_color[6];
blue = strtol(buf,NULL,16);
break;
case 10:
buf[3] = '\0';
buf[0] = image.colorTable[i].c_color[1];
buf[1] = image.colorTable[i].c_color[2];
buf[2] = image.colorTable[i].c_color[3];
red = strtol(buf,NULL,16);
red /= 64;
buf[0] = image.colorTable[i].c_color[5];
buf[1] = image.colorTable[i].c_color[6];
buf[2] = image.colorTable[i].c_color[7];
buf[3] = image.colorTable[i].c_color[8];
green = strtol (buf, NULL, 16);
green /= 256;
buf[0] = image.colorTable[i].c_color[4];
buf[1] = image.colorTable[i].c_color[5];
buf[2] = image.colorTable[i].c_color[6];
green = strtol(buf,NULL,16);
green /= 64;
buf[0] = image.colorTable[i].c_color[7];
buf[1] = image.colorTable[i].c_color[8];
buf[2] = image.colorTable[i].c_color[9];
blue = strtol(buf,NULL,16);
blue /= 64;
break;
case 13:
buf[4] = '\0';
buf[0] = image.colorTable[i].c_color[1];
buf[1] = image.colorTable[i].c_color[2];
buf[2] = image.colorTable[i].c_color[3];
buf[3] = image.colorTable[i].c_color[4];
red = strtol(buf,NULL,16);
red /= 256;
buf[0] = image.colorTable[i].c_color[5];
buf[1] = image.colorTable[i].c_color[6];
buf[2] = image.colorTable[i].c_color[7];
buf[3] = image.colorTable[i].c_color[8];
green = strtol(buf,NULL,16);
green /= 256;
buf[0] = image.colorTable[i].c_color[9];
buf[1] = image.colorTable[i].c_color[10];
buf[2] = image.colorTable[i].c_color[11];
buf[3] = image.colorTable[i].c_color[12];
blue = strtol(buf,NULL,16);
blue /= 256;
break;
}
colors[i] = gdImageColorResolve(im,red,green,blue);
if (colors[i] == -1)
fprintf(stderr,"ARRRGH\n");
}
apixel = (char *)gdMalloc(image.cpp+1);
if (apixel == NULL)
return(0);
apixel[image.cpp] = '\0';
pointer = image.data;
for(i=0;i<image.height;i++)
{
for(j=0;j<image.width;j++)
{
k = *pointer++;
gdImageSetPixel(im,j,i,colors[k]);
}
}
gdFree(apixel);
gdFree(colors);
return(im);
buf[0] = image.colorTable[i].c_color[9];
buf[1] = image.colorTable[i].c_color[10];
buf[2] = image.colorTable[i].c_color[11];
buf[3] = image.colorTable[i].c_color[12];
blue = strtol (buf, NULL, 16);
blue /= 256;
break;
}
colors[i] = gdImageColorResolve (im, red, green, blue);
if (colors[i] == -1)
fprintf (stderr, "ARRRGH\n");
}
apixel = (char *) gdMalloc (image.cpp + 1);
if (apixel == NULL)
return (0);
apixel[image.cpp] = '\0';
pointer = image.data;
for (i = 0; i < image.height; i++)
{
for (j = 0; j < image.width; j++)
{
k = *pointer++;
gdImageSetPixel (im, j, i, colors[k]);
}
}
gdFree (apixel);
gdFree (colors);
return (im);
}
#endif

View File

@ -1,40 +1,45 @@
#include <stdio.h>
#include "gd.h"
/* A short program which converts a .png file into a .gd file, for
your convenience in creating images on the fly from a
basis image that must be loaded quickly. The .gd format
is not intended to be a general-purpose format. */
your convenience in creating images on the fly from a
basis image that must be loaded quickly. The .gd format
is not intended to be a general-purpose format. */
int main(int argc, char **argv)
int
main (int argc, char **argv)
{
gdImagePtr im;
FILE *in, *out;
if (argc != 3) {
fprintf(stderr, "Usage: pngtogd filename.png filename.gd\n");
exit(1);
}
in = fopen(argv[1], "rb");
if (!in) {
fprintf(stderr, "Input file does not exist!\n");
exit(1);
}
im = gdImageCreateFromPng(in);
fclose(in);
if (!im) {
fprintf(stderr, "Input is not in PNG format!\n");
exit(1);
}
out = fopen(argv[2], "wb");
if (!out) {
fprintf(stderr, "Output file cannot be written to!\n");
gdImageDestroy(im);
exit(1);
}
gdImageGd(im, out);
fclose(out);
gdImageDestroy(im);
gdImagePtr im;
FILE *in, *out;
if (argc != 3)
{
fprintf (stderr, "Usage: pngtogd filename.png filename.gd\n");
exit (1);
}
in = fopen (argv[1], "rb");
if (!in)
{
fprintf (stderr, "Input file does not exist!\n");
exit (1);
}
im = gdImageCreateFromPng (in);
fclose (in);
if (!im)
{
fprintf (stderr, "Input is not in PNG format!\n");
exit (1);
}
out = fopen (argv[2], "wb");
if (!out)
{
fprintf (stderr, "Output file cannot be written to!\n");
gdImageDestroy (im);
exit (1);
}
gdImageGd (im, out);
fclose (out);
gdImageDestroy (im);
return 0;
return 0;
}

View File

@ -1,47 +1,52 @@
#include <stdio.h>
#include <stdlib.h>
#include "gd.h"
/* A short program which converts a .png file into a .gd file, for
your convenience in creating images on the fly from a
basis image that must be loaded quickly. The .gd format
is not intended to be a general-purpose format. */
your convenience in creating images on the fly from a
basis image that must be loaded quickly. The .gd format
is not intended to be a general-purpose format. */
int main(int argc, char **argv)
int
main (int argc, char **argv)
{
gdImagePtr im;
FILE *in, *out;
int cs, fmt;
gdImagePtr im;
FILE *in, *out;
int cs, fmt;
if (argc != 5) {
fprintf(stderr, "Usage: pngtogd2 filename.png filename.gd2 cs fmt\n");
fprintf(stderr, " where cs is the chunk size\n");
fprintf(stderr, " fmt is 1 for raw, 2 for compressed\n");
exit(1);
}
in = fopen(argv[1], "rb");
if (!in) {
fprintf(stderr, "Input file does not exist!\n");
exit(1);
}
im = gdImageCreateFromPng(in);
fclose(in);
if (!im) {
fprintf(stderr, "Input is not in PNG format!\n");
exit(1);
}
out = fopen(argv[2], "wb");
if (!out) {
fprintf(stderr, "Output file cannot be written to!\n");
gdImageDestroy(im);
exit(1);
}
cs = atoi(argv[3]);
fmt = atoi(argv[4]);
gdImageGd2(im, out, cs, fmt);
fclose(out);
gdImageDestroy(im);
if (argc != 5)
{
fprintf (stderr, "Usage: pngtogd2 filename.png filename.gd2 cs fmt\n");
fprintf (stderr, " where cs is the chunk size\n");
fprintf (stderr, " fmt is 1 for raw, 2 for compressed\n");
exit (1);
}
in = fopen (argv[1], "rb");
if (!in)
{
fprintf (stderr, "Input file does not exist!\n");
exit (1);
}
im = gdImageCreateFromPng (in);
fclose (in);
if (!im)
{
fprintf (stderr, "Input is not in PNG format!\n");
exit (1);
}
out = fopen (argv[2], "wb");
if (!out)
{
fprintf (stderr, "Output file cannot be written to!\n");
gdImageDestroy (im);
exit (1);
}
cs = atoi (argv[3]);
fmt = atoi (argv[4]);
gdImageGd2 (im, out, cs, fmt);
fclose (out);
gdImageDestroy (im);
return 0;
return 0;
}

View File

@ -1,5 +1,5 @@
This is gd 2.0.0 BETA.
This is gd 2.0.1 BETA.
_If you have problems, report them in detail, and consider using gd
1.8.4 until gd 2.0 final is out._
@ -8,13 +8,13 @@
are documented to some degree and the what's new section is reasonably
complete. Enjoy!
gd 2.0.0
gd 2.0.1
A graphics library for fast image creation
Follow this link to the latest version of this document.
_HEY! READ THIS!_ gd 2.0.0 creates PNG, JPEG and WBMP images, not
_HEY! READ THIS!_ gd 2.0.1 creates PNG, JPEG and WBMP images, not
GIF images. This is a good thing. PNG is a more compact format, and
full compression is available. JPEG works well with photographic
images, and is still more compatible with the major Web browsers
@ -27,7 +27,7 @@ gd 2.0.0
well-compressed, modern image formats such as PNG and JPEG as soon
as possible.
gd 2.0.0 _requires_ that the following libraries also be installed:
gd 2.0.1 _requires_ that the following libraries also be installed:
libpng (see the libpng home page)
@ -118,7 +118,7 @@ COPYRIGHT STATEMENT FOLLOWS THIS LINE
particular purpose, with respect to this code and accompanying
documentation.
Although their code does not appear in gd 2.0.0, the authors wish
Although their code does not appear in gd 2.0.1, the authors wish
to thank David Koblas, David Rowley, and Hutchison Avenue Software
Corporation for their prior contributions.
@ -147,7 +147,7 @@ END OF COPYRIGHT STATEMENT
What if I want to use another programming language?
Not all of these tools are necessarily up to date and fully compatible
with 2.0.0.
with 2.0.1.
Perl
@ -183,6 +183,39 @@ END OF COPYRIGHT STATEMENT
* tgd, by Bradley K. Sherman
* fly, by Martin Gleeson
What's new in version 2.0.1?
* Workaround for a bug in gcc, apparently found in gcc 2.7.2 and up.
I reproduced and fixed it while using gcc 2.9.5.2. The bug
occurred only when the -g option was in use. This problem caused
gcc to spew internal error messages unrelated to the correctness
of the code in gd_gd2.c. Howard Jones was first to report it.
* gdImageFilledEllipse documented and altered; no longer requires a
superfluous style argument. Thanks to Francis James Franklin.
* The Makefile now offers the correct syntax for optionally creating
a static library. Thanks to Jean-Lous Regez, among others.
* A nested comment, an attempt to return the value of a void
function, and a potentially significant error in
gdImageCopyResampled were fixed thanks to Joseph Shirley.
* A bug preventing proper truecolor text rendering was fixed, thanks
to Jason Gallagher.
* gdImageStringFT (FreeType) should now work better against a
transparent or semitransparent background, and should act in a
manner consistent with the most recent gdImageAlphaBlending
setting. Antialiasing is now done via the alpha channel mechanism
if the image is a truecolor image.
* Bugs in the output of gdImageArc and gdImageFilledArc were
reported by Bruce Verderaime. A simple and correct but inefficient
implementation has been substituted until fixes are contributed
for the faster code, which is in gd_arc_f_buggy.c along with the
test program that reproduces the bug(s).
* gdImageFilledArc now offers additional style options, which can be
combined to produce various effects.
* Masahito Yamaga (ma@yama-ga.com) sent a patch to improve support
for Japanese output via gdImageStringFT. He also added a new
readme.jpn file.
* Zillions of documentation fixes.
What's new in version 2.0?
* _Support for truecolor images!_ Version 2.0 can load truecolor
@ -592,11 +625,11 @@ END OF COPYRIGHT STATEMENT
(Windows), please consult with an experienced user of your system.
Sorry, we cannot answer questions about basic Internet skills.
Unpacking the archive will produce a directory called "gd-2.0.0".
Unpacking the archive will produce a directory called "gd-2.0.1".
For Unix
cd to the 2.0.0 directory. Edit the Makefile with your preferred text
cd to the 2.0.1 directory. Edit the Makefile with your preferred text
editor and make any necessary changes to the settings at the top,
especially if you want Xpm or TrueType support. Next, type "make
install". Because gd 2.0 and above installs as a shared library, it is
@ -926,15 +959,17 @@ gdImageDestroy(im);
gdImageCreateTrueColor(sx, sy) _(FUNCTION)_
gdImageCreateTrueColor is called to create truecolor images,
with an essentially unlimited number of colors. Invoke
gdImageCreate with the x and y dimensions of the desired image.
gdImageCreate returns a gdImagePtr to the new image, or NULL if
unable to allocate the image. The image must eventually be
destroyed using gdImageDestroy().
gdImageCreateTrueColor with the x and y dimensions of the
desired image. gdImageCreateTrueColor returns a gdImagePtr to
the new image, or NULL if unable to allocate the image. The
image must eventually be destroyed using gdImageDestroy().
Truecolor images are always filled with black at creation time.
... inside a function ...
gdImagePtr im;
im = gdImageCreate(64, 64);
im = gdImageCreateTrueColor(64, 64);
/* ... Use the image ... */
gdImageDestroy(im);
@ -1641,17 +1676,30 @@ gdImageDestroy(im);
void gdImageFilledArc(gdImagePtr im, int cx, int cy, int w, int h, int
s, int e, int color, int style) _(FUNCTION)_
gdImageArc is used to draw a partial ellipse centered at the
given point, with the specified width and height in pixels. The
arc begins at the position in degrees specified by s and ends
at the position specified by e. The arc is filled in the color
specified by the second to last argument. A circle can be drawn
by beginning from 0 degrees and ending at 360 degrees, with
width and height being equal. e must be greater than s. Values
greater than 360 are interpreted modulo 360. The last argument
specifies whether the function should draw a triangular chord
(gdImageChord) or the more frequently desired pie slice
(gdImagePie).
gdImageFilledArc is used to draw a partial ellipse centered at
the given point, with the specified width and height in pixels.
The arc begins at the position in degrees specified by s and
ends at the position specified by e. The arc is filled in the
color specified by the second to last argument. A circle can be
drawn by beginning from 0 degrees and ending at 360 degrees,
with width and height being equal. e must be greater than s.
Values greater than 360 are interpreted modulo 360. The last
argument is a bitwise OR of the following possibilities:
+ gdArc
+ gdChord
+ gdPie (synonym for gdChord)
+ gdNoFill
+ gdEdged
gdArc and gdChord are mutually exclusive; gdChord just connects
the starting and ending angles with a straight line, while
gdArc produces a rounded edge. gdPie is a synonym for gdArc.
gdNoFill indicates that the arc or chord should be outlined,
not filled. gdEdged, used together with gdNoFill, indicates
that the beginning and ending angles should be connected to the
center; this is a good way to outline (rather than fill) a 'pie
slice'.
... inside a function ...
@ -1664,7 +1712,33 @@ black = gdImageColorAllocate(im, 0, 0, 0);
/* Allocate the color white (red, green and blue all maximum). */
white = gdImageColorAllocate(im, 255, 255, 255);
/* Inscribe a filled pie slice in the image. */
gdImageFilledArc(im, 50, 25, 98, 48, 0, 45, white, gdPie);
gdImageFilledArc(im, 50, 25, 98, 48, 0, 45, white, gdArc);
/* ... Do something with the image, such as saving it to a file... */
/* Destroy it */
gdImageDestroy(im);
void gdImageFilledEllipse(gdImagePtr im, int cx, int cy, int w, int h,
int s, int e, int color) _(FUNCTION)_
gdImageFilledEllipse is used to draw an ellipse centered at the
given point, with the specified width and height in pixels. The
ellipse is filled in the color specified by the last argument.
A circle can be drawn by beginning from 0 degrees and ending at
360 degrees, with width and height being equal. e must be
greater than s. Values greater than 360 are interpreted modulo
360.
... inside a function ...
gdImagePtr im;
int black;
int white;
im = gdImageCreate(100, 50);
/* Background color (first allocated) */
black = gdImageColorAllocate(im, 0, 0, 0);
/* Allocate the color white (red, green and blue all maximum). */
white = gdImageColorAllocate(im, 255, 255, 255);
/* Inscribe a filled ellipse in the image. */
gdImageFilledEllipse(im, 50, 25, 98, 48, white);
/* ... Do something with the image, such as saving it to a file... */
/* Destroy it */
gdImageDestroy(im);
@ -1943,13 +2017,13 @@ gdImagePtr im;
int red, blue;
im = gdImageCreateTrueColor(100, 100);
/* Background color */
red = gdTrueColor(im, 255, 0, 0);
red = gdTrueColor(255, 0, 0);
gdImageFilledRectangle(im, 0, 0, 100, 100, red);
/* Drawing color. Full transparency would be an alpha channel value
of 127 (gd has a 7 bit alpha chnanel). 0 is opaque,
127 is transparent. So cut gdAlphaTransparent in half to get
50% blending. */
blue = gdTrueColorAlpha(im, 0, 0, 255, gdAlphaTransparent / 2);
blue = gdTrueColorAlpha(0, 0, 255, gdAlphaTransparent / 2);
/* Draw with blending. Result will be 50% red, 50% blue: yellow
(emitted light, remember, not reflected light. What you learned
in Kindergarten is wrong here). */
@ -2350,7 +2424,10 @@ gdImageDestroy(im);
color index in the image specified, sets its RGB
values to those requested (255 is the maximum for
each), and returns the index of the new color table
entry. When creating a new image, the first time
entry, or an RGBA value in the case of a truecolor
image; in either case you can then use the returned
value as a parameter to drawing functions. When
creating a new palette-based image, the first time
you invoke this function, you are setting the
background color for that image.
@ -2381,6 +2458,50 @@ red = gdImageColorAllocate(im, 255, 0, 0);
gdImageDashedLine(im, 0, 0, 99, 99, red);
/* ... Do something with the image, such as saving it to a file... */
/* Destroy it */
gdImageDestroy(im);
int gdImageColorAllocateAlpha(gdImagePtr im, int r, int g,
int b, int a) _(FUNCTION)_
gdImageColorAllocateAlpha finds the first available
color index in the image specified, sets its RGBA
values to those requested (255 is the maximum for
red, green and blue, and 127 represents full
transparency for alpha), and returns the index of
the new color table entry, or an RGBA value in the
case of a truecolor image; in either case you can
then use the returned value as a parameter to
drawing functions. When creating a new
palette-based image, the first time you invoke this
function, you are setting the background color for
that image.
In the event that all gdMaxColors colors (256) have
already been allocated, gdImageColorAllocate will
return -1 to indicate failure. (This is not
uncommon when working with existing palette-based
PNG files that already use 256 colors.) Note that
gdImageColorAllocateAlpha does not check for
existing colors that match your request; see
gdImageColorExactAlpha and gdImageColorClosestAlpha
for ways to locate existing colors that approximate
the color desired in situations where a new color
is not available. Also see
gdImageColorResolveAlpha.
... inside a function ...
gdImagePtr im;
int black;
int red;
im = gdImageCreate(100, 100);
/* Background color (first allocated) */
black = gdImageColorAllocate(im, 0, 0, 0);
/* Allocate the color red, 50% transparent. */
red = gdImageColorAllocateAlpha(im, 255, 0, 0, 64);
/* Draw a dashed line from the upper left corner to the lower right corner. */
gdImageDashedLine(im, 0, 0, 99, 99, red);
/* ... Do something with the image, such as saving it to a file... */
/* Destroy it */
gdImageDestroy(im);
int gdImageColorClosest(gdImagePtr im, int r, int g, int b)
@ -2396,6 +2517,9 @@ gdImageDestroy(im);
If no colors have yet been allocated in the image,
gdImageColorClosest returns -1.
When applied to a truecolor image, this function
always succeeds in returning the desired color.
This function is most useful as a backup method for
choosing a drawing color when an image already
contains gdMaxColors (256) colors and no more can
@ -2425,6 +2549,54 @@ if (red == (-1)) {
gdImageDashedLine(im, 0, 0, 99, 99, red);
/* ... Do something with the image, such as saving it to a file... */
/* Destroy it */
gdImageDestroy(im);
int gdImageColorClosestAlpha(gdImagePtr im, int r, int g,
int b, int a) _(FUNCTION)_
gdImageColorClosest searches the colors which have
been defined thus far in the image specified and
returns the index of the color with RGBA values
closest to those of the request. (Closeness is
determined by Euclidian distance, which is used to
determine the distance in four-dimensional
color/alpha space between colors.)
If no colors have yet been allocated in the image,
gdImageColorClosestAlpha returns -1.
When applied to a truecolor image, this function
always succeeds in returning the desired color.
This function is most useful as a backup method for
choosing a drawing color when a palette-based image
already contains gdMaxColors (256) colors and no
more can be allocated. (This is not uncommon when
working with existing palette-based PNG files that
already use many colors.) See
gdImageColorExactAlpha for a method of locating
exact matches only.
... inside a function ...
gdImagePtr im;
FILE *in;
int red;
/* Let's suppose that photo.png is a scanned photograph with
many colors. */
in = fopen("photo.png", "rb");
im = gdImageCreateFromPng(in);
fclose(in);
/* Try to allocate red, 50% transparent, directly */
red = gdImageColorAllocateAlpha(im, 255, 0, 0, 64);
/* If we fail to allocate red... */
if (red == (-1)) {
/* Find the _closest_ color instead. */
red = gdImageColorClosestAlpha(im, 255, 0, 0, 64);
}
/* Draw a dashed line from the upper left corner to the lower right corner */
gdImageDashedLine(im, 0, 0, 99, 99, red);
/* ... Do something with the image, such as saving it to a file... */
/* Destroy it */
gdImageDestroy(im);
int gdImageColorClosestHWB(gdImagePtr im, int r, int g, int
@ -2440,6 +2612,9 @@ gdImageDestroy(im);
If no colors have yet been allocated in the image,
gdImageColorClosestHWB returns -1.
When applied to a truecolor image, this function
always succeeds in returning the desired color.
This function is most useful as a backup method for
choosing a drawing color when an image already
contains gdMaxColors (256) colors and no more can
@ -2482,6 +2657,9 @@ gdImageDestroy(im);
gdImageColorClosest for a way to find the color
closest to the color requested.
When applied to a truecolor image, this function
always succeeds in returning the desired color.
... inside a function ...
gdImagePtr im;
@ -2519,6 +2697,9 @@ gdImageDestroy(im);
color (as in gdImageColorClosest). This function
always returns an index of a color.
When applied to a truecolor image, this function
always succeeds in returning the desired color.
... inside a function ...
gdImagePtr im;
@ -2534,31 +2715,62 @@ red = gdImageColorResolve(im, 255, 0, 0);
gdImageDashedLine(im, 0, 0, 99, 99, red);
/* ... Do something with the image, such as saving it to a file... */
/* Destroy it */
gdImageDestroy(im);
int gdImageColorResolveAlpha(gdImagePtr im, int r, int g,
int b, int a) _(FUNCTION)_
gdImageColorResolveAlpha searches the colors which
have been defined thus far in the image specified
and returns the index of the first color with RGBA
values which exactly match those of the request. If
no allocated color matches the request precisely,
then gdImageColorResolveAlpha tries to allocate the
exact color. If there is no space left in the color
table then gdImageColorResolveAlpha returns the
closest color (as in gdImageColorClosestAlpha).
This function always returns an index of a color.
When applied to a truecolor image, this function
always succeeds in returning the desired color.
... inside a function ...
gdImagePtr im;
int red;
in = fopen("photo.png", "rb");
im = gdImageCreateFromPng(in);
fclose(in);
/* The image may already contain red; if it does, we'll save a slot
in the color table by using that color. */
/* Get index of red, 50% transparent, or the next best thing */
red = gdImageColorResolveAlpha(im, 255, 0, 0, 64);
/* Draw a dashed line from the upper left corner to the lower right corner */
gdImageDashedLine(im, 0, 0, 99, 99, red);
/* ... Do something with the image, such as saving it to a file... */
/* Destroy it */
gdImageDestroy(im);
int gdImageColorsTotal(gdImagePtr im) _(MACRO)_
gdImageColorsTotal is a macro which returns the
number of colors currently allocated in the image.
Use this macro to obtain this information; do not
access the structure directly.
number of colors currently allocated in a palette
image. For truecolor images, the result of this
call is undefined and should not be used.
int gdImageColorRed(gdImagePtr im, int c) _(MACRO)_
gdImageColorRed is a macro which returns the red
portion of the specified color in the image. Use
this macro to obtain this information; do not
access the structure directly.
portion of the specified color in the image. This
macro works for both palette and truecolor images.
int gdImageColorGreen(gdImagePtr im, int c) _(MACRO)_
gdImageColorGreen is a macro which returns the
green portion of the specified color in the image.
Use this macro to obtain this information; do not
access the structure directly.
This macro works for both palette and truecolor
images.
int gdImageColorBlue(gdImagePtr im, int c) _(MACRO)_
gdImageColorBlue is a macro which returns the green
portion of the specified color in the image. Use
this macro to obtain this information; do not
access the structure directly.
portion of the specified color in the image. This
macro works for both palette and truecolor images.
int gdImageGetInterlaced(gdImagePtr im) _(MACRO)_
gdImageGetInterlaced is a macro which returns true
@ -2655,6 +2867,29 @@ fclose(out);
/* Destroy it */
gdImageDestroy(im);
void gdImageTrueColor(int red, int green, int blue)
_(MACRO)_
gdImageTrueColor returns an RGBA color value for
use when drawing on a truecolor image. Red, green,
and blue are all in the range between 0 (off) and
255 (maximum). This macro should not be used with
palette-based images. If you need to write code
which is compatible with both palette-based and
truecolor images, use gdImageColorResolve.
void gdImageTrueColorAlpha(int red, int green, int blue,
int alpha) _(MACRO)_
gdImageTrueColorAlpha returns an RGBA color value
for use when drawing on a truecolor image with
alpha channel transparency. Red, green, and blue
are all in the range between 0 (off) and 255
(maximum). Alpha is in the range between 0 (opaque)
and 127 (fully transparent). This macro should not
be used with palette-based images. If you need to
write code which is compatible with both
palette-based and truecolor images, use
gdImageColorResolveAlpha.
Copying and resizing functions
void gdImageCopy(gdImagePtr dst, gdImagePtr src, int dstX,
@ -3217,11 +3452,16 @@ typedef struct gdIOCtx {
gdImageBlue | gdImageBoundsSafe |
gdImageChar | gdImageCharUp |
gdImageColorAllocate |
gdImageColorAllocateAlpha |
gdImageColorClosest |
gdImageColorClosestAlpha |
gdImageColorDeallocate |
gdImageColorExact | gdImageColorResolve
| gdImageColorTransparent | gdImageCopy
| gdImageCopyMerge | gdImageMergeGray |
gdImageColorExact |
gdImageColorExactAlpha |
gdImageColorResolve |
gdImageColorResolveAlpha |
gdImageColorTransparent | gdImageCopy |
gdImageCopyMerge | gdImageMergeGray |
gdImageCopyResized |
gdImageCopyResampled | gdImageCreate |
gdImageCreatePalette |
@ -3236,6 +3476,7 @@ typedef struct gdIOCtx {
gdImageCreateFromXpm |
gdImageDashedLine | gdImageDestroy |
gdImageFill | gdImageFilledArc |
gdImageFilledEllipse |
gdImageFillToBorder |
gdImageFilledRectangle | gdImageGd |
gdImageGd2 | gdImageGetInterlaced |

View File

@ -1,122 +1,129 @@
#include <stdio.h>
#include "gd.h"
/* If palette is true, we convert from truecolor to palette at the end,
to test gdImageTrueColorToPalette and see file size/
quality tradeoffs. */
to test gdImageTrueColorToPalette and see file size/
quality tradeoffs. */
void testDrawing(
gdImagePtr im_in,
double scale,
int blending,
int palette,
char *filename);
void testDrawing (
gdImagePtr im_in,
double scale,
int blending,
int palette,
char *filename);
int main(int argc, char *argv[])
int
main (int argc, char *argv[])
{
/* Input and output files */
FILE *in;
FILE *out;
/* Input and output files */
FILE *in;
FILE *out;
/* Input image */
gdImagePtr im_in = 0;
/* Input image */
gdImagePtr im_in = 0;
/* Colors */
int lightBlue;
/* Colors */
int lightBlue;
if (argc != 2) {
fprintf(stderr, "Usage: testac filename.png\n");
exit(1);
}
/* Load original PNG, which should contain alpha channel
information. We will use it in two ways: preserving it
literally, for use with compatible browsers, and
compositing it ourselves against a background of our
choosing (alpha blending). We'll change its size
and try creating palette versions of it. */
in = fopen(argv[1], "rb");
if (!in) {
fprintf(stderr, "Can't load %s.\n", argv[1]);
exit(1);
} else {
im_in = gdImageCreateFromPng(in);
fclose(in);
}
testDrawing(im_in, 1.0, 0, 0, "noblending-fullsize-truecolor.png");
testDrawing(im_in, 1.0, 1, 0, "blending-fullsize-truecolor.png");
testDrawing(im_in, 0.5, 0, 0, "noblending-halfsize-truecolor.png");
testDrawing(im_in, 0.5, 1, 0, "blending-halfsize-truecolor.png");
testDrawing(im_in, 2.0, 0, 0, "noblending-doublesize-truecolor.png");
testDrawing(im_in, 2.0, 1, 0, "blending-doublesize-truecolor.png");
testDrawing(im_in, 1.0, 0, 1, "noblending-fullsize-palette.png");
testDrawing(im_in, 1.0, 1, 1, "blending-fullsize-palette.png");
testDrawing(im_in, 0.5, 0, 1, "noblending-halfsize-palette.png");
testDrawing(im_in, 0.5, 1, 1, "blending-halfsize-palette.png");
testDrawing(im_in, 2.0, 0, 1, "noblending-doublesize-palette.png");
testDrawing(im_in, 2.0, 1, 1, "blending-doublesize-palette.png");
gdImageDestroy(im_in);
return 0;
if (argc != 2)
{
fprintf (stderr, "Usage: testac filename.png\n");
exit (1);
}
/* Load original PNG, which should contain alpha channel
information. We will use it in two ways: preserving it
literally, for use with compatible browsers, and
compositing it ourselves against a background of our
choosing (alpha blending). We'll change its size
and try creating palette versions of it. */
in = fopen (argv[1], "rb");
if (!in)
{
fprintf (stderr, "Can't load %s.\n", argv[1]);
exit (1);
}
else
{
im_in = gdImageCreateFromPng (in);
fclose (in);
}
testDrawing (im_in, 1.0, 0, 0, "noblending-fullsize-truecolor.png");
testDrawing (im_in, 1.0, 1, 0, "blending-fullsize-truecolor.png");
testDrawing (im_in, 0.5, 0, 0, "noblending-halfsize-truecolor.png");
testDrawing (im_in, 0.5, 1, 0, "blending-halfsize-truecolor.png");
testDrawing (im_in, 2.0, 0, 0, "noblending-doublesize-truecolor.png");
testDrawing (im_in, 2.0, 1, 0, "blending-doublesize-truecolor.png");
testDrawing (im_in, 1.0, 0, 1, "noblending-fullsize-palette.png");
testDrawing (im_in, 1.0, 1, 1, "blending-fullsize-palette.png");
testDrawing (im_in, 0.5, 0, 1, "noblending-halfsize-palette.png");
testDrawing (im_in, 0.5, 1, 1, "blending-halfsize-palette.png");
testDrawing (im_in, 2.0, 0, 1, "noblending-doublesize-palette.png");
testDrawing (im_in, 2.0, 1, 1, "blending-doublesize-palette.png");
gdImageDestroy (im_in);
return 0;
}
/* If palette is true, we convert from truecolor to palette at the end,
to test gdImageTrueColorToPalette and see file size/
quality tradeoffs. */
void testDrawing(
gdImagePtr im_in,
double scale,
int blending,
int palette,
char *filename)
to test gdImageTrueColorToPalette and see file size/
quality tradeoffs. */
void
testDrawing (
gdImagePtr im_in,
double scale,
int blending,
int palette,
char *filename)
{
gdImagePtr im_out;
FILE *out;
/* Create output image. */
im_out = gdImageCreateTrueColor((int) (gdImageSX(im_in) * scale),
(int) (gdImageSY(im_in) * scale));
/*
Request alpha blending. This causes future
drawing operations to perform alpha channel blending
with the background, resulting in an opaque image.
Without this call, pixels in the foreground color are
copied literally, *including* the alpha channel value,
resulting in an output image which is potentially
not opaque. This flag can be set and cleared as often
as desired. */
gdImageAlphaBlending(im_out, blending);
gdImagePtr im_out;
FILE *out;
/* Create output image. */
im_out = gdImageCreateTrueColor ((int) (gdImageSX (im_in) * scale),
(int) (gdImageSY (im_in) * scale));
/*
Request alpha blending. This causes future
drawing operations to perform alpha channel blending
with the background, resulting in an opaque image.
Without this call, pixels in the foreground color are
copied literally, *including* the alpha channel value,
resulting in an output image which is potentially
not opaque. This flag can be set and cleared as often
as desired. */
gdImageAlphaBlending (im_out, blending);
/* Flood with light blue. */
gdImageFill(im_out, (int) (gdImageSX(im_in) * scale / 2),
(int) (gdImageSY(im_in) * scale / 2),
gdTrueColor(192, 192, 255));
/* Copy the source image. Alpha blending should result in
compositing against red. With blending turned off, the
browser or viewer will composite against its preferred
background, or, if it does not support an alpha channel,
we will see the original colors for the pixels that
ought to be transparent or semitransparent. */
gdImageCopyResampled(im_out, im_in,
0, 0,
0, 0,
(int) (gdImageSX(im_in) * scale), (int) (gdImageSY(im_in) * scale),
gdImageSX(im_in), gdImageSY(im_in));
/* Write PNG */
out = fopen(filename, "wb");
/* Flood with light blue. */
gdImageFill (im_out, (int) (gdImageSX (im_in) * scale / 2),
(int) (gdImageSY (im_in) * scale / 2),
gdTrueColor (192, 192, 255));
/* Copy the source image. Alpha blending should result in
compositing against red. With blending turned off, the
browser or viewer will composite against its preferred
background, or, if it does not support an alpha channel,
we will see the original colors for the pixels that
ought to be transparent or semitransparent. */
gdImageCopyResampled (im_out, im_in,
0, 0,
0, 0,
(int) (gdImageSX (im_in) * scale), (int) (gdImageSY (im_in) * scale),
gdImageSX (im_in), gdImageSY (im_in));
/* Write PNG */
out = fopen (filename, "wb");
/* If this image is the result of alpha channel blending,
it will not contain an interesting alpha channel itself.
Save a little file size by not saving the alpha channel.
Otherwise the file would typically be slightly larger. */
gdImageSaveAlpha(im_out, !blending);
/* If this image is the result of alpha channel blending,
it will not contain an interesting alpha channel itself.
Save a little file size by not saving the alpha channel.
Otherwise the file would typically be slightly larger. */
gdImageSaveAlpha (im_out, !blending);
/* If requested, convert from truecolor to palette. */
if (palette) {
/* Dithering, 256 colors. */
gdImageTrueColorToPalette(im_out, 1, 256);
}
/* If requested, convert from truecolor to palette. */
if (palette)
{
/* Dithering, 256 colors. */
gdImageTrueColorToPalette (im_out, 1, 256);
}
gdImagePng(im_out, out);
fclose(out);
gdImagePng (im_out, out);
fclose (out);
gdImageDestroy(im_out);
gdImageDestroy (im_out);
}

View File

@ -1,12 +1,13 @@
/* WBMP
** ----
** WBMP Level 0: B/W, Uncompressed
** This implements the WBMP format as specified in WAPSpec 1.1 and 1.2.
** It does not support ExtHeaders as defined in the spec. The spec states
** that a WAP client does not need to implement ExtHeaders.
**
** (c) 2000 Johan Van den Brande <johan@vandenbrande.com>
*/
** ----
** WBMP Level 0: B/W, Uncompressed
** This implements the WBMP format as specified in WAPSpec 1.1 and 1.2.
** It does not support ExtHeaders as defined in the spec. The spec states
** that a WAP client does not need to implement ExtHeaders.
**
** (c) 2000 Johan Van den Brande <johan@vandenbrande.com>
*/
#include <stdio.h>
@ -20,335 +21,349 @@
#ifdef NOTDEF
#define __TEST /* Compile with main function */
#define __DEBUG /* Extra verbose when with __TEST */
#define __WRITE /* readwbmp and writewbmp(stdout) */
#define __DEBUG /* Extra verbose when with __TEST */
#define __WRITE /* readwbmp and writewbmp(stdout) */
#define __VIEW /* view the wbmp on stdout */
#endif
/* getmbi
** ------
** Get a multibyte integer from a generic getin function
** 'getin' can be getc, with in = NULL
** you can find getin as a function just above the main function
** This way you gain a lot of flexibilty about how this package
** reads a wbmp file.
*/
int getmbi ( int (*getin)(void *in), void *in )
** ------
** Get a multibyte integer from a generic getin function
** 'getin' can be getc, with in = NULL
** you can find getin as a function just above the main function
** This way you gain a lot of flexibilty about how this package
** reads a wbmp file.
*/
int
getmbi (int (*getin) (void *in), void *in)
{
int i, mbi = 0;
int i, mbi = 0;
do
{
i = getin (in);
if ( i<0 ) return (-1);
mbi = mbi << 7 | i & 0x7f;
} while ( i & 0x80 );
do
{
i = getin (in);
if (i < 0)
return (-1);
mbi = mbi << 7 | i & 0x7f;
}
while (i & 0x80);
return ( mbi );
return (mbi);
}
/* putmbi
** ------
** Put a multibyte intgerer in some kind of output stream
** I work here with a function pointer, to make it as generic
** as possible. Look at this function as an iterator on the
** mbi integers it spits out.
**
*/
void putmbi ( int i, void (*putout)(int c, void *out), void *out )
** ------
** Put a multibyte intgerer in some kind of output stream
** I work here with a function pointer, to make it as generic
** as possible. Look at this function as an iterator on the
** mbi integers it spits out.
**
*/
void
putmbi (int i, void (*putout) (int c, void *out), void *out)
{
int cnt, l, accu;
/* Get number of septets */
cnt=0;
accu=0;
while ( accu != i )
accu+= i & 0x7f << 7*cnt++;
/* Produce the multibyte output */
for ( l=cnt-1; l>0; l--)
putout( 0x80 | (i & 0x7f << 7*l ) >> 7*l, out );
putout( i & 0x7f, out );
}
int cnt, l, accu;
/* Get number of septets */
cnt = 0;
accu = 0;
while (accu != i)
accu += i & 0x7f << 7 * cnt++;
/* Produce the multibyte output */
for (l = cnt - 1; l > 0; l--)
putout (0x80 | (i & 0x7f << 7 * l) >> 7 * l, out);
putout (i & 0x7f, out);
}
/* skipheader
** ----------
** Skips the ExtHeader. Not needed for the moment
**
*/
int skipheader( int (*getin)(void *in), void *in )
** ----------
** Skips the ExtHeader. Not needed for the moment
**
*/
int
skipheader (int (*getin) (void *in), void *in)
{
int i;
int i;
do
{
i = getin ( in );
if (i<0)
return (-1);
} while ( i & 0x80 );
do
{
i = getin (in);
if (i < 0)
return (-1);
}
while (i & 0x80);
return ( 0 );
return (0);
}
/* create wbmp
** -----------
** create an empty wbmp
**
*/
Wbmp *createwbmp(int width, int height, int color)
** -----------
** create an empty wbmp
**
*/
Wbmp *
createwbmp (int width, int height, int color)
{
int i;
int i;
Wbmp *wbmp;
if ( (wbmp = (Wbmp *) gdMalloc( sizeof(Wbmp) )) == NULL)
return (NULL);
Wbmp *wbmp;
if ((wbmp = (Wbmp *) gdMalloc (sizeof (Wbmp))) == NULL)
return (NULL);
if ( (wbmp->bitmap = (int *) gdMalloc( sizeof(int)*width*height )) == NULL)
if ((wbmp->bitmap = (int *) gdMalloc (sizeof (int) * width * height)) == NULL)
{
gdFree( wbmp );
return (NULL);
}
gdFree (wbmp);
return (NULL);
}
wbmp->width = width;
wbmp->height= height;
wbmp->width = width;
wbmp->height = height;
for (i=0; i<width*height; wbmp->bitmap[i++] = color);
for (i = 0; i < width * height; wbmp->bitmap[i++] = color);
return(wbmp);
return (wbmp);
}
/* readwbmp
** -------
** Actually reads the WBMP format from an open file descriptor
** It goes along by returning a pointer to a WBMP struct.
**
*/
int readwbmp ( int (*getin)(void *in), void *in, Wbmp **return_wbmp )
** -------
** Actually reads the WBMP format from an open file descriptor
** It goes along by returning a pointer to a WBMP struct.
**
*/
int
readwbmp (int (*getin) (void *in), void *in, Wbmp ** return_wbmp)
{
int row, col, byte, pel, pos;
Wbmp *wbmp;
if ( (wbmp = (Wbmp *) gdMalloc( sizeof(Wbmp) )) == NULL)
return (-1);
int row, col, byte, pel, pos;
Wbmp *wbmp;
wbmp->type = getin( in );
if ( wbmp->type != 0 )
if ((wbmp = (Wbmp *) gdMalloc (sizeof (Wbmp))) == NULL)
return (-1);
wbmp->type = getin (in);
if (wbmp->type != 0)
{
gdFree (wbmp);
return (-1);
}
if (skipheader (getin, in))
return (-1);
wbmp->width = getmbi (getin, in);
if (wbmp->width == -1)
{
gdFree (wbmp);
return (-1);
}
wbmp->height = getmbi (getin, in);
if (wbmp->height == -1)
{
gdFree (wbmp);
return (-1);
}
#ifdef __DEBUG
printf ("W: %d, H: %d\n", wbmp->width, wbmp->height);
#endif
if ((wbmp->bitmap = (int *) gdMalloc (sizeof (int) * wbmp->width * wbmp->height)) == NULL)
{
gdFree (wbmp);
return (-1);
}
#ifdef __DEBUG
printf ("DATA CONSTRUCTED\n");
#endif
pos = 0;
for (row = 0; row < wbmp->height; row++)
{
for (col = 0; col < wbmp->width;)
{
gdFree( wbmp );
return (-1);
}
byte = getin (in);
if ( skipheader( getin, in ) )
return (-1);
wbmp->width = getmbi ( getin, in );
if ( wbmp->width == -1 )
{
gdFree( wbmp );
return (-1);
}
wbmp->height = getmbi ( getin, in );
if ( wbmp->height == -1 )
{
gdFree( wbmp );
return (-1);
}
#ifdef __DEBUG
printf("W: %d, H: %d\n", wbmp->width, wbmp->height);
#endif
if ( (wbmp->bitmap = (int *) gdMalloc( sizeof(int)*wbmp->width*wbmp->height )) == NULL)
{
gdFree( wbmp );
return (-1);
}
#ifdef __DEBUG
printf("DATA CONSTRUCTED\n");
#endif
pos = 0;
for ( row=0; row<wbmp->height; row++)
{
for ( col=0; col<wbmp->width; )
for (pel = 7; pel >= 0; pel--)
{
if (col++ < wbmp->width)
{
byte = getin( in );
for ( pel=7; pel>=0; pel--)
{
if ( col++ < wbmp->width )
{
if ( byte & 1<<pel )
{
wbmp->bitmap[pos] = WBMP_WHITE;
}
else
{
wbmp->bitmap[pos] = WBMP_BLACK;
}
pos++;
}
}
if (byte & 1 << pel)
{
wbmp->bitmap[pos] = WBMP_WHITE;
}
else
{
wbmp->bitmap[pos] = WBMP_BLACK;
}
pos++;
}
}
}
*return_wbmp = wbmp;
}
return (0);
}
*return_wbmp = wbmp;
return (0);
}
/* writewbmp
** ---------
** Write a wbmp to a file descriptor
**
** Why not just giving a filedescriptor to this function?
** Well, the incentive to write this function was the complete
** integration in gd library from www.boutell.com. They use
** their own io functions, so the passing of a function seemed to be
** a logic(?) decision ...
**
*/
int writewbmp( Wbmp *wbmp, void (*putout)(int c, void *out), void *out )
** ---------
** Write a wbmp to a file descriptor
**
** Why not just giving a filedescriptor to this function?
** Well, the incentive to write this function was the complete
** integration in gd library from www.boutell.com. They use
** their own io functions, so the passing of a function seemed to be
** a logic(?) decision ...
**
*/
int
writewbmp (Wbmp * wbmp, void (*putout) (int c, void *out), void *out)
{
int row, col;
int bitpos, octet;
int row, col;
int bitpos, octet;
/* Generate the header */
putout(0, out); /* WBMP Type 0: B/W, Uncompressed bitmap */
putout(0, out); /* FixHeaderField */
/* Generate the header */
putout (0, out); /* WBMP Type 0: B/W, Uncompressed bitmap */
putout (0, out); /* FixHeaderField */
/* Size of the image */
putmbi(wbmp->width, putout, out); /* width */
putmbi(wbmp->height, putout, out); /* height*/
/* Size of the image */
putmbi (wbmp->width, putout, out); /* width */
putmbi (wbmp->height, putout, out); /* height */
/* Image data */
for (row=0; row<wbmp->height; row++)
/* Image data */
for (row = 0; row < wbmp->height; row++)
{
bitpos=8;
octet=0;
for (col=0; col<wbmp->width; col++)
{
octet|= ((wbmp->bitmap[ row*wbmp->width + col] == 1)?WBMP_WHITE:WBMP_BLACK) << --bitpos;
if (bitpos == 0)
{
bitpos=8;
putout(octet, out);
octet=0;
}
}
if (bitpos != 8)
putout(octet, out);
}
return (0);
bitpos = 8;
octet = 0;
for (col = 0; col < wbmp->width; col++)
{
octet |= ((wbmp->bitmap[row * wbmp->width + col] == 1) ? WBMP_WHITE : WBMP_BLACK) << --bitpos;
if (bitpos == 0)
{
bitpos = 8;
putout (octet, out);
octet = 0;
}
}
if (bitpos != 8)
putout (octet, out);
}
return (0);
}
/* freewbmp
** --------
** gdFrees up memory occupied by a WBMP structure
**
*/
void freewbmp( Wbmp *wbmp )
** --------
** gdFrees up memory occupied by a WBMP structure
**
*/
void
freewbmp (Wbmp * wbmp)
{
gdFree( wbmp->bitmap );
gdFree( wbmp );
gdFree (wbmp->bitmap);
gdFree (wbmp);
}
/* printwbmp
** ---------
** print a WBMP to stdout for visualisation
**
*/
void printwbmp( Wbmp *wbmp )
** ---------
** print a WBMP to stdout for visualisation
**
*/
void
printwbmp (Wbmp * wbmp)
{
int row, col;
for( row=0; row<wbmp->height; row++)
int row, col;
for (row = 0; row < wbmp->height; row++)
{
for (col = 0; col < wbmp->width; col++)
{
for ( col=0; col<wbmp->width; col++)
{
if ( wbmp->bitmap[wbmp->width * row + col] == WBMP_BLACK )
{
putchar('#');
}
else
{
putchar(' ');
}
}
putchar('\n');
}
if (wbmp->bitmap[wbmp->width * row + col] == WBMP_BLACK)
{
putchar ('#');
}
else
{
putchar (' ');
}
}
putchar ('\n');
}
}
#ifdef __TEST
/* putout to file descriptor
** -------------------------
*/
int putout(int c, void *out)
** -------------------------
*/
int
putout (int c, void *out)
{
return(putc(c, (FILE *) out));
return (putc (c, (FILE *) out));
}
/* getin from file descriptor
** --------------------------
*/
int getin( void *in )
** --------------------------
*/
int
getin (void *in)
{
return( getc( (FILE *) in ) );
return (getc ((FILE *) in));
}
/* Main function
** -------------
**
*/
int main ( int argc, char *argv[] )
** -------------
**
*/
int
main (int argc, char *argv[])
{
FILE *wbmp_file;
Wbmp *wbmp;
FILE *wbmp_file;
Wbmp *wbmp;
wbmp_file = fopen(argv[1], "rb");
if ( wbmp_file )
{
readwbmp( &getin, wbmp_file, &wbmp );
wbmp_file = fopen (argv[1], "rb");
if (wbmp_file)
{
readwbmp (&getin, wbmp_file, &wbmp);
#ifdef __VIEW
#ifdef __VIEW
#ifdef __DEBUG
printf("\nVIEWING IMAGE\n");
#endif
printwbmp( wbmp );
#endif
#ifdef __DEBUG
printf ("\nVIEWING IMAGE\n");
#endif
#ifdef __WRITE
printwbmp (wbmp);
#endif
#ifdef __DEBUG
printf("\nDUMPING WBMP to STDOUT\n");
#endif
writewbmp( wbmp, &putout, stdout );
#endif
#ifdef __WRITE
freewbmp( wbmp );
fclose ( wbmp_file );
}
#ifdef __DEBUG
printf ("\nDUMPING WBMP to STDOUT\n");
#endif
writewbmp (wbmp, &putout, stdout);
#endif
freewbmp (wbmp);
fclose (wbmp_file);
}
}
#endif
#endif

View File

@ -3,203 +3,252 @@
/* Bring in standard I/O and string manipulation functions */
#include <stdio.h>
#include <stdlib.h> /* for atoi() */
#include <stdlib.h> /* for atoi() */
#include <string.h>
#ifdef _WIN32
#include <process.h>
int getpid() {
return _getpid();
}
#else
#include <unistd.h> /* for getpid(), unlink() */
#endif
int main(int argc, char **argv)
int
getpid ()
{
FILE *in;
FILE *out;
char outFn[20];
int useStdinStdout=0;
/* Declare our image pointer */
gdImagePtr im = 0;
int i;
/* We'll clear 'no' once we know the user has made a
reasonable request. */
int no = 1;
/* We'll set 'write' once we know the user's request
requires that the image be written back to disk. */
int write = 0;
/* C programs always get at least one argument; we want at
least one more (the image), more in practice. */
if (argc < 2 || !strcmp(argv[1], "--help")) {
no = 1;
goto usage;
}
/* The last argument should be the image. Open the file. */
if (strcmp("-", argv[argc-1])==0) { /* - is synonymous with STDIN */
useStdinStdout = 1;
in = stdin;
} else {
in = fopen(argv[argc-1], "rb");
}
if (!in) {
fprintf(stderr,
"Error: can't open file %s.\n", argv[argc-1]);
exit(1);
}
/* Now load the image. */
im = gdImageCreateFromPng(in);
fclose(in);
/* If the load failed, it must not be a PNG file. */
if (!im) {
fprintf(stderr,
"Error: %s is not a valid PNG file.\n", argv[argc-1]);
exit(1);
}
/* Consider each argument in turn. */
for (i=1; (i < (argc-1)); i++) {
/* -i turns on and off interlacing. */
if (!strcmp(argv[i], "--help")) {
/* Every program should use this for help! :) */
no = 1;
goto usage;
} else if (!strcmp(argv[i], "-i")) {
if (i == (argc-2)) {
fprintf(stderr,
"Error: -i specified without y or n.\n");
no = 1;
goto usage;
}
if (!strcmp(argv[i+1], "y")) {
/* Set interlace. */
gdImageInterlace(im, 1);
} else if (!strcmp(argv[i+1], "n")) {
/* Clear interlace. */
gdImageInterlace(im, 0);
} else {
fprintf(stderr,
"Error: -i specified without y or n.\n");
no = 1;
goto usage;
}
i++;
no = 0;
write = 1;
} else if (!strcmp(argv[i], "-t")) {
/* Set transparent index (or none). */
int index;
if (i == (argc-2)) {
fprintf(stderr,
"Error: -t specified without a color table index.\n");
no = 1;
goto usage;
}
if (!strcmp(argv[i+1], "none")) {
/* -1 means not transparent. */
gdImageColorTransparent(im, -1);
} else {
/* OK, get an integer and set the index. */
index = atoi(argv[i+1]);
gdImageColorTransparent(im, index);
}
i++;
write = 1;
no = 0;
} else if (!strcmp(argv[i], "-l")) {
/* List the colors in the color table. */
int j;
if (!im->trueColor) {
/* Tabs used below. */
printf("Index Red Green Blue Alpha\n");
for (j=0; (j < gdImageColorsTotal(im)); j++) {
/* Use access macros to learn colors. */
printf("%d %d %d %d %d\n",
j,
gdImageRed(im, j),
gdImageGreen(im, j),
gdImageBlue(im, j),
gdImageAlpha(im, j));
}
} else {
printf("Truecolor image, no palette entries to list.\n");
}
no = 0;
} else if (!strcmp(argv[i], "-d")) {
/* Output dimensions, etc. */
int t;
printf("Width: %d Height: %d Colors: %d\n",
gdImageSX(im), gdImageSY(im),
gdImageColorsTotal(im));
t = gdImageGetTransparent(im);
if (t != (-1)) {
printf("First 100% transparent index: %d\n", t);
} else {
/* -1 means the image is not transparent. */
printf("First 100% transparent index: none\n");
}
if (gdImageGetInterlaced(im)) {
printf("Interlaced: yes\n");
} else {
printf("Interlaced: no\n");
}
no = 0;
} else {
fprintf(stderr, "Unknown argument: %s\n", argv[i]);
break;
}
}
usage:
if (no) {
/* If the command failed, output an explanation. */
fprintf(stderr,
"Usage: webpng [-i y|n ] [-l] [-t index|none ] [-d] pngname.png\n"
" -i [y|n] Turns on/off interlace\n"
" -l Prints the table of color indexes\n"
" -t [index] Set the transparent color to the specified index (0-255 or \"none\")\n"
" -d Reports the dimensions and other characteristics of the image.\n"
"\n"
"If you specify '-' as the input file, stdin/stdout will be used input/output.\n"
);
}
if (write) {
if (useStdinStdout) {
out = stdout;
} else {
/* Open a temporary file. */
/* "temp.tmp" is not good temporary filename. */
sprintf(outFn, "webpng.tmp%d", getpid());
out = fopen(outFn, "wb");
if (!out) {
fprintf(stderr,
"Unable to write to %s -- exiting\n", outFn);
exit(1);
}
}
/* Write the new PNG. */
gdImagePng(im, out);
if (!useStdinStdout) {
fclose(out);
/* Erase the old PNG. */
unlink(argv[argc-1]);
/* Rename the new to the old. */
if (rename(outFn, argv[argc-1])!=0) {
perror("rename");
exit(1);
}
}
}
/* Delete the image from memory. */
if (im) {
gdImageDestroy(im);
}
/* All's well that ends well. */
return 0;
return _getpid ();
}
#else
#include <unistd.h> /* for getpid(), unlink() */
#endif
int
main (int argc, char **argv)
{
FILE *in;
FILE *out;
char outFn[20];
int useStdinStdout = 0;
/* Declare our image pointer */
gdImagePtr im = 0;
int i;
/* We'll clear 'no' once we know the user has made a
reasonable request. */
int no = 1;
/* We'll set 'write' once we know the user's request
requires that the image be written back to disk. */
int write = 0;
/* C programs always get at least one argument; we want at
least one more (the image), more in practice. */
if (argc < 2 || !strcmp (argv[1], "--help"))
{
no = 1;
goto usage;
}
/* The last argument should be the image. Open the file. */
if (strcmp ("-", argv[argc - 1]) == 0)
{ /* - is synonymous with STDIN */
useStdinStdout = 1;
in = stdin;
}
else
{
in = fopen (argv[argc - 1], "rb");
}
if (!in)
{
fprintf (stderr,
"Error: can't open file %s.\n", argv[argc - 1]);
exit (1);
}
/* Now load the image. */
im = gdImageCreateFromPng (in);
fclose (in);
/* If the load failed, it must not be a PNG file. */
if (!im)
{
fprintf (stderr,
"Error: %s is not a valid PNG file.\n", argv[argc - 1]);
exit (1);
}
/* Consider each argument in turn. */
for (i = 1; (i < (argc - 1)); i++)
{
/* -i turns on and off interlacing. */
if (!strcmp (argv[i], "--help"))
{
/* Every program should use this for help! :) */
no = 1;
goto usage;
}
else if (!strcmp (argv[i], "-i"))
{
if (i == (argc - 2))
{
fprintf (stderr,
"Error: -i specified without y or n.\n");
no = 1;
goto usage;
}
if (!strcmp (argv[i + 1], "y"))
{
/* Set interlace. */
gdImageInterlace (im, 1);
}
else if (!strcmp (argv[i + 1], "n"))
{
/* Clear interlace. */
gdImageInterlace (im, 0);
}
else
{
fprintf (stderr,
"Error: -i specified without y or n.\n");
no = 1;
goto usage;
}
i++;
no = 0;
write = 1;
}
else if (!strcmp (argv[i], "-t"))
{
/* Set transparent index (or none). */
int index;
if (i == (argc - 2))
{
fprintf (stderr,
"Error: -t specified without a color table index.\n");
no = 1;
goto usage;
}
if (!strcmp (argv[i + 1], "none"))
{
/* -1 means not transparent. */
gdImageColorTransparent (im, -1);
}
else
{
/* OK, get an integer and set the index. */
index = atoi (argv[i + 1]);
gdImageColorTransparent (im, index);
}
i++;
write = 1;
no = 0;
}
else if (!strcmp (argv[i], "-l"))
{
/* List the colors in the color table. */
int j;
if (!im->trueColor)
{
/* Tabs used below. */
printf ("Index Red Green Blue Alpha\n");
for (j = 0; (j < gdImageColorsTotal (im)); j++)
{
/* Use access macros to learn colors. */
printf ("%d %d %d %d %d\n",
j,
gdImageRed (im, j),
gdImageGreen (im, j),
gdImageBlue (im, j),
gdImageAlpha (im, j));
}
}
else
{
printf ("Truecolor image, no palette entries to list.\n");
}
no = 0;
}
else if (!strcmp (argv[i], "-d"))
{
/* Output dimensions, etc. */
int t;
printf ("Width: %d Height: %d Colors: %d\n",
gdImageSX (im), gdImageSY (im),
gdImageColorsTotal (im));
t = gdImageGetTransparent (im);
if (t != (-1))
{
printf ("First 100% transparent index: %d\n", t);
}
else
{
/* -1 means the image is not transparent. */
printf ("First 100% transparent index: none\n");
}
if (gdImageGetInterlaced (im))
{
printf ("Interlaced: yes\n");
}
else
{
printf ("Interlaced: no\n");
}
no = 0;
}
else
{
fprintf (stderr, "Unknown argument: %s\n", argv[i]);
break;
}
}
usage:
if (no)
{
/* If the command failed, output an explanation. */
fprintf (stderr,
"Usage: webpng [-i y|n ] [-l] [-t index|none ] [-d] pngname.png\n"
" -i [y|n] Turns on/off interlace\n"
" -l Prints the table of color indexes\n"
" -t [index] Set the transparent color to the specified index (0-255 or \"none\")\n"
" -d Reports the dimensions and other characteristics of the image.\n"
"\n"
"If you specify '-' as the input file, stdin/stdout will be used input/output.\n"
);
}
if (write)
{
if (useStdinStdout)
{
out = stdout;
}
else
{
/* Open a temporary file. */
/* "temp.tmp" is not good temporary filename. */
sprintf (outFn, "webpng.tmp%d", getpid ());
out = fopen (outFn, "wb");
if (!out)
{
fprintf (stderr,
"Unable to write to %s -- exiting\n", outFn);
exit (1);
}
}
/* Write the new PNG. */
gdImagePng (im, out);
if (!useStdinStdout)
{
fclose (out);
/* Erase the old PNG. */
unlink (argv[argc - 1]);
/* Rename the new to the old. */
if (rename (outFn, argv[argc - 1]) != 0)
{
perror ("rename");
exit (1);
}
}
}
/* Delete the image from memory. */
if (im)
{
gdImageDestroy (im);
}
/* All's well that ends well. */
return 0;
}