コード例 #1
0
ファイル: gdgen.c プロジェクト: aosm/graphviz
static  void
gd_bezier(point* A, int n, int arrow_at_start, int arrow_at_end)
{
	pointf		p0, p1, V[4];
	int		i, j, step;
	int		style[20]; 
	int		pen, width;
	gdImagePtr	brush = NULL;

	if (cstk[SP].pen != P_NONE) {
		if (cstk[SP].pen == P_DASHED) {
			for (i = 0; i < 10; i++)
				style[i] = cstk[SP].pencolor;
			for (; i < 20; i++)
				style[i] = gdTransparent;
			gdImageSetStyle(im, style, 20);
			pen = gdStyled;
		} else if (cstk[SP].pen == P_DOTTED) {
			for (i = 0; i < 2; i++)
				style[i] = cstk[SP].pencolor;
			for (; i < 12; i++)
				style[i] = gdTransparent;
			gdImageSetStyle(im, style, 12);
			pen = gdStyled;
		} else {
			pen = cstk[SP].pencolor;
		}
#if 0
                if (cstk[SP].penwidth != WIDTH_NORMAL) {
			width=cstk[SP].penwidth;
                        brush = gdImageCreate(width,width);
                        gdImagePaletteCopy(brush, im);
                        gdImageFilledRectangle(brush,
                           0,0,width-1, width-1, cstk[SP].pencolor);
                        gdImageSetBrush(im, brush);
			if (pen == gdStyled) pen = gdStyledBrushed;      
			else pen = gdBrushed;      
		}
#else
		width = cstk[SP].penwidth;
		gdImageSetThickness(im, width);
#endif
		V[3].x = A[0].x; V[3].y = A[0].y;
		for (i = 0; i+3 < n; i += 3) {
			V[0] = V[3];
			for (j = 1; j <= 3; j++) {
				V[j].x  = A[i+j].x; V[j].y = A[i+j].y;
			}
			p0 = gdpt(V[0]); 
			for (step = 1; step <= BEZIERSUBDIVISION; step++) {
				p1 = gdpt(Bezier(V, 3, (double)step/BEZIERSUBDIVISION, NULL, NULL));
				gdImageLine(im, ROUND(p0.x), ROUND(p0.y),
					ROUND(p1.x), ROUND(p1.y), pen);
				p0 = p1;
			}
		}
		if (brush)
			gdImageDestroy(brush);
	}
}
コード例 #2
0
ファイル: gdgen.c プロジェクト: aosm/graphviz
static  void
gd_polyline(point* A, int n)
{
	pointf		p, p1;
	int		i;
	int		style[20];
	int		pen, width;
	gdImagePtr	brush = NULL;

	if (cstk[SP].pen != P_NONE) {
		if (cstk[SP].pen == P_DASHED) {
			for (i = 0; i < 10; i++)
				style[i] = cstk[SP].pencolor;
			for (; i < 20; i++)
				style[i] = gdTransparent;
			gdImageSetStyle(im, style, 20);
			pen = gdStyled;
		} else if (cstk[SP].pen == P_DOTTED) {
			for (i = 0; i < 2; i++)
				style[i] = cstk[SP].pencolor;
			for (; i < 12; i++)
				style[i] = gdTransparent;
			gdImageSetStyle(im, style, 12);
			pen = gdStyled;
		} else {
			pen = cstk[SP].pencolor;
		}
#if 0
                if (cstk[SP].penwidth != WIDTH_NORMAL) {
			width = cstk[SP].penwidth;
                        brush = gdImageCreate(width,width);
                        gdImagePaletteCopy(brush, im);
                        gdImageFilledRectangle(brush,
                           0,0,width-1,width-1,cstk[SP].pencolor);
                        gdImageSetBrush(im, brush);
			if (pen == gdStyled) pen = gdStyledBrushed;      
			else pen = gdBrushed;      
		}
#else
		width = cstk[SP].penwidth;
		gdImageSetThickness(im, width);
#endif
		p.x = A[0].x;
		p.y = A[0].y;
		p = gdpt(p);
		for (i = 1; i < n; i++) {
			p1.x = A[i].x;
			p1.y = A[i].y;
			p1 = gdpt(p1);
			gdImageLine(im, ROUND(p.x), ROUND(p.y),
				ROUND(p1.x), ROUND(p1.y), pen);
			p.x = p1.x;
			p.y = p1.y;
		}
		if (brush)
			gdImageDestroy(brush);
	}
}
コード例 #3
0
ファイル: gdgen.c プロジェクト: aosm/graphviz
static  void
gd_ellipse(point p, int rx, int ry, int filled)
{
	pointf		mp;
	int		i;
	int		style[40];  /* need 2* size for arcs, I don't know why */
	int		pen, width;
	gdImagePtr	brush = NULL;

	if (cstk[SP].pen != P_NONE) {
		if (cstk[SP].pen == P_DASHED) {
			for (i = 0; i < 20; i++)
				style[i] = cstk[SP].pencolor;
			for (; i < 40; i++)
				style[i] = gdTransparent;
			gdImageSetStyle(im, style, 40);
			pen = gdStyled;
		} else if (cstk[SP].pen == P_DOTTED) {
			for (i = 0; i < 2; i++)
				style[i] = cstk[SP].pencolor;
			for (; i < 24; i++)
				style[i] = gdTransparent;
			gdImageSetStyle(im, style, 24);
			pen = gdStyled;
		} else {
			pen = cstk[SP].pencolor;
		}
#if 1
		/* use brush instead of Thickness to improve outline appearance */
		gdImageSetThickness(im, WIDTH_NORMAL);
                if (cstk[SP].penwidth != WIDTH_NORMAL) {
			width = cstk[SP].penwidth;
                        brush = gdImageCreate(width,width);
                        gdImagePaletteCopy(brush, im);
                        gdImageFilledRectangle(brush,
                           0,0,width-1, width-1, cstk[SP].pencolor);
                        gdImageSetBrush(im, brush);
			if (pen == gdStyled) pen = gdStyledBrushed;      
			else pen = gdBrushed;      
		}
#else
		width = cstk[SP].penwidth;
		gdImageSetThickness(im, width);
#endif
		if (Rot) {int t; t = rx; rx = ry; ry = t;}
		mp.x = p.x; mp.y = p.y;
		mp = gdpt(mp);
		if (filled) {
			gdImageFilledEllipse(im, ROUND(mp.x), ROUND(mp.y),
				ROUND(Zoom*(rx + rx)), ROUND(Zoom*(ry + ry)),
				cstk[SP].fillcolor);
		}
		gdImageArc(im, ROUND(mp.x), ROUND(mp.y),
			ROUND(Zoom*(rx + rx)), ROUND(Zoom*(ry + ry)), 0, 360, pen);
		if (brush)
			gdImageDestroy(brush);
	}
}
コード例 #4
0
ファイル: gdgen.c プロジェクト: aosm/graphviz
static  void
gd_polygon(point *A, int n, int filled)
{
	pointf		p;
	int		i;
	gdPoint		*points;
	int		style[20];
	int		pen, width;
	gdImagePtr	brush = NULL;

	if (cstk[SP].pen != P_NONE) {
		if (cstk[SP].pen == P_DASHED) {
			for (i = 0; i < 10; i++)
				style[i] = cstk[SP].pencolor;
			for (; i < 20; i++)
				style[i] = gdTransparent;
			gdImageSetStyle(im, style, 20);
			pen = gdStyled;
		} else if (cstk[SP].pen == P_DOTTED) {
			for (i = 0; i < 2; i++)
				style[i] = cstk[SP].pencolor;
			for (; i < 12; i++)
				style[i] = gdTransparent;
			gdImageSetStyle(im, style, 12);
			pen = gdStyled;
		} else {
			pen = cstk[SP].pencolor;
		}
#if 1
		/* use brush instead of Thickness to improve end butts */
		gdImageSetThickness(im, WIDTH_NORMAL);
                if (cstk[SP].penwidth != WIDTH_NORMAL) {
			width=cstk[SP].penwidth * Zoom;
                        brush = gdImageCreate(width,width);
                        gdImagePaletteCopy(brush, im);
                        gdImageFilledRectangle(brush,
                           0,0,width-1, width-1, cstk[SP].pencolor);
                        gdImageSetBrush(im, brush);
			if (pen == gdStyled) pen = gdStyledBrushed;      
			else pen = gdBrushed;      
		}
#else
		width = cstk[SP].penwidth;
		gdImageSetThickness(im, width);
#endif
		points = N_GNEW(n,gdPoint);
		for (i = 0; i < n; i++) {
			p.x = A[i].x; p.y = A[i].y;
			p = gdpt(p);
			points[i].x = ROUND(p.x); points[i].y = ROUND(p.y);
		}
		if (filled) gdImageFilledPolygon(im, points, n, cstk[SP].fillcolor);
		gdImagePolygon(im, points, n, pen);
		free(points);
		if (brush)
			gdImageDestroy(brush);
	}
}
コード例 #5
0
ファイル: gd2copypal.c プロジェクト: kanbang/Colt
int
main (int argc, char **argv)
{
  gdImagePtr im;
  gdImagePtr pal;
  FILE *in, *out;
  if (argc != 3)
    {
      fprintf (stderr, "Usage: gd2copypal palettefile.gd2 filename.gd2\n");
      exit (1);
    }
  in = fopen (argv[1], "rb");
  if (!in)
    {
      fprintf (stderr, "Palette file does not exist!\n");
      exit (1);
    }
  pal = gdImageCreateFromGd2 (in);
  fclose (in);
  if (!pal)
    {
      fprintf (stderr, "Palette is not in GD2 format!\n");
      exit (1);
    }

  in = fopen (argv[2], "rb");
  if (!in)
    {
      fprintf (stderr, "Input file does not exist!\n");
      exit (1);
    }
  im = gdImageCreateFromGd2 (in);
  fclose (in);
  if (!im)
    {
      fprintf (stderr, "Input is not in GD2 format!\n");
      exit (1);
    }

  gdImagePaletteCopy (im, pal);

  out = fopen (argv[2], "wb");
  if (!out)
    {
      fprintf (stderr, "Output file cannot be written to!\n");
      gdImageDestroy (im);
      exit (1);
    }
  gdImageGd2 (im, out, 128, 2);
  fclose (out);
  gdImageDestroy (pal);
  gdImageDestroy (im);

  return 0;
}
コード例 #6
0
ファイル: gd_crop.c プロジェクト: 0x1111/php-src
/**
 * Function: gdImageCrop
 *  Crops the src image using the area defined by the <crop> rectangle.
 *  The result is returned as a new image.
 *
 *
 * Parameters:
 * 	src - Source image
 *  crop - Rectangular region to crop
 *
 * Returns:
 *  <gdImagePtr> on success or NULL
 */
gdImagePtr gdImageCrop(gdImagePtr src, const gdRectPtr crop)
{
	gdImagePtr dst;
	int y;

	/* allocate the requested size (could be only partially filled) */
	if (src->trueColor) {
		dst = gdImageCreateTrueColor(crop->width, crop->height);
		if (dst == NULL) {
			return NULL;
		}
		gdImageSaveAlpha(dst, 1);
	} else {
		dst = gdImageCreate(crop->width, crop->height);
		if (dst == NULL) {
			return NULL;
		}
		gdImagePaletteCopy(dst, src);
	}
	dst->transparent = src->transparent;

	/* check position in the src image */
	if (crop->x < 0 || crop->x>=src->sx || crop->y<0 || crop->y>=src->sy) {
		return dst;
	}

	/* reduce size if needed */
	if ((src->sx - crop->width) < crop->x) {
		crop->width = src->sx - crop->x;
	}
	if ((src->sy - crop->height) < crop->y) {
		crop->height = src->sy - crop->y;
	}

#if 0
printf("rect->x: %i\nrect->y: %i\nrect->width: %i\nrect->height: %i\n", crop->x, crop->y, crop->width, crop->height);
#endif
	y = crop->y;
	if (src->trueColor) {
		unsigned int dst_y = 0;
		while (y < (crop->y + (crop->height - 1))) {
			/* TODO: replace 4 w/byte per channel||pitch once available */
			memcpy(dst->tpixels[dst_y++], src->tpixels[y++] + crop->x, crop->width * 4);
		}
	} else {
		int x;
		for (y = crop->y; y < (crop->y + (crop->height - 1)); y++) {
			for (x = crop->x; x < (crop->x + (crop->width - 1)); x++) {
				dst->pixels[y - crop->y][x - crop->x] = src->pixels[y][x];
			}
		}
	}
	return dst;
}
コード例 #7
0
ファイル: mapgd.c プロジェクト: bb1ackwe11/mapserver
int getRasterBufferCopyGD(imageObj *img, rasterBufferObj *rb) {
	gdImagePtr gdImg = MS_IMAGE_GET_GDIMAGEPTR(img);
	int row;
	rb->type = MS_BUFFER_GD;
	rb->width = gdImg->sx;
	rb->height = gdImg->sy;
	rb->data.gd_img = gdImageCreate(gdImg->sx,gdImg->sy);
	rb->data.gd_img->transparent = gdImg->transparent;
	gdImagePaletteCopy(rb->data.gd_img,gdImg);
	for(row=0;row<gdImg->sy;row++)
	   memcpy(rb->data.gd_img->pixels[row],gdImg->pixels[row],gdImg->sx);
	return MS_SUCCESS;
}
コード例 #8
0
void write_frame(int time) {
  if (rank != 0) {
    MPI_Send(u+1, nxl, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD);
  } else {
    int source, i, j, count, global_index;
    MPI_Status status;

    im = gdImageCreate(nx*PWIDTH,PHEIGHT);
    if (time == 0) {
      for (j=0; j<MAXCOLORS; j++)
	colors[j] = gdImageColorAllocate (im, j, 0, MAXCOLORS-j-1); 
      gdImageGifAnimBegin(im, file, 1, -1);
    } else {
      gdImagePaletteCopy(im, previm);
    }
    global_index = 0;
    for (source = 0; source < nprocs; source++) {
      if (source != 0) {
	MPI_Recv(buf, 1+nx/nprocs, MPI_DOUBLE, source, 0, MPI_COMM_WORLD,
		 &status);
	MPI_Get_count(&status, MPI_DOUBLE, &count);
      } else {
	for (i = 1; i <= nxl; i++) buf[i-1] = u[i];
	count = nxl;
      }
      for (i = 0; i < count; i++) {

	int color = (int)(buf[i]*MAXCOLORS/M);

	assert(color >= 0);
	if (color >= MAXCOLORS) color = MAXCOLORS-1;
	gdImageFilledRectangle
	  (im, global_index*PWIDTH, 0, (global_index+1)*PWIDTH-1,
	   PHEIGHT-1, colors[color]);
	global_index++;
      }
    }
    if (time == 0) {
      gdImageGifAnimAdd(im, file, 0, 0, 0, 0, gdDisposalNone, NULL);
    } else {
      gdImageGifAnimAdd(im, file, 0, 0, 0, 5, gdDisposalNone, previm);
      gdImageDestroy(previm);
    }
    previm=im;
    im=NULL;
  }
#ifdef DEBUG
  write_plain(time);
#endif
}
コード例 #9
0
ファイル: Image.cpp プロジェクト: 540513310/fibjs
result_t Image::rotate(int32_t dir)
{
    if (dir != gd_base::_LEFT && dir != gd_base::_RIGHT)
        return CHECK_ERROR(CALL_E_INVALIDARG);

    int32_t sx = gdImageSX(m_image);
    int32_t sy = gdImageSY(m_image);
    int32_t i, j;
    gdImagePtr newImage;

    if (gdImageTrueColor(m_image))
        newImage = gdImageCreateTrueColor(sy, sx);
    else
    {
        newImage = gdImageCreate(sy, sx);
        gdImagePaletteCopy(newImage, m_image);
    }

    gdImageColorTransparent(newImage, gdImageGetTransparent(m_image));

    if (dir == gd_base::_LEFT)
    {
        for (i = 0; i < sx; i++)
            for (j = 0; j < sy; j++)
                gdImageSetPixel(newImage, j, sx - i - 1,
                                gdImageGetPixel(m_image, i, j));
    }
    else
    {
        for (i = 0; i < sx; i++)
            for (j = 0; j < sy; j++)
                gdImageSetPixel(newImage, sy - j - 1, i,
                                gdImageGetPixel(m_image, i, j));
    }

    setExtMemory(-1);
    gdImageDestroy(m_image);
    m_image = newImage;
    setExtMemory();

    return 0;
}
コード例 #10
0
ファイル: Image.cpp プロジェクト: 540513310/fibjs
result_t Image::New(int32_t width, int32_t height, obj_ptr<Image> &retVal)
{
    if (width <= 0 || height <= 0)
        return CHECK_ERROR(CALL_E_INVALIDARG);

    obj_ptr<Image> img = new Image();

    if (gdImageTrueColor(m_image))
        img->m_image = gdImageCreateTrueColor(width, height);
    else
        img->m_image = gdImageCreate(width, height);

    gdImagePaletteCopy(img->m_image, m_image);
    gdImageColorTransparent(img->m_image, gdImageGetTransparent(m_image));

    img->setExtMemory();

    retVal = img;
    return 0;
}
コード例 #11
0
ファイル: gvrender_gd_vrml.c プロジェクト: ekoontz/graphviz
static int set_penstyle(GVJ_t * job, gdImagePtr im, gdImagePtr brush)
{
    obj_state_t *obj = job->obj;
    int i, pen, pencolor, transparent, width, dashstyle[40];

    pen = pencolor = color_index(im, obj->pencolor);
    transparent = gdImageGetTransparent(im);
    if (obj->pen == PEN_DASHED) {
        for (i = 0; i < 20; i++)
            dashstyle[i] = pencolor;
        for (; i < 40; i++)
            dashstyle[i] = transparent;
        gdImageSetStyle(im, dashstyle, 20);
        pen = gdStyled;
    } else if (obj->pen == PEN_DOTTED) {
        for (i = 0; i < 2; i++)
            dashstyle[i] = pencolor;
        for (; i < 24; i++)
            dashstyle[i] = transparent;
        gdImageSetStyle(im, dashstyle, 24);
        pen = gdStyled;
    }
    width = obj->penwidth * job->scale.x;
    if (width < PENWIDTH_NORMAL)
        width = PENWIDTH_NORMAL;  /* gd can't do thin lines */
    gdImageSetThickness(im, width);
    /* use brush instead of Thickness to improve end butts */
    if (width != PENWIDTH_NORMAL) {
        brush = gdImageCreate(width, width);
        gdImagePaletteCopy(brush, im);
        gdImageFilledRectangle(brush, 0, 0, width - 1, width - 1, pencolor);
        gdImageSetBrush(im, brush);
        if (pen == gdStyled)
            pen = gdStyledBrushed;
        else
            pen = gdBrushed;
    }
    return pen;
}
コード例 #12
0
ファイル: Image.cpp プロジェクト: 540513310/fibjs
result_t Image::getData(int32_t format, int32_t quality,
                        obj_ptr<Buffer_base> &retVal, AsyncEvent *ac)
{
    if (!m_image)
        return CHECK_ERROR(CALL_E_INVALID_CALL);

    if (!ac)
        return CHECK_ERROR(CALL_E_NOSYNC);

    int32_t size = 0;
    void *data = NULL;
    int32_t sx = gdImageSX(m_image);
    int32_t sy = gdImageSY(m_image);
    int32_t i, j;
    int32_t trans = -1;

    if (gdImageTrueColor(m_image))
    {
        for (i = 0; i < sx && trans == -1; i ++)
            for (j = 0; j < sy && trans == -1; j++)
                if ((gdImageGetPixel(m_image, i, j) & 0xff000000) != 0)
                    trans = 0;
    }
    else
        trans = gdImageGetTransparent(m_image);

    gdImagePtr nowImage = m_image;

    if (trans != -1)
    {
        if (format != gd_base::_PNG)
        {
            if (gdImageTrueColor(m_image))
                nowImage = gdImageCreateTrueColor(sx, sy);
            else
            {
                nowImage = gdImageCreate(sx, sy);
                gdImagePaletteCopy(nowImage, m_image);
            }

            gdImageFilledRectangle(nowImage, 0, 0, sx, sy, gdImageColorAllocate(nowImage, 255, 255, 255));
            gdImageCopy(nowImage, m_image, 0, 0, 0, 0, sx, sy);
        }
        else if (gdImageTrueColor(m_image))
            gdImageSaveAlpha(m_image, 1);
    }

    switch (format)
    {
    case gd_base::_GIF:
        data = gdImageGifPtr(nowImage, &size);
        break;
    case gd_base::_PNG:
        data = gdImagePngPtr(nowImage, &size);
        break;
    case gd_base::_JPEG:
    {
        unsigned char *ed_data = NULL;
        uint32_t  ed_size = 0;

        data = gdImageJpegPtr(nowImage, &size, quality, ed_data, ed_size);

        if (ed_data)
            free(ed_data);

        break;
    }
    case gd_base::_TIFF:
        data = gdImageTiffPtr(nowImage, &size);
        break;
    case gd_base::_BMP:
        data = gdImageBmpPtr(nowImage, &size, 1);
        break;
    case gd_base::_WEBP:
        data = gdImageWebpPtrEx(nowImage, &size, quality);
        break;
    }

    if (nowImage != m_image)
        gdImageDestroy(nowImage);

    if (data == NULL)
        return CHECK_ERROR(CALL_E_INVALIDARG);

    retVal = new Buffer(std::string((char *) data, size));
    gdFree(data);

    return 0;
}
コード例 #13
0
ファイル: gd_gif_out.c プロジェクト: mikekhusid/libgd
/*
  Function: gdImageGifAnimAddCtx

    Adds an animation frame via a <gdIOCtxPtr>.  See gdImageGifAnimAdd>.

  Parameters:

    im          - The image to add.
    out         - The output <gdIOCtxPtr>.
    LocalCM     - Flag.  If 1, use a local color map for this frame.
    LeftOfs     - Left offset of image in frame.
    TopOfs      - Top offset of image in frame.
    Delay       - Delay before next frame (in 1/100 seconds)
    Disposal    - MODE: How to treat this frame when the next one loads.
    previm      - NULL or a pointer to the previous image written.

  Returns:

    Nothing.

*/
BGD_DECLARE(void) gdImageGifAnimAddCtx(gdImagePtr im, gdIOCtxPtr out,
                                       int LocalCM, int LeftOfs, int TopOfs,
                                       int Delay, int Disposal,
                                       gdImagePtr previm)
{
	gdImagePtr pim = NULL, tim = im;
	int interlace, transparent, BitsPerPixel;
	interlace = im->interlace;
	transparent = im->transparent;

	/* Default is no local color map */
	if(LocalCM < 0) {
		LocalCM = 0;
	}

	if(im->trueColor) {
		/* Expensive, but the only way that produces an
			acceptable result: mix down to a palette
			based temporary image. */
		pim = gdImageCreatePaletteFromTrueColor(im, 1, 256);
		if (!pim) {
			return;
		}
		tim = pim;
	}

	if (previm) {
		/* create optimized animation.  Compare this image to
		   the previous image and crop the temporary copy of
		   current image to include only changed rectangular
		   area.  Also replace unchanged pixels inside this
		   area with transparent color.  Transparent color
		   needs to be already allocated!
		   Preconditions:
		   TopOfs, LeftOfs are assumed 0

		   Images should be of same size.  If not, a temporary
		   copy is made with the same size as previous image.

		*/
		gdImagePtr prev_pim = 0, prev_tim = previm;
		int x, y;
		int min_x = 0;
		int min_y = tim->sy;
		int max_x = 0;
		int max_y = 0;
		int colorMap[256];

		if (previm->trueColor) {
			prev_pim = gdImageCreatePaletteFromTrueColor(previm, 1, 256);
			if (!prev_pim) {
				goto fail_end;
			}
			prev_tim = prev_pim;
		}

		for (x = 0; x < 256; ++x) {
			colorMap[x] = -2;
		}

		/* First find bounding box of changed areas. */
		/* first find the top changed row */
		for (y = 0; y < tim->sy; ++y) {
			for (x = 0; x < tim->sx; ++x) {
				if (!comparewithmap(prev_tim, tim,
				                    prev_tim->pixels[y][x],
				                    tim->pixels[y][x],
				                    colorMap)) {
					min_y = max_y = y;
					min_x = max_x = x;
					goto break_top;
				}
			}
		}

break_top:
		if (tim->sy == min_y) {
			/* No changes in this frame!! Encode empty image. */
			transparent = 0;
			min_x = min_y = 1;
			max_x = max_y = 0;
		} else {
			/* Then the bottom row */
			for (y = tim->sy - 1; y > min_y; --y) {
				for (x = 0; x < tim->sx; ++x) {
					if (!comparewithmap
					        (prev_tim, tim,
					         prev_tim->pixels[y][x],
					         tim->pixels[y][x],
					         colorMap)) {
						max_y = y;
						if(x < min_x) {
							min_x = x;
						}
						if(x > max_x) {
							max_x = x;
						}
						goto break_bot;
					}
				}
			}

break_bot:
			/* left side */
			for (x = 0; x < min_x; ++x) {
				for (y = min_y; y <= max_y; ++y) {
					if (!comparewithmap
					        (prev_tim, tim,
					         prev_tim->pixels[y][x],
					         tim->pixels[y][x],
					         colorMap)) {
						min_x = x;
						goto break_left;
					}
				}
			}

break_left:
			/* right side */
			for (x = tim->sx - 1; x > max_x; --x) {
				for (y = min_y; y <= max_y; ++y) {
					if (!comparewithmap
					        (prev_tim, tim,
					         prev_tim->pixels[y][x],
					         tim->pixels[y][x],
					         colorMap)) {
						max_x = x;
						goto break_right;
					}
				}
			}

break_right:
			;
		}

		LeftOfs = min_x;
		TopOfs = min_y;
		Disposal = 1;

		/* Make a copy of the image with the new offsets.
		   But only if necessary. */
		if (min_x != 0 || max_x != tim->sx - 1
		        || min_y != 0 || max_y != tim->sy - 1
		        || transparent >= 0) {

			gdImagePtr pim2 = gdImageCreate(max_x-min_x + 1, max_y-min_y + 1);

			if (!pim2) {
				if (prev_pim) {
					gdImageDestroy(prev_pim);
				}
				goto fail_end;
			}

			gdImagePaletteCopy(pim2, LocalCM ? tim : prev_tim);
			gdImageCopy(pim2, tim, 0, 0, min_x, min_y,
			            max_x - min_x + 1, max_y - min_y + 1);

			if (pim) {
				gdImageDestroy(pim);
			}

			tim = pim = pim2;
		}

		/* now let's compare pixels for transparent
		   optimization.  But only if transparent is set. */
		if (transparent >= 0) {
			for(y = 0; y < tim->sy; ++y) {
				for (x = 0; x < tim->sx; ++x) {
					if(comparewithmap
					        (prev_tim, tim,
					         prev_tim->pixels[min_y + y][min_x + x],
					         tim->pixels[y][x], 0)) {
						gdImageSetPixel(tim, x, y, transparent);
						break;
					}
				}
			}
		}

		if(prev_pim) {
			gdImageDestroy(prev_pim);
		}
	}

	BitsPerPixel = colorstobpp(tim->colorsTotal);

	/* All set, let's do it. */
	GIFAnimEncode(
	    out, tim->sx, tim->sy, LeftOfs, TopOfs, interlace, transparent,
	    Delay, Disposal, BitsPerPixel,
	    LocalCM ? tim->red : 0, tim->green, tim->blue, tim);

fail_end:
	if(pim) {
		/* Destroy palette based temporary image. */
		gdImageDestroy(pim);
	}
}
コード例 #14
0
ファイル: gdgen.c プロジェクト: Goettsch/game-editor
static void
gd_bezier(point * A, int n, int arrow_at_start, int arrow_at_end, int filled)
{
    pointf p, p0, p1, V[4];
    int i, j, step;
    int style[20];
    int pen, width;
    gdImagePtr brush = NULL;
    gdPoint F[4];

    if (!im)
        return;

    if (cstk[SP].pen != P_NONE) {
        if (cstk[SP].pen == P_DASHED) {
            for (i = 0; i < 10; i++)
                style[i] = cstk[SP].pencolor;
            for (; i < 20; i++)
                style[i] = transparent;
            gdImageSetStyle(im, style, 20);
            pen = gdStyled;
        } else if (cstk[SP].pen == P_DOTTED) {
            for (i = 0; i < 2; i++)
                style[i] = cstk[SP].pencolor;
            for (; i < 12; i++)
                style[i] = transparent;
            gdImageSetStyle(im, style, 12);
            pen = gdStyled;
        } else {
            pen = cstk[SP].pencolor;
        }
        width = cstk[SP].penwidth * CompScale;
        if (width < WIDTH_NORMAL)
            width = WIDTH_NORMAL;  /* gd can't do thin lines */
        gdImageSetThickness(im, width);
        if (width > WIDTH_NORMAL) {
            brush = gdImageCreate(width, width);
            gdImagePaletteCopy(brush, im);
            gdImageFilledRectangle(brush,
                                   0, 0, width - 1, width - 1,
                                   cstk[SP].pencolor);
            gdImageSetBrush(im, brush);
            if (pen == gdStyled)
                pen = gdStyledBrushed;
            else
                pen = gdBrushed;
        }
        p.x = A[0].x;
        p.y = A[0].y;
        p = gdpt(p);
        F[0].x = ROUND(p.x);
        F[0].y = ROUND(p.y);
        p.x = A[n-1].x;
        p.y = A[n-1].y;
        p = gdpt(p);
        F[3].x = ROUND(p.x);
        F[3].y = ROUND(p.y);
        V[3].x = A[0].x;
        V[3].y = A[0].y;
        for (i = 0; i + 3 < n; i += 3) {
            V[0] = V[3];
            for (j = 1; j <= 3; j++) {
                V[j].x = A[i + j].x;
                V[j].y = A[i + j].y;
            }
            p0 = gdpt(V[0]);
            for (step = 1; step <= BEZIERSUBDIVISION; step++) {
                p1 = gdpt(Bezier
                          (V, 3, (double) step / BEZIERSUBDIVISION, NULL,
                           NULL));
                gdImageLine(im, ROUND(p0.x), ROUND(p0.y), ROUND(p1.x),
                            ROUND(p1.y), pen);
                if (filled) {
                    F[1].x = ROUND(p0.x);
                    F[1].y = ROUND(p0.y);
                    F[2].x = ROUND(p1.x);
                    F[2].y = ROUND(p1.y);
                    gdImageFilledPolygon(im, F, 4, cstk[SP].fillcolor);
                }
                p0 = p1;
            }
        }
        if (brush)
            gdImageDestroy(brush);
    }
}