- sync to 1.8.0
parent
bdbb50ad58
commit
0c29f6af63
20
src/Makefile
20
src/Makefile
|
@ -13,23 +13,23 @@ AR=ar
|
|||
#an explicit path for it here, or install manually.
|
||||
INSTALL=install
|
||||
|
||||
#If you don't have FreeType and/or Xpm installed, including the
|
||||
#If you don't have FreeType, libjpeg and/or Xpm installed, including the
|
||||
#header files, uncomment this (default).
|
||||
CFLAGS=-O
|
||||
#If you do have FreeType and/or Xpm fully installed, uncomment a
|
||||
#CFLAGS=-O
|
||||
#If you do have FreeType, libjpeg and/or Xpm fully installed, uncomment a
|
||||
#variation of this and comment out the line above. See also LIBS below.
|
||||
#CFLAGS=-O -DHAVE_XPM -DHAVE_LIBTTF
|
||||
CFLAGS=-O -DHAVE_XPM -DHAVE_JPEG -DHAVE_LIBTTF
|
||||
|
||||
#If you don't have FreeType and/or Xpm fully installed, uncomment this
|
||||
#(default).
|
||||
LIBS=-lm -lgd -lpng -lz
|
||||
#LIBS=-lm -lgd -lpng -lz
|
||||
|
||||
#If you do have FreeType and/or Xpm fully installed, uncomment a
|
||||
#If you do have FreeType, JPEG and/or Xpm fully installed, uncomment a
|
||||
#variation of this and comment out the line above. Note that
|
||||
#Xpm requires X11. See also CFLAGS above.
|
||||
#LIBS=-lm -lgd -lpng -lz -lttf -lXpm -lX11
|
||||
LIBS=-lm -lgd -lpng -lz -ljpeg -lttf -lXpm -lX11
|
||||
|
||||
#Typical install locations for freetype, zlib, xpm and libpng header files.
|
||||
#Typical install locations for freetype, zlib, xpm, libjpeg and libpng header files.
|
||||
#If yours are somewhere else, change this.
|
||||
INCLUDEDIRS=-I/usr/local/include -I/usr/include/X11 -I/usr/X11R6/include/X11
|
||||
|
||||
|
@ -121,12 +121,12 @@ gdtestttf: gdtestttf.o libgd.a
|
|||
$(CC) gdtestttf.o -o gdtestttf $(LIBDIRS) $(LIBS)
|
||||
|
||||
libgd.a: gd.o gd_gd.o gd_gd2.o gd_io.o gd_io_dp.o gd_io_file.o gd_ss.o \
|
||||
gd_io_ss.o gd_png.o gdxpm.o gdfontt.o gdfonts.o gdfontmb.o gdfontl.o \
|
||||
gd_io_ss.o gd_png.o gd_jpeg.o gdxpm.o gdfontt.o gdfonts.o gdfontmb.o gdfontl.o \
|
||||
gdfontg.o gdtables.o gdttf.o gdcache.o gdkanji.o \
|
||||
gd.h gdfontt.h gdfonts.h gdfontmb.h gdfontl.h gdfontg.h
|
||||
rm -f libgd.a
|
||||
$(AR) rc libgd.a gd.o gd_gd.o gd_gd2.o gd_io.o gd_io_dp.o \
|
||||
gd_io_file.o gd_ss.o gd_io_ss.o gd_png.o gdxpm.o \
|
||||
gd_io_file.o gd_ss.o gd_io_ss.o gd_png.o gd_jpeg.o gdxpm.o \
|
||||
gdfontt.o gdfonts.o gdfontmb.o gdfontl.o gdfontg.o \
|
||||
gdtables.o gdttf.o gdcache.o gdkanji.o
|
||||
-ranlib libgd.a
|
||||
|
|
133
src/gd.c
133
src/gd.c
|
@ -85,6 +85,137 @@ int gdImageColorClosest(gdImagePtr im, int r, int g, int b)
|
|||
return ct;
|
||||
}
|
||||
|
||||
/* This code is taken from http://www.acm.org/jgt/papers/SmithLyons96/hwb_rgb.html, an article
|
||||
* on colour conversion to/from RBG and HWB colour systems.
|
||||
* It has been modified to return the converted value as a * parameter.
|
||||
*/
|
||||
|
||||
#define RETURN_HWB(h, w, b) {HWB->H = h; HWB->W = w; HWB->B = b; return HWB;}
|
||||
#define RETURN_RGB(r, g, b) {RGB->R = r; RGB->G = g; RGB->B = b; return RGB;}
|
||||
#define HWB_UNDEFINED -1
|
||||
#define SETUP_RGB(s, r, g, b) {s.R = r/255.0; s.G = g/255.0; s.B = b/255.0;}
|
||||
|
||||
#define MIN(a,b) ((a)<(b)?(a):(b))
|
||||
#define MIN3(a,b,c) ((a)<(b)?(MIN(a,c)):(MIN(b,c)))
|
||||
#define MAX(a,b) ((a)<(b)?(b):(a))
|
||||
#define MAX3(a,b,c) ((a)<(b)?(MAX(b,c)):(MAX(a,c)))
|
||||
|
||||
|
||||
/*
|
||||
* Theoretically, hue 0 (pure red) is identical to hue 6 in these transforms. Pure
|
||||
* red always maps to 6 in this implementation. Therefore UNDEFINED can be
|
||||
* defined as 0 in situations where only unsigned numbers are desired.
|
||||
*/
|
||||
typedef struct {float R, G, B;} RGBType;
|
||||
typedef struct {float H, W, B;} HWBType;
|
||||
|
||||
static HWBType* RGB_to_HWB( RGBType RGB, HWBType* HWB) {
|
||||
|
||||
/*
|
||||
* RGB are each on [0, 1]. W and B are returned on [0, 1] and H is
|
||||
* returned on [0, 6]. Exception: H is returned UNDEFINED if W == 1 - B.
|
||||
*/
|
||||
|
||||
float R = RGB.R, G = RGB.G, B = RGB.B, w, v, b, f;
|
||||
int i;
|
||||
|
||||
w = MIN3(R, G, B);
|
||||
v = MAX3(R, G, B);
|
||||
b = 1 - v;
|
||||
if (v == w) RETURN_HWB(HWB_UNDEFINED, w, b);
|
||||
f = (R == w) ? G - B : ((G == w) ? B - R : R - G);
|
||||
i = (R == w) ? 3 : ((G == w) ? 5 : 1);
|
||||
RETURN_HWB(i - f /(v - w), w, b);
|
||||
|
||||
}
|
||||
|
||||
static float HWB_Diff(int r1, int g1, int b1, int r2, int g2, int b2) {
|
||||
RGBType RGB1, RGB2;
|
||||
HWBType HWB1, HWB2;
|
||||
float diff;
|
||||
|
||||
SETUP_RGB(RGB1, r1, g1, b1);
|
||||
SETUP_RGB(RGB2, r2, g2, b2);
|
||||
|
||||
RGB_to_HWB(RGB1, &HWB1);
|
||||
RGB_to_HWB(RGB2, &HWB2);
|
||||
|
||||
/*
|
||||
* I made this bit up; it seems to produce OK results, and it is certainly
|
||||
* more visually correct than the current RGB metric. (PJW)
|
||||
*/
|
||||
|
||||
if ( (HWB1.H == HWB_UNDEFINED) || (HWB2.H == HWB_UNDEFINED) ) {
|
||||
diff = 0; /* Undefined hues always match... */
|
||||
} else {
|
||||
diff = abs(HWB1.H - HWB2.H);
|
||||
if (diff > 3) {
|
||||
diff = 6 - diff; /* Remember, it's a colour circle */
|
||||
}
|
||||
}
|
||||
|
||||
diff = diff*diff + (HWB1.W - HWB2.W)*(HWB1.W - HWB2.W) + (HWB1.B - HWB2.B)*(HWB1.B - HWB2.B);
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This is not actually used, but is here for completeness, in case someone wants to
|
||||
* use the HWB stuff for anything else...
|
||||
*/
|
||||
static RGBType* HWB_to_RGB( HWBType HWB, RGBType* RGB ) {
|
||||
|
||||
/*
|
||||
* H is given on [0, 6] or UNDEFINED. W and B are given on [0, 1].
|
||||
* RGB are each returned on [0, 1].
|
||||
*/
|
||||
|
||||
float h = HWB.H, w = HWB.W, b = HWB.B, v, n, f;
|
||||
int i;
|
||||
|
||||
v = 1 - b;
|
||||
if (h == HWB_UNDEFINED) RETURN_RGB(v, v, v);
|
||||
i = floor(h);
|
||||
f = h - i;
|
||||
if (i & 1) f = 1 - f; /* if i is odd */
|
||||
n = w + f * (v - w); /* linear interpolation between w and v */
|
||||
switch (i) {
|
||||
case 6:
|
||||
case 0: RETURN_RGB(v, n, w);
|
||||
case 1: RETURN_RGB(n, v, w);
|
||||
case 2: RETURN_RGB(w, v, n);
|
||||
case 3: RETURN_RGB(w, n, v);
|
||||
case 4: RETURN_RGB(n, w, v);
|
||||
case 5: RETURN_RGB(v, w, n);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int gdImageColorClosestHWB(gdImagePtr im, int r, int g, int b)
|
||||
{
|
||||
int i;
|
||||
long rd, gd, bd;
|
||||
int ct = (-1);
|
||||
int first = 1;
|
||||
float mindist = 0;
|
||||
for (i=0; (i<(im->colorsTotal)); i++) {
|
||||
float dist;
|
||||
if (im->open[i]) {
|
||||
continue;
|
||||
}
|
||||
dist = HWB_Diff(im->red[i], im->green[i], im->blue[i], r, g, b);
|
||||
if (first || (dist < mindist)) {
|
||||
mindist = dist;
|
||||
ct = i;
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
return ct;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int gdImageColorExact(gdImagePtr im, int r, int g, int b)
|
||||
{
|
||||
int i;
|
||||
|
@ -200,7 +331,7 @@ void gdImagePaletteCopy(gdImagePtr to, gdImagePtr from)
|
|||
for (y=0 ; y < (to->sy) ; y++) {
|
||||
p = gdImageGetPixel(to, x, y);
|
||||
if (xlate[p] == -1) {
|
||||
xlate[p] = gdImageColorClosest(from, to->red[p], to->green[p], to->blue[p]);
|
||||
xlate[p] = gdImageColorClosestHWB(from, to->red[p], to->green[p], to->blue[p]);
|
||||
/*printf("Mapping %d (%d, %d, %d) to %d (%d, %d, %d)\n", */
|
||||
/* p, to->red[p], to->green[p], to->blue[p], */
|
||||
/* xlate[p], from->red[xlate[p]], from->green[xlate[p]], from->blue[xlate[p]]); */
|
||||
|
|
11
src/gd.h
11
src/gd.h
|
@ -156,8 +156,17 @@ void gdImageColorTransparent(gdImagePtr im, int color);
|
|||
void gdImagePaletteCopy(gdImagePtr dst, gdImagePtr src);
|
||||
void gdImagePng(gdImagePtr im, FILE *out);
|
||||
void gdImagePngCtx(gdImagePtr im, gdIOCtx *out);
|
||||
void gdImageWBMP(gdImagePtr image, int fg, FILE *out);
|
||||
void gdImageWBMPCtx(gdImagePtr image, int fg, gdIOCtx *out);
|
||||
|
||||
/* A custom data sink. */
|
||||
void gdImageJpeg(gdImagePtr im, FILE *out, int quality);
|
||||
void gdImageJpegCtx(gdImagePtr im, gdIOCtx *out, int quality);
|
||||
void *gdImageJpegPtr(gdImagePtr im, int *size, int quality);
|
||||
gdImagePtr gdImageCreateFromJpeg(FILE *infile);
|
||||
gdImagePtr gdImageCreateFromJpegCtx(gdIOCtx *infile);
|
||||
|
||||
/* A custom data sink. For backwards compatibility. Use
|
||||
gdIOCtx instead. */
|
||||
/* The sink function must return -1 on error, otherwise the number
|
||||
of bytes written, which must be equal to len. */
|
||||
/* context will be passed to your sink function. */
|
||||
|
|
|
@ -0,0 +1,757 @@
|
|||
/*
|
||||
* gd_jpeg.c: Read and write JPEG (JFIF) format image files using the
|
||||
* gd graphics library (http://www.boutell.com/gd/).
|
||||
*
|
||||
* This software is based in part on the work of the Independent JPEG
|
||||
* Group. For more information on the IJG JPEG software (and JPEG
|
||||
* documentation, etc.), see ftp://ftp.uu.net/graphics/jpeg/.
|
||||
*
|
||||
* NOTE: IJG 12-bit JSAMPLE (BITS_IN_JSAMPLE == 12) mode, although
|
||||
* theoretically supported in this code, has not really been tested.
|
||||
* Caveat emptor.
|
||||
*
|
||||
* Copyright 2000 Doug Becker, mailto:thebeckers@home.com
|
||||
*/
|
||||
|
||||
#ifdef HAVE_JPEG
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <setjmp.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include "jinclude.h"
|
||||
#include "jpeglib.h"
|
||||
#include "jerror.h"
|
||||
#include "gd.h"
|
||||
|
||||
static const char * const GD_JPEG_VERSION = "1.0";
|
||||
|
||||
typedef struct _jmpbuf_wrapper {
|
||||
jmp_buf jmpbuf;
|
||||
} jmpbuf_wrapper;
|
||||
|
||||
/* Called by the IJG JPEG library upon encountering a fatal error */
|
||||
static void
|
||||
fatal_jpeg_error(j_common_ptr cinfo)
|
||||
{
|
||||
jmpbuf_wrapper *jmpbufw;
|
||||
|
||||
fprintf(stderr, "gd-jpeg: JPEG library reports unrecoverable error: ");
|
||||
(*cinfo->err->output_message)(cinfo);
|
||||
fflush(stderr);
|
||||
|
||||
jmpbufw = (jmpbuf_wrapper *)cinfo->client_data;
|
||||
jpeg_destroy(cinfo);
|
||||
|
||||
if (jmpbufw != 0) {
|
||||
longjmp(jmpbufw->jmpbuf, 1);
|
||||
fprintf(stderr, "gd-jpeg: EXTREMELY fatal error: longjmp"
|
||||
" returned control; terminating\n");
|
||||
} else {
|
||||
fprintf(stderr, "gd-jpeg: EXTREMELY fatal error: jmpbuf"
|
||||
" unrecoverable; terminating\n");
|
||||
}
|
||||
|
||||
fflush(stderr);
|
||||
exit(99);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write IM to OUTFILE as a JFIF-formatted JPEG image, using quality
|
||||
* QUALITY. If QUALITY is in the range 0-100, increasing values
|
||||
* represent higher quality but also larger image size. If QUALITY is
|
||||
* negative, the IJG JPEG library's default quality is used (which
|
||||
* should be near optimal for many applications). See the IJG JPEG
|
||||
* library documentation for more details. */
|
||||
|
||||
void gdImageJpeg(gdImagePtr im, FILE *outFile, int quality)
|
||||
{
|
||||
gdIOCtx *out = gdNewFileCtx(outFile);
|
||||
gdImageJpegCtx(im, out, quality);
|
||||
out->free(out);
|
||||
}
|
||||
|
||||
void* gdImageJpegPtr(gdImagePtr im, int *size, int quality)
|
||||
{
|
||||
void *rv;
|
||||
gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
|
||||
gdImageJpegCtx(im, out, quality);
|
||||
rv = gdDPExtractData(out, size);
|
||||
out->free(out);
|
||||
return rv;
|
||||
}
|
||||
|
||||
void jpeg_gdIOCtx_dest (j_compress_ptr cinfo, gdIOCtx * outfile);
|
||||
|
||||
void
|
||||
gdImageJpegCtx(gdImagePtr im, gdIOCtx *outfile, int quality)
|
||||
{
|
||||
struct jpeg_compress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
int i, j, jidx;
|
||||
/* volatile so we can free it on return from longjmp */
|
||||
volatile JSAMPROW row = 0;
|
||||
JSAMPROW rowptr[1];
|
||||
jmpbuf_wrapper jmpbufw;
|
||||
JDIMENSION nlines;
|
||||
char comment[255];
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION);
|
||||
printf("gd-jpeg: JPEG library version %d, %d-bit sample values\n",
|
||||
JPEG_LIB_VERSION, BITS_IN_JSAMPLE);
|
||||
|
||||
for (i = 0; i < im->colorsTotal; i++) {
|
||||
if (!im->open[i])
|
||||
printf("gd-jpeg: gd colormap index %d: (%d, %d, %d)\n", i,
|
||||
im->red[i], im->green[i], im->blue[i]);
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
memset(&cinfo, 0, sizeof(cinfo));
|
||||
memset(&jerr, 0, sizeof(jerr));
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
cinfo.client_data = &jmpbufw;
|
||||
if (setjmp(jmpbufw.jmpbuf) != 0) {
|
||||
/* we're here courtesy of longjmp */
|
||||
if (row)
|
||||
free(row);
|
||||
return;
|
||||
}
|
||||
|
||||
cinfo.err->error_exit = fatal_jpeg_error;
|
||||
|
||||
jpeg_create_compress(&cinfo);
|
||||
|
||||
cinfo.image_width = im->sx;
|
||||
cinfo.image_height = im->sy;
|
||||
cinfo.input_components = 3; /* # of color components per pixel */
|
||||
cinfo.in_color_space = JCS_RGB; /* colorspace of input image */
|
||||
jpeg_set_defaults(&cinfo);
|
||||
if (quality >= 0)
|
||||
jpeg_set_quality(&cinfo, quality, TRUE);
|
||||
|
||||
/* If user requests interlace, translate that to progressive JPEG */
|
||||
if (gdImageGetInterlaced(im)) {
|
||||
#ifdef DEBUG
|
||||
printf("gd-jpeg: interlace set, outputting progressive"
|
||||
" JPEG image\n");
|
||||
#endif
|
||||
jpeg_simple_progression(&cinfo);
|
||||
}
|
||||
|
||||
jpeg_gdIOCtx_dest(&cinfo, outfile);
|
||||
|
||||
row = (JSAMPROW)calloc(1, cinfo.image_width * cinfo.input_components
|
||||
* sizeof(JSAMPLE));
|
||||
if (row == 0) {
|
||||
fprintf(stderr, "gd-jpeg: error: unable to allocate JPEG row "
|
||||
"structure: calloc returns NULL\n");
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
return;
|
||||
}
|
||||
|
||||
rowptr[0] = row;
|
||||
|
||||
jpeg_start_compress(&cinfo, TRUE);
|
||||
|
||||
sprintf(comment, "CREATOR: gd-jpeg v%s (using IJG JPEG v%d),",
|
||||
GD_JPEG_VERSION, JPEG_LIB_VERSION);
|
||||
if (quality >= 0)
|
||||
sprintf(comment + strlen(comment), " quality = %d\n",
|
||||
quality);
|
||||
else
|
||||
strcat(comment + strlen(comment), " default quality\n");
|
||||
jpeg_write_marker(&cinfo, JPEG_COM, (JOCTET *)comment,
|
||||
(unsigned int)strlen(comment));
|
||||
|
||||
for (i = 0; i < im->sy; i++) {
|
||||
for (jidx = 0, j = 0; j < im->sx; j++) {
|
||||
int idx = im->pixels[i][j];
|
||||
|
||||
/*
|
||||
* NB: Although gd RGB values are ints, their max value is
|
||||
* 255 (see the documentation for gdImageColorAllocate())
|
||||
* -- perfect for 8-bit JPEG encoding (which is the norm)
|
||||
*/
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
row[jidx++] = im->red[idx];
|
||||
row[jidx++] = im->green[idx];
|
||||
row[jidx++] = im->blue[idx];
|
||||
#elif BITS_IN_JSAMPLE == 12
|
||||
row[jidx++] = im->red[idx] << 4;
|
||||
row[jidx++] = im->green[idx] << 4;
|
||||
row[jidx++] = im->blue[idx] << 4;
|
||||
#else
|
||||
#error IJG JPEG library BITS_IN_JSAMPLE value must be 8 or 12
|
||||
#endif
|
||||
}
|
||||
|
||||
nlines = jpeg_write_scanlines(&cinfo, rowptr, 1);
|
||||
if (nlines != 1)
|
||||
fprintf(stderr, "gd_jpeg: warning: jpeg_write_scanlines"
|
||||
" returns %u -- expected 1\n", nlines);
|
||||
}
|
||||
|
||||
jpeg_finish_compress(&cinfo);
|
||||
jpeg_destroy_compress(&cinfo);
|
||||
free(row);
|
||||
}
|
||||
|
||||
gdImagePtr gdImageCreateFromJpeg(FILE *inFile)
|
||||
{
|
||||
gdImagePtr im;
|
||||
gdIOCtx *in = gdNewFileCtx(inFile);
|
||||
im = gdImageCreateFromJpegCtx(in);
|
||||
in->free(in);
|
||||
return im;
|
||||
}
|
||||
|
||||
void
|
||||
jpeg_gdIOCtx_src (j_decompress_ptr cinfo,
|
||||
gdIOCtx *infile);
|
||||
|
||||
/*
|
||||
* Create a gd-format image from the JPEG-format INFILE. Returns the
|
||||
* image, or NULL upon error.
|
||||
*/
|
||||
gdImagePtr
|
||||
gdImageCreateFromJpegCtx(gdIOCtx *infile)
|
||||
{
|
||||
struct jpeg_decompress_struct cinfo;
|
||||
struct jpeg_error_mgr jerr;
|
||||
jmpbuf_wrapper jmpbufw;
|
||||
/* volatile so we can free them after longjmp */
|
||||
volatile JSAMPROW row = 0;
|
||||
volatile gdImagePtr im = 0;
|
||||
JSAMPROW rowptr[1];
|
||||
int i, j, retval;
|
||||
JDIMENSION nrows;
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("gd-jpeg: gd JPEG version %s\n", GD_JPEG_VERSION);
|
||||
printf("gd-jpeg: JPEG library version %d, %d-bit sample values\n",
|
||||
JPEG_LIB_VERSION, BITS_IN_JSAMPLE);
|
||||
#endif
|
||||
|
||||
memset(&cinfo, 0, sizeof(cinfo));
|
||||
memset(&jerr, 0, sizeof(jerr));
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr);
|
||||
cinfo.client_data = &jmpbufw;
|
||||
if (setjmp(jmpbufw.jmpbuf) != 0) {
|
||||
/* we're here courtesy of longjmp */
|
||||
if (row)
|
||||
free(row);
|
||||
if (im)
|
||||
gdImageDestroy(im);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cinfo.err->error_exit = fatal_jpeg_error;
|
||||
|
||||
jpeg_create_decompress(&cinfo);
|
||||
|
||||
jpeg_gdIOCtx_src(&cinfo, infile);
|
||||
|
||||
retval = jpeg_read_header(&cinfo, TRUE);
|
||||
if (retval != JPEG_HEADER_OK)
|
||||
fprintf(stderr, "gd-jpeg: warning: jpeg_read_header returns"
|
||||
" %d, expected %d\n", retval, JPEG_HEADER_OK);
|
||||
|
||||
if (cinfo.image_height > INT_MAX)
|
||||
fprintf(stderr, "gd-jpeg: warning: JPEG image height (%u) is"
|
||||
" greater than INT_MAX (%d) (and thus greater than"
|
||||
" gd can handle)", cinfo.image_height,
|
||||
INT_MAX);
|
||||
|
||||
if (cinfo.image_width > INT_MAX)
|
||||
fprintf(stderr, "gd-jpeg: warning: JPEG image width (%u) is"
|
||||
" greater than INT_MAX (%d) (and thus greater than"
|
||||
" gd can handle)\n", cinfo.image_width, INT_MAX);
|
||||
|
||||
im = gdImageCreate((int)cinfo.image_width,
|
||||
(int)cinfo.image_height);
|
||||
if (im == 0) {
|
||||
fprintf(stderr, "gd-jpeg error: cannot allocate gdImage"
|
||||
" struct\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Have the JPEG library quantize the number of image colors to
|
||||
* 256 maximum; force into RGB colorspace
|
||||
*/
|
||||
cinfo.out_color_space = JCS_RGB;
|
||||
cinfo.quantize_colors = TRUE;
|
||||
cinfo.desired_number_of_colors = gdMaxColors;
|
||||
|
||||
if (jpeg_start_decompress(&cinfo) != TRUE)
|
||||
fprintf(stderr, "gd-jpeg: warning: jpeg_start_decompress"
|
||||
" reports suspended data source\n");
|
||||
|
||||
#ifdef DEBUG
|
||||
printf("gd-jpeg: JPEG image information:");
|
||||
if (cinfo.saw_JFIF_marker)
|
||||
printf(" JFIF version %d.%.2d",
|
||||
(int)cinfo.JFIF_major_version,
|
||||
(int)cinfo.JFIF_minor_version);
|
||||
else if (cinfo.saw_Adobe_marker)
|
||||
printf(" Adobe format");
|
||||
else
|
||||
printf(" UNKNOWN format");
|
||||
|
||||
printf(" %ux%u (raw) / %ux%u (scaled) %d-bit", cinfo.image_width,
|
||||
cinfo.image_height, cinfo.output_width,
|
||||
cinfo.output_height, cinfo.data_precision);
|
||||
printf(" %s", (cinfo.progressive_mode ? "progressive" :
|
||||
"baseline"));
|
||||
printf(" image, %d quantized colors, ",
|
||||
cinfo.actual_number_of_colors);
|
||||
|
||||
switch (cinfo.jpeg_color_space) {
|
||||
case JCS_GRAYSCALE:
|
||||
printf("grayscale");
|
||||
break;
|
||||
|
||||
case JCS_RGB:
|
||||
printf("RGB");
|
||||
break;
|
||||
|
||||
case JCS_YCbCr:
|
||||
printf("YCbCr (a.k.a. YUV)");
|
||||
break;
|
||||
|
||||
case JCS_CMYK:
|
||||
printf("CMYK");
|
||||
break;
|
||||
|
||||
case JCS_YCCK:
|
||||
printf("YCbCrK");
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("UNKNOWN (value: %d)", (int)cinfo.jpeg_color_space);
|
||||
break;
|
||||
}
|
||||
printf(" colorspace\n");
|
||||
fflush(stdout);
|
||||
#endif /* DEBUG */
|
||||
|
||||
gdImageInterlace(im, cinfo.progressive_mode != 0);
|
||||
|
||||
im->colorsTotal = cinfo.actual_number_of_colors;
|
||||
if (cinfo.output_components != 1) {
|
||||
fprintf(stderr, "gd-jpeg: error: JPEG color quantization"
|
||||
" request resulted in output_components == %d"
|
||||
" (expected 1)\n", cinfo.output_components);
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (i = 0; i < im->colorsTotal; i++) {
|
||||
#if BITS_IN_JSAMPLE == 8
|
||||
im->red[i] = cinfo.colormap[0][i];
|
||||
im->green[i] = cinfo.colormap[1][i];
|
||||
im->blue[i] = cinfo.colormap[2][i];
|
||||
#elif BITS_IN_JSAMPLE == 12
|
||||
im->red[i] = (cinfo.colormap[0][i] >> 4) & 0xff;
|
||||
im->green[i] = (cinfo.colormap[1][i] >> 4) & 0xff;
|
||||
im->blue[i] = (cinfo.colormap[2][i] >> 4) & 0xff;
|
||||
#else
|
||||
#error IJG JPEG library BITS_IN_JSAMPLE value must be 8 or 12
|
||||
#endif
|
||||
im->open[i] = 0;
|
||||
#ifdef DEBUG
|
||||
printf("gd-jpeg: gd colormap index %d set to (%d, %d, %d)\n", i,
|
||||
im->red[i], im->green[i], im->blue[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
row = calloc(cinfo.output_width, sizeof(JSAMPLE));
|
||||
if (row == 0) {
|
||||
fprintf(stderr, "gd-jpeg: error: unable to allocate row for"
|
||||
" JPEG scanline: calloc returns NULL\n");
|
||||
goto error;
|
||||
}
|
||||
rowptr[0] = row;
|
||||
|
||||
for (i = 0; i < cinfo.output_height; i++) {
|
||||
nrows = jpeg_read_scanlines(&cinfo, rowptr, 1);
|
||||
if (nrows != 1) {
|
||||
fprintf(stderr, "gd-jpeg: error: jpeg_read_scanlines"
|
||||
" returns %u, expected 1\n", nrows);
|
||||
goto error;
|
||||
}
|
||||
|
||||
for (j = 0; j < cinfo.output_width; j++)
|
||||
im->pixels[i][j] = row[j];
|
||||
}
|
||||
|
||||
if (jpeg_finish_decompress(&cinfo) != TRUE)
|
||||
fprintf(stderr, "gd-jpeg: warning: jpeg_finish_decompress"
|
||||
" reports suspended data source\n");
|
||||
|
||||
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
free(row);
|
||||
return im;
|
||||
|
||||
error:
|
||||
jpeg_destroy_decompress(&cinfo);
|
||||
if (row)
|
||||
free(row);
|
||||
if (im)
|
||||
gdImageDestroy(im);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* gdIOCtx JPEG data sources and sinks, T. Boutell
|
||||
* almost a simple global replace from T. Lane's stdio versions.
|
||||
*
|
||||
*/
|
||||
|
||||
/* Different versions of libjpeg use either 'jboolean' or 'boolean', and
|
||||
some platforms define 'boolean', and so forth. Deal with this
|
||||
madness by typedeffing 'safeboolean' to 'boolean' if HAVE_BOOLEAN
|
||||
is already set, because this is the test that libjpeg uses.
|
||||
Otherwise, typedef it to int, because that's what libjpeg does
|
||||
if HAVE_BOOLEAN is not defined. -TBB */
|
||||
|
||||
#ifdef HAVE_BOOLEAN
|
||||
typedef boolean safeboolean;
|
||||
#else
|
||||
typedef int safeboolean;
|
||||
#endif /* HAVE_BOOLEAN */
|
||||
|
||||
/* Expanded data source object for gdIOCtx input */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_source_mgr pub; /* public fields */
|
||||
|
||||
gdIOCtx *infile; /* source stream */
|
||||
JOCTET * buffer; /* start of buffer */
|
||||
safeboolean start_of_file; /* have we gotten any data yet? */
|
||||
} my_source_mgr;
|
||||
|
||||
typedef my_source_mgr * my_src_ptr;
|
||||
|
||||
#define INPUT_BUF_SIZE 4096 /* choose an efficiently fread'able size */
|
||||
|
||||
/*
|
||||
* Initialize source --- called by jpeg_read_header
|
||||
* before any data is actually read.
|
||||
*/
|
||||
|
||||
void
|
||||
init_source (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||
|
||||
/* We reset the empty-input-file flag for each image,
|
||||
* but we don't clear the input buffer.
|
||||
* This is correct behavior for reading a series of images from one source.
|
||||
*/
|
||||
src->start_of_file = TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Fill the input buffer --- called whenever buffer is emptied.
|
||||
*
|
||||
* In typical applications, this should read fresh data into the buffer
|
||||
* (ignoring the current state of next_input_byte & bytes_in_buffer),
|
||||
* reset the pointer & count to the start of the buffer, and return TRUE
|
||||
* indicating that the buffer has been reloaded. It is not necessary to
|
||||
* fill the buffer entirely, only to obtain at least one more byte.
|
||||
*
|
||||
* There is no such thing as an EOF return. If the end of the file has been
|
||||
* reached, the routine has a choice of ERREXIT() or inserting fake data into
|
||||
* the buffer. In most cases, generating a warning message and inserting a
|
||||
* fake EOI marker is the best course of action --- this will allow the
|
||||
* decompressor to output however much of the image is there. However,
|
||||
* the resulting error message is misleading if the real problem is an empty
|
||||
* input file, so we handle that case specially.
|
||||
*
|
||||
* In applications that need to be able to suspend compression due to input
|
||||
* not being available yet, a FALSE return indicates that no more data can be
|
||||
* obtained right now, but more may be forthcoming later. In this situation,
|
||||
* the decompressor will return to its caller (with an indication of the
|
||||
* number of scanlines it has read, if any). The application should resume
|
||||
* decompression after it has loaded more data into the input buffer. Note
|
||||
* that there are substantial restrictions on the use of suspension --- see
|
||||
* the documentation.
|
||||
*
|
||||
* When suspending, the decompressor will back up to a convenient restart point
|
||||
* (typically the start of the current MCU). next_input_byte & bytes_in_buffer
|
||||
* indicate where the restart point will be if the current call returns FALSE.
|
||||
* Data beyond this point must be rescanned after resumption, so move it to
|
||||
* the front of the buffer rather than discarding it.
|
||||
*/
|
||||
|
||||
#define END_JPEG_SEQUENCE "\r\n[*]--:END JPEG:--[*]\r\n"
|
||||
|
||||
safeboolean
|
||||
fill_input_buffer (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||
size_t nbytes = 0;
|
||||
size_t got;
|
||||
char *s;
|
||||
memset(src->buffer, 0, INPUT_BUF_SIZE);
|
||||
while (nbytes < INPUT_BUF_SIZE) {
|
||||
int got = gdGetBuf(src->buffer + nbytes,
|
||||
INPUT_BUF_SIZE - nbytes,
|
||||
src->infile);
|
||||
if ((got == EOF) || (got == 0)) {
|
||||
/* EOF or error. If we got any data, don't worry about it.
|
||||
If we didn't, then this is unexpected. */
|
||||
if (!nbytes) {
|
||||
nbytes = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
nbytes += got;
|
||||
}
|
||||
if (nbytes <= 0) {
|
||||
if (src->start_of_file) /* Treat empty input file as fatal error */
|
||||
ERREXIT(cinfo, JERR_INPUT_EMPTY);
|
||||
WARNMS(cinfo, JWRN_JPEG_EOF);
|
||||
/* Insert a fake EOI marker */
|
||||
src->buffer[0] = (JOCTET) 0xFF;
|
||||
src->buffer[1] = (JOCTET) JPEG_EOI;
|
||||
nbytes = 2;
|
||||
}
|
||||
|
||||
src->pub.next_input_byte = src->buffer;
|
||||
src->pub.bytes_in_buffer = nbytes;
|
||||
src->start_of_file = FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Skip data --- used to skip over a potentially large amount of
|
||||
* uninteresting data (such as an APPn marker).
|
||||
*
|
||||
* Writers of suspendable-input applications must note that skip_input_data
|
||||
* is not granted the right to give a suspension return. If the skip extends
|
||||
* beyond the data currently in the buffer, the buffer can be marked empty so
|
||||
* that the next read will cause a fill_input_buffer call that can suspend.
|
||||
* Arranging for additional bytes to be discarded before reloading the input
|
||||
* buffer is the application writer's problem.
|
||||
*/
|
||||
|
||||
void
|
||||
skip_input_data (j_decompress_ptr cinfo, long num_bytes)
|
||||
{
|
||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||
|
||||
/* Just a dumb implementation for now. Not clear that being smart is worth
|
||||
* any trouble anyway --- large skips are infrequent.
|
||||
*/
|
||||
if (num_bytes > 0) {
|
||||
while (num_bytes > (long) src->pub.bytes_in_buffer) {
|
||||
num_bytes -= (long) src->pub.bytes_in_buffer;
|
||||
(void) fill_input_buffer(cinfo);
|
||||
/* note we assume that fill_input_buffer will never return FALSE,
|
||||
* so suspension need not be handled.
|
||||
*/
|
||||
}
|
||||
src->pub.next_input_byte += (size_t) num_bytes;
|
||||
src->pub.bytes_in_buffer -= (size_t) num_bytes;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* An additional method that can be provided by data source modules is the
|
||||
* resync_to_restart method for error recovery in the presence of RST markers.
|
||||
* For the moment, this source module just uses the default resync method
|
||||
* provided by the JPEG library. That method assumes that no backtracking
|
||||
* is possible.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Terminate source --- called by jpeg_finish_decompress
|
||||
* after all data has been read. Often a no-op.
|
||||
*
|
||||
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
|
||||
* application must deal with any cleanup that should happen even
|
||||
* for error exit.
|
||||
*/
|
||||
|
||||
void
|
||||
term_source (j_decompress_ptr cinfo)
|
||||
{
|
||||
my_src_ptr src = (my_src_ptr) cinfo->src;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Prepare for input from a gdIOCtx stream.
|
||||
* The caller must have already opened the stream, and is responsible
|
||||
* for closing it after finishing decompression.
|
||||
*/
|
||||
|
||||
void
|
||||
jpeg_gdIOCtx_src (j_decompress_ptr cinfo,
|
||||
gdIOCtx *infile)
|
||||
{
|
||||
my_src_ptr src;
|
||||
|
||||
/* The source object and input buffer are made permanent so that a series
|
||||
* of JPEG images can be read from the same file by calling jpeg_gdIOCtx_src
|
||||
* only before the first one. (If we discarded the buffer at the end of
|
||||
* one image, we'd likely lose the start of the next one.)
|
||||
* This makes it unsafe to use this manager and a different source
|
||||
* manager serially with the same JPEG object. Caveat programmer.
|
||||
*/
|
||||
if (cinfo->src == NULL) { /* first time for this JPEG object? */
|
||||
cinfo->src = (struct jpeg_source_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
SIZEOF(my_source_mgr));
|
||||
src = (my_src_ptr) cinfo->src;
|
||||
src->buffer = (JOCTET *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
INPUT_BUF_SIZE * SIZEOF(JOCTET));
|
||||
}
|
||||
|
||||
src = (my_src_ptr) cinfo->src;
|
||||
src->pub.init_source = init_source;
|
||||
src->pub.fill_input_buffer = fill_input_buffer;
|
||||
src->pub.skip_input_data = skip_input_data;
|
||||
src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */
|
||||
src->pub.term_source = term_source;
|
||||
src->infile = infile;
|
||||
src->pub.bytes_in_buffer = 0; /* forces fill_input_buffer on first read */
|
||||
src->pub.next_input_byte = NULL; /* until buffer loaded */
|
||||
}
|
||||
|
||||
/* Expanded data destination object for stdio output */
|
||||
|
||||
typedef struct {
|
||||
struct jpeg_destination_mgr pub; /* public fields */
|
||||
gdIOCtx * outfile; /* target stream */
|
||||
JOCTET * buffer; /* start of buffer */
|
||||
} my_destination_mgr;
|
||||
|
||||
typedef my_destination_mgr * my_dest_ptr;
|
||||
|
||||
#define OUTPUT_BUF_SIZE 4096 /* choose an efficiently fwrite'able size */
|
||||
|
||||
/*
|
||||
* Initialize destination --- called by jpeg_start_compress
|
||||
* before any data is actually written.
|
||||
*/
|
||||
|
||||
void init_destination (j_compress_ptr cinfo)
|
||||
{
|
||||
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
|
||||
|
||||
/* Allocate the output buffer --- it will be released when done with image */
|
||||
dest->buffer = (JOCTET *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
|
||||
OUTPUT_BUF_SIZE * SIZEOF(JOCTET));
|
||||
|
||||
dest->pub.next_output_byte = dest->buffer;
|
||||
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Empty the output buffer --- called whenever buffer fills up.
|
||||
*
|
||||
* In typical applications, this should write the entire output buffer
|
||||
* (ignoring the current state of next_output_byte & free_in_buffer),
|
||||
* reset the pointer & count to the start of the buffer, and return TRUE
|
||||
* indicating that the buffer has been dumped.
|
||||
*
|
||||
* In applications that need to be able to suspend compression due to output
|
||||
* overrun, a FALSE return indicates that the buffer cannot be emptied now.
|
||||
* In this situation, the compressor will return to its caller (possibly with
|
||||
* an indication that it has not accepted all the supplied scanlines). The
|
||||
* application should resume compression after it has made more room in the
|
||||
* output buffer. Note that there are substantial restrictions on the use of
|
||||
* suspension --- see the documentation.
|
||||
*
|
||||
* When suspending, the compressor will back up to a convenient restart point
|
||||
* (typically the start of the current MCU). next_output_byte & free_in_buffer
|
||||
* indicate where the restart point will be if the current call returns FALSE.
|
||||
* Data beyond this point will be regenerated after resumption, so do not
|
||||
* write it out when emptying the buffer externally.
|
||||
*/
|
||||
|
||||
safeboolean empty_output_buffer (j_compress_ptr cinfo)
|
||||
{
|
||||
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
|
||||
|
||||
if (gdPutBuf(dest->buffer, OUTPUT_BUF_SIZE, dest->outfile) !=
|
||||
(size_t) OUTPUT_BUF_SIZE)
|
||||
ERREXIT(cinfo, JERR_FILE_WRITE);
|
||||
|
||||
dest->pub.next_output_byte = dest->buffer;
|
||||
dest->pub.free_in_buffer = OUTPUT_BUF_SIZE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Terminate destination --- called by jpeg_finish_compress
|
||||
* after all data has been written. Usually needs to flush buffer.
|
||||
*
|
||||
* NB: *not* called by jpeg_abort or jpeg_destroy; surrounding
|
||||
* application must deal with any cleanup that should happen even
|
||||
* for error exit.
|
||||
*/
|
||||
|
||||
void term_destination (j_compress_ptr cinfo)
|
||||
{
|
||||
my_dest_ptr dest = (my_dest_ptr) cinfo->dest;
|
||||
size_t datacount = OUTPUT_BUF_SIZE - dest->pub.free_in_buffer;
|
||||
|
||||
/* Write any data remaining in the buffer */
|
||||
if (datacount > 0) {
|
||||
if (gdPutBuf(dest->buffer, datacount, dest->outfile) != datacount)
|
||||
ERREXIT(cinfo, JERR_FILE_WRITE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Prepare for output to a stdio stream.
|
||||
* The caller must have already opened the stream, and is responsible
|
||||
* for closing it after finishing compression.
|
||||
*/
|
||||
|
||||
void jpeg_gdIOCtx_dest (j_compress_ptr cinfo, gdIOCtx * outfile)
|
||||
{
|
||||
my_dest_ptr dest;
|
||||
|
||||
/* The destination object is made permanent so that multiple JPEG images
|
||||
* can be written to the same file without re-executing jpeg_stdio_dest.
|
||||
* This makes it dangerous to use this manager and a different destination
|
||||
* manager serially with the same JPEG object, because their private object
|
||||
* sizes may be different. Caveat programmer.
|
||||
*/
|
||||
if (cinfo->dest == NULL) { /* first time for this JPEG object? */
|
||||
cinfo->dest = (struct jpeg_destination_mgr *)
|
||||
(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT,
|
||||
SIZEOF(my_destination_mgr));
|
||||
}
|
||||
|
||||
dest = (my_dest_ptr) cinfo->dest;
|
||||
dest->pub.init_destination = init_destination;
|
||||
dest->pub.empty_output_buffer = empty_output_buffer;
|
||||
dest->pub.term_destination = term_destination;
|
||||
dest->outfile = outfile;
|
||||
}
|
||||
|
||||
#endif /* HAVE_JPEG */
|
||||
|
|
@ -0,0 +1,292 @@
|
|||
/*
|
||||
Creation of wbmp image files with gd library
|
||||
gd_wbmp.c
|
||||
|
||||
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.
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
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:
|
||||
|
||||
gdCreateFromWBMP function for reading WBMP files
|
||||
|
||||
-----------------------------------------------------------------------------------------
|
||||
|
||||
Compilation:
|
||||
|
||||
* testing the mbi data structure:
|
||||
gcc -Wall -W -D__MBI_DEBUG__ gd_wbmp.c -o mbi -L/usr/local/lib -lgd
|
||||
|
||||
* testing generation of wbmp images
|
||||
gcc -Wall -W -D__GD_WBMP_DEBUG__ gd_wbmp.c -o gd_wbmp -L/usr/local/lib -lgd -lpng
|
||||
|
||||
* simply making the object file
|
||||
gcc -c -Wall -W gd_wbmp.c -o gd_wbmp.o
|
||||
*/
|
||||
|
||||
#include <gd.h>
|
||||
#include <gdfonts.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
|
||||
/* *************************** Multi Byte Integer Funcionnalities *************************** */
|
||||
|
||||
/* **************************************************
|
||||
An mbi is an array of bytes.
|
||||
For 32 bit integers, 5 bytes are sufficient.
|
||||
*/
|
||||
typedef unsigned char mbi_t[6];
|
||||
|
||||
|
||||
/* **************************************************
|
||||
initialization of an mbi in order to be used by the int2mbi function
|
||||
*/
|
||||
static void mbiInit(mbi_t mbi) {
|
||||
int i;
|
||||
mbi[0] = mbi[5] = (unsigned char)0;
|
||||
for(i=1; i<5; mbi[i++] = 0x80);
|
||||
}
|
||||
|
||||
|
||||
/* **************************************************
|
||||
Displays the content of the mbi as a serie of hexa bytes.
|
||||
For debuging purpose only
|
||||
*/
|
||||
#ifdef __MBI_DEBUG__
|
||||
static void mbiDisplay(mbi_t mbi, FILE *out) {
|
||||
unsigned int i;
|
||||
fprintf(out, "MBI:%d [", (unsigned int)mbi[0]);
|
||||
if(mbi[0] > 0)
|
||||
fprintf(out, "%X", (unsigned int)mbi[1]);
|
||||
for(i=2; i<=mbi[0]; i++)
|
||||
fprintf(out, ":%02X", (unsigned int)mbi[i]);
|
||||
fprintf(out, "]\n");
|
||||
}
|
||||
#endif /* __MBI_DEBUG__ */
|
||||
|
||||
|
||||
/* **************************************************
|
||||
writes the bytes constituing the mbi on the stream 'out'
|
||||
*/
|
||||
static void mbiPrint(mbi_t mbi, gdIOCtx *out) {
|
||||
unsigned int i;
|
||||
for(i=1; i<=(unsigned int)mbi[0]; gdPutC(mbi[i++], out));
|
||||
}
|
||||
|
||||
|
||||
/* **************************************************
|
||||
Conversion routines:
|
||||
unsigned int -> multi byte integer
|
||||
multi byte integer -> unsigned int
|
||||
*/
|
||||
static void int2mbi(mbi_t mbi, unsigned int val) {
|
||||
unsigned int i, j;
|
||||
mbiInit(mbi);
|
||||
for(i=5; i>0; i--) {
|
||||
mbi[i] = mbi[i] | (val & 0x7F);
|
||||
val = val >> 7;
|
||||
}
|
||||
for(j=1; (mbi[j] & 0x7F) == 0 && j<=5; j++);
|
||||
mbi[0] = (unsigned char)(5-j+1);
|
||||
for(i=1; i<=mbi[0]; mbi[i++] = mbi[j++]);
|
||||
}
|
||||
|
||||
static unsigned int mbi2int(mbi_t mbi) {
|
||||
unsigned int res=0, i;
|
||||
for(i=0; i<(unsigned int)mbi[0]; i++)
|
||||
res = (res << 7) | (unsigned int) ( mbi[i+1] & 0x7F );
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef __MBI_DEBUG__
|
||||
int main(void) {
|
||||
mbi_t mbi;
|
||||
fprintf(stdout, "testing Multi Byte Integers:\n");
|
||||
|
||||
int2mbi(mbi, 0);
|
||||
mbiDisplay(mbi, stdout);
|
||||
fprintf(stdout, ">> = %u\n", mbi2int(mbi));
|
||||
|
||||
/* 0xA0 and 0x60 are the two examples from the wbmp specs */
|
||||
int2mbi(mbi, 0xA0);
|
||||
mbiDisplay(mbi, stdout);
|
||||
fprintf(stdout, ">> = %u\n", mbi2int(mbi));
|
||||
|
||||
int2mbi(mbi, 0x60);
|
||||
mbiDisplay(mbi, stdout);
|
||||
fprintf(stdout, ">> = %u\n", mbi2int(mbi));
|
||||
|
||||
int2mbi(mbi, 1024+512);
|
||||
mbiDisplay(mbi, stdout);
|
||||
fprintf(stdout, ">> = %u\n", mbi2int(mbi));
|
||||
|
||||
int2mbi(mbi, 1024+512+1);
|
||||
mbiDisplay(mbi, stdout);
|
||||
fprintf(stdout, ">> = %u\n", mbi2int(mbi));
|
||||
|
||||
int2mbi(mbi, 775432);
|
||||
mbiDisplay(mbi, stdout);
|
||||
fprintf(stdout, ">> = %u\n", mbi2int(mbi));
|
||||
|
||||
int2mbi(mbi, 405589432);
|
||||
mbiDisplay(mbi, stdout);
|
||||
fprintf(stdout, ">> = %u\n", mbi2int(mbi));
|
||||
|
||||
int2mbi(mbi, UINT_MAX);
|
||||
mbiDisplay(mbi, stdout);
|
||||
fprintf(stdout, ">> = %u\n", mbi2int(mbi));
|
||||
|
||||
fprintf(stdout, "\n");
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* *************************** GD interface *************************** */
|
||||
|
||||
/*
|
||||
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;
|
||||
mbi_t mbi;
|
||||
|
||||
/* wbmp images are type 0: B&W; no compression; empty FixHeaderFlield */
|
||||
gdPutC(0, out); /* header */
|
||||
gdPutC(0, out); /* FixHeaderFlield */
|
||||
|
||||
/* width and height as mbi */
|
||||
int2mbi(mbi, gdImageSX(image)); /* width */
|
||||
mbiPrint(mbi, out);
|
||||
int2mbi(mbi, gdImageSY(image)); /* height */
|
||||
mbiPrint(mbi, out);
|
||||
|
||||
/*
|
||||
now come the pixels as strings of bits padded with 0's at the end of the
|
||||
lines, if necessary
|
||||
*/
|
||||
for(y=0; y<gdImageSY(image); y++) {
|
||||
unsigned char nbPixs = 0; /* how many pixels already written */
|
||||
unsigned char pixels = 0; /* the 8 pixels string */
|
||||
for(x=0; x<gdImageSX(image); x++) {
|
||||
if(gdImageGetPixel(image, x, y) == fg) {
|
||||
pixels = pixels | (1 << (7-nbPixs));
|
||||
}
|
||||
nbPixs ++;
|
||||
if(nbPixs == 8) { /* 8 pixels written -> write to file */
|
||||
gdPutC(pixels, out);
|
||||
pixels = 0;
|
||||
nbPixs = 0;
|
||||
}
|
||||
}
|
||||
/* if there are pixels left to write, write them */
|
||||
if(nbPixs != 0)
|
||||
gdPutC(pixels, out);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
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 gdImageWBMP(gdImagePtr image, int fg, FILE *out)
|
||||
{
|
||||
gdIOCtx *out = gdNewFileCtx(outFile);
|
||||
gdImageWBMPCtx(im, out);
|
||||
out->free(out);
|
||||
}
|
||||
|
||||
void* gdImageWBMPPtr(gdImagePtr im, int *size)
|
||||
{
|
||||
void *rv;
|
||||
gdIOCtx *out = gdNewDynamicCtx(2048, NULL);
|
||||
gdImageWBMPCtx(im, out);
|
||||
rv = gdDPExtractData(out, size);
|
||||
out->free(out);
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef __GD_WBMP_DEBUG__
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
gdImagePtr image;
|
||||
int bg, fg;
|
||||
FILE *out;
|
||||
|
||||
if(argc != 2) {
|
||||
fprintf(stderr, "usage %s <wbmp file>\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fprintf(stdout, "testing gd generation of WBMP files\n");
|
||||
|
||||
fprintf(stdout, "Opening WBMP file '%s'\n", argv[1]);
|
||||
if(!(out = fopen(argv[1], "w"))) {
|
||||
fprintf(stderr, "Cannot open out file '%s'\n", argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fprintf(stdout, "Creating GD image and drawing...y\n");
|
||||
if(!(image = gdImageCreate(60, 30))) {
|
||||
fprintf(stderr, "Cannot create image 30x60\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* don't really care about rgb values */
|
||||
bg = gdImageColorAllocate(image, 0, 0, 0);
|
||||
fg = gdImageColorAllocate(image, 255, 255, 255);
|
||||
|
||||
/* draw something : */
|
||||
gdImageRectangle(image, 1, 1, gdImageSX(image)-2, gdImageSY(image)-2, fg);
|
||||
|
||||
/* write something interesting */
|
||||
gdImageString(image, gdFontSmall, 3, 0, "Hello", fg);
|
||||
|
||||
/* write the wbmp file */
|
||||
fprintf(stdout, "Writing WBMP file '%s':\n", argv[1]);
|
||||
gdImageWBMP(image, fg, out);
|
||||
fclose(out);
|
||||
fprintf(stdout, "Written.\nTry now to load the file '%s' with a WAP browser.\n", argv[1]);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
fprintf(stdout, "\n");
|
||||
return 0;
|
||||
}
|
||||
#endif /* __GD_WBMP_DEBUG__ */
|
||||
|
||||
|
||||
|
||||
|
26
src/gdtest.c
26
src/gdtest.c
|
@ -246,13 +246,31 @@ int main(int argc, char **argv)
|
|||
printf("[Merged Image has %d colours]\n",im2->colorsTotal);
|
||||
CompareImages("Merged (gdtest.png, gdtest_merge.png)", im2, im3);
|
||||
|
||||
/*out = fopen("gdtest_merge.png", "wb"); */
|
||||
/*gdImageLzw(im2, out); */
|
||||
/*fclose(out); */
|
||||
|
||||
gdImageDestroy(im2);
|
||||
gdImageDestroy(im3);
|
||||
|
||||
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");
|
||||
gdImageDestroy(im);
|
||||
gdImageDestroy(ref);
|
||||
|
||||
|
|
349
src/index.html
349
src/index.html
|
@ -1,30 +1,35 @@
|
|||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>gd 1.7.3</TITLE>
|
||||
<TITLE>gd 1.8</TITLE>
|
||||
</HEAD>
|
||||
<BODY>
|
||||
<!-- BANNER HERE -->
|
||||
<H1>gd 1.7.3</H1>
|
||||
<H1>gd 1.8</H1>
|
||||
<H2>A graphics library for fast image creation</H2>
|
||||
<H2>Follow this link to the
|
||||
<A HREF="http://www.boutell.com/gd/">latest version
|
||||
of this document</A>.</H2>
|
||||
<blockquote>
|
||||
<strong>HEY! READ THIS!</strong>
|
||||
gd 1.7.3 creates PNG images, not GIF images. This is a good thing.
|
||||
PNG is a more compact format, and full compression is available.
|
||||
Existing code will need modification to call gdImagePng instead
|
||||
gd 1.8 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 than even PNG is. WBMP is
|
||||
intended for wireless devices (not regular web browsers). Existing
|
||||
code will need modification to call gdImagePng or gdImageJpeg instead
|
||||
of gdImageGif. <strong>Please do not ask us to send you the old GIF
|
||||
version of GD.</strong> Unisys holds a patent on the LZW compression
|
||||
algorithm, which is used in fully compressed GIF images. We are
|
||||
still investigating the legal issues surrounding various
|
||||
alternative means of producing a valid GIF file.
|
||||
algorithm, which is used in fully compressed GIF images. The best
|
||||
solution is to move to legally unencumbered, well-compressed,
|
||||
modern image formats such as PNG and JPEG as soon as possible.
|
||||
<p>
|
||||
gd 1.7.3 <strong>requires</strong> that the following libraries
|
||||
gd 1.8 <strong>requires</strong> that the following libraries
|
||||
also be installed:
|
||||
<p>
|
||||
libpng
|
||||
<p>
|
||||
jpeg-6b or later
|
||||
<p>
|
||||
zlib
|
||||
<p>
|
||||
If you want to use the TrueType font support, you must also
|
||||
|
@ -46,6 +51,7 @@ information. Thank you!
|
|||
<H3>Table of Contents</H3>
|
||||
<UL>
|
||||
<LI><A HREF="#notice">Credits and license terms</A>
|
||||
<LI><A HREF="#whatsnew1.8">What's new in version 1.8?</A>
|
||||
<LI><A HREF="#whatsnew1.7.3">What's new in version 1.7.3?</A>
|
||||
<LI><A HREF="#whatsnew1.7.2">What's new in version 1.7.2?</A>
|
||||
<LI><A HREF="#whatsnew1.7.1">What's new in version 1.7.1?</A>
|
||||
|
@ -83,19 +89,25 @@ COPYRIGHT STATEMENT FOLLOWS THIS LINE
|
|||
</pre>
|
||||
<blockquote>
|
||||
|
||||
Portions copyright 1994, 1995, 1996, 1997, 1998, 1999, by Cold Spring
|
||||
Portions copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000 by Cold Spring
|
||||
Harbor Laboratory. Funded under Grant P41-RR02188 by the National
|
||||
Institutes of Health.
|
||||
<P>
|
||||
Portions copyright 1996, 1997, 1998, 1999, by Boutell.Com, Inc.
|
||||
Portions copyright 1996, 1997, 1998, 1999, 2000 by Boutell.Com, Inc.
|
||||
<p>
|
||||
Portions relating to GD2 format copyright 1999 Philip Warner.
|
||||
Portions relating to GD2 format copyright 1999, 2000 Philip Warner.
|
||||
<p>
|
||||
Portions relating to PNG copyright 1999, Greg Roelofs.
|
||||
Portions relating to PNG copyright 1999, 2000 Greg Roelofs.
|
||||
<p>
|
||||
Portions relating to libttf copyright 1999, John Ellson (ellson@lucent.com).
|
||||
Portions relating to libttf copyright 1999, 2000 John Ellson (ellson@lucent.com).
|
||||
<p>
|
||||
<strong>Permission has been granted to copy and distribute gd in any
|
||||
Portions relating to JPEG copyright 2000, Doug Becker and copyright (C)
|
||||
1994-1998, Thomas G. Lane. This software is based in part on the work
|
||||
of the Independent JPEG Group.
|
||||
<p>
|
||||
Portions relating to WBMP copyright 2000 Maurice Szmurlo.
|
||||
<p>
|
||||
<strong>Permission has been granted to copy, distribute and modify gd in any
|
||||
context without fee, including a commercial application, provided that this notice
|
||||
is present in user-accessible supporting documentation.</strong>
|
||||
<p>
|
||||
|
@ -111,7 +123,7 @@ including but not limited to implied warranties of merchantability and
|
|||
fitness for a particular purpose, with respect to this code and accompanying
|
||||
documentation.
|
||||
<p>
|
||||
Although their code does not appear in gd 1.7.3, the authors wish to
|
||||
Although their code does not appear in gd 1.8, the authors wish to
|
||||
thank David Koblas, David Rowley, and Hutchison Avenue Software
|
||||
Corporation for their prior contributions.
|
||||
</blockquote>
|
||||
|
@ -123,8 +135,8 @@ END OF COPYRIGHT STATEMENT
|
|||
gd is a graphics library. It allows your code to quickly
|
||||
draw images complete with lines, arcs, text, multiple
|
||||
colors, cut and paste from other images, and flood fills, and
|
||||
write out the result as a .PNG file. This is particularly
|
||||
useful in World Wide Web applications, where .PNG is one
|
||||
write out the result as a PNG or JPEG file. This is particularly
|
||||
useful in World Wide Web applications, where PNG and JPEG are two
|
||||
of the formats accepted for inline images by most browsers.
|
||||
<P>
|
||||
gd is not a paint program.
|
||||
|
@ -136,8 +148,8 @@ gd does not provide for every possible desirable graphics
|
|||
operation. It is not necessary or desirable for gd to become
|
||||
a kitchen-sink graphics package, but version 1.7.3 incorporates
|
||||
most of the commonly requested features for an 8-bit 2D package.
|
||||
Support for truecolor images, JPEG and
|
||||
truecolor PNG is planned for version 2.0.
|
||||
Support for truecolor images, including truecolor JPEG and PNG,
|
||||
is planned for version 2.0.
|
||||
<P>
|
||||
<A NAME="gdother"><H3>What if I want to use another programming
|
||||
language?</h3></A>
|
||||
|
@ -152,6 +164,9 @@ gd can be used from Tcl with John Ellson's
|
|||
<a href=http://www.tcltk.com/ftp/ellson/>Gdtclft</a>
|
||||
dynamically loaded extension package.
|
||||
(Gdtclft2.0 or later is needed for gd-1.6 and up with PNG output.)
|
||||
<h4>Pascal</h4>
|
||||
Pascal enthusiasts should look into Michael Bradbury's
|
||||
<a href="http://www.elj.com/dev/free-pascal/gdfp/">gdfp</a> package.
|
||||
<h4>Any Language</h4>
|
||||
There are, at the moment, at least three simple interpreters that
|
||||
perform gd operations. You can output the desired commands to a simple
|
||||
|
@ -163,6 +178,27 @@ These packages have not been updated to gd 1.6 and up as of this writing.
|
|||
<li><a href="http://s27w007.pswfs.gov/tgd/">tgd</a>, by Bradley K. Sherman
|
||||
<li><a href="http://www.unimelb.edu.au/fly/fly.html">fly</a>, by Martin Gleeson
|
||||
</ul>
|
||||
<P><A NAME="whatsnew1.8"><H3>What's new in version 1.8?</H3></A>
|
||||
<ul>
|
||||
<li>Support for JPEG output, courtesy of Doug Becker
|
||||
<li>A link to Michael Bradbery's Pascal wrapper
|
||||
<li>Support for WBMP output, courtesy of Maurice Szmurlo
|
||||
<li>gdImageColorClosestHWB function based on hue, whiteness, blackness,
|
||||
superior to the regular gdImageColorClosest function, courtesy
|
||||
of Philip Warner
|
||||
<li>License clarification: yes, you can modify gd
|
||||
</ul>
|
||||
<h4>Additional JPEG Information</h4>
|
||||
Support for reading and writing JPEG-format images is courtesy
|
||||
of Doug Becker and the Independent JPEG Group / Thomas G. Lane. You
|
||||
can get the latest version of the IJG JPEG software from <A
|
||||
HREF="ftp://ftp.uu.net/graphics/jpeg/">ftp://ftp.uu.net/graphics/jpeg/</A>
|
||||
(e.g., the <A
|
||||
HREF="ftp://ftp.uu.net/graphics/jpeg/jpegsrc.v6b.tar.gz">jpegsrc.v6b.tar.gz</A>
|
||||
file). You <strong>must</strong> use
|
||||
version 6b or later of the IJG JPEG software. You might also consult
|
||||
the <A HREF="http://www.faqs.org/faqs/jpeg-faq/">JPEG FAQ</A> at
|
||||
<A HREF="http://www.faqs.org/faqs/jpeg-faq/">http://www.faqs.org/faqs/jpeg-faq/</A>.
|
||||
<P><A NAME="whatsnew1.7.3"><H3>What's new in version 1.7.3?</H3></A>
|
||||
Another attempt at Makefile fixes to permit
|
||||
linking with all libraries required on platforms with order-
|
||||
|
@ -295,7 +331,7 @@ Version 1.5 featured the following changes:
|
|||
<br>gdImageGd2, gdImageCreateFromGd2 - Support for new format
|
||||
<br>gdImageCopyMerge - Merges two images (useful to highlight part of an image)
|
||||
<br>gdImageCopyMergeGray - Similar to gdImageCopyMerge, but tries to preserve source image hue.
|
||||
<br>gdImagePngPtr, gdImageGdPtr, gdImageGd2Ptr - return memort blocks for each type of image.
|
||||
<br>gdImagePngPtr, gdImageJpegPtr, gdImageWBMPPtr, gdImageGdPtr, gdImageGd2Ptr - return memort blocks for each type of image.
|
||||
<br>gdImageCreateFromPngCtx, gdImageCreateFromGdCtx, gdImageCreateFromGd2Ctx, gdImageCreateFromGd2PartCtx - Support for new I/O context.
|
||||
|
||||
</dl>
|
||||
|
@ -403,13 +439,13 @@ newsgroups relevant to your particular system.
|
|||
<A NAME="getgd"><H3>How do I get gd?</H3></A>
|
||||
<h4>By HTTP</h4>
|
||||
<ul>
|
||||
<li><a href="http://www.boutell.com/gd/http/gd-1.7.3.tar.gz">Gzipped Tar File (Unix)</a>
|
||||
<li><a href="http://www.boutell.com/gd/http/gd-1.7.3.zip">.ZIP File (Windows)</a>
|
||||
<li><a href="http://www.boutell.com/gd/http/gd-1.8.tar.gz">Gzipped Tar File (Unix)</a>
|
||||
<li><a href="http://www.boutell.com/gd/http/gd-1.8.zip">.ZIP File (Windows)</a>
|
||||
</ul>
|
||||
<h4>By FTP</h4>
|
||||
<ul>
|
||||
<li><a href="ftp://ftp.boutell.com/pub/boutell/gd/gd-1.7.3.tar.gz">Gzipped Tar File (Unix)</a>
|
||||
<li><a href="ftp://ftp.boutell.com/pub/boutell/gd/gd-1.7.3.zip">.ZIP File (Windows)</a>
|
||||
<li><a href="ftp://ftp.boutell.com/pub/boutell/gd/gd-1.8.tar.gz">Gzipped Tar File (Unix)</a>
|
||||
<li><a href="ftp://ftp.boutell.com/pub/boutell/gd/gd-1.8.zip">.ZIP File (Windows)</a>
|
||||
</ul>
|
||||
<P>
|
||||
<A NAME="buildgd"><H3>How do I build gd?</H3></A>
|
||||
|
@ -420,10 +456,10 @@ downloaded. If you are not familiar with <code>tar</code> and
|
|||
consult with an experienced user of your system. Sorry, we cannot
|
||||
answer questions about basic Internet skills.
|
||||
<p>
|
||||
Unpacking the archive will produce a directory called "gd-1.7.3".
|
||||
Unpacking the archive will produce a directory called "gd-1.8".
|
||||
<p>
|
||||
<h4>For Unix</h4>
|
||||
<code>cd</code> to the 1.7.3 directory. Edit the Makefile with
|
||||
<code>cd</code> to the 1.8 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". If you are the system administrator, and you
|
||||
|
@ -432,6 +468,10 @@ also wish to type "make install".
|
|||
<p>
|
||||
If you get errors, edit the Makefile again, paying special attention
|
||||
to the INCLUDEDIRS and LIBDIRS settings.
|
||||
<p>
|
||||
IF YOU GET LINKER ERRORS, TRY JUGGLING THE ORDER OF THE -l DIRECTIVES
|
||||
IN THE MAKEFILE. Some platforms may prefer that the libraries be listed
|
||||
in the opposite order.
|
||||
<h4>For Windows, Mac, Et Cetera</h4>
|
||||
Create a project using your favorite programming environment.
|
||||
Copy all of the gd files to the project directory. Add <code>gd.c</code>
|
||||
|
@ -459,7 +499,7 @@ Look at demoin.png to see the original space shuttle
|
|||
image which was scaled and copied into the output image.
|
||||
<P>
|
||||
<A NAME="basics"><H3>gd basics: using gd in your program</H3></A>
|
||||
gd lets you create PNG images on the fly. To use gd in your
|
||||
gd lets you create PNG or JPEG images on the fly. To use gd in your
|
||||
program, include the file gd.h, and link with the libgd.a
|
||||
library produced by "make libgd.a", under Unix. Under other
|
||||
operating systems you will add gd.c to your own project.
|
||||
|
@ -487,8 +527,8 @@ it demonstrates additional features!)</strong>
|
|||
int main() {
|
||||
/* Declare the image */
|
||||
<A HREF="#gdImagePtr">gdImagePtr</A> im;
|
||||
/* Declare an output file */
|
||||
FILE *out;
|
||||
/* Declare output files */
|
||||
FILE *pngout, *jpegout;
|
||||
/* Declare color indexes */
|
||||
int black;
|
||||
int white;
|
||||
|
@ -510,13 +550,21 @@ int main() {
|
|||
|
||||
/* Open a file for writing. "wb" means "write binary", important
|
||||
under MSDOS, harmless under Unix. */
|
||||
out = fopen("test.png", "wb");
|
||||
pngout = fopen("test.png", "wb");
|
||||
|
||||
/* Output the image to the disk file. */
|
||||
<A HREF="#gdImagePng">gdImagePng</A>(im, out);
|
||||
/* Do the same for a JPEG-format file. */
|
||||
jpegout = fopen("test.jpg", "wb");
|
||||
|
||||
/* Close the file. */
|
||||
fclose(out);
|
||||
/* Output the image to the disk file in PNG format. */
|
||||
<A HREF="#gdImagePng">gdImagePng</A>(im, pngout);
|
||||
|
||||
/* Output the same image in JPEG format, using the default
|
||||
JPEG quality setting. */
|
||||
<A HREF="#gdImageJpeg">gdImageJpeg</A>(im, jpegout, -1);
|
||||
|
||||
/* Close the files. */
|
||||
fclose(pngout);
|
||||
fclose(jpegout);
|
||||
|
||||
/* Destroy the image in memory. */
|
||||
<A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
|
||||
|
@ -525,7 +573,7 @@ int main() {
|
|||
When executed, this program creates an image, allocates
|
||||
two colors (the first color allocated becomes the background
|
||||
color), draws a diagonal line (note that 0, 0 is the upper
|
||||
left corner), writes the image to a PNG file, and
|
||||
left corner), writes the image to PNG and JPEG files, and
|
||||
destroys the image.
|
||||
<P>
|
||||
The above example program should
|
||||
|
@ -686,6 +734,33 @@ im = gdImageCreate(64, 64);
|
|||
/* ... Use the image ... */
|
||||
<A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
|
||||
</PRE>
|
||||
<DT><A NAME="gdImageCreateFromJpeg">gdImageCreateFromJpeg(FILE *in)</A>
|
||||
<strong>(FUNCTION)</strong>
|
||||
<br>
|
||||
<A NAME="gdImageCreateFromJpegCtx">gdImageCreateFromJpegCtx(FILE *in)</A>
|
||||
<strong>(FUNCTION)</strong>
|
||||
<p>
|
||||
<DD>
|
||||
gdImageCreateFromJpeg is called to load images from JPEG format files.
|
||||
Invoke gdImageCreateFromJpeg with an already opened pointer to a file
|
||||
containing the desired image.
|
||||
gdImageCreateFromJpeg
|
||||
returns a <A HREF="#gdImagePtr">gdImagePtr</A> to the new image, or NULL
|
||||
if unable to load the image (most often because the file is corrupt or
|
||||
does not contain a JPEG image). gdImageCreateFromPng does <em>not</em>
|
||||
close the file. You can inspect the sx and sy members of the
|
||||
image to determine its size. The image must eventually be destroyed
|
||||
using <A HREF="#gdImageDestroy">gdImageDestroy()</A>.
|
||||
<PRE>
|
||||
<A HREF="#gdImagePtr">gdImagePtr</A> im;
|
||||
... inside a function ...
|
||||
FILE *in;
|
||||
in = fopen("myjpeg.jpg", "rb");
|
||||
im = gdImageCreateFromJpeg(in);
|
||||
fclose(in);
|
||||
/* ... Use the image ... */
|
||||
<A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
|
||||
</PRE>
|
||||
<DT><A NAME="gdImageCreateFromPng">gdImageCreateFromPng(FILE *in)</A>
|
||||
<strong>(FUNCTION)</strong>
|
||||
<BR><A NAME="gdImageCreateFromPngCtx">gdImageCreateFromPngCtx(<a href=#gdioctx>gdIOCtx</a> *in)</A>
|
||||
|
@ -763,7 +838,7 @@ Invoke gdImageCreateFromGd
|
|||
with an already opened pointer to a file containing the desired image
|
||||
in the <A HREF="#gdformat">gd file format</A>, which is specific to
|
||||
gd and intended for very fast loading. (It is <em>not</em> intended for
|
||||
compression; for compression, use PNG.)
|
||||
compression; for compression, use PNG or JPEG.)
|
||||
gdImageCreateFromGd
|
||||
returns a <A HREF="#gdImagePtr">gdImagePtr</A> to the new image, or NULL
|
||||
if unable to load the image (most often because the file is corrupt or
|
||||
|
@ -889,6 +964,61 @@ im = <A HREF="#gdImageCreate">gdImageCreate</A>(10, 10);
|
|||
/* Now destroy it */
|
||||
<A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
|
||||
</PRE>
|
||||
<DT><A NAME="gdImageJpeg">
|
||||
void gdImageJpeg(gdImagePtr im, FILE *out, int quality)</A>
|
||||
<STRONG>(FUNCTION)</STRONG><BR>
|
||||
void gdImageJpegCtx(gdImagePtr im, gdIOCtx *out, int quality)</A>
|
||||
<STRONG>(FUNCTION)</STRONG><BR>
|
||||
<DD>
|
||||
gdImageJpeg outputs the specified image to the specified
|
||||
file in JPEG format. The file must be open for writing. Under MSDOS
|
||||
and all versions of Windows, it is important to use "wb" as opposed
|
||||
to simply "w" as the mode when opening the file, and under Unix there
|
||||
is no penalty for doing so. gdImageJpeg does <em>not</em>
|
||||
close the file; your code must do so.
|
||||
<P>
|
||||
If quality is negative, the default IJG JPEG quality value (which
|
||||
should yield a good general quality / size tradeoff for most
|
||||
situations) is used. Otherwise, for practical purposes, quality
|
||||
should be a value in the range 0-95, higher quality values usually
|
||||
implying both higher quality and larger image sizes.
|
||||
<P>
|
||||
If you have set image interlacing using
|
||||
<A HREF="#gdImageInterlace">gdImageInterlace</A>, this function will
|
||||
interpret that to mean you wish to output a progressive JPEG. Some
|
||||
programs (e.g., Web browsers) can display progressive JPEGs
|
||||
incrementally; this can be useful when browsing over a relatively slow
|
||||
communications link, for example. Progressive JPEGs can also be
|
||||
slightly smaller than sequential (non-progressive) JPEGs.
|
||||
<PRE>
|
||||
... inside a function ...
|
||||
<A HREF="#gdImagePtr">gdImagePtr</A> im;
|
||||
int black, white;
|
||||
FILE *out;
|
||||
/* Create the image */
|
||||
im = <A HREF="#gdImageCreate">gdImageCreate</A>(100, 100);
|
||||
/* Allocate background */
|
||||
white = <A HREF="#gdImageColorAllocate">gdImageColorAllocate</A>(im, 255, 255, 255);
|
||||
/* Allocate drawing color */
|
||||
black = <A HREF="#gdImageColorAllocate">gdImageColorAllocate</A>(im, 0, 0, 0);
|
||||
/* Draw rectangle */
|
||||
<A HREF="#gdImageRectangle">gdImageRectangle</A>(im, 0, 0, 99, 99, black);
|
||||
/* Open output file in binary mode */
|
||||
out = fopen("rect.jpg", "wb");
|
||||
/* Write JPEG using default quality */
|
||||
gdImageJpeg(im, out, -1);
|
||||
/* Close file */
|
||||
fclose(out);
|
||||
/* Destroy image */
|
||||
<A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
|
||||
</PRE>
|
||||
<DT><A NAME="gdImageJpegPtr">
|
||||
void* gdImageJpegPtr(gdImagePtr im, int *size)</A>
|
||||
<STRONG>(FUNCTION)</STRONG>
|
||||
<DD>Identical to gdImageJpeg except that it returns a pointer to a memory
|
||||
area with the JPEG data. This memory must be freed by the caller when it is
|
||||
no longer needed. The 'size' parameter receives the total size of the block
|
||||
of memory.
|
||||
<DT><A NAME="gdImagePng">
|
||||
void gdImagePng(gdImagePtr im, FILE *out)</A>
|
||||
<STRONG>(FUNCTION)</STRONG>
|
||||
|
@ -927,7 +1057,7 @@ void* gdImagePngPtr(gdImagePtr im, int *size)</A>
|
|||
<STRONG>(FUNCTION)</STRONG>
|
||||
<DD>Identical to gdImagePng except that it returns a pointer to a memory
|
||||
area with the PNG data. This memory must be freed by the caller when it is
|
||||
no longer needed. The 'size' parameter received the total size of the block
|
||||
no longer needed. The 'size' parameter receives the total size of the block
|
||||
of memory.
|
||||
|
||||
<DT><A NAME="gdImagePngToSink">gdImagePngToSink(gdImagePtr im, gdSinkPtr out)</A>
|
||||
|
@ -966,6 +1096,51 @@ void gdImagePng(gdImagePtr im, FILE *out)
|
|||
gdImagePngToSink(im, &mySink);
|
||||
}
|
||||
</pre>
|
||||
<DT><A NAME="gdImageWBMP">
|
||||
void gdImageWBMP(gdImagePtr im, int fg, FILE *out)</A>
|
||||
<BR><A NAME="gdImageWBMPCtx">gdImageWBMPCtx(<a href=#gdioctx>gdIOCtx</a> *out)</A>
|
||||
<strong>(FUNCTION)</strong><STRONG>(FUNCTION)</STRONG>
|
||||
<DD>
|
||||
gdImageWBMP outputs the specified image to the specified
|
||||
file in WBMP format. The file must be open for writing. Under MSDOS
|
||||
and all versions of Windows, it is important to use "wb" as opposed
|
||||
to simply "w" as the mode when opening the file, and under Unix there
|
||||
is no penalty for doing so. gdImageWBMP does <em>not</em>
|
||||
close the file; your code must do so.
|
||||
<p>
|
||||
<strong>WBMP file support is black and white only. The color index
|
||||
specified by the fg argument is the "foreground," and only pixels
|
||||
of this color will be set in the WBMP file.</strong> All other pixels
|
||||
will be considered "background."
|
||||
<PRE>
|
||||
... inside a function ...
|
||||
<A HREF="#gdImagePtr">gdImagePtr</A> im;
|
||||
int black, white;
|
||||
FILE *out;
|
||||
/* Create the image */
|
||||
im = <A HREF="#gdImageCreate">gdImageCreate</A>(100, 100);
|
||||
/* Allocate background */
|
||||
white = <A HREF="#gdImageColorAllocate">gdImageColorAllocate</A>(im, 255, 255, 255);
|
||||
/* Allocate drawing color */
|
||||
black = <A HREF="#gdImageColorAllocate">gdImageColorAllocate</A>(im, 0, 0, 0);
|
||||
/* Draw rectangle */
|
||||
<A HREF="#gdImageRectangle">gdImageRectangle</A>(im, 0, 0, 99, 99, black);
|
||||
/* Open output file in binary mode */
|
||||
out = fopen("rect.wbmp", "wb");
|
||||
/* Write WBMP, with black as foreground */
|
||||
gdImageWBMP(im, black, out);
|
||||
/* Close file */
|
||||
fclose(out);
|
||||
/* Destroy image */
|
||||
<A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
|
||||
</PRE>
|
||||
<DT><A NAME="gdImageWBMPPtr">
|
||||
void* gdImageWBMPPtr(gdImagePtr im, int *size)</A>
|
||||
<STRONG>(FUNCTION)</STRONG>
|
||||
<DD>Identical to gdImageWBMP except that it returns a pointer to a memory
|
||||
area with the WBMP data. This memory must be freed by the caller when it is
|
||||
no longer needed. The 'size' parameter receives the total size of the block
|
||||
of memory.
|
||||
<DT><A NAME="gdImageGd">
|
||||
void gdImageGd(gdImagePtr im, FILE *out)</A>
|
||||
<STRONG>(FUNCTION)</STRONG>
|
||||
|
@ -1010,7 +1185,7 @@ void* gdImageGdPtr(gdImagePtr im, int *size)</A>
|
|||
<STRONG>(FUNCTION)</STRONG>
|
||||
<DD>Identical to gdImageGd except that it returns a pointer to a memory
|
||||
area with the GD data. This memory must be freed by the caller when it is
|
||||
no longer needed. The 'size' parameter received the total size of the block
|
||||
no longer needed. The 'size' parameter receives the total size of the block
|
||||
of memory.
|
||||
|
||||
<DT><A NAME="gdImageGd2">
|
||||
|
@ -1067,7 +1242,7 @@ void* gdImageGd2Ptr(gdImagePtr im, int chunkSize, int fmt, int *size)</A>
|
|||
<STRONG>(FUNCTION)</STRONG>
|
||||
<DD>Identical to gdImageGd2 except that it returns a pointer to a memory
|
||||
area with the GD2 data. This memory must be freed by the caller when it is
|
||||
no longer needed. The 'size' parameter received the total size of the block
|
||||
no longer needed. The 'size' parameter receives the total size of the block
|
||||
of memory.
|
||||
|
||||
</DL>
|
||||
|
@ -1975,8 +2150,9 @@ return -1 to indicate failure. (This is not uncommon when
|
|||
working with existing PNG files that already use 256 colors.)
|
||||
Note that gdImageColorAllocate
|
||||
does not check for existing colors that match your request;
|
||||
see <A HREF="#gdImageColorExact">gdImageColorExact</A>
|
||||
and <A HREF="#gdImageColorClosest">gdImageColorClosest</A>
|
||||
see <A HREF="#gdImageColorExact">gdImageColorExact</A>,
|
||||
<A HREF="#gdImageColorClosest">gdImageColorClosest</A> and
|
||||
<A HREF="#gdImageColorClosest">gdImageColorClosestHWB</A>
|
||||
for ways to locate existing colors that approximate the
|
||||
color desired in situations where a new color is not available.
|
||||
Also see <A HREF="#gdImageColorResolve">gdImageColorResolve</A>,
|
||||
|
@ -2041,7 +2217,50 @@ gdImageDashedLine(im, 0, 0, 99, 99, red);
|
|||
/* Destroy it */
|
||||
<A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
|
||||
</PRE>
|
||||
<DT><A NAME="gdImageColorExact">
|
||||
<DT><A NAME="gdImageColorClosestHWB">
|
||||
int gdImageColorClosestHWB(gdImagePtr im, int r, int g, int b)</A>
|
||||
<STRONG>(FUNCTION)</STRONG>
|
||||
<DD>
|
||||
gdImageColorClosestHWB searches the colors which have been
|
||||
defined thus far in the image specified and returns the
|
||||
index of the color with hue, whiteness and blackness closest to the
|
||||
requested color. This scheme is typically superior to the
|
||||
Euclidian distance scheme used by
|
||||
<a href="#gdImageColorClosest">gdImageColorClosest</a>.
|
||||
<P>
|
||||
If no colors have yet been allocated in the image,
|
||||
gdImageColorClosestHWB returns -1.
|
||||
<P>
|
||||
This function is most useful as a backup method for choosing
|
||||
a drawing color when an image already contains
|
||||
<A HREF="#gdMaxColors">gdMaxColors</A> (256) colors and
|
||||
no more can be allocated. (This is not uncommon when
|
||||
working with existing PNG files that already use many colors.)
|
||||
See <A HREF="#gdImageColorExact">gdImageColorExact</A>
|
||||
for a method of locating exact matches only.
|
||||
<PRE>
|
||||
... inside a function ...
|
||||
<A HREF="#gdImagePtr">gdImagePtr</A> im;
|
||||
FILE *in;
|
||||
int red;
|
||||
/* Let's suppose that photo.png is a scanned photograph with
|
||||
many colors. */
|
||||
in = fopen("photo.png", "rb");
|
||||
im = <A HREF="#gdImageCreateFromPng">gdImageCreateFromPng</A>(in);
|
||||
fclose(in);
|
||||
/* Try to allocate red directly */
|
||||
red = <A HREF="#gdImageColorAllocate">gdImageColorAllocate</A>(im, 255, 0, 0);
|
||||
/* If we fail to allocate red... */
|
||||
if (red == (-1)) {
|
||||
/* Find the <em>closest</em> color instead. */
|
||||
red = gdImageColorClosestHWB(im, 255, 0, 0);
|
||||
}
|
||||
/* 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 */
|
||||
<A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
|
||||
</PRE><DT><A NAME="gdImageColorExact">
|
||||
int gdImageColorExact(gdImagePtr im, int r, int g, int b)</A>
|
||||
<STRONG>(FUNCTION)</STRONG>
|
||||
<DD>
|
||||
|
@ -2145,7 +2364,7 @@ gdImageGetInterlaced is a macro which returns true (1)
|
|||
if the image is interlaced, false (0) if not.
|
||||
Use this macro to obtain this information; do not
|
||||
access the structure directly.
|
||||
See <A NAME="gdImageInterlace">gdImageInterlace</A> for
|
||||
See <A HREF="#gdImageInterlace">gdImageInterlace</A> for
|
||||
a means of interlacing images.
|
||||
<DT><A NAME="gdImageGetTransparent">
|
||||
int gdImageGetTransparent(gdImagePtr im)</A>
|
||||
|
@ -2199,7 +2418,9 @@ void gdImageColorTransparent(gdImagePtr im, int color)</A>
|
|||
gdImageColorTransparent sets the transparent color index
|
||||
for the specified image to the specified index. To indicate
|
||||
that there should be <em>no</em> transparent color, invoke
|
||||
gdImageColorTransparent with a color index of -1.
|
||||
gdImageColorTransparent with a color index of -1. Note that
|
||||
JPEG images do not support transparency, so this setting has no effect
|
||||
when writing JPEG images.
|
||||
<P>
|
||||
The color index used should be an index
|
||||
allocated by <A HREF="#gdImageColorAllocate">gdImageColorAllocate</A>,
|
||||
|
@ -2207,10 +2428,11 @@ whether explicitly invoked by your code or implicitly
|
|||
invoked by loading an image.
|
||||
In order to ensure that your image has a reasonable appearance
|
||||
when viewed by users who do not have transparent background
|
||||
capabilities, be sure to give reasonable RGB values to the
|
||||
capabilities (or when you are writing a JPEG-format file, which does
|
||||
not support transparency), be sure to give reasonable RGB values to the
|
||||
color you allocate for use as a transparent color,
|
||||
<em>even though it will be transparent on systems
|
||||
that support transparency</em>.
|
||||
that support PNG transparency</em>.
|
||||
<PRE>
|
||||
... inside a function ...
|
||||
<A HREF="#gdImagePtr">gdImagePtr</A> im;
|
||||
|
@ -2400,7 +2622,7 @@ gdImageCopyMergeGray(im_out, im_in, 100, 200, 0, 0, 30, 50, 50);
|
|||
<DT><A NAME="gdImagePaletteCopy">void gdImagePaletteCopy(gdImagePtr dst, gdImagePtr src)
|
||||
<STRONG> (FUNCTION)</STRONG>
|
||||
<DD>
|
||||
Copies a palette from one image to another, doing it's best to match the colors in the target image
|
||||
Copies a palette from one image to another, attempting to match the colors in the target image
|
||||
to the colors
|
||||
in the source palette.
|
||||
</DL>
|
||||
|
@ -2426,20 +2648,27 @@ gdImageInterlace is used to determine whether an image should be stored
|
|||
in a linear fashion, in which lines will appear on the display from
|
||||
first to last, or in an interlaced fashion, in which the image
|
||||
will "fade in" over several passes. By default, images are not
|
||||
interlaced.
|
||||
interlaced. (When writing JPEG images, interlacing implies generating
|
||||
progressive JPEG files, which are represented as a series of scans of
|
||||
increasing quality. Noninterlaced gd images result in regular
|
||||
[sequential] JPEG data streams.)
|
||||
<P>
|
||||
A nonzero value for the interlace argument turns on interlace;
|
||||
a zero value turns it off. Note that interlace has no effect
|
||||
on other functions, and has no meaning unless you save the
|
||||
image in PNG format; the gd and xbm formats do not support
|
||||
image in PNG or JPEG format; the gd and xbm formats do not support
|
||||
interlace.
|
||||
<P>
|
||||
When a PNG is loaded with <A HREF="#gdImageCreateFromPng">gdImageCreateFromPng
|
||||
</A>, interlace will be set according to the setting in the PNG file.
|
||||
When a PNG is loaded with
|
||||
<A HREF="#gdImageCreateFromPng">gdImageCreateFromPng</A> or a JPEG is
|
||||
loaded with
|
||||
<A HREF="#gdImageCreateFromJpeg">gdImageCreateFromJpeg</A>, interlace
|
||||
will be set according to the setting in the PNG or JPEG file.
|
||||
<P>
|
||||
Note that many PNG viewers and web browsers do <em>not</em> support
|
||||
interlace. However, the interlaced PNG should still display; it
|
||||
will simply appear all at once, just as other images do.
|
||||
Note that many PNG and JPEG viewers and web browsers do <em>not</em>
|
||||
support interlace or the incremental display of progressive
|
||||
JPEGs. However, the interlaced PNG or progressive JPEG should still
|
||||
display; it will simply appear all at once, just as other images do.
|
||||
<PRE>
|
||||
gdImagePtr im;
|
||||
FILE *out;
|
||||
|
@ -2449,7 +2678,7 @@ FILE *out;
|
|||
gdImageInterlace(im, 1);
|
||||
/* And open an output file */
|
||||
out = fopen("test.png", "wb");
|
||||
/* And save the image */
|
||||
/* And save the image -- could also use <A HREF="#gdImageJpeg">gdImageJpeg</A> */
|
||||
<A HREF="#gdImagePng">gdImagePng</A>(im, out);
|
||||
fclose(out);
|
||||
<A HREF="#gdImageDestroy">gdImageDestroy</A>(im);
|
||||
|
@ -2539,7 +2768,7 @@ see <A HREF="gdImageColorTransparent">gdImageColorTransparent</A>.
|
|||
</DL>
|
||||
|
||||
<A NAME="gdformat"><H3>About the additional .gd image file format</H3></A>
|
||||
In addition to reading and writing the PNG format and reading the
|
||||
In addition to reading and writing the PNG and JPEG formats and reading the
|
||||
X Bitmap format, gd has the capability to read and write its
|
||||
own ".gd" format. This format is <em>not</em> intended for
|
||||
general purpose use and should never be used to distribute
|
||||
|
@ -2567,7 +2796,7 @@ images. It is a compressed format allowing pseudo-random access
|
|||
to large image files. Its purpose is solely to
|
||||
allow very fast loading of <strong>parts</strong> of images
|
||||
If you are experiencing
|
||||
performance problems when loading large, fixed PNG images your
|
||||
performance problems when loading large, fixed PNG or JPEG images your
|
||||
program needs to produce its output images, you may wish
|
||||
to examine the functions <A HREF="#gdImageCreateFromGd2">
|
||||
gdImageCreateFromGd2</A>, <A HREF="#gdImageCreateFromGd2Part">
|
||||
|
@ -2660,6 +2889,7 @@ Be sure to read this manual carefully first.
|
|||
<A HREF="#gdImageCreateFromGd">gdImageCreateFromGd</A> |
|
||||
<A HREF="#gdImageCreateFromGd2">gdImageCreateFromGd2</A> |
|
||||
<A HREF="#gdImageCreateFromGd2Part">gdImageCreateFromGd2Part</A> |
|
||||
<A HREF="#gdImageCreateFromJpeg">gdImageCreateFromJpeg</A> |
|
||||
<A HREF="#gdImageCreateFromPng">gdImageCreateFromPng</A> |
|
||||
<A HREF="#gdImageCreateFromPngSource">gdImageCreateFromPngSource</A> |
|
||||
<A HREF="#gdImageCreateFromXbm">gdImageCreateFromXbm</A> |
|
||||
|
@ -2676,6 +2906,7 @@ Be sure to read this manual carefully first.
|
|||
<A HREF="#gdImageGetTransparent">gdImageGetTransparent</A> |
|
||||
<A HREF="#gdImageGreen">gdImageGreen</A> |
|
||||
<A HREF="#gdImageInterlace">gdImageInterlace</A> |
|
||||
<A HREF="#gdImageJpeg">gdImageJpeg</A> |
|
||||
<A HREF="#gdImageLine">gdImageLine</A> |
|
||||
<A HREF="#gdImageFilledPolygon">gdImageFilledPolygon</A> |
|
||||
<A HREF="#gdImagePaletteCopy">gdImagePaletteCopy</A> |
|
||||
|
@ -2683,6 +2914,7 @@ Be sure to read this manual carefully first.
|
|||
<A HREF="#gdImagePngToSink">gdImagePngToSink</A> |
|
||||
<A HREF="#gdImagePolygon">gdImagePolygon</A> |
|
||||
<A HREF="#gdImagePtr">gdImagePtr</A> |
|
||||
<A HREF="#gdImageWBMP">gdImageWBMP</A> |
|
||||
<A HREF="#gdImageRectangle">gdImageRectangle</A> |
|
||||
<A HREF="#gdImageRed">gdImageRed</A> |
|
||||
<A HREF="#gdImageSetBrush">gdImageSetBrush</A> |
|
||||
|
@ -2694,6 +2926,7 @@ Be sure to read this manual carefully first.
|
|||
<A HREF="#gdImageStringTTF">gdImageStringTTF</A> |
|
||||
<A HREF="#gdImageStringUp">gdImageStringUp</A> |
|
||||
<A HREF="#gdImageStringUp">gdImageStringUp16</A> |
|
||||
<A HREF="#gdImageWBMP">gdImageWBMP</A> |
|
||||
<A HREF="#gdMaxColors">gdMaxColors</A> |
|
||||
<A HREF="#gdPoint">gdPoint</A> |
|
||||
<A HREF="#gdStyled">gdStyled</A> |
|
||||
|
|
562
src/readme.txt
562
src/readme.txt
|
@ -1,23 +1,29 @@
|
|||
|
||||
gd 1.7.3
|
||||
gd 1.8
|
||||
|
||||
A graphics library for fast image creation
|
||||
|
||||
Follow this link to the latest version of this document.
|
||||
|
||||
_HEY! READ THIS!_ gd 1.7.3 creates PNG images, not GIF images. This
|
||||
is a good thing. PNG is a more compact format, and full compression
|
||||
is available. Existing code will need modification to call
|
||||
gdImagePng instead of gdImageGif. _Please do not ask us to send you
|
||||
the old GIF version of GD._ Unisys holds a patent on the LZW
|
||||
compression algorithm, which is used in fully compressed GIF
|
||||
images. We are still investigating the legal issues surrounding
|
||||
various alternative means of producing a valid GIF file.
|
||||
_HEY! READ THIS!_ gd 1.8 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
|
||||
than even PNG is. WBMP is intended for wireless devices (not
|
||||
regular web browsers). Existing code will need modification to call
|
||||
gdImagePng or gdImageJpeg instead of gdImageGif. _Please do not ask
|
||||
us to send you the old GIF version of GD._ Unisys holds a patent on
|
||||
the LZW compression algorithm, which is used in fully compressed
|
||||
GIF images. The best solution is to move to legally unencumbered,
|
||||
well-compressed, modern image formats such as PNG and JPEG as soon
|
||||
as possible.
|
||||
|
||||
gd 1.7.3 _requires_ that the following libraries also be installed:
|
||||
gd 1.8 _requires_ that the following libraries also be installed:
|
||||
|
||||
libpng
|
||||
|
||||
jpeg-6b or later
|
||||
|
||||
zlib
|
||||
|
||||
If you want to use the TrueType font support, you must also install
|
||||
|
@ -36,6 +42,7 @@ Follow this link to the latest version of this document.
|
|||
Table of Contents
|
||||
|
||||
* Credits and license terms
|
||||
* What's new in version 1.8?
|
||||
* What's new in version 1.7.3?
|
||||
* What's new in version 1.7.2?
|
||||
* What's new in version 1.7.1?
|
||||
|
@ -69,22 +76,29 @@ Follow this link to the latest version of this document.
|
|||
|
||||
COPYRIGHT STATEMENT FOLLOWS THIS LINE
|
||||
|
||||
Portions copyright 1994, 1995, 1996, 1997, 1998, 1999, by Cold
|
||||
Portions copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000 by Cold
|
||||
Spring Harbor Laboratory. Funded under Grant P41-RR02188 by the
|
||||
National Institutes of Health.
|
||||
|
||||
Portions copyright 1996, 1997, 1998, 1999, by Boutell.Com, Inc.
|
||||
Portions copyright 1996, 1997, 1998, 1999, 2000 by Boutell.Com,
|
||||
Inc.
|
||||
|
||||
Portions relating to GD2 format copyright 1999 Philip Warner.
|
||||
Portions relating to GD2 format copyright 1999, 2000 Philip Warner.
|
||||
|
||||
Portions relating to PNG copyright 1999, Greg Roelofs.
|
||||
Portions relating to PNG copyright 1999, 2000 Greg Roelofs.
|
||||
|
||||
Portions relating to libttf copyright 1999, John Ellson
|
||||
Portions relating to libttf copyright 1999, 2000 John Ellson
|
||||
(ellson@lucent.com).
|
||||
|
||||
_Permission has been granted to copy and distribute gd in any
|
||||
context without fee, including a commercial application, provided
|
||||
that this notice is present in user-accessible supporting
|
||||
Portions relating to JPEG copyright 2000, Doug Becker and copyright
|
||||
(C) 1994-1998, Thomas G. Lane. This software is based in part on
|
||||
the work of the Independent JPEG Group.
|
||||
|
||||
Portions relating to WBMP copyright 2000 Maurice Szmurlo.
|
||||
|
||||
_Permission has been granted to copy, distribute and modify gd in
|
||||
any context without fee, including a commercial application,
|
||||
provided that this notice is present in user-accessible supporting
|
||||
documentation._
|
||||
|
||||
This does not affect your ownership of the derived work itself, and
|
||||
|
@ -99,8 +113,8 @@ COPYRIGHT STATEMENT FOLLOWS THIS LINE
|
|||
particular purpose, with respect to this code and accompanying
|
||||
documentation.
|
||||
|
||||
Although their code does not appear in gd 1.7.3, the authors wish
|
||||
to thank David Koblas, David Rowley, and Hutchison Avenue Software
|
||||
Although their code does not appear in gd 1.8, the authors wish to
|
||||
thank David Koblas, David Rowley, and Hutchison Avenue Software
|
||||
Corporation for their prior contributions.
|
||||
|
||||
END OF COPYRIGHT STATEMENT
|
||||
|
@ -109,10 +123,10 @@ END OF COPYRIGHT STATEMENT
|
|||
|
||||
gd is a graphics library. It allows your code to quickly draw images
|
||||
complete with lines, arcs, text, multiple colors, cut and paste from
|
||||
other images, and flood fills, and write out the result as a .PNG
|
||||
file. This is particularly useful in World Wide Web applications,
|
||||
where .PNG is one of the formats accepted for inline images by most
|
||||
browsers.
|
||||
other images, and flood fills, and write out the result as a PNG or
|
||||
JPEG file. This is particularly useful in World Wide Web applications,
|
||||
where PNG and JPEG are two of the formats accepted for inline images
|
||||
by most browsers.
|
||||
|
||||
gd is not a paint program. If you are looking for a paint program, you
|
||||
are looking in the wrong place. If you are not a programmer, you are
|
||||
|
@ -122,7 +136,7 @@ END OF COPYRIGHT STATEMENT
|
|||
It is not necessary or desirable for gd to become a kitchen-sink
|
||||
graphics package, but version 1.7.3 incorporates most of the commonly
|
||||
requested features for an 8-bit 2D package. Support for truecolor
|
||||
images, JPEG and truecolor PNG is planned for version 2.0.
|
||||
images, including truecolor JPEG and PNG, is planned for version 2.0.
|
||||
|
||||
What if I want to use another programming language?
|
||||
|
||||
|
@ -138,6 +152,10 @@ END OF COPYRIGHT STATEMENT
|
|||
extension package. (Gdtclft2.0 or later is needed for gd-1.6 and up
|
||||
with PNG output.)
|
||||
|
||||
Pascal
|
||||
|
||||
Pascal enthusiasts should look into Michael Bradbury's gdfp package.
|
||||
|
||||
Any Language
|
||||
|
||||
There are, at the moment, at least three simple interpreters that
|
||||
|
@ -150,6 +168,25 @@ END OF COPYRIGHT STATEMENT
|
|||
* tgd, by Bradley K. Sherman
|
||||
* fly, by Martin Gleeson
|
||||
|
||||
What's new in version 1.8?
|
||||
|
||||
* Support for JPEG output, courtesy of Doug Becker
|
||||
* A link to Michael Bradbery's Pascal wrapper
|
||||
* Support for WBMP output, courtesy of Maurice Szmurlo
|
||||
* gdImageColorClosestHWB function based on hue, whiteness,
|
||||
blackness, superior to the regular gdImageColorClosest function,
|
||||
courtesy of Philip Warner
|
||||
* License clarification: yes, you can modify gd
|
||||
|
||||
Additional JPEG Information
|
||||
|
||||
Support for reading and writing JPEG-format images is courtesy of Doug
|
||||
Becker and the Independent JPEG Group / Thomas G. Lane. You can get
|
||||
the latest version of the IJG JPEG software from
|
||||
ftp://ftp.uu.net/graphics/jpeg/ (e.g., the jpegsrc.v6b.tar.gz file).
|
||||
You _must_ use version 6b or later of the IJG JPEG software. You might
|
||||
also consult the JPEG FAQ at http://www.faqs.org/faqs/jpeg-faq/.
|
||||
|
||||
What's new in version 1.7.3?
|
||||
|
||||
Another attempt at Makefile fixes to permit linking with all libraries
|
||||
|
@ -295,8 +332,8 @@ END OF COPYRIGHT STATEMENT
|
|||
of an image)
|
||||
gdImageCopyMergeGray - Similar to gdImageCopyMerge, but tries
|
||||
to preserve source image hue.
|
||||
gdImagePngPtr, gdImageGdPtr, gdImageGd2Ptr - return memort
|
||||
blocks for each type of image.
|
||||
gdImagePngPtr, gdImageJpegPtr, gdImageWBMPPtr, gdImageGdPtr,
|
||||
gdImageGd2Ptr - return memort blocks for each type of image.
|
||||
gdImageCreateFromPngCtx, gdImageCreateFromGdCtx,
|
||||
gdImageCreateFromGd2Ctx, gdImageCreateFromGd2PartCtx - Support
|
||||
for new I/O context.
|
||||
|
@ -420,11 +457,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-1.7.3".
|
||||
Unpacking the archive will produce a directory called "gd-1.8".
|
||||
|
||||
For Unix
|
||||
|
||||
cd to the 1.7.3 directory. Edit the Makefile with your preferred text
|
||||
cd to the 1.8 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". If
|
||||
you are the system administrator, and you wish to make the gd library
|
||||
|
@ -433,6 +470,10 @@ END OF COPYRIGHT STATEMENT
|
|||
If you get errors, edit the Makefile again, paying special attention
|
||||
to the INCLUDEDIRS and LIBDIRS settings.
|
||||
|
||||
IF YOU GET LINKER ERRORS, TRY JUGGLING THE ORDER OF THE -l DIRECTIVES
|
||||
IN THE MAKEFILE. Some platforms may prefer that the libraries be
|
||||
listed in the opposite order.
|
||||
|
||||
For Windows, Mac, Et Cetera
|
||||
|
||||
Create a project using your favorite programming environment. Copy all
|
||||
|
@ -460,10 +501,10 @@ END OF COPYRIGHT STATEMENT
|
|||
|
||||
gd basics: using gd in your program
|
||||
|
||||
gd lets you create PNG images on the fly. To use gd in your program,
|
||||
include the file gd.h, and link with the libgd.a library produced by
|
||||
"make libgd.a", under Unix. Under other operating systems you will add
|
||||
gd.c to your own project.
|
||||
gd lets you create PNG or JPEG images on the fly. To use gd in your
|
||||
program, include the file gd.h, and link with the libgd.a library
|
||||
produced by "make libgd.a", under Unix. Under other operating systems
|
||||
you will add gd.c to your own project.
|
||||
|
||||
If you want to use the provided fonts, include gdfontt.h, gdfonts.h,
|
||||
gdfontmb.h, gdfontl.h and/or gdfontg.h. For more impressive results,
|
||||
|
@ -486,8 +527,8 @@ END OF COPYRIGHT STATEMENT
|
|||
int main() {
|
||||
/* Declare the image */
|
||||
gdImagePtr im;
|
||||
/* Declare an output file */
|
||||
FILE *out;
|
||||
/* Declare output files */
|
||||
FILE *pngout, *jpegout;
|
||||
/* Declare color indexes */
|
||||
int black;
|
||||
int white;
|
||||
|
@ -509,13 +550,21 @@ int main() {
|
|||
|
||||
/* Open a file for writing. "wb" means "write binary", important
|
||||
under MSDOS, harmless under Unix. */
|
||||
out = fopen("test.png", "wb");
|
||||
pngout = fopen("test.png", "wb");
|
||||
|
||||
/* Output the image to the disk file. */
|
||||
gdImagePng(im, out);
|
||||
/* Do the same for a JPEG-format file. */
|
||||
jpegout = fopen("test.jpg", "wb");
|
||||
|
||||
/* Close the file. */
|
||||
fclose(out);
|
||||
/* Output the image to the disk file in PNG format. */
|
||||
gdImagePng(im, pngout);
|
||||
|
||||
/* Output the same image in JPEG format, using the default
|
||||
JPEG quality setting. */
|
||||
gdImageJpeg(im, jpegout, -1);
|
||||
|
||||
/* Close the files. */
|
||||
fclose(pngout);
|
||||
fclose(jpegout);
|
||||
|
||||
/* Destroy the image in memory. */
|
||||
gdImageDestroy(im);
|
||||
|
@ -524,7 +573,7 @@ int main() {
|
|||
When executed, this program creates an image, allocates two colors
|
||||
(the first color allocated becomes the background color), draws a
|
||||
diagonal line (note that 0, 0 is the upper left corner), writes the
|
||||
image to a PNG file, and destroys the image.
|
||||
image to PNG and JPEG files, and destroys the image.
|
||||
|
||||
The above example program should give you an idea of how the package
|
||||
works. gd provides many additional functions, which are listed in the
|
||||
|
@ -671,6 +720,30 @@ typedef struct {
|
|||
gdImagePtr im;
|
||||
im = gdImageCreate(64, 64);
|
||||
/* ... Use the image ... */
|
||||
gdImageDestroy(im);
|
||||
|
||||
gdImageCreateFromJpeg(FILE *in) _(FUNCTION)_
|
||||
gdImageCreateFromJpegCtx(FILE *in) _(FUNCTION)_
|
||||
|
||||
|
||||
gdImageCreateFromJpeg is called to load images from JPEG format
|
||||
files. Invoke gdImageCreateFromJpeg with an already opened
|
||||
pointer to a file containing the desired image.
|
||||
gdImageCreateFromJpeg returns a gdImagePtr to the new image, or
|
||||
NULL if unable to load the image (most often because the file
|
||||
is corrupt or does not contain a JPEG image).
|
||||
gdImageCreateFromPng does _not_ close the file. You can inspect
|
||||
the sx and sy members of the image to determine its size. The
|
||||
image must eventually be destroyed using gdImageDestroy().
|
||||
|
||||
|
||||
gdImagePtr im;
|
||||
... inside a function ...
|
||||
FILE *in;
|
||||
in = fopen("myjpeg.jpg", "rb");
|
||||
im = gdImageCreateFromJpeg(in);
|
||||
fclose(in);
|
||||
/* ... Use the image ... */
|
||||
gdImageDestroy(im);
|
||||
|
||||
gdImageCreateFromPng(FILE *in) _(FUNCTION)_
|
||||
|
@ -742,13 +815,13 @@ static int freadWrapper(void *context, char *buf, int len)
|
|||
pointer to a file containing the desired image in the gd file
|
||||
format, which is specific to gd and intended for very fast
|
||||
loading. (It is _not_ intended for compression; for
|
||||
compression, use PNG.) gdImageCreateFromGd returns a gdImagePtr
|
||||
to the new image, or NULL if unable to load the image (most
|
||||
often because the file is corrupt or does not contain a gd
|
||||
format image). gdImageCreateFromGd does _not_ close the file.
|
||||
You can inspect the sx and sy members of the image to determine
|
||||
its size. The image must eventually be destroyed using
|
||||
gdImageDestroy().
|
||||
compression, use PNG or JPEG.) gdImageCreateFromGd returns a
|
||||
gdImagePtr to the new image, or NULL if unable to load the
|
||||
image (most often because the file is corrupt or does not
|
||||
contain a gd format image). gdImageCreateFromGd does _not_
|
||||
close the file. You can inspect the sx and sy members of the
|
||||
image to determine its size. The image must eventually be
|
||||
destroyed using gdImageDestroy().
|
||||
|
||||
|
||||
... inside a function ...
|
||||
|
@ -858,14 +931,65 @@ im = gdImageCreate(10, 10);
|
|||
/* Now destroy it */
|
||||
gdImageDestroy(im);
|
||||
|
||||
void gdImagePng(gdImagePtr im, FILE *out) _(FUNCTION)_
|
||||
gdImagePng outputs the specified image to the specified file in
|
||||
PNG format. The file must be open for writing. Under MSDOS and
|
||||
all versions of Windows, it is important to use "wb" as opposed
|
||||
to simply "w" as the mode when opening the file, and under Unix
|
||||
there is no penalty for doing so. gdImagePng does _not_ close
|
||||
the file; your code must do so.
|
||||
void gdImageJpeg(gdImagePtr im, FILE *out, int quality) _(FUNCTION)_
|
||||
void gdImageJpegCtx(gdImagePtr im, gdIOCtx *out, int quality)
|
||||
|
||||
_(FUNCTION)_
|
||||
|
||||
gdImageJpeg outputs the specified image to the specified file in JPEG
|
||||
format. The file must be open for writing. Under MSDOS and all
|
||||
versions of Windows, it is important to use "wb" as opposed to simply
|
||||
"w" as the mode when opening the file, and under Unix there is no
|
||||
penalty for doing so. gdImageJpeg does _not_ close the file; your code
|
||||
must do so.
|
||||
|
||||
If quality is negative, the default IJG JPEG quality value (which
|
||||
should yield a good general quality / size tradeoff for most
|
||||
situations) is used. Otherwise, for practical purposes, quality should
|
||||
be a value in the range 0-95, higher quality values usually implying
|
||||
both higher quality and larger image sizes.
|
||||
|
||||
If you have set image interlacing using gdImageInterlace, this
|
||||
function will interpret that to mean you wish to output a progressive
|
||||
JPEG. Some programs (e.g., Web browsers) can display progressive JPEGs
|
||||
incrementally; this can be useful when browsing over a relatively slow
|
||||
communications link, for example. Progressive JPEGs can also be
|
||||
slightly smaller than sequential (non-progressive) JPEGs.
|
||||
|
||||
... inside a function ...
|
||||
gdImagePtr im;
|
||||
int black, white;
|
||||
FILE *out;
|
||||
/* Create the image */
|
||||
im = gdImageCreate(100, 100);
|
||||
/* Allocate background */
|
||||
white = gdImageColorAllocate(im, 255, 255, 255);
|
||||
/* Allocate drawing color */
|
||||
black = gdImageColorAllocate(im, 0, 0, 0);
|
||||
/* Draw rectangle */
|
||||
gdImageRectangle(im, 0, 0, 99, 99, black);
|
||||
/* Open output file in binary mode */
|
||||
out = fopen("rect.jpg", "wb");
|
||||
/* Write JPEG using default quality */
|
||||
gdImageJpeg(im, out, -1);
|
||||
/* Close file */
|
||||
fclose(out);
|
||||
/* Destroy image */
|
||||
gdImageDestroy(im);
|
||||
|
||||
void* gdImageJpegPtr(gdImagePtr im, int *size) _(FUNCTION)_
|
||||
Identical to gdImageJpeg except that it returns a pointer to a memory
|
||||
area with the JPEG data. This memory must be freed by the caller when
|
||||
it is no longer needed. The 'size' parameter receives the total size
|
||||
of the block of memory.
|
||||
|
||||
void gdImagePng(gdImagePtr im, FILE *out) _(FUNCTION)_
|
||||
gdImagePng outputs the specified image to the specified file in PNG
|
||||
format. The file must be open for writing. Under MSDOS and all
|
||||
versions of Windows, it is important to use "wb" as opposed to simply
|
||||
"w" as the mode when opening the file, and under Unix there is no
|
||||
penalty for doing so. gdImagePng does _not_ close the file; your code
|
||||
must do so.
|
||||
|
||||
... inside a function ...
|
||||
gdImagePtr im;
|
||||
|
@ -889,29 +1013,27 @@ fclose(out);
|
|||
gdImageDestroy(im);
|
||||
|
||||
void* gdImagePngPtr(gdImagePtr im, int *size) _(FUNCTION)_
|
||||
Identical to gdImagePng except that it returns a pointer to a
|
||||
memory area with the PNG data. This memory must be freed by the
|
||||
caller when it is no longer needed. The 'size' parameter
|
||||
received the total size of the block of memory.
|
||||
|
||||
Identical to gdImagePng except that it returns a pointer to a memory
|
||||
area with the PNG data. This memory must be freed by the caller when
|
||||
it is no longer needed. The 'size' parameter receives the total size
|
||||
of the block of memory.
|
||||
|
||||
gdImagePngToSink(gdImagePtr im, gdSinkPtr out) _(FUNCTION)_
|
||||
gdImagePngToSink is called to write a PNG to a data "sink"
|
||||
(destination) other than a file. Usage is very similar to the
|
||||
gdImagePng function, except that the programmer provides a
|
||||
custom data sink.
|
||||
|
||||
The programmer must write an output function which accepts a
|
||||
context pointer, a buffer, and a number of bytes to be written
|
||||
as arguments. This function must write the number of bytes
|
||||
requested and return that number, unless an error has occurred,
|
||||
in which case the function should return -1. The programmer
|
||||
then creates a gdSink structure and sets the sink pointer to
|
||||
the output function and the context pointer to any value which
|
||||
is useful to the programmer.
|
||||
|
||||
The example below implements gdImagePng by creating a custom
|
||||
data source and invoking gdImagePngFromSink.
|
||||
|
||||
gdImagePngToSink is called to write a PNG to a data "sink"
|
||||
(destination) other than a file. Usage is very similar to the
|
||||
gdImagePng function, except that the programmer provides a custom data
|
||||
sink.
|
||||
|
||||
The programmer must write an output function which accepts a context
|
||||
pointer, a buffer, and a number of bytes to be written as arguments.
|
||||
This function must write the number of bytes requested and return that
|
||||
number, unless an error has occurred, in which case the function
|
||||
should return -1. The programmer then creates a gdSink structure and
|
||||
sets the sink pointer to the output function and the context pointer
|
||||
to any value which is useful to the programmer.
|
||||
|
||||
The example below implements gdImagePng by creating a custom data
|
||||
source and invoking gdImagePngFromSink.
|
||||
|
||||
static int stdioSink(void *context, char *buffer, int len)
|
||||
{
|
||||
|
@ -926,19 +1048,58 @@ void gdImagePng(gdImagePtr im, FILE *out)
|
|||
gdImagePngToSink(im, &mySink);
|
||||
}
|
||||
|
||||
void gdImageWBMP(gdImagePtr im, int fg, FILE *out)
|
||||
gdImageWBMPCtx(gdIOCtx *out) _(FUNCTION)__(FUNCTION)_
|
||||
gdImageWBMP outputs the specified image to the specified file in WBMP
|
||||
format. The file must be open for writing. Under MSDOS and all
|
||||
versions of Windows, it is important to use "wb" as opposed to simply
|
||||
"w" as the mode when opening the file, and under Unix there is no
|
||||
penalty for doing so. gdImageWBMP does _not_ close the file; your code
|
||||
must do so.
|
||||
|
||||
_WBMP file support is black and white only. The color index specified
|
||||
by the fg argument is the "foreground," and only pixels of this color
|
||||
will be set in the WBMP file._ All other pixels will be considered
|
||||
"background."
|
||||
|
||||
... inside a function ...
|
||||
gdImagePtr im;
|
||||
int black, white;
|
||||
FILE *out;
|
||||
/* Create the image */
|
||||
im = gdImageCreate(100, 100);
|
||||
/* Allocate background */
|
||||
white = gdImageColorAllocate(im, 255, 255, 255);
|
||||
/* Allocate drawing color */
|
||||
black = gdImageColorAllocate(im, 0, 0, 0);
|
||||
/* Draw rectangle */
|
||||
gdImageRectangle(im, 0, 0, 99, 99, black);
|
||||
/* Open output file in binary mode */
|
||||
out = fopen("rect.wbmp", "wb");
|
||||
/* Write WBMP, with black as foreground */
|
||||
gdImageWBMP(im, black, out);
|
||||
/* Close file */
|
||||
fclose(out);
|
||||
/* Destroy image */
|
||||
gdImageDestroy(im);
|
||||
|
||||
void* gdImageWBMPPtr(gdImagePtr im, int *size) _(FUNCTION)_
|
||||
Identical to gdImageWBMP except that it returns a pointer to a memory
|
||||
area with the WBMP data. This memory must be freed by the caller when
|
||||
it is no longer needed. The 'size' parameter receives the total size
|
||||
of the block of memory.
|
||||
|
||||
void gdImageGd(gdImagePtr im, FILE *out) _(FUNCTION)_
|
||||
gdImageGd outputs the specified image to the specified file in
|
||||
the gd image format. The file must be open for writing. Under
|
||||
MSDOS and all versions of Windows, it is important to use "wb"
|
||||
as opposed to simply "w" as the mode when opening the file, and
|
||||
under Unix there is no penalty for doing so. gdImagePng does
|
||||
_not_ close the file; your code must do so.
|
||||
|
||||
The gd image format is intended for fast reads and writes of
|
||||
images your program will need frequently to build other images.
|
||||
It is _not_ a compressed format, and is not intended for
|
||||
general use.
|
||||
|
||||
gdImageGd outputs the specified image to the specified file in the gd
|
||||
image format. The file must be open for writing. Under MSDOS and all
|
||||
versions of Windows, it is important to use "wb" as opposed to simply
|
||||
"w" as the mode when opening the file, and under Unix there is no
|
||||
penalty for doing so. gdImagePng does _not_ close the file; your code
|
||||
must do so.
|
||||
|
||||
The gd image format is intended for fast reads and writes of images
|
||||
your program will need frequently to build other images. It is _not_ a
|
||||
compressed format, and is not intended for general use.
|
||||
|
||||
... inside a function ...
|
||||
gdImagePtr im;
|
||||
|
@ -962,34 +1123,31 @@ fclose(out);
|
|||
gdImageDestroy(im);
|
||||
|
||||
void* gdImageGdPtr(gdImagePtr im, int *size) _(FUNCTION)_
|
||||
Identical to gdImageGd except that it returns a pointer to a
|
||||
memory area with the GD data. This memory must be freed by the
|
||||
caller when it is no longer needed. The 'size' parameter
|
||||
received the total size of the block of memory.
|
||||
|
||||
Identical to gdImageGd except that it returns a pointer to a memory
|
||||
area with the GD data. This memory must be freed by the caller when it
|
||||
is no longer needed. The 'size' parameter receives the total size of
|
||||
the block of memory.
|
||||
|
||||
void gdImageGd2(gdImagePtr im, FILE *out, int chunkSize, int fmt)
|
||||
_(FUNCTION)_
|
||||
gdImageGd2 outputs the specified image to the specified file in
|
||||
the gd2 image format. The file must be open for writing. Under
|
||||
MSDOS and all versions of Windows, it is important to use "wb"
|
||||
as opposed to simply "w" as the mode when opening the file, and
|
||||
under Unix there is no penalty for doing so. gdImageGd2 does
|
||||
_not_ close the file; your code must do so.
|
||||
|
||||
The gd2 image format is intended for fast reads and writes of
|
||||
parts of images. It is a compressed format, and well suited to
|
||||
retrieving smll sections of much larger images. The third and
|
||||
fourth parameters are the 'chunk size' and format
|
||||
resposectively.
|
||||
|
||||
The file is stored as a series of compressed subimages, and the
|
||||
_Chunk Size_ determines the sub-image size - a value of zero
|
||||
causes the GD library to use the default.
|
||||
|
||||
It is also possible to store GD2 files in an uncompressed
|
||||
format, in which case the fourth parameter should be
|
||||
GD2_FMT_RAW.
|
||||
|
||||
_(FUNCTION)_
|
||||
gdImageGd2 outputs the specified image to the specified file in the
|
||||
gd2 image format. The file must be open for writing. Under MSDOS and
|
||||
all versions of Windows, it is important to use "wb" as opposed to
|
||||
simply "w" as the mode when opening the file, and under Unix there is
|
||||
no penalty for doing so. gdImageGd2 does _not_ close the file; your
|
||||
code must do so.
|
||||
|
||||
The gd2 image format is intended for fast reads and writes of parts of
|
||||
images. It is a compressed format, and well suited to retrieving smll
|
||||
sections of much larger images. The third and fourth parameters are
|
||||
the 'chunk size' and format resposectively.
|
||||
|
||||
The file is stored as a series of compressed subimages, and the _Chunk
|
||||
Size_ determines the sub-image size - a value of zero causes the GD
|
||||
library to use the default.
|
||||
|
||||
It is also possible to store GD2 files in an uncompressed format, in
|
||||
which case the fourth parameter should be GD2_FMT_RAW.
|
||||
|
||||
... inside a function ...
|
||||
gdImagePtr im;
|
||||
|
@ -1013,12 +1171,12 @@ fclose(out);
|
|||
gdImageDestroy(im);
|
||||
|
||||
void* gdImageGd2Ptr(gdImagePtr im, int chunkSize, int fmt, int *size)
|
||||
_(FUNCTION)_
|
||||
Identical to gdImageGd2 except that it returns a pointer to a
|
||||
memory area with the GD2 data. This memory must be freed by the
|
||||
caller when it is no longer needed. The 'size' parameter
|
||||
received the total size of the block of memory.
|
||||
|
||||
_(FUNCTION)_
|
||||
Identical to gdImageGd2 except that it returns a pointer to a memory
|
||||
area with the GD2 data. This memory must be freed by the caller when
|
||||
it is no longer needed. The 'size' parameter receives the total size
|
||||
of the block of memory.
|
||||
|
||||
Drawing Functions
|
||||
|
||||
void gdImageSetPixel(gdImagePtr im, int x, int y, int color)
|
||||
|
@ -1865,10 +2023,11 @@ gdImageDestroy(im);
|
|||
working with existing PNG files that already use 256
|
||||
colors.) Note that gdImageColorAllocate does not check
|
||||
for existing colors that match your request; see
|
||||
gdImageColorExact and gdImageColorClosest for ways to
|
||||
locate existing colors that approximate the color desired
|
||||
in situations where a new color is not available. Also
|
||||
see gdImageColorResolve, new in gd-1.6.2.
|
||||
gdImageColorExact, gdImageColorClosest and
|
||||
gdImageColorClosestHWB for ways to locate existing colors
|
||||
that approximate the color desired in situations where a
|
||||
new color is not available. Also see gdImageColorResolve,
|
||||
new in gd-1.6.2.
|
||||
|
||||
|
||||
... inside a function ...
|
||||
|
@ -1927,6 +2086,49 @@ 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 gdImageColorClosestHWB(gdImagePtr im, int r, int g, int b)
|
||||
_(FUNCTION)_
|
||||
gdImageColorClosestHWB searches the colors which have
|
||||
been defined thus far in the image specified and returns
|
||||
the index of the color with hue, whiteness and blackness
|
||||
closest to the requested color. This scheme is typically
|
||||
superior to the Euclidian distance scheme used by
|
||||
gdImageColorClosest.
|
||||
|
||||
If no colors have yet been allocated in the image,
|
||||
gdImageColorClosestHWB returns -1.
|
||||
|
||||
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 be allocated.
|
||||
(This is not uncommon when working with existing PNG
|
||||
files that already use many colors.) See
|
||||
gdImageColorExact 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 directly */
|
||||
red = gdImageColorAllocate(im, 255, 0, 0);
|
||||
/* If we fail to allocate red... */
|
||||
if (red == (-1)) {
|
||||
/* Find the _closest_ color instead. */
|
||||
red = gdImageColorClosestHWB(im, 255, 0, 0);
|
||||
}
|
||||
/* 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 gdImageColorExact(gdImagePtr im, int r, int g, int b)
|
||||
|
@ -2070,16 +2272,20 @@ gdImageDestroy(im);
|
|||
for the specified image to the specified index. To
|
||||
indicate that there should be _no_ transparent color,
|
||||
invoke gdImageColorTransparent with a color index of -1.
|
||||
Note that JPEG images do not support transparency, so
|
||||
this setting has no effect when writing JPEG images.
|
||||
|
||||
The color index used should be an index allocated by
|
||||
gdImageColorAllocate, whether explicitly invoked by your
|
||||
code or implicitly invoked by loading an image. In order
|
||||
to ensure that your image has a reasonable appearance
|
||||
when viewed by users who do not have transparent
|
||||
background capabilities, be sure to give reasonable RGB
|
||||
values to the color you allocate for use as a transparent
|
||||
color, _even though it will be transparent on systems
|
||||
that support transparency_.
|
||||
background capabilities (or when you are writing a
|
||||
JPEG-format file, which does not support transparency),
|
||||
be sure to give reasonable RGB values to the color you
|
||||
allocate for use as a transparent color, _even though it
|
||||
will be transparent on systems that support PNG
|
||||
transparency_.
|
||||
|
||||
|
||||
... inside a function ...
|
||||
|
@ -2267,9 +2473,9 @@ gdImageCopyMergeGray(im_out, im_in, 100, 200, 0, 0, 30, 50, 50);
|
|||
|
||||
void gdImagePaletteCopy(gdImagePtr dst, gdImagePtr src)
|
||||
_(FUNCTION)_
|
||||
Copies a palette from one image to another, doing it's
|
||||
best to match the colors in the target image to the
|
||||
colors in the source palette.
|
||||
Copies a palette from one image to another, attempting to
|
||||
match the colors in the target image to the colors in the
|
||||
source palette.
|
||||
|
||||
Miscellaneous Functions
|
||||
|
||||
|
@ -2296,22 +2502,31 @@ cmpMask = gdImageCompare(im1, im2);
|
|||
which lines will appear on the display from first
|
||||
to last, or in an interlaced fashion, in which the
|
||||
image will "fade in" over several passes. By
|
||||
default, images are not interlaced.
|
||||
default, images are not interlaced. (When writing
|
||||
JPEG images, interlacing implies generating
|
||||
progressive JPEG files, which are represented as a
|
||||
series of scans of increasing quality.
|
||||
Noninterlaced gd images result in regular
|
||||
[sequential] JPEG data streams.)
|
||||
|
||||
A nonzero value for the interlace argument turns on
|
||||
interlace; a zero value turns it off. Note that
|
||||
interlace has no effect on other functions, and has
|
||||
no meaning unless you save the image in PNG format;
|
||||
the gd and xbm formats do not support interlace.
|
||||
no meaning unless you save the image in PNG or JPEG
|
||||
format; the gd and xbm formats do not support
|
||||
interlace.
|
||||
|
||||
When a PNG is loaded with gdImageCreateFromPng ,
|
||||
When a PNG is loaded with gdImageCreateFromPng or a
|
||||
JPEG is loaded with gdImageCreateFromJpeg,
|
||||
interlace will be set according to the setting in
|
||||
the PNG file.
|
||||
the PNG or JPEG file.
|
||||
|
||||
Note that many PNG viewers and web browsers do _not_
|
||||
support interlace. However, the interlaced PNG
|
||||
should still display; it will simply appear all at
|
||||
once, just as other images do.
|
||||
Note that many PNG and JPEG viewers and web
|
||||
browsers do _not_ support interlace or the
|
||||
incremental display of progressive JPEGs. However,
|
||||
the interlaced PNG or progressive JPEG should still
|
||||
display; it will simply appear all at once, just as
|
||||
other images do.
|
||||
|
||||
|
||||
gdImagePtr im;
|
||||
|
@ -2322,7 +2537,7 @@ FILE *out;
|
|||
gdImageInterlace(im, 1);
|
||||
/* And open an output file */
|
||||
out = fopen("test.png", "wb");
|
||||
/* And save the image */
|
||||
/* And save the image -- could also use gdImageJpeg */
|
||||
gdImagePng(im, out);
|
||||
fclose(out);
|
||||
gdImageDestroy(im);
|
||||
|
@ -2410,21 +2625,21 @@ gdImageDestroy(im);
|
|||
About the additional .gd image file format
|
||||
|
||||
In addition to reading and writing the PNG
|
||||
format and reading the X Bitmap format, gd
|
||||
has the capability to read and write its own
|
||||
".gd" format. This format is _not_ intended
|
||||
for general purpose use and should never be
|
||||
used to distribute images. It is not a
|
||||
compressed format. Its purpose is solely to
|
||||
allow very fast loading of images your
|
||||
program needs often in order to build other
|
||||
images for output. If you are experiencing
|
||||
performance problems when loading large,
|
||||
fixed PNG images your program needs to
|
||||
produce its output images, you may wish to
|
||||
examine the functions gdImageCreateFromGd and
|
||||
gdImageGd, which read and write .gd format
|
||||
images.
|
||||
and JPEG formats and reading the X Bitmap
|
||||
format, gd has the capability to read and
|
||||
write its own ".gd" format. This format is
|
||||
_not_ intended for general purpose use and
|
||||
should never be used to distribute images. It
|
||||
is not a compressed format. Its purpose is
|
||||
solely to allow very fast loading of images
|
||||
your program needs often in order to build
|
||||
other images for output. If you are
|
||||
experiencing performance problems when
|
||||
loading large, fixed PNG images your program
|
||||
needs to produce its output images, you may
|
||||
wish to examine the functions
|
||||
gdImageCreateFromGd and gdImageGd, which read
|
||||
and write .gd format images.
|
||||
|
||||
The program "pngtogd.c" is provided as a
|
||||
simple way of converting .png files to .gd
|
||||
|
@ -2445,9 +2660,9 @@ gdImageDestroy(im);
|
|||
image files. Its purpose is solely to allow
|
||||
very fast loading of _parts_ of images If you
|
||||
are experiencing performance problems when
|
||||
loading large, fixed PNG images your program
|
||||
needs to produce its output images, you may
|
||||
wish to examine the functions
|
||||
loading large, fixed PNG or JPEG images your
|
||||
program needs to produce its output images,
|
||||
you may wish to examine the functions
|
||||
gdImageCreateFromGd2,
|
||||
gdImageCreateFromGd2Part and gdImageGd2,
|
||||
which read and write .gd2 format images.
|
||||
|
@ -2539,24 +2754,25 @@ typedef struct gdIOCtx {
|
|||
gdImageCopyResized | gdImageCreate |
|
||||
gdImageCreateFromGd | gdImageCreateFromGd2 |
|
||||
gdImageCreateFromGd2Part |
|
||||
gdImageCreateFromPng |
|
||||
gdImageCreateFromPngSource |
|
||||
gdImageCreateFromJpeg | gdImageCreateFromPng
|
||||
| gdImageCreateFromPngSource |
|
||||
gdImageCreateFromXbm | gdImageCreateFromXpm |
|
||||
gdImageDashedLine | gdImageDestroy |
|
||||
gdImageFill | gdImageFillToBorder |
|
||||
gdImageFilledRectangle | gdImageGd |
|
||||
gdImageGd2 | gdImageGetInterlaced |
|
||||
gdImageGetPixel | gdImageGetTransparent |
|
||||
gdImageGreen | gdImageInterlace | gdImageLine
|
||||
| gdImageFilledPolygon | gdImagePaletteCopy |
|
||||
gdImagePng | gdImagePngToSink |
|
||||
gdImagePolygon | gdImagePtr |
|
||||
gdImageRectangle | gdImageRed |
|
||||
gdImageSetBrush | gdImageSetPixel |
|
||||
gdImageSetStyle | gdImageSetTile |
|
||||
gdImageString | gdImageString16 |
|
||||
gdImageStringTTF | gdImageStringUp |
|
||||
gdImageStringUp16 | gdMaxColors | gdPoint |
|
||||
gdImageGreen | gdImageInterlace | gdImageJpeg
|
||||
| gdImageLine | gdImageFilledPolygon |
|
||||
gdImagePaletteCopy | gdImagePng |
|
||||
gdImagePngToSink | gdImagePolygon |
|
||||
gdImagePtr | gdImageWBMP | gdImageRectangle |
|
||||
gdImageRed | gdImageSetBrush |
|
||||
gdImageSetPixel | gdImageSetStyle |
|
||||
gdImageSetTile | gdImageString |
|
||||
gdImageString16 | gdImageStringTTF |
|
||||
gdImageStringUp | gdImageStringUp16 |
|
||||
gdImageWBMP | gdMaxColors | gdPoint |
|
||||
gdStyled | gdStyledBrushed | gdTiled |
|
||||
gdTransparent
|
||||
|
||||
|
|
Loading…
Reference in New Issue