⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gd.c

📁 PHP v6.0 For Linux 运行环境:Win9X/ WinME/ WinNT/ Win2K/ WinXP
💻 C
📖 第 1 页 / 共 5 页
字号:
#include <stdio.h>#include <math.h>#include <string.h>#include <stdlib.h>#include "gd.h"#include "gdhelpers.h"#include "php.h"#ifdef _MSC_VER# if _MSC_VER >= 1300/* in MSVC.NET these are available but only for __cplusplus and not _MSC_EXTENSIONS */#  if !defined(_MSC_EXTENSIONS) && defined(__cplusplus)#   define HAVE_FABSF 1extern float fabsf(float x);#   define HAVE_FLOORF 1extern float floorf(float x);#  endif /*MSVC.NET */# endif /* MSC */#endif#ifndef HAVE_FABSF# define HAVE_FABSF 0#endif#ifndef HAVE_FLOORF# define HAVE_FLOORF 0#endif#if HAVE_FABSF == 0/* float fabsf(float x); */# define fabsf(x) ((float)(fabs(x)))#endif#if HAVE_FLOORF == 0/* float floorf(float x);*/#define floorf(x) ((float)(floor(x)))#endif#ifdef _OSD_POSIX		/* BS2000 uses the EBCDIC char set instead of ASCII */#define CHARSET_EBCDIC#define __attribute__(any)	/*nothing */#endif/*_OSD_POSIX*/#ifndef CHARSET_EBCDIC#define ASC(ch)  ch#else /*CHARSET_EBCDIC */#define ASC(ch) gd_toascii[(unsigned char)ch]static const unsigned char gd_toascii[256] ={/*00 */ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f,  0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,	/*................ *//*10 */ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97,  0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f,	/*................ *//*20 */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b,  0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07,	/*................ *//*30 */ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04,  0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a,	/*................ *//*40 */ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5,  0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c,	/* .........`.<(+| *//*50 */ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef,  0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f,	/*&.........!$*);. *//*60 */ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5,  0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f,/*-/........^,%_>?*//*70 */ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf,  0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22,	/*..........:#@'=" *//*80 */ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,  0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1,	/*.abcdefghi...... *//*90 */ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70,  0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4,	/*.jklmnopqr...... *//*a0 */ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,  0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae,	/*..stuvwxyz...... *//*b0 */ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc,  0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7,	/*...........[\].. *//*c0 */ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,  0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5,	/*.ABCDEFGHI...... *//*d0 */ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50,  0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff,	/*.JKLMNOPQR...... *//*e0 */ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,  0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5,	/*..STUVWXYZ...... *//*f0 */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,  0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e	/*0123456789.{.}.~ */};#endif /*CHARSET_EBCDIC *//* 2.0.10: cast instead of floor() yields 35% performance improvement. Thanks to John Buckman. */#define floor_cast(exp) ((long) exp)extern int gdCosT[];extern int gdSinT[];static void gdImageBrushApply(gdImagePtr im, int x, int y);static void gdImageTileApply(gdImagePtr im, int x, int y);static void gdImageAntiAliasedApply(gdImagePtr im, int x, int y);static int gdLayerOverlay(int dst, int src);static int gdAlphaOverlayColor(int src, int dst, int max);int gdImageGetTrueColorPixel(gdImagePtr im, int x, int y);void php_gd_error_ex(int type, const char *format, ...){	va_list args;	TSRMLS_FETCH();	va_start(args, format);	php_verror(NULL, "", type, format, args TSRMLS_CC);	va_end(args);}void php_gd_error(const char *format, ...){	va_list args;	TSRMLS_FETCH();	va_start(args, format);	php_verror(NULL, "", E_WARNING, format, args TSRMLS_CC);	va_end(args);}gdImagePtr gdImageCreate (int sx, int sy){	int i;	gdImagePtr im;	im = (gdImage *) gdMalloc(sizeof(gdImage));	memset(im, 0, sizeof(gdImage));	/* Row-major ever since gd 1.3 */	im->pixels = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy);	im->AA_opacity = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy);	im->polyInts = 0;	im->polyAllocated = 0;	im->brush = 0;	im->tile = 0;	im->style = 0;	for (i = 0; i < sy; i++) {		/* Row-major ever since gd 1.3 */		im->pixels[i] = (unsigned char *) gdCalloc(sx, sizeof(unsigned char));		im->AA_opacity[i] = (unsigned char *) gdCalloc(sx, sizeof(unsigned char));	}	im->sx = sx;	im->sy = sy;	im->colorsTotal = 0;	im->transparent = (-1);	im->interlace = 0;	im->thick = 1;	im->AA = 0;	im->AA_polygon = 0;	for (i = 0; i < gdMaxColors; i++) {		im->open[i] = 1;		im->red[i] = 0;		im->green[i] = 0;		im->blue[i] = 0;	}	im->trueColor = 0;	im->tpixels = 0;	im->cx1 = 0;	im->cy1 = 0;	im->cx2 = im->sx - 1;	im->cy2 = im->sy - 1;	return im;}gdImagePtr gdImageCreateTrueColor (int sx, int sy){	int i;	gdImagePtr im;	im = (gdImage *) gdMalloc(sizeof(gdImage));	memset(im, 0, sizeof(gdImage));	im->tpixels = (int **) gdMalloc(sizeof(int *) * sy);	im->AA_opacity = (unsigned char **) gdMalloc(sizeof(unsigned char *) * sy);	im->polyInts = 0;	im->polyAllocated = 0;	im->brush = 0;	im->tile = 0;	im->style = 0;	for (i = 0; i < sy; i++) {		im->tpixels[i] = (int *) gdCalloc(sx, sizeof(int));		im->AA_opacity[i] = (unsigned char *) gdCalloc(sx, sizeof(unsigned char));	}	im->sx = sx;	im->sy = sy;	im->transparent = (-1);	im->interlace = 0;	im->trueColor = 1;	/* 2.0.2: alpha blending is now on by default, and saving of alpha is	 * off by default. This allows font antialiasing to work as expected	 * on the first try in JPEGs -- quite important -- and also allows	 * for smaller PNGs when saving of alpha channel is not really	 * desired, which it usually isn't!	 */	im->saveAlphaFlag = 0;	im->alphaBlendingFlag = 1;	im->thick = 1;	im->AA = 0;	im->AA_polygon = 0;	im->cx1 = 0;	im->cy1 = 0;	im->cx2 = im->sx - 1;	im->cy2 = im->sy - 1;	return im;}void gdImageDestroy (gdImagePtr im){	int i;	if (im->pixels) {		for (i = 0; i < im->sy; i++) {			gdFree(im->pixels[i]);		}		gdFree(im->pixels);	}	if (im->tpixels) {		for (i = 0; i < im->sy; i++) {			gdFree(im->tpixels[i]);		}		gdFree(im->tpixels);	}	if (im->AA_opacity) {		for (i = 0; i < im->sy; i++) {			gdFree(im->AA_opacity[i]);		}		gdFree(im->AA_opacity);	}	if (im->polyInts) {		gdFree(im->polyInts);	}	if (im->style) {		gdFree(im->style);	}	gdFree(im);}int gdImageColorClosest (gdImagePtr im, int r, int g, int b){	return gdImageColorClosestAlpha (im, r, g, b, gdAlphaOpaque);}int gdImageColorClosestAlpha (gdImagePtr im, int r, int g, int b, int a){	int i;	long rd, gd, bd, ad;	int ct = (-1);	int first = 1;	long mindist = 0;	if (im->trueColor) {		return gdTrueColorAlpha(r, g, b, a);	}	for (i = 0; i < im->colorsTotal; i++) {		long dist;		if (im->open[i]) {			continue;		}		rd = im->red[i] - r;		gd = im->green[i] - g;		bd = im->blue[i] - b;		/* gd 2.02: whoops, was - b (thanks to David Marwood) */		ad = im->alpha[i] - a;		dist = rd * rd + gd * gd + bd * bd + ad * ad;		if (first || (dist < mindist)) {			mindist = dist;			ct = i;			first = 0;		}	}	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.0f; s.G = g/255.0f; s.B = b/255.0f;}#ifndef MIN#define MIN(a,b) ((a)<(b)?(a):(b))#endif#define MIN3(a,b,c) ((a)<(b)?(MIN(a,c)):(MIN(b,c)))#ifndef MAX#define MAX(a,b) ((a)<(b)?(b):(a))#endif#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.0f;	/* Undefined hues always match... */	} else {		diff = fabsf(HWB1.H - HWB2.H);		if (diff > 3.0f) {			diff = 6.0f - 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;}#if 0/* * 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);	}	return RGB;}#endifint gdImageColorClosestHWB (gdImagePtr im, int r, int g, int b){	int i;	/* long rd, gd, bd; */	int ct = (-1);	int first = 1;	float mindist = 0;	if (im->trueColor) {		return gdTrueColor(r, g, b);	}	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){	return gdImageColorExactAlpha (im, r, g, b, gdAlphaOpaque);}int gdImageColorExactAlpha (gdImagePtr im, int r, int g, int b, int a){	int i;	if (im->trueColor) {		return gdTrueColorAlpha(r, g, b, a);	}	for (i = 0; i < im->colorsTotal; i++) {		if (im->open[i]) {			continue;		}		if ((im->red[i] == r) && (im->green[i] == g) && (im->blue[i] == b) && (im->alpha[i] == a)) {			return i;		}	}	return -1;}int gdImageColorAllocate (gdImagePtr im, int r, int g, int b){	return gdImageColorAllocateAlpha (im, r, g, b, gdAlphaOpaque);}int gdImageColorAllocateAlpha (gdImagePtr im, int r, int g, int b, int a){	int i;	int ct = (-1);	if (im->trueColor) {		return gdTrueColorAlpha(r, g, b, a);	}	for (i = 0; i < im->colorsTotal; i++) {		if (im->open[i]) {			ct = i;			break;		}	}	if (ct == (-1)) {		ct = im->colorsTotal;		if (ct == gdMaxColors) {			return -1;		}		im->colorsTotal++;	}	im->red[ct] = r;	im->green[ct] = g;	im->blue[ct] = b;	im->alpha[ct] = a;	im->open[ct] = 0;	return ct;}/* * gdImageColorResolve is an alternative for the code fragment: * *      if ((color=gdImageColorExact(im,R,G,B)) < 0) *        if ((color=gdImageColorAllocate(im,R,G,B)) < 0) *          color=gdImageColorClosest(im,R,G,B); * * in a single function.    Its advantage is that it is guaranteed to * return a color index in one search over the color table. */int gdImageColorResolve (gdImagePtr im, int r, int g, int b){	return gdImageColorResolveAlpha(im, r, g, b, gdAlphaOpaque);}int gdImageColorResolveAlpha (gdImagePtr im, int r, int g, int b, int a){  int c;  int ct = -1;  int op = -1;  long rd, gd, bd, ad, dist;  long mindist = 4 * 255 * 255;	/* init to max poss dist */  if (im->trueColor)    {      return gdTrueColorAlpha (r, g, b, a);    }  for (c = 0; c < im->colorsTotal; c++)    {      if (im->open[c])	{	  op = c;		/* Save open slot */	  continue;		/* Color not in use */	}      if (c == im->transparent)        {          /* don't ever resolve to the color that has           * been designated as the transparent color */          continue;	}      rd = (long) (im->red[c] - r);      gd = (long) (im->green[c] - g);      bd = (long) (im->blue[c] - b);      ad = (long) (im->alpha[c] - a);      dist = rd * rd + gd * gd + bd * bd + ad * ad;      if (dist < mindist)	{	  if (dist == 0)	    {	      return c;		/* Return exact match color */	    }	  mindist = dist;	  ct = c;	}    }  /* no exact match.  We now know closest, but first try to allocate exact */  if (op == -1)    {      op = im->colorsTotal;      if (op == gdMaxColors)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -