- sync to 2.0.1
parent
ff50323cfa
commit
1cdea7482e
22
src/gd.h
22
src/gd.h
|
@ -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);
|
||||
|
|
103
src/gd2copypal.c
103
src/gd2copypal.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
376
src/gd_gd.c
376
src/gd_gd.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
1403
src/gd_gd2.c
1403
src/gd_gd2.c
File diff suppressed because it is too large
Load Diff
202
src/gd_io.c
202
src/gd_io.c
|
@ -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"));
|
||||
}
|
||||
|
||||
|
|
436
src/gd_io_dp.c
436
src/gd_io_dp.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
135
src/gd_io_file.c
135
src/gd_io_file.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
175
src/gd_io_ss.c
175
src/gd_io_ss.c
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
807
src/gd_jpeg.c
807
src/gd_jpeg.c
File diff suppressed because it is too large
Load Diff
1139
src/gd_png.c
1139
src/gd_png.c
File diff suppressed because it is too large
Load Diff
28
src/gd_ss.c
28
src/gd_ss.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
1766
src/gd_topal.c
1766
src/gd_topal.c
File diff suppressed because it is too large
Load Diff
306
src/gd_wbmp.c
306
src/gd_wbmp.c
|
@ -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;
|
||||
}
|
||||
|
|
205
src/gdcache.c
205
src/gdcache.c
|
@ -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 */
|
||||
|
|
203
src/gddemo.c
203
src/gddemo.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
7712
src/gdfontg.c
7712
src/gdfontg.c
File diff suppressed because it is too large
Load Diff
8224
src/gdfontl.c
8224
src/gdfontl.c
File diff suppressed because it is too large
Load Diff
6686
src/gdfontmb.c
6686
src/gdfontmb.c
File diff suppressed because it is too large
Load Diff
6686
src/gdfonts.c
6686
src/gdfonts.c
File diff suppressed because it is too large
Load Diff
4128
src/gdfontt.c
4128
src/gdfontt.c
File diff suppressed because it is too large
Load Diff
1312
src/gdft.c
1312
src/gdft.c
File diff suppressed because it is too large
Load Diff
124
src/gdhelpers.c
124
src/gdhelpers.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
825
src/gdkanji.c
825
src/gdkanji.c
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
617
src/gdtest.c
617
src/gdtest.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
119
src/gdtestft.c
119
src/gdtestft.c
|
@ -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 */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
247
src/gdxpm.c
247
src/gdxpm.c
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
325
src/readme.txt
325
src/readme.txt
|
@ -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 |
|
||||
|
|
211
src/testac.c
211
src/testac.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
521
src/wbmp.c
521
src/wbmp.c
|
@ -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
|
||||
|
|
435
src/webpng.c
435
src/webpng.c
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue