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

📄 gd.c

📁 Linux/Unix下的绘图函数库(Graphic Drawing Library)
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdio.h>#include <math.h>#include <string.h>#include <stdlib.h>/* 2.03: don't include zlib here or we can't build without PNG */#include "gd.h"#include "gdhelpers.h"/* 2.0.12: this now checks the clipping rectangle */#define gdImageBoundsSafeMacro(im, x, y) (!((((y) < (im)->cy1) || ((y) > (im)->cy2)) || (((x) < (im)->cx1) || ((x) > (im)->cx2))))#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 */extern int gdCosT[];extern int gdSinT[];static void gdImageBrushApply (gdImagePtr im, int x, int y);static void gdImageTileApply (gdImagePtr im, int x, int y);BGD_DECLARE(int) gdImageGetTrueColorPixel (gdImagePtr im, int x, int y);BGD_DECLARE(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->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->sx = sx;  im->sy = sy;  im->colorsTotal = 0;  im->transparent = (-1);  im->interlace = 0;  im->thick = 1;  im->AA = 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;}BGD_DECLARE(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->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->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->cx1 = 0;  im->cy1 = 0;  im->cx2 = im->sx - 1;  im->cy2 = im->sy - 1;  return im;}BGD_DECLARE(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->polyInts)    {      gdFree (im->polyInts);    }  if (im->style)    {      gdFree (im->style);    }  gdFree (im);}BGD_DECLARE(int) gdImageColorClosest (gdImagePtr im, int r, int g, int b){  return gdImageColorClosestAlpha (im, r, g, b, gdAlphaOpaque);}BGD_DECLARE(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) */      /* gd 2.16: was blue rather than alpha! Geez! Thanks to          Artur Jakub Jerzak */      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.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 floatHWB_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;}#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;}#endifBGD_DECLARE(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;  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;}BGD_DECLARE(int) gdImageColorExact (gdImagePtr im, int r, int g, int b){  return gdImageColorExactAlpha (im, r, g, b, gdAlphaOpaque);}BGD_DECLARE(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;}BGD_DECLARE(int) gdImageColorAllocate (gdImagePtr im, int r, int g, int b){  return gdImageColorAllocateAlpha (im, r, g, b, gdAlphaOpaque);}BGD_DECLARE(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. */BGD_DECLARE(int) gdImageColorResolve (gdImagePtr im, int r, int g, int b){  return gdImageColorResolveAlpha (im, r, g, b, gdAlphaOpaque);}BGD_DECLARE(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)	{			/* No room for more colors */	  return ct;		/* Return closest available color */	}      im->colorsTotal++;    }  im->red[op] = r;  im->green[op] = g;  im->blue[op] = b;  im->alpha[op] = a;  im->open[op] = 0;  return op;			/* Return newly allocated color */}BGD_DECLARE(void) gdImageColorDeallocate (gdImagePtr im, int color){  if (im->trueColor)    {      return;    }  /* Mark it open. */  im->open[color] = 1;}BGD_DECLARE(void) gdImageColorTransparent (gdImagePtr im, int color){  if (!im->trueColor)    {      if (im->transparent != -1)	{	  im->alpha[im->transparent] = gdAlphaOpaque;	}      if (color != -1)	{	  im->alpha[color] = gdAlphaTransparent;	}    }  im->transparent = color;}BGD_DECLARE(void) gdImagePaletteCopy (gdImagePtr to, gdImagePtr from){  int i;  int x, y, p;  int xlate[256];  if (to->trueColor)    {      return;    }  if (from->trueColor)    {      return;    }  for (i = 0; i < 256; i++)    {      xlate[i] = -1;    };  for (x = 0; x < (to->sx); x++)    {      for (y = 0; y < (to->sy); y++)	{          /* Optimization: no gdImageGetPixel */	  p = to->pixels[y][x];	  if (xlate[p] == -1)	    {	      /* This ought to use HWB, but we don't have an alpha-aware	         version of that yet. */	      xlate[p] =		gdImageColorClosestAlpha (from, to->red[p], to->green[p],					  to->blue[p], to->alpha[p]);	      /*printf("Mapping %d (%d, %d, %d, %d) to %d (%d, %d, %d, %d)\n", */	      /*      p,  to->red[p], to->green[p], to->blue[p], to->alpha[p], */	      /*      xlate[p], from->red[xlate[p]], from->green[xlate[p]], from->blue[xlate[p]], from->alpha[xlate[p]]); */

⌨️ 快捷键说明

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