Back to index

tetex-bin  3.0
Classes | Defines | Functions | Variables
gd.c File Reference
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include "gd.h"
#include "gdhelpers.h"

Go to the source code of this file.

Classes

struct  RGBType
struct  HWBType

Defines

#define gdImageBoundsSafeMacro(im, x, y)   (!((((y) < (im)->cy1) || ((y) > (im)->cy2)) || (((x) < (im)->cx1) || ((x) > (im)->cx2))))
#define ASC(ch)   ch
#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)))
#define floor2(exp)   ((long) exp)
#define BLEND_COLOR(a, nc, c, cc)   nc = (cc) + (((((c) - (cc)) * (a)) + ((((c) - (cc)) * (a)) >> 8) + 0x80) >> 8);

Functions

static void gdImageBrushApply (gdImagePtr im, int x, int y)
static void gdImageTileApply (gdImagePtr im, int x, int y)
 BGD_DECLARE (int)
 BGD_DECLARE (gdImagePtr)
 BGD_DECLARE (void)
static HWBTypeRGB_to_HWB (RGBType RGB, HWBType *HWB)
static float HWB_Diff (int r1, int g1, int b1, int r2, int g2, int b2)
static int clip_1d (int *x0, int *y0, int *x1, int *y1, int mindim, int maxdim)
static void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col)
static void dashedSet (gdImagePtr im, int x, int y, int color, int *onP, int *dashStepP, int wid, int vert)
static int strlen16 (unsigned short *s)
long lsqrt (long n)
static void gdImageSetAAPixelColor (gdImagePtr im, int x, int y, int color, int t)

Variables

int gdCosT []
int gdSinT []

Class Documentation

struct RGBType

Definition at line 240 of file gd.c.

Class Members
float B
float G
float R
struct HWBType

Definition at line 245 of file gd.c.

Class Members
float B
float H
float W

Define Documentation

#define ASC (   ch)    ch

Definition at line 23 of file gd.c.

#define BLEND_COLOR (   a,
  nc,
  c,
  cc 
)    nc = (cc) + (((((c) - (cc)) * (a)) + ((((c) - (cc)) * (a)) >> 8) + 0x80) >> 8);

Definition at line 3029 of file gd.c.

#define floor2 (   exp)    ((long) exp)

Definition at line 2277 of file gd.c.

#define gdImageBoundsSafeMacro (   im,
  x,
  y 
)    (!((((y) < (im)->cy1) || ((y) > (im)->cy2)) || (((x) < (im)->cx1) || ((x) > (im)->cx2))))

Definition at line 14 of file gd.c.

#define HWB_UNDEFINED   -1

Definition at line 226 of file gd.c.

#define MAX (   a,
  b 
)    ((a)<(b)?(b):(a))

Definition at line 231 of file gd.c.

#define MAX3 (   a,
  b,
  c 
)    ((a)<(b)?(MAX(b,c)):(MAX(a,c)))

Definition at line 232 of file gd.c.

#define MIN (   a,
  b 
)    ((a)<(b)?(a):(b))

Definition at line 229 of file gd.c.

#define MIN3 (   a,
  b,
  c 
)    ((a)<(b)?(MIN(a,c)):(MIN(b,c)))

Definition at line 230 of file gd.c.

#define RETURN_HWB (   h,
  w,
  b 
)    {HWB->H = h; HWB->W = w; HWB->B = b; return HWB;}

Definition at line 224 of file gd.c.

#define RETURN_RGB (   r,
  g,
  b 
)    {RGB->R = r; RGB->G = g; RGB->B = b; return RGB;}

Definition at line 225 of file gd.c.

#define SETUP_RGB (   s,
  r,
  g,
  b 
)    {s.R = r/255.0; s.G = g/255.0; s.B = b/255.0;}

Definition at line 227 of file gd.c.


Function Documentation

Definition at line 68 of file gd.c.

{
  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;
}

Here is the call graph for this function:

Definition at line 111 of file gd.c.

{
  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;
}

Here is the call graph for this function:

Definition at line 148 of file gd.c.

{
  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);
}
static int clip_1d ( int x0,
int y0,
int x1,
int y1,
int  mindim,
int  maxdim 
) [static]

Definition at line 638 of file gd.c.

{
  double m;                 /* gradient of line */
  if (*x0 < mindim)
    {                       /* start of line is left of window */
      if (*x1 < mindim)            /* as is the end, so the line never cuts the window */
       return 0;
      m = (*y1 - *y0) / (double) (*x1 - *x0);    /* calculate the slope of the line */
      /* adjust x0 to be on the left boundary (ie to be zero), and y0 to match */
      *y0 -= m * (*x0 - mindim);
      *x0 = mindim;
      /* now, perhaps, adjust the far end of the line as well */
      if (*x1 > maxdim)
       {
         *y1 += m * (maxdim - *x1);
         *x1 = maxdim;
       }
      return 1;
    }
  if (*x0 > maxdim)
    {                       /* start of line is right of window -
                               complement of above */
      if (*x1 > maxdim)            /* as is the end, so the line misses the window */
       return 0;
      m = (*y1 - *y0) / (double) (*x1 - *x0);    /* calculate the slope of the line */
      *y0 += m * (maxdim - *x0);   /* adjust so point is on the right
                                      boundary */
      *x0 = maxdim;
      /* now, perhaps, adjust the end of the line */
      if (*x1 < mindim)
       {
         *y1 -= m * (*x1 - mindim);
         *x1 = mindim;
       }
      return 1;
    }
  /* the final case - the start of the line is inside the window */
  if (*x1 > maxdim)
    {                       /* other end is outside to the right */
      m = (*y1 - *y0) / (double) (*x1 - *x0);    /* calculate the slope of the line */
      *y1 += m * (maxdim - *x1);
      *x1 = maxdim;
      return 1;
    }
  if (*x1 < mindim)
    {                       /* other end is outside to the left */
      m = (*y1 - *y0) / (double) (*x1 - *x0);    /* calculate the slope of the line */
      *y1 -= m * (*x1 - mindim);
      *x1 = mindim;
      return 1;
    }
  /* only get here if both points are inside the window */
  return 1;
}

Here is the caller graph for this function:

static void dashedSet ( gdImagePtr  im,
int  x,
int  y,
int  color,
int onP,
int dashStepP,
int  wid,
int  vert 
) [static]

Definition at line 1305 of file gd.c.

{
  int dashStep = *dashStepP;
  int on = *onP;
  int w, wstart;

  dashStep++;
  if (dashStep == gdDashSize)
    {
      dashStep = 0;
      on = !on;
    }
  if (on)
    {
      if (vert)
       {
         wstart = y - wid / 2;
         for (w = wstart; w < wstart + wid; w++)
           gdImageSetPixel (im, x, w, color);
       }
      else
       {
         wstart = x - wid / 2;
         for (w = wstart; w < wstart + wid; w++)
           gdImageSetPixel (im, w, y, color);
       }
    }
  *dashStepP = dashStep;
  *onP = on;
}
static void gdImageAALine ( gdImagePtr  im,
int  x1,
int  y1,
int  x2,
int  y2,
int  col 
) [static]

Definition at line 3058 of file gd.c.

{
       /* keep them as 32bits */
       long x, y, inc;
       long dx, dy,tmp;
       if (!im->trueColor) {
              /* TBB: don't crash when the image is of the wrong type */
              gdImageLine(im, x1, y1, x2, y2, col);
              return;
       }
        /* TBB: use the clipping rectangle */
        if (clip_1d (&x1, &y1, &x2, &y2, im->cx1, im->cx2) == 0)
          return;
        if (clip_1d (&y1, &x1, &y2, &x2, im->cy1, im->cy2) == 0)
          return;
       dx = x2 - x1;
       dy = y2 - y1;

       if (dx == 0 && dy == 0) {
              /* TBB: allow setting points */
              gdImageSetAAPixelColor(im, x1, y1, col, 0xFF);
              return;
       }
       if (abs(dx) > abs(dy)) {
              if (dx < 0) {
                     tmp = x1;
                     x1 = x2;
                     x2 = tmp;
                     tmp = y1;
                     y1 = y2;
                     y2 = tmp;
                     dx = x2 - x1;
                     dy = y2 - y1;
              }
              x = x1 << 16;
              y = y1 << 16;
              inc = (dy * 65536) / dx;
              /* TBB: set the last pixel for consistency (<=) */
              while ((x >> 16) <= x2) {
                     gdImageSetAAPixelColor(im, x >> 16, y >> 16, col, (y >> 8) & 0xFF);
                     gdImageSetAAPixelColor(im, x >> 16, (y >> 16) + 1,col, (~y >> 8) & 0xFF);
                     x += (1 << 16);
                     y += inc;
              }
       } else {
              if (dy < 0) {
                     tmp = x1;
                     x1 = x2;
                     x2 = tmp;
                     tmp = y1;
                     y1 = y2;
                     y2 = tmp;
                     dx = x2 - x1;
                     dy = y2 - y1;
              }
              x = x1 << 16;
              y = y1 << 16;
              inc = (dx * 65536) / dy;
              /* TBB: set the last pixel for consistency (<=) */
              while ((y>>16) <= y2) {
                     gdImageSetAAPixelColor(im, x >> 16, y >> 16, col, (x >> 8) & 0xFF);
                     gdImageSetAAPixelColor(im, (x >> 16) + 1, (y >> 16),col, (~x >> 8) & 0xFF);
                     x += inc;
                     y += (1<<16);
              }
       }
}

Here is the call graph for this function:

static void gdImageBrushApply ( gdImagePtr  im,
int  x,
int  y 
) [static]

Definition at line 764 of file gd.c.

{
  int lx, ly;
  int hy;
  int hx;
  int x1, y1, x2, y2;
  int srcx, srcy;
  if (!im->brush)
    {
      return;
    }
  hy = gdImageSY (im->brush) / 2;
  y1 = y - hy;
  y2 = y1 + gdImageSY (im->brush);
  hx = gdImageSX (im->brush) / 2;
  x1 = x - hx;
  x2 = x1 + gdImageSX (im->brush);
  srcy = 0;
  if (im->trueColor)
    {
      if (im->brush->trueColor)
       {
         for (ly = y1; (ly < y2); ly++)
           {
             srcx = 0;
             for (lx = x1; (lx < x2); lx++)
              {
                int p;
                p = gdImageGetTrueColorPixel (im->brush, srcx, srcy);
                /* 2.0.9, Thomas Winzig: apply simple full transparency */
                if (p != gdImageGetTransparent (im->brush))
                  {
                    gdImageSetPixel (im, lx, ly, p);
                  }
                srcx++;
              }
             srcy++;
           }
       }
      else
       {
         /* 2.0.12: Brush palette, image truecolor (thanks to Thorben Kundinger
            for pointing out the issue) */
         for (ly = y1; (ly < y2); ly++)
           {
             srcx = 0;
             for (lx = x1; (lx < x2); lx++)
              {
                int p, tc;
                p = gdImageGetPixel (im->brush, srcx, srcy);
                tc = gdImageGetTrueColorPixel (im->brush, srcx, srcy);
                /* 2.0.9, Thomas Winzig: apply simple full transparency */
                if (p != gdImageGetTransparent (im->brush))
                  {
                    gdImageSetPixel (im, lx, ly, tc);
                  }
                srcx++;
              }
             srcy++;
           }
       }
    }
  else
    {
      for (ly = y1; (ly < y2); ly++)
       {
         srcx = 0;
         for (lx = x1; (lx < x2); lx++)
           {
             int p;
             p = gdImageGetPixel (im->brush, srcx, srcy);
             /* Allow for non-square brushes! */
             if (p != gdImageGetTransparent (im->brush))
              {
                /* Truecolor brush. Very slow
                   on a palette destination. */
                if (im->brush->trueColor)
                  {
                    gdImageSetPixel (im, lx, ly,
                                   gdImageColorResolveAlpha (im,
                                                         gdTrueColorGetRed
                                                         (p),
                                                         gdTrueColorGetGreen
                                                         (p),
                                                         gdTrueColorGetBlue
                                                         (p),
                                                         gdTrueColorGetAlpha
                                                         (p)));
                  }
                else
                  {
                    gdImageSetPixel (im, lx, ly, im->brushColorMap[p]);
                  }
              }
             srcx++;
           }
         srcy++;
       }
    }
}
static void gdImageSetAAPixelColor ( gdImagePtr  im,
int  x,
int  y,
int  color,
int  t 
) [static]

Definition at line 3032 of file gd.c.

{
       int dr,dg,db,p,r,g,b;
       p = gdImageGetPixel(im,x,y);
        /* TBB: we have to implement the dont_blend stuff to provide
          the full feature set of the old implementation */
        if ((p == color)
         || ((p == im->AA_dont_blend)
             && (t != 0x00)))
        {
          return;
        }
       dr = gdTrueColorGetRed(color);
       dg = gdTrueColorGetGreen(color);
       db = gdTrueColorGetBlue(color);

       r = gdTrueColorGetRed(p);
       g = gdTrueColorGetGreen(p);
       b = gdTrueColorGetBlue(p);

       BLEND_COLOR(t, dr, r, dr);
       BLEND_COLOR(t, dg, g, dg);
       BLEND_COLOR(t, db, b, db);
       im->tpixels[y][x]=gdTrueColorAlpha(dr, dg, db,  gdAlphaOpaque);
}  

Here is the caller graph for this function:

static void gdImageTileApply ( gdImagePtr  im,
int  x,
int  y 
) [static]

Definition at line 866 of file gd.c.

{
  int srcx, srcy;
  int p;
  if (!im->tile)
    {
      return;
    }
  srcx = x % gdImageSX (im->tile);
  srcy = y % gdImageSY (im->tile);
  if (im->trueColor)
    {
      p = gdImageGetTrueColorPixel (im->tile, srcx, srcy);
      gdImageSetPixel (im, x, y, p);
    }
  else
    {
      p = gdImageGetPixel (im->tile, srcx, srcy);
      /* Allow for transparency */
      if (p != gdImageGetTransparent (im->tile))
       {
         if (im->tile->trueColor)
           {
             /* Truecolor tile. Very slow
                on a palette destination. */
             gdImageSetPixel (im, x, y,
                            gdImageColorResolveAlpha (im,
                                                  gdTrueColorGetRed
                                                  (p),
                                                  gdTrueColorGetGreen
                                                  (p),
                                                  gdTrueColorGetBlue
                                                  (p),
                                                  gdTrueColorGetAlpha
                                                  (p)));
           }
         else
           {
             gdImageSetPixel (im, x, y, im->tileColorMap[p]);
           }
       }
    }
}
static float HWB_Diff ( int  r1,
int  g1,
int  b1,
int  r2,
int  g2,
int  b2 
) [static]

Definition at line 275 of file gd.c.

{
  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;
}

Here is the call graph for this function:

long lsqrt ( long  n)

Definition at line 1473 of file gd.c.

{
  long result = (long) sqrt ((double) n);
  return result;
}
static HWBType* RGB_to_HWB ( RGBType  RGB,
HWBType HWB 
) [static]

Definition at line 252 of file gd.c.

{

  /*
   * 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);

}

Here is the caller graph for this function:

static int strlen16 ( unsigned short s) [static]

Definition at line 1457 of file gd.c.

{
  int len = 0;
  while (*s)
    {
      s++;
      len++;
    }
  return len;
}

Variable Documentation

Definition at line 2 of file gdtables.c.

Definition at line 365 of file gdtables.c.