Exemple #1
0
int main()
{
	gdImagePtr im;
	int x, y, c;
	FILE *out;
	char path[1024];
	int r=0;


	im = gdImageCreateTrueColor(256, 256);
	gdImageAlphaBlending( im, gdEffectReplace );
	for (x=0; x<256; x++) {
		for (y=0; y<256; y++) {
			c = (y/2 << 24) + (x << 16) + (x << 8) + x;
			gdImageSetPixel(im, x, y, c );
		}
	}
	gdImageAlphaBlending( im, gdEffectOverlay );
	gdImageFilledRectangle(im, 0, 0, 255, 255, 0xff7f00);

	if (gdTrueColorGetGreen(gdImageGetPixel(im, 0, 128)) != 0x00) {
		r = 1;
	}
	if (gdTrueColorGetGreen(gdImageGetPixel(im, 128, 128)) != 0x80) {
		r = 1;
	}
	if (gdTrueColorGetGreen(gdImageGetPixel(im, 255, 128)) != 0xff) {
		r = 1;
	}
	gdImageDestroy(im);
	return r;
}
Exemple #2
0
gdImagePtr rs_gdImageThickLineBrush(int line_weight, RS_Color& color)
{
    if (line_weight % 2 == 1)
        line_weight += 1;

    int sx = line_weight;
    int sy = line_weight;

    gdImagePtr brush = gdImageCreateTrueColor(sx, sy);
    int transparent = gdImageColorAllocateAlpha(brush, 0, 0, 0, 127);

    gdImageAlphaBlending(brush, 0);
    gdImageFilledRectangle(brush, 0, 0, sx, sy, transparent);

    //compute fractional alpha value for antialiasing effect
    //each pixel should be hit by line_weight / 2 number of circles
    //so the alpha is computed as 255 / line_weight * 2
    RS_Color falpha = color;
    falpha.alpha() = falpha.alpha() / line_weight * 2 + 1;
    falpha.alpha() = (falpha.alpha() < 255)? falpha.alpha() : 255;

    //outer transparent circle -- for antialiased effect
    rs_gdImageCircleForBrush(brush, sx/2, sy/2, line_weight / 2,  falpha);

    gdImageAlphaBlending(brush, 1);

    //inner non-transparent circle
    rs_gdImageCircleForBrush(brush, sx/2, sy/2, (line_weight - 2) / 2, color);

    return brush;
}
Exemple #3
0
result_t Image::resample(int32_t width, int32_t height,
                         obj_ptr<Image_base> &retVal, AsyncEvent *ac)
{
    if (width <= 0 || height <= 0)
        return CHECK_ERROR(CALL_E_INVALIDARG);

    if (!m_image)
        return CHECK_ERROR(CALL_E_INVALID_CALL);

    if (!ac)
        return CHECK_ERROR(CALL_E_NOSYNC);

    obj_ptr<Image> dst;
    result_t hr = New(width, height, dst);
    if (hr < 0)
        return hr;

    gdImageAlphaBlending(dst->m_image, 0);
    gdImageCopyResampled(dst->m_image, m_image, 0, 0, 0, 0, width, height,
                         gdImageSX(m_image), gdImageSY(m_image));
    gdImageAlphaBlending(dst->m_image, 1);

    retVal = dst;
    return 0;
}
Exemple #4
0
int main()
{
 	gdImagePtr im, im2;
 	int error = 0;
	char path[2048];
	const char *file_exp = "bug00132_exp.png";
	char *ret = NULL;

	im = gdImageCreateTrueColor(50, 30);

	if (!im) {
		printf("can't get truecolor image\n");
		return 1;
	}

	gdImageAlphaBlending(im, 0);
	gdImageFilledRectangle(im, 0, 0, 200, 200, gdTrueColorAlpha(0, 0, 0, 127));

	sprintf(path, "%s/freetype/DejaVuSans.ttf", GDTEST_TOP_DIR);

	ret = gdImageStringFT(im, NULL,  - 0xFFFFFF, path, 14.0, 0.0, 10, 20, "&thetasym; &theta;");
	if (ret) {
		error = 1;
		printf(ret);
	} else {
		sprintf(path, "%s/freetype/%s", GDTEST_TOP_DIR, file_exp);
		if (!gdAssertImageEqualsToFile(path, im)) {
			error = 1;
			printf("Reference image and destination differ\n");
		}
	}
	gdImageDestroy(im);
	return error;
}
Exemple #5
0
int main()
{
	gdImagePtr im;
	int bordercolor, color;

	im = gdImageCreateTrueColor(100, 100);

	gdImageAlphaBlending(im, 1);
	gdImageSaveAlpha(im, 1);
	bordercolor = gdImageColorAllocateAlpha(im, 0, 0, 0, 2);
	color = gdImageColorAllocateAlpha(im, 0, 0, 0, 1);

	gdImageFillToBorder(im, 5, 5, bordercolor, color);

	color = gdImageGetPixel(im, 5, 5);

	gdImageDestroy(im);
	if (gdTestAssert(color==0x1000000)) {
		return 0;
	} else {
		printf("c: %X, expected %X\n", color, 0x1000000);
		return -1;
	}

}
Exemple #6
0
result_t Image::set_alphaBlending(bool newVal)
{
    if (!m_image)
        return CHECK_ERROR(CALL_E_INVALID_CALL);

    gdImageAlphaBlending(m_image, newVal);
    return 0;
}
Exemple #7
0
/**
 * Function: gdImageCrop
 *
 * Crop an image to a given rectangle
 *
 * Parameters:
 *   src  - The image.
 *   crop - The cropping rectangle, see <gdRect>.
 *
 * Returns:
 *   The newly created cropped image, or NULL on failure.
 *
 * See also:
 *   - <gdImageCropAuto>
 *   - <gdImageCropThreshold>
 */
BGD_DECLARE(gdImagePtr) gdImageCrop(gdImagePtr src, const gdRect *crop)
{
	gdImagePtr dst;
	int alphaBlendingFlag;

	if (gdImageTrueColor(src)) {
		dst = gdImageCreateTrueColor(crop->width, crop->height);
	} else {
		dst = gdImageCreate(crop->width, crop->height);
	}
	if (!dst) return NULL;
	alphaBlendingFlag = dst->alphaBlendingFlag;
	gdImageAlphaBlending(dst, gdEffectReplace);
	gdImageCopy(dst, src, 0, 0, crop->x, crop->y, crop->width, crop->height);
	gdImageAlphaBlending(dst, alphaBlendingFlag);

	return dst;
}
Exemple #8
0
void hqx_scale(gdImagePtr srcIm, int factor, gdImagePtr* result)
{
    gdImagePtr dstIm;
    uint32_t *srcBuffer, *dstBuffer;
    size_t srcSize, dstSize;
    uint32_t w, h;
    uint32_t x, y;

    w = gdImageSX(srcIm);
    h = gdImageSY(srcIm);

    srcSize = sizeof(uint32_t) * w * h;
    dstSize = sizeof(uint32_t) * factor * w * factor * h;

    // Unfortunately it doesn't work to simply pass the gd buffer from the
    // gdImage struct to hqx, and the gd documentation explicitly says
    // not to access member fields directly. Thus we allocate two buffers
    // and copy the data back and forth as a workaround.

    srcBuffer = (uint32_t*)emalloc(srcSize);
    for (y = 0; y < h; y++) {
        for (x = 0; x < w; x++) {
            srcBuffer[w*y + x] = gdImageGetPixel(srcIm, x, y);
        }
    }

    dstBuffer = (uint32_t*)emalloc(dstSize);
    if (factor == 4) {
        hq4x_32_rb(srcBuffer, sizeof(uint32_t)*w,
                   dstBuffer, sizeof(uint32_t)*factor*w,
                   w, h);
    } else if (factor == 3) {
        hq3x_32_rb(srcBuffer, sizeof(uint32_t)*w,
                   dstBuffer, sizeof(uint32_t)*factor*w,
                   w, h);
    } else if (factor == 2) {
        hq2x_32_rb(srcBuffer, sizeof(uint32_t)*w,
                   dstBuffer, sizeof(uint32_t)*factor*w,
                   w, h);
    }

    dstIm = gdImageCreateTrueColor(factor*w, factor*h);
    gdImageAlphaBlending(dstIm, 0);
    gdImageSaveAlpha(dstIm, 1);

    for (y = 0; y < factor*h; y++) {
        for (x = 0; x < factor*w; x++) {
            gdImageSetPixel(dstIm, x, y, dstBuffer[factor*w*y + x]);
        }
    }

    efree(srcBuffer);
    efree(dstBuffer);

    *result = dstIm;
}
Exemple #9
0
/* If palette is true, we convert from truecolor to palette at the end,
   to test gdImageTrueColorToPalette and see file size/
   quality tradeoffs. */
void
testDrawing (gdImagePtr im_in,
	     double scale, int blending, int palette, char *filename)
{
	gdImagePtr im_out;
	FILE *out;
	/* Create output image. */
	im_out = gdImageCreateTrueColor ((int) (gdImageSX (im_in) * scale),
					 (int) (gdImageSY (im_in) * scale));
	/*
	   Request alpha blending. This causes future
	   drawing operations to perform alpha channel blending
	   with the background, resulting in an opaque image.
	   Without this call, pixels in the foreground color are
	   copied literally, *including* the alpha channel value,
	   resulting in an output image which is potentially
	   not opaque. This flag can be set and cleared as often
	   as desired. */
	gdImageAlphaBlending (im_out, blending);

	/* Flood with light blue. */
	gdImageFill (im_out, (int) (gdImageSX (im_in) * scale / 2),
		     (int) (gdImageSY (im_in) * scale / 2),
		     gdTrueColor (192, 192, 255));
	/* Copy the source image. Alpha blending should result in
	   compositing against red. With blending turned off, the
	   browser or viewer will composite against its preferred
	   background, or, if it does not support an alpha channel,
	   we will see the original colors for the pixels that
	   ought to be transparent or semitransparent. */
	gdImageCopyResampled (im_out, im_in,
			      0, 0,
			      0, 0,
			      (int) (gdImageSX (im_in) * scale),
			      (int) (gdImageSY (im_in) * scale), gdImageSX (im_in),
			      gdImageSY (im_in));
	/* Write PNG */
	out = fopen (filename, "wb");

	/* If this image is the result of alpha channel blending,
	   it will not contain an interesting alpha channel itself.
	   Save a little file size by not saving the alpha channel.
	   Otherwise the file would typically be slightly larger. */
	gdImageSaveAlpha (im_out, !blending);

	/* If requested, convert from truecolor to palette. */
	if (palette) {
		/* Dithering, 256 colors. */
		gdImageTrueColorToPalette (im_out, 1, 256);
	}

	gdImagePng (im_out, out);
	fclose (out);

	gdImageDestroy (im_out);
}
Exemple #10
0
int
main (int argc, char *argv[])
{
#ifdef HAVE_LIBFREETYPE
  	FILE *out;
	int transparent, green, black;
	gdImagePtr im;

	im = gdImageCreateTrueColor(100,100);

        black =  gdImageColorResolveAlpha(im, 0, 0, 0, gdAlphaOpaque);
        green =  gdImageColorResolveAlpha(im, 0, gdGreenMax, 0, gdAlphaOpaque);
        transparent = gdImageColorResolveAlpha(im,
                        gdRedMax-1, gdGreenMax, gdBlueMax, gdAlphaTransparent);
        gdImageColorTransparent(im, transparent);

	/* Blending must be off to lay a transparent basecolor.
                Nothing to blend with anyway. */
        gdImageAlphaBlending(im, FALSE);
        gdImageFill (im, im->sx/2, im->sy/2, transparent);
        /* Blend everything else together,
                especially fonts over non-transparent backgrounds */
        gdImageAlphaBlending(im, TRUE);

	gdImageFilledRectangle (im, 30, 30, 70, 70, green);
	gdImageStringFT (im, NULL, black, "Times", 18, 0, 50, 50, "Hello");

	gdImageSaveAlpha (im, TRUE);
#ifdef HAVE_LIBPNG
	out = fopen ("testtr.png", "wb");
	gdImagePng (im, out);
	fclose (out);
#else
	fprintf(stderr, "Compiled without libpng support\n");
#endif /* HAVE_LIBPNG */
	gdImageDestroy (im);

	return 0;
#else
	fprintf(stderr, "Compiled without freetype support\n");
	return 0;
#endif /* HAVE_LIBFREETYPE */
}
gdImagePtr rotatePixmapGD(gdImagePtr img, double angle_rad)
{
    gdImagePtr rimg = NULL;
    double cos_a, sin_a;
    double x1 = 0.0, y1 = 0.0; /* destination rectangle */
    double x2 = 0.0, y2 = 0.0;
    double x3 = 0.0, y3 = 0.0;
    double x4 = 0.0, y4 = 0.0;

    long minx, miny, maxx, maxy;

    int width=0, height=0;
    /* int color; */

    sin_a = sin(angle_rad);
    cos_a = cos(angle_rad);

    /* compute distination rectangle (x1,y1 is known) */
    x1 = 0 ;
    y1 = 0 ;
    x2 = img->sy * sin_a;
    y2 = -img->sy * cos_a;
    x3 = (img->sx * cos_a) + (img->sy * sin_a);
    y3 = (img->sx * sin_a) - (img->sy * cos_a);
    x4 = (img->sx * cos_a);
    y4 = (img->sx * sin_a);

    minx = (long) MS_MIN(x1,MS_MIN(x2,MS_MIN(x3,x4)));
    miny = (long) MS_MIN(y1,MS_MIN(y2,MS_MIN(y3,y4)));
    maxx = (long) MS_MAX(x1,MS_MAX(x2,MS_MAX(x3,x4)));
    maxy = (long) MS_MAX(y1,MS_MAX(y2,MS_MAX(y3,y4)));

    width = (int)ceil(maxx-minx);
    height = (int)ceil(maxy-miny);

    /* create the new image based on the computed width/height */

    if (gdImageTrueColor(img)) {
        rimg = gdImageCreateTrueColor(width, height);
        gdImageAlphaBlending(rimg, 0);
        gdImageFilledRectangle(rimg, 0, 0, width, height, gdImageColorAllocateAlpha(rimg, 0, 0, 0, gdAlphaTransparent));
    } else {
        int tc = gdImageGetTransparent(img);
        rimg = gdImageCreate(width, height);
        if(tc != -1)
            gdImageColorTransparent(rimg, gdImageColorAllocate(rimg, gdImageRed(img, tc), gdImageGreen(img, tc), gdImageBlue(img, tc)));
    }
    if(!rimg) {
        msSetError(MS_GDERR,"failed to create rotated pixmap","rotatePixmapGD()");
        return NULL;
    }

    gdImageCopyRotated (rimg, img, width*0.5, height*0.5, 0, 0, gdImageSX(img), gdImageSY(img), angle_rad*MS_RAD_TO_DEG);
    return rimg;
}
Exemple #12
0
int main()
{
	gdImagePtr dst_tc, src;
	int c1;

	src = gdImageCreate(5,5);
	gdImageAlphaBlending(src, 0);

	gdImageColorAllocate(src, 255,255,255); /* allocate white for background color */
	c1 = gdImageColorAllocateAlpha(src, 255,0,0,70);

	gdImageFilledRectangle(src, 0,0, 4,4, c1);

	dst_tc  = gdImageCreateTrueColor(5,5);
	gdImageAlphaBlending(dst_tc, 0);
	gdImageCopy(dst_tc, src, 0,0, 0,0, gdImageSX(src), gdImageSY(src));

	/* CuAssertImageEquals(tc, src, dst_tc); */

	/* Destroy it */
	gdImageDestroy(dst_tc);
	gdImageDestroy(src);
	return 0;
}
Exemple #13
0
static    void  set_transparency( gdImagePtr gd ){
    /*
    gdImagePtr ggg = *gd;
    if( gdImageTrueColor( ggg ) == 0 ) return;
    gdImagePtr gnew = gdImageCreatePaletteFromTrueColor( ggg, 1, 256 );
    gdImageDestroy( ggg );
    if( gdImageTrueColor( gnew ) == 1 ){
        LOGPRINT( 1, "Error horrible, no puede convertirse a paleta %p", gnew );
    }
    *gd = gnew;
    */
    // if( gdImageTrueColor( gd ) == 0 ) return;
    gdImageSaveAlpha( gd, 1 );
    gdImageAlphaBlending( gd, 0 );
}
static void make_thumb(void *conf)
{
	int colors = 0;
	int transparent = -1;
	ngx_image_conf_t *info = conf;
	info->dst_im = gdImageCreateTrueColor(info->width,info->height);
	colors = gdImageColorsTotal(info->src_im);
	transparent = gdImageGetTransparent(info->src_im);
	if (transparent == -1)
        {
		gdImageSaveAlpha(info->src_im,1);
		gdImageColorTransparent(info->src_im, -1);
		if(colors == 0)
		{
			gdImageAlphaBlending(info->dst_im,0);
			gdImageSaveAlpha(info->dst_im,1);
		}
		if(colors)
		{
			gdImageTrueColorToPalette(info->dst_im,1,256);
		}
    }
    if(info->w_margin == 1)
    {

		info->w_im = gdImageCreateTrueColor(info->width,info->height);
		gdImageFilledRectangle(info->w_im, 0, 0, info->width,info->height, gdImageColorAllocate(info->w_im, 255, 255, 255));
        info->dst_im = gdImageCreateTrueColor(info->max_width,info->max_height);
        gdImageFilledRectangle(info->dst_im, 0, 0, info->max_width,info->max_height, gdImageColorAllocate(info->dst_im, 255, 255, 255));
		gdImageCopyResampled(info->w_im, info->src_im, 0, 0, info->src_x, info->src_y,info->width, info->height, info->src_w,info->src_h);
		gdImageCopyResampled(info->dst_im, info->w_im, info->dst_x,info->dst_y, 0, 0,info->width, info->height, info->width, info->height);
        gdImageDestroy(info->w_im);
    }
    else
    {

        gdImageCopyResampled(info->dst_im,info->src_im,info->dst_x,info->dst_y,info->src_x,info->src_y,info->width,info->height,info->src_w,info->src_h);
    }
    gdImageDestroy(info->src_im);
}
Exemple #15
0
gdImagePtr renderDrawing(ei::DnaDrawing *d)
{
    // make new image, true color, with alpha support
    gdImagePtr img = 0;
    img = gdImageCreateTrueColor(ei::Tools::maxWidth, ei::Tools::maxHeight);
    if (0 == img)
    {
        std::cout << "Could not create image" << std::endl;
        return 0;
    }
    gdImageAlphaBlending(img, 1);
    int black = gdTrueColor(0,0,0);         // also acts as background

    // render image:
    // * for each polygon:
    ei::DnaPolygonList *polys = d->polygons();
    ei::DnaPolygonList::iterator iter;
    for (iter = polys->begin(); iter != polys->end(); iter++)
    {
        ei::DnaPolygon *poly = *iter;
        // ** allocate its color & alpha
        ei::DnaBrush *brush = poly->brush();
        int color = gdTrueColorAlpha(brush->r, brush->g, brush->b, brush->a);
        // ** render a closed polygon:
        // *** make array of gdPoints
        ei::DnaPointList *points = poly->points();
        gdPoint gdPts[points->size()];
        // *** translate points
        ei::DnaPointList::iterator eachPt;
        for (int i=0; i < points->size(); i++)
        {
            gdPts[i].x = (*points)[i]->x;
            gdPts[i].y = (*points)[i]->y;
        }
        // *** render via gdImageFilledPolygon().
        gdImageFilledPolygon(img, gdPts, points->size(), color);
    }

    return img;
}
Exemple #16
0
gdImagePtr blendTransparency(gdImagePtr image, int height)
{
	gdImageAlphaBlending(image, 0);
	
	int w = TARGET_WIDTH;
	int h = height;
	int h1 = h / 6;
	int h2 = 5 * h1;
	int l1 = w / 6;
	int l2 = 5 * 11;
	int row, col;
	
	for (row = 0; row < h; row++) {
		for (col = 0; col < w; col++) {
			int aval = 40;
			
			if ((row < h1) || (row > h2))
				aval = 80;
			else
				if ((col < l1) || (col > l2))
					aval = 80;
			
			int c = gdImageGetPixel(image, col, row);
			int r = gdImageRed(image, c);
			int g = gdImageGreen(image, c);
			int b = gdImageBlue(image, c);
			int c1 = gdImageColorAllocateAlpha(image, r, g, b, aval);
			
			gdImageSetPixel(image, col, row, c1);
		}
	}
	
	gdImageSaveAlpha(image, 1);
	
	return image;
}
static ngx_buf_t *
ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
{
    int                            sx, sy, dx, dy, ox, oy, ax, ay, size,
                                   colors, palette, transparent, sharpen,
                                   red, green, blue, t,
                                   offset_x, offset_y;
    u_char                        *out;
    ngx_buf_t                     *b;
    ngx_uint_t                     resize;
    gdImagePtr                     src, dst;
    ngx_pool_cleanup_t            *cln;
    ngx_http_image_filter_conf_t  *conf;

    src = ngx_http_image_source(r, ctx);

    if (src == NULL) {
        return NULL;
    }

    sx = gdImageSX(src);
    sy = gdImageSY(src);

    conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);

    if (!ctx->force
        && ctx->angle == 0
        && (ngx_uint_t) sx <= ctx->max_width
        && (ngx_uint_t) sy <= ctx->max_height)
    {
        gdImageDestroy(src);
        return ngx_http_image_asis(r, ctx);
    }

    colors = gdImageColorsTotal(src);

    if (colors && conf->transparency) {
        transparent = gdImageGetTransparent(src);

        if (transparent != -1) {
            palette = colors;
            red = gdImageRed(src, transparent);
            green = gdImageGreen(src, transparent);
            blue = gdImageBlue(src, transparent);

            goto transparent;
        }
    }

    palette = 0;
    transparent = -1;
    red = 0;
    green = 0;
    blue = 0;

transparent:

    gdImageColorTransparent(src, -1);

    dx = sx;
    dy = sy;

    if (conf->filter == NGX_HTTP_IMAGE_RESIZE) {

        if ((ngx_uint_t) dx > ctx->max_width) {
            dy = dy * ctx->max_width / dx;
            dy = dy ? dy : 1;
            dx = ctx->max_width;
        }

        if ((ngx_uint_t) dy > ctx->max_height) {
            dx = dx * ctx->max_height / dy;
            dx = dx ? dx : 1;
            dy = ctx->max_height;
        }

        resize = 1;

    } else if (conf->filter == NGX_HTTP_IMAGE_ROTATE) {

        resize = 0;

    } else { /* NGX_HTTP_IMAGE_CROP */

        resize = 0;

        if ((double) dx / dy < (double) ctx->max_width / ctx->max_height) {
            if ((ngx_uint_t) dx > ctx->max_width) {
                dy = dy * ctx->max_width / dx;
                dy = dy ? dy : 1;
                dx = ctx->max_width;
                resize = 1;
            }

        } else {
            if ((ngx_uint_t) dy > ctx->max_height) {
                dx = dx * ctx->max_height / dy;
                dx = dx ? dx : 1;
                dy = ctx->max_height;
                resize = 1;
            }
        }
    }

    if (resize) {
        dst = ngx_http_image_new(r, dx, dy, palette);
        if (dst == NULL) {
            gdImageDestroy(src);
            return NULL;
        }

        if (colors == 0) {
            gdImageSaveAlpha(dst, 1);
            gdImageAlphaBlending(dst, 0);
        }

        gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy);

        if (colors) {
            gdImageTrueColorToPalette(dst, 1, 256);
        }

        gdImageDestroy(src);

    } else {
        dst = src;
    }

    if (ctx->angle) {
        src = dst;

        ax = (dx % 2 == 0) ? 1 : 0;
        ay = (dy % 2 == 0) ? 1 : 0;

        switch (ctx->angle) {

        case 90:
        case 270:
            dst = ngx_http_image_new(r, dy, dx, palette);
            if (dst == NULL) {
                gdImageDestroy(src);
                return NULL;
            }
            if (ctx->angle == 90) {
                ox = dy / 2 + ay;
                oy = dx / 2 - ax;

            } else {
                ox = dy / 2 - ay;
                oy = dx / 2 + ax;
            }

            gdImageCopyRotated(dst, src, ox, oy, 0, 0,
                               dx + ax, dy + ay, ctx->angle);
            gdImageDestroy(src);

            t = dx;
            dx = dy;
            dy = t;
            break;

        case 180:
            dst = ngx_http_image_new(r, dx, dy, palette);
            if (dst == NULL) {
                gdImageDestroy(src);
                return NULL;
            }
            gdImageCopyRotated(dst, src, dx / 2 - ax, dy / 2 - ay, 0, 0,
                               dx + ax, dy + ay, ctx->angle);
            gdImageDestroy(src);
            break;
        }
    }

    if (conf->filter == NGX_HTTP_IMAGE_CROP) {

        src = dst;

        if ((ngx_uint_t) dx > ctx->max_width) {
            ox = dx - ctx->max_width;

        } else {
            ox = 0;
        }

        if ((ngx_uint_t) dy > ctx->max_height) {
            oy = dy - ctx->max_height;

        } else {
            oy = 0;
        }

        if (ox || oy) {

            dst = ngx_http_image_new(r, dx - ox, dy - oy, colors);

            if (dst == NULL) {
                gdImageDestroy(src);
                return NULL;
            }

            offset_x = ngx_http_image_filter_get_value(r, conf->oxcv,
                                                       conf->offset_x);
            offset_y = ngx_http_image_filter_get_value(r, conf->oycv,
                                                       conf->offset_y);

            if (offset_x == NGX_HTTP_IMAGE_OFFSET_LEFT) {
                ox = 0;

            } else if (offset_x == NGX_HTTP_IMAGE_OFFSET_CENTER) {
                ox /= 2;
            }

            if (offset_y == NGX_HTTP_IMAGE_OFFSET_TOP) {
                oy = 0;

            } else if (offset_y == NGX_HTTP_IMAGE_OFFSET_CENTER) {
                oy /= 2;
            }

            ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "image crop: %d x %d @ %d x %d",
                           dx, dy, ox, oy);

            if (colors == 0) {
                gdImageSaveAlpha(dst, 1);
                gdImageAlphaBlending(dst, 0);
            }

            gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy);

            if (colors) {
                gdImageTrueColorToPalette(dst, 1, 256);
            }

            gdImageDestroy(src);
        }
    }

    if (transparent != -1 && colors) {
        gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue));
    }

    sharpen = ngx_http_image_filter_get_value(r, conf->shcv, conf->sharpen);
    if (sharpen > 0) {
        gdImageSharpen(dst, sharpen);
    }

    out = ngx_http_image_out(r, ctx->type, dst, &size);

    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "image: %d x %d %d", sx, sy, colors);

    gdImageDestroy(dst);
    ngx_pfree(r->pool, ctx->image);

    if (out == NULL) {
        return NULL;
    }

    cln = ngx_pool_cleanup_add(r->pool, 0);
    if (cln == NULL) {
        gdFree(out);
        return NULL;
    }

    b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
    if (b == NULL) {
        gdFree(out);
        return NULL;
    }

    cln->handler = ngx_http_image_cleanup;
    cln->data = out;

    b->pos = out;
    b->last = out + size;
    b->memory = 1;
    b->last_buf = 1;

    ngx_http_image_length(r, b);

    return b;
}
bool GdImageRenderer::create(
    const WaveformBuffer& buffer,
    const double start_time,
    const int image_width,
    const int image_height,
    const WaveformColors& colors,
    const bool render_axis_labels)
{
    if (start_time < 0.0) {
        error_stream << "Invalid start time: minimum 0\n";
        return false;
    }
    else if (start_time > MAX_START_TIME) {
        error_stream << "Invalid start time: maximum " << MAX_START_TIME << '\n';
        return false;
    }

    if (image_width < 1) {
        error_stream << "Invalid image width: minimum 1\n";
        return false;
    }

    if (image_height < 1) {
        error_stream << "Invalid image height: minimum 1\n";
        return false;
    }

    const int sample_rate = buffer.getSampleRate();

    if (sample_rate > MAX_SAMPLE_RATE) {
        error_stream << "Invalid sample rate: " << sample_rate
                     << " Hz, maximum " << MAX_SAMPLE_RATE << " Hz\n";
        return false;
    }

    const int samples_per_pixel = buffer.getSamplesPerPixel();

    if (samples_per_pixel > MAX_ZOOM) {
        error_stream << "Invalid zoom: maximum " << MAX_ZOOM << '\n';
        return false;
    }

    image_ = gdImageCreateTrueColor(image_width, image_height);

    if (image_ == nullptr) {
        error_stream << "Failed to create image\n";
        return false;
    }

    assert(sample_rate != 0);
    assert(samples_per_pixel != 0);

    image_width_        = image_width;
    image_height_       = image_height;
    start_time_         = start_time;
    sample_rate_        = buffer.getSampleRate();
    samples_per_pixel_  = samples_per_pixel;
    start_index_        = secondsToPixels(start_time);
    render_axis_labels_ = render_axis_labels;

    output_stream << "Image dimensions: " << image_width_ << "x" << image_height_ << " pixels"
                  << "\nSample rate: " << sample_rate_ << " Hz"
                  << "\nSamples per pixel: " << samples_per_pixel_
                  << "\nStart time: " << start_time_ << " seconds"
                  << "\nStart index: " << start_index_
                  << "\nBuffer size: " << buffer.getSize()
                  << "\nAxis labels: " << (render_axis_labels_ ? "yes" : "no") << std::endl;

    if (colors.hasAlpha()) {
        gdImageSaveAlpha(image_, 1);
        gdImageAlphaBlending(image_, 0);
    }

    initColors(colors);
    drawBackground();

    if (render_axis_labels_) {
        drawBorder();
    }

    drawWaveform(buffer);

    if (render_axis_labels_) {
        drawTimeAxisLabels();
    }

    return true;
}
Exemple #19
0
/*
	Function: gdImageCreateFromTgaCtx

	Creates a gdImage from a gdIOCtx referencing a TGA binary file.

	Parameters:
		ctx - Pointer to a gdIOCtx structure
 */
BGD_DECLARE(gdImagePtr) gdImageCreateFromTgaCtx(gdIOCtx* ctx)
{
	int bitmap_caret = 0;
	oTga *tga = NULL;
	/*	int pixel_block_size = 0;
		int image_block_size = 0; */
	volatile gdImagePtr image = NULL;
	int x = 0;
	int y = 0;

	tga = (oTga *) gdMalloc(sizeof(oTga));
	if (!tga) {
		return NULL;
	}

	tga->bitmap = NULL;
	tga->ident = NULL;

	if (read_header_tga(ctx, tga) < 0) {
		free_tga(tga);
		return NULL;
	}

	/*TODO: Will this be used?
		pixel_block_size = tga->bits / 8;
		image_block_size = (tga->width * tga->height) * pixel_block_size;
	*/

	if (read_image_tga(ctx, tga) < 0) {
		free_tga(tga);
		return NULL;
	}

	image = gdImageCreateTrueColor((int)tga->width, (int)tga->height );

	if (image == 0) {
		free_tga( tga );
		return NULL;
	}

	/*!	\brief Populate GD image object
	 *  Copy the pixel data from our tga bitmap buffer into the GD image
	 *  Disable blending and save the alpha channel per default
	 */
	if (tga->alphabits) {
		gdImageAlphaBlending(image, 0);
		gdImageSaveAlpha(image, 1);
	}

	/* TODO: use alphabits as soon as we support 24bit and other alpha bps (ie != 8bits) */
	for (y = 0; y < tga->height; y++) {
		register int *tpix = image->tpixels[y];
		for ( x = 0; x < tga->width; x++, tpix++) {
			if (tga->bits == TGA_BPP_24) {
				*tpix = gdTrueColor(tga->bitmap[bitmap_caret + 2], tga->bitmap[bitmap_caret + 1], tga->bitmap[bitmap_caret]);
				bitmap_caret += 3;
			} else if (tga->bits == TGA_BPP_32 && tga->alphabits) {
				register int a = tga->bitmap[bitmap_caret + 3];

				*tpix = gdTrueColorAlpha(tga->bitmap[bitmap_caret + 2], tga->bitmap[bitmap_caret + 1], tga->bitmap[bitmap_caret], gdAlphaMax - (a >> 1));
				bitmap_caret += 4;
			}
		}
	}

	if (tga->flipv && tga->fliph) {
		gdImageFlipBoth(image);
	} else if (tga->flipv) {
		gdImageFlipVertical(image);
	} else if (tga->fliph) {
		gdImageFlipHorizontal(image);
	}

	free_tga(tga);

	return image;
}
ngx_int_t ngx_http_small_light_gd_process(ngx_http_request_t *r, ngx_http_small_light_ctx_t *ctx)
{
    ngx_http_small_light_gd_ctx_t     *ictx;
    ngx_http_small_light_image_size_t  sz;
    gdImagePtr                         src, dst, canvas;
    ngx_int_t                          colors, transparent, palette, red, green, blue;
    ngx_int_t                          ax, ay, ox, oy, type;
    int                                iw, ih, radius, ccolor, bcolor;
    char                              *sharpen, *of;
    u_char                            *out;
    int                                size;
    double                             q;

    ictx = (ngx_http_small_light_gd_ctx_t *)ctx->ictx;
    src  = ngx_http_small_light_gd_src(ictx);
    if (src == NULL) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "failed to get image source %s:%d",
                      __FUNCTION__,
                      __LINE__);
        return NGX_ERROR;
    }

    /* adjust image size */
    iw = gdImageSX(src);
    ih = gdImageSY(src);
    ngx_http_small_light_calc_image_size(r, ctx, &sz, iw, ih);

    colors      = gdImageColorsTotal(src);
    palette     = 0;
    transparent = -1;
    red         = 0;
    green       = 0;
    blue        = 0;

    if (colors) {
        transparent = gdImageGetTransparent(src);

        if (transparent != -1) {
            palette = colors;
            red     = gdImageRed(src,   transparent);
            green   = gdImageGreen(src, transparent);
            blue    = gdImageBlue(src,  transparent);
        }
    }

    gdImageColorTransparent(src, -1);

    /* rotate. */
    if (sz.angle) {
        dst = src;
        ax  = (iw % 2 == 0) ? 1 : 0;
        ay  = (ih % 2 == 0) ? 1 : 0;
        switch (sz.angle) {
        case 90:
        case 270:
            dst = ngx_http_small_light_gd_new(ih, iw, palette);
            if (dst == NULL) {
                gdImageDestroy(src);
                return NGX_ERROR;
            }

            if (sz.angle == 90) {
                ox = ih / 2 - ay;
                oy = iw / 2 + ax;
            } else {
                ox = ih / 2 + ay;
                oy = iw / 2 - ax;
            }

            gdImageCopyRotated(dst, src, ox, oy, 0, 0,
                               iw, ih, -sz.angle);
            gdImageDestroy(src);

            break;
        case 180:
            dst = ngx_http_small_light_gd_new(iw, ih, palette);
            if (dst == NULL) {
                gdImageDestroy(src);
                return NGX_ERROR;
            }
            gdImageCopyRotated(dst, src, iw / 2 - ax, ih / 2 - ay, 0, 0,
                               iw + ax, ih + ay, sz.angle);
            gdImageDestroy(src);
            break;
        default:
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                          "image not rotated. 'angle'(%ui) must be 90 or 180 or 270. %s:%d",
                          sz.angle,
                          __FUNCTION__,
                          __LINE__);
            break;
        }
        src = dst;
    }

    /* calc size. */
    iw = gdImageSX(src);
    ih = gdImageSY(src);
    ngx_http_small_light_calc_image_size(r, ctx, &sz, iw, ih);

    /* pass through. */
    if (sz.pt_flg != 0) {
        gdImageDestroy(src);
        ctx->of = ctx->inf;
        return NGX_OK;
    }

    /* crop, scale. */
    if (sz.scale_flg != 0) {
        dst = ngx_http_small_light_gd_new(sz.dw, sz.dh, palette);
        if (dst == NULL) {
            gdImageDestroy(src);
            return NGX_ERROR;
        }

        if (colors == 0) {
            gdImageSaveAlpha(dst, 1);
            gdImageAlphaBlending(dst, 0);
        }

        gdImageCopyResampled(dst, src, 0, 0, sz.sx, sz.sy, sz.dw, sz.dh, sz.sw, sz.sh);

        if (colors) {
            gdImageTrueColorToPalette(dst, 1, 256);
        }

        gdImageDestroy(src);
    } else {
        dst = src;
    }

    if (transparent != -1 && colors) {
        gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue));
    }

    /* effects. */
    sharpen = NGX_HTTP_SMALL_LIGHT_PARAM_GET_LIT(&ctx->hash, "sharpen");
    if (sharpen != NULL) {
        radius = ngx_http_small_light_parse_int(sharpen);
        if (radius > 0) {
            gdImageSharpen(dst, radius);
        }
    }

    /* interlace */
    gdImageInterlace(dst, 1);

    /* create canvas then draw image to the canvas. */
    if (sz.cw > 0.0 && sz.ch > 0.0) {
        canvas = gdImageCreateTrueColor(sz.cw, sz.ch);
        if (canvas == NULL) {
            gdImageDestroy(dst);
            return NGX_ERROR;
        }
        ccolor = gdImageColorAllocateAlpha(canvas, sz.cc.r, sz.cc.g, sz.cc.b, sz.cc.a);
        gdImageFilledRectangle(canvas, 0, 0, sz.cw, sz.ch, ccolor);
        gdImageCopy(canvas, dst, sz.dx, sz.dy, 0, 0, sz.dw, sz.dh);
        gdImageDestroy(dst);
        dst = canvas;
    }

    /* border. */
    if (sz.bw > 0.0 || sz.bh > 0.0) {
        bcolor = gdImageColorAllocateAlpha(dst, sz.bc.r, sz.bc.g, sz.bc.b, sz.bc.a);
        if (sz.cw > 0.0 && sz.ch > 0.0) {
            gdImageFilledRectangle(dst, 0, 0, sz.cw, sz.bh, bcolor);
            gdImageFilledRectangle(dst, 0, 0, sz.bw, sz.ch, bcolor);
            gdImageFilledRectangle(dst, 0, sz.ch - sz.bh, sz.cw - 1, sz.ch - 1, bcolor);
            gdImageFilledRectangle(dst, sz.cw - sz.bw, 0, sz.cw - 1, sz.ch - 1, bcolor);
        } else {
            gdImageFilledRectangle(dst, 0, 0, sz.dw, sz.bh, bcolor);
            gdImageFilledRectangle(dst, 0, 0, sz.bw, sz.dh, bcolor);
            gdImageFilledRectangle(dst, 0, sz.dh - sz.bh, sz.dw - 1, sz.dh - 1, bcolor);
            gdImageFilledRectangle(dst, sz.dw - sz.bw, 0, sz.dw - 1, sz.dh - 1, bcolor);
        }
    }

    of = NGX_HTTP_SMALL_LIGHT_PARAM_GET_LIT(&ctx->hash, "of");
    if (ngx_strlen(of) > 0) {
        type = ngx_http_small_light_type(of);
        if (type == NGX_HTTP_SMALL_LIGHT_IMAGE_NONE) {
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                          "of is invalid(%s) %s:%d",
                          of,
                          __FUNCTION__,
                          __LINE__);
        } else if (type == NGX_HTTP_SMALL_LIGHT_IMAGE_WEBP) {
#ifdef NGX_HTTP_SMALL_LIGHT_GD_WEBP_ENABLED
            ictx->type = type;
#else
            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                          "WebP is not supported %s:%d",
                          __FUNCTION__,
                          __LINE__);
#endif
        } else {
            ictx->type = type;
        }
    }

    ctx->of = ngx_http_small_light_image_types[ictx->type - 1];

    q = ngx_http_small_light_parse_double(NGX_HTTP_SMALL_LIGHT_PARAM_GET_LIT(&ctx->hash, "q"));
    if (q == 0) {
        q = 100;
    }
    out = ngx_http_small_light_gd_out(dst, ictx->type, (int *)&size, q);
    gdImageDestroy(dst);

    if (out == NULL) {
        return NGX_ERROR;
    }

    /* get small_lighted image as binary. */
    ctx->content        = out;
    ctx->content_length = size;

    ngx_pfree(r->pool, ctx->content_orig);

    ictx->complete = 1;

    return NGX_OK;
}
static ngx_buf_t *
ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
{
    int                            sx, sy, dx, dy, ox, oy, size,
                                   colors, palette, transparent,
                                   red, green, blue;
    u_char                        *out;
    ngx_buf_t                     *b;
    ngx_uint_t                     resize;
    gdImagePtr                     src, dst;
    ngx_pool_cleanup_t            *cln;
    ngx_http_image_filter_conf_t  *conf;

    src = ngx_http_image_source(r, ctx);

    if (src == NULL) {
        return NULL;
    }

    sx = gdImageSX(src);
    sy = gdImageSY(src);

    conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);

    if (!ctx->force
        && (ngx_uint_t) sx <= ctx->max_width
        && (ngx_uint_t) sy <= ctx->max_height)
    {
        gdImageDestroy(src);
        return ngx_http_image_asis(r, ctx);
    }

    colors = gdImageColorsTotal(src);

    if (colors && conf->transparency) {
        transparent = gdImageGetTransparent(src);

        if (transparent != -1) {
            palette = colors;
            red = gdImageRed(src, transparent);
            green = gdImageGreen(src, transparent);
            blue = gdImageBlue(src, transparent);

            goto transparent;
        }
    }

    palette = 0;
    transparent = -1;
    red = 0;
    green = 0;
    blue = 0;

transparent:

    gdImageColorTransparent(src, -1);

    dx = sx;
    dy = sy;

    if (conf->filter == NGX_HTTP_IMAGE_RESIZE) {

        if ((ngx_uint_t) dx > ctx->max_width) {
            dy = dy * ctx->max_width / dx;
            dy = dy ? dy : 1;
            dx = ctx->max_width;
        }

        if ((ngx_uint_t) dy > ctx->max_height) {
            dx = dx * ctx->max_height / dy;
            dx = dx ? dx : 1;
            dy = ctx->max_height;
        }

        resize = 1;

    } else { /* NGX_HTTP_IMAGE_CROP */

        resize = 0;

        if ((ngx_uint_t) (dx * 100 / dy)
            < ctx->max_width * 100 / ctx->max_height)
        {
            if ((ngx_uint_t) dx > ctx->max_width) {
                dy = dy * ctx->max_width / dx;
                dy = dy ? dy : 1;
                dx = ctx->max_width;
                resize = 1;
            }

        } else {
            if ((ngx_uint_t) dy > ctx->max_height) {
                dx = dx * ctx->max_height / dy;
                dx = dx ? dx : 1;
                dy = ctx->max_height;
                resize = 1;
            }
        }
    }

    if (resize) {
        dst = ngx_http_image_new(r, dx, dy, palette);
        if (dst == NULL) {
            gdImageDestroy(src);
            return NULL;
        }

        if (colors == 0) {
            gdImageSaveAlpha(dst, 1);
            gdImageAlphaBlending(dst, 0);
        }

        gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy);

        if (colors) {
            gdImageTrueColorToPalette(dst, 1, 256);
        }

        gdImageDestroy(src);

    } else {
        dst = src;
    }

    if (conf->filter == NGX_HTTP_IMAGE_CROP) {

        src = dst;

        if ((ngx_uint_t) dx > ctx->max_width) {
            ox = dx - ctx->max_width;

        } else {
            ox = 0;
        }

        if ((ngx_uint_t) dy > ctx->max_height) {
            oy = dy - ctx->max_height;

        } else {
            oy = 0;
        }

        if (ox || oy) {

            dst = ngx_http_image_new(r, dx - ox, dy - oy, colors);

            if (dst == NULL) {
                gdImageDestroy(src);
                return NULL;
            }

            ox /= 2;
            oy /= 2;

            ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "image crop: %d x %d @ %d x %d",
                           dx, dy, ox, oy);

            if (colors == 0) {
                gdImageSaveAlpha(dst, 1);
                gdImageAlphaBlending(dst, 0);
            }

            gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy);

            if (colors) {
                gdImageTrueColorToPalette(dst, 1, 256);
            }

            gdImageDestroy(src);
        }
    }

    if (transparent != -1 && colors) {
        gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue));
    }

    out = ngx_http_image_out(r, ctx->type, dst, &size);

    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "image: %d x %d %d", sx, sy, colors);

    gdImageDestroy(dst);
    ngx_pfree(r->pool, ctx->image);

    if (out == NULL) {
        return NULL;
    }

    cln = ngx_pool_cleanup_add(r->pool, 0);
    if (cln == NULL) {
        gdFree(out);
        return NULL;
    }

    b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
    if (b == NULL) {
        gdFree(out);
        return NULL;
    }

    cln->handler = ngx_http_image_cleanup;
    cln->data = out;

    b->pos = out;
    b->last = out + size;
    b->memory = 1;
    b->last_buf = 1;

    ngx_http_image_length(r, b);

    return b;
}
static VALUE fir_resize_image(VALUE self, VALUE raw_filename_in, VALUE raw_filename_out, VALUE raw_width, VALUE raw_height, VALUE raw_image_type, VALUE raw_jpeg_quality) {
  gdImagePtr im_in, im_out;
  FILE *in, *out;
  char *filename_in; char *filename_out;
  int w; int h; int image_type; int jpeg_quality;
  int trans = 0, x = 0, y = 0, f = 0;

  filename_in = RSTRING_PTR(raw_filename_in);
  filename_out = RSTRING_PTR(raw_filename_out);
  w = NUM2INT(raw_width);
  h = NUM2INT(raw_height);
  image_type = NUM2INT(raw_image_type);
  jpeg_quality = NUM2INT(raw_jpeg_quality);

  in = fopen(filename_in, "rb");
  if (!in) return Qnil;

  switch(image_type) {
    case 0: im_in = gdImageCreateFromJpeg(in);
            break;
    case 1: im_in = gdImageCreateFromPng(in);
            break;
    case 2: im_in = gdImageCreateFromGif(in);
            trans = gdImageGetTransparent(im_in);
            /* find a transparent pixel, then turn off transparency
               so that it copies correctly */
            if (trans >= 0) {
              for (x=0; x<gdImageSX(im_in); x++) {
                for (y=0; y<gdImageSY(im_in); y++) {
                  if (gdImageGetPixel(im_in, x, y) == trans) {
                    f = 1;
                    break;
                  }
                }
                if (f) break;
              }
              gdImageColorTransparent(im_in, -1);
              if (!f) trans = -1;  /* no transparent pixel found */
            }
            break;
    default: return Qnil;
  }

  if (w == 0 || h == 0) {
    int originalWidth  = gdImageSX(im_in);
    int originalHeight = gdImageSY(im_in);
    if (w == 0) {
      w = (int)(h * originalWidth / originalHeight);
    } else {
      h = (int)(w * originalHeight / originalWidth);
    }
  }

  im_out = gdImageCreateTrueColor(w, h);  /* must be truecolor */

  if (image_type == 1) {
    gdImageAlphaBlending(im_out, 0);  /* handle transparency correctly */
    gdImageSaveAlpha(im_out, 1);
  }
  
  fclose(in);
  
  /* Now copy the original */
  gdImageCopyResampled(im_out, im_in, 0, 0, 0, 0,
    gdImageSX(im_out), gdImageSY(im_out),
    gdImageSX(im_in), gdImageSY(im_in));

  out = fopen(filename_out, "wb");
  if (out) {
    switch(image_type) {
      case 0: gdImageJpeg(im_out, out, jpeg_quality);
              break;
      case 1: gdImagePng(im_out, out);
              break;
      case 2: gdImageTrueColorToPalette(im_out, 0, 256);
              if (trans >= 0) {
                trans = gdImageGetPixel(im_out, x, y);  /* get the color index of our transparent pixel */
                gdImageColorTransparent(im_out, trans); /* may not always work as hoped */
              }
              gdImageGif(im_out, out);
              break;
    }
    fclose(out);
  }
  gdImageDestroy(im_in);
  gdImageDestroy(im_out);
  return Qnil;
}
static ngx_buf_t *
ngx_http_image_resize(ngx_http_request_t *r, ngx_http_image_filter_ctx_t *ctx)
{
    int                            sx, sy, dx, dy, ox, oy, ax, ay, size,
                                   colors, palette, transparent, sharpen,
                                   red, green, blue, t;
    u_char                        *out;
    ngx_buf_t                     *b;
    ngx_uint_t                     resize;
    gdImagePtr                     src, dst;
    ngx_pool_cleanup_t            *cln;
    ngx_http_image_filter_conf_t  *conf;

    src = ngx_http_image_source(r, ctx);

    if (src == NULL) {
        return NULL;
    }

    sx = gdImageSX(src);
    sy = gdImageSY(src);

    conf = ngx_http_get_module_loc_conf(r, ngx_http_image_filter_module);

    if (!ctx->force
        && ctx->angle == 0
        && (ngx_uint_t) sx <= ctx->max_width
        && (ngx_uint_t) sy <= ctx->max_height)
    {
        gdImageDestroy(src);
        return ngx_http_image_asis(r, ctx);
    }

    colors = gdImageColorsTotal(src);

    if (colors && conf->transparency) {
        transparent = gdImageGetTransparent(src);

        if (transparent != -1) {
            palette = colors;
            red = gdImageRed(src, transparent);
            green = gdImageGreen(src, transparent);
            blue = gdImageBlue(src, transparent);

            goto transparent;
        }
    }

    palette = 0;
    transparent = -1;
    red = 0;
    green = 0;
    blue = 0;

transparent:

    gdImageColorTransparent(src, -1);

    dx = sx;
    dy = sy;

    if (conf->filter == NGX_HTTP_IMAGE_RESIZE) {

        if ((ngx_uint_t) dx > ctx->max_width) {
            dy = dy * ctx->max_width / dx;
            dy = dy ? dy : 1;
            dx = ctx->max_width;
        }

        if ((ngx_uint_t) dy > ctx->max_height) {
            dx = dx * ctx->max_height / dy;
            dx = dx ? dx : 1;
            dy = ctx->max_height;
        }

        resize = 1;

    } else if (conf->filter == NGX_HTTP_IMAGE_ROTATE) {

        resize = 0;

    } else if (conf->filter == NGX_HTTP_IMAGE_WATERMARK) {

        resize = 0;

    } else { /* NGX_HTTP_IMAGE_CROP */

        resize = 0;

        if ((double) dx / dy < (double) ctx->max_width / ctx->max_height) {
            if ((ngx_uint_t) dx > ctx->max_width) {
                dy = dy * ctx->max_width / dx;
                dy = dy ? dy : 1;
                dx = ctx->max_width;
                resize = 1;
            }

        } else {
            if ((ngx_uint_t) dy > ctx->max_height) {
                dx = dx * ctx->max_height / dy;
                dx = dx ? dx : 1;
                dy = ctx->max_height;
                resize = 1;
            }
        }
    }

    if (resize) {
        dst = ngx_http_image_new(r, dx, dy, palette);
        if (dst == NULL) {
            gdImageDestroy(src);
            return NULL;
        }

        if (colors == 0) {
            gdImageSaveAlpha(dst, 1);
            gdImageAlphaBlending(dst, 0);
        }

        gdImageCopyResampled(dst, src, 0, 0, 0, 0, dx, dy, sx, sy);

        if (colors) {
            gdImageTrueColorToPalette(dst, 1, 256);
        }

        gdImageDestroy(src);

    } else {
        dst = src;
    }

    if (ctx->angle) {
        src = dst;

        ax = (dx % 2 == 0) ? 1 : 0;
        ay = (dy % 2 == 0) ? 1 : 0;

        switch (ctx->angle) {

        case 90:
        case 270:
            dst = ngx_http_image_new(r, dy, dx, palette);
            if (dst == NULL) {
                gdImageDestroy(src);
                return NULL;
            }
            if (ctx->angle == 90) {
                ox = dy / 2 + ay;
                oy = dx / 2 - ax;

            } else {
                ox = dy / 2 - ay;
                oy = dx / 2 + ax;
            }

            gdImageCopyRotated(dst, src, ox, oy, 0, 0,
                               dx + ax, dy + ay, ctx->angle);
            gdImageDestroy(src);

            t = dx;
            dx = dy;
            dy = t;
            break;

        case 180:
            dst = ngx_http_image_new(r, dx, dy, palette);
            if (dst == NULL) {
                gdImageDestroy(src);
                return NULL;
            }
            gdImageCopyRotated(dst, src, dx / 2 - ax, dy / 2 - ay, 0, 0,
                               dx + ax, dy + ay, ctx->angle);
            gdImageDestroy(src);
            break;
        }
    }

    if (conf->filter == NGX_HTTP_IMAGE_CROP) {

        src = dst;

        if ((ngx_uint_t) dx > ctx->max_width) {
            ox = dx - ctx->max_width;

        } else {
            ox = 0;
        }

        if ((ngx_uint_t) dy > ctx->max_height) {
            oy = dy - ctx->max_height;

        } else {
            oy = 0;
        }

        if (ox || oy) {

            dst = ngx_http_image_new(r, dx - ox, dy - oy, colors);

            if (dst == NULL) {
                gdImageDestroy(src);
                return NULL;
            }

            ox /= 2;
            oy /= 2;

            ngx_log_debug4(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "image crop: %d x %d @ %d x %d",
                           dx, dy, ox, oy);

            if (colors == 0) {
                gdImageSaveAlpha(dst, 1);
                gdImageAlphaBlending(dst, 0);
            }

            gdImageCopy(dst, src, 0, 0, ox, oy, dx - ox, dy - oy);

            if (colors) {
                gdImageTrueColorToPalette(dst, 1, 256);
            }

            gdImageDestroy(src);
        }
    }

    if (transparent != -1 && colors) {
        gdImageColorTransparent(dst, gdImageColorExact(dst, red, green, blue));
    }

    if (conf->filter == NGX_HTTP_IMAGE_WATERMARK && conf->watermark.data) {
        FILE *watermark_file = fopen((const char *)conf->watermark.data, "r");

        if (watermark_file) {
            gdImagePtr watermark, watermark_mix;
            ngx_int_t wdx = 0, wdy = 0;

            watermark = gdImageCreateFromPng(watermark_file);

            if(watermark != NULL) {
                watermark_mix = gdImageCreateTrueColor(watermark->sx, watermark->sy);

                if (ngx_strcmp(conf->watermark_position.data, "bottom-right") == 0) {
                    wdx = dx - watermark->sx - 10;
                    wdy = dy - watermark->sy - 10;
                } else if (ngx_strcmp(conf->watermark_position.data, "top-left") == 0) {
                    wdx = wdy = 10;
                } else if (ngx_strcmp(conf->watermark_position.data, "top-right") == 0) {
                    wdx = dx - watermark->sx - 10;
                    wdy = 10;
                } else if (ngx_strcmp(conf->watermark_position.data, "bottom-left") == 0) {
                    wdx = 10;
                    wdy = dy - watermark->sy - 10;
                } else if (ngx_strcmp(conf->watermark_position.data, "center") == 0) {
                    wdx = dx / 2 - watermark->sx / 2;
                    wdy = dy / 2 - watermark->sy / 2;
                }

                gdImageCopy(watermark_mix, dst, 0, 0, wdx, wdy, watermark->sx, watermark->sy);
                gdImageCopy(watermark_mix, watermark, 0, 0, 0, 0, watermark->sx, watermark->sy);
                gdImageCopyMerge(dst, watermark_mix, wdx, wdy, 0, 0, watermark->sx, watermark->sy, 75);
                gdFree(watermark);
                gdFree(watermark_mix);

            } else { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "watermark file '%s' is not PNG", conf->watermark.data);}

        } else {

            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "watermark file '%s' not found", conf->watermark.data);
        }
    }

    sharpen = ngx_http_image_filter_get_value(r, conf->shcv, conf->sharpen);
    if (sharpen > 0) {
        gdImageSharpen(dst, sharpen);
    }

    gdImageInterlace(dst, (int) conf->interlace);

    out = ngx_http_image_out(r, ctx->type, dst, &size);

    ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "image: %d x %d %d", sx, sy, colors);

    gdImageDestroy(dst);
    ngx_pfree(r->pool, ctx->image);

    if (out == NULL) {
        return NULL;
    }

    cln = ngx_pool_cleanup_add(r->pool, 0);
    if (cln == NULL) {
        gdFree(out);
        return NULL;
    }

    b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
    if (b == NULL) {
        gdFree(out);
        return NULL;
    }

    cln->handler = ngx_http_image_cleanup;
    cln->data = out;

    b->pos = out;
    b->last = out + size;
    b->memory = 1;
    b->last_buf = 1;

    ngx_http_image_length(r, b);

    return b;
}
static VALUE fastimage_native_resize(
        VALUE self,
        VALUE rb_in, VALUE rb_out,
        VALUE rb_w, VALUE rb_h,
        VALUE rb_image_type,
        VALUE rb_jpeg_quality,
        VALUE rb_orientation
       ) {
  char *filename_in  = StringValuePtr(rb_in);
  char *filename_out = StringValuePtr(rb_out);
  int w              = NUM2INT(rb_w);
  int h              = NUM2INT(rb_h);
  int image_type     = NUM2INT(rb_image_type);
  int jpeg_quality   = NUM2INT(rb_jpeg_quality);
  int orientation    = NUM2INT(rb_orientation);


  gdImagePtr im_in, im_out;
  FILE *in, *out;
  int trans = 0, x = 0, y = 0, f = 0;

  in = fopen(filename_in, "rb");
  if (!in) return Qnil;

  switch(image_type) {
    case 0: im_in = gdImageCreateFromJpeg(in);
            break;
    case 1: im_in = gdImageCreateFromPng(in);
            break;
    case 2: im_in = gdImageCreateFromGif(in);
            trans = gdImageGetTransparent(im_in);
            /* find a transparent pixel, then turn off transparency
               so that it copies correctly */
            if (trans >= 0) {
              for (x=0; x<gdImageSX(im_in); x++) {
                for (y=0; y<gdImageSY(im_in); y++) {
                  if (gdImageGetPixel(im_in, x, y) == trans) {
                    f = 1;
                    break;
                  }
                }
                if (f) break;
              }
              gdImageColorTransparent(im_in, -1);
              if (!f) trans = -1;  /* no transparent pixel found */
            }
            break;
  }

  if (!im_in) {
    fclose(in);
    return Qnil;
  }



  /*  Handle orientation */
  if (orientation == 5 || orientation == 6) {
    im_in = gdImageRotateInterpolated(im_in, 270.0, 0);
  }
  if (orientation == 7 || orientation == 8) {
    im_in = gdImageRotateInterpolated(im_in, 90.0, 0);
  }
  if (!im_in) {
    fclose(in);
    return Qnil;
  }

  if (orientation == 2 || orientation == 5 || orientation == 7) {
    gdImageFlipHorizontal(im_in);
  }
  if (orientation == 3) {
      gdImageFlipBoth(im_in);
  }
  if (orientation == 4) {
    gdImageFlipVertical(im_in);
  }



  /* Compute target size */
  if (w == 0 || h == 0) {
    int originalWidth  = gdImageSX(im_in);
    int originalHeight = gdImageSY(im_in);
    if (h != 0) {
      w = (int)(h * originalWidth / originalHeight);
    } else if (w != 0) {
      h = (int)(w * originalHeight / originalWidth);
    } else {
      w = originalWidth;
      h = originalHeight;
    }
  }



  im_out = gdImageCreateTrueColor(w, h);  /* must be truecolor */
  if (im_out) {
    if (image_type == 1) {
      gdImageAlphaBlending(im_out, 0);  /* handle transparency correctly */
      gdImageSaveAlpha(im_out, 1);
    }
    fclose(in);
  } else {
    fclose(in);
    return Qnil;
  }

  /* Now copy the original */
  gdImageCopyResampled(im_out, im_in, 0, 0, 0, 0,
    gdImageSX(im_out), gdImageSY(im_out),
    gdImageSX(im_in), gdImageSY(im_in));

  out = fopen(filename_out, "wb");
  if (out) {
    switch(image_type) {
      case 0: gdImageJpeg(im_out, out, jpeg_quality);
              break;
      case 1: gdImagePng(im_out, out);
              break;
      case 2: gdImageTrueColorToPalette(im_out, 0, 256);
              if (trans >= 0) {
                trans = gdImageGetPixel(im_out, x, y);  /* get the color index of our transparent pixel */
                gdImageColorTransparent(im_out, trans); /* may not always work as hoped */
              }
              gdImageGif(im_out, out);
              break;
    }
    fclose(out);
  }
  gdImageDestroy(im_in);
  gdImageDestroy(im_out);
  return Qnil;
}
static void water_mark(void *conf)
{
	ngx_image_conf_t *info = conf;
	int water_w=0;//水印宽度
	int water_h=0;//水印高度
	int posX = 0;//X位置
	int posY = 0;//Y位置
	int water_color = 0;//文字水印GD颜色值
	char *water_text;//图片文字
	char *water_font;//文字字体
	char *water_color_text;//图片颜色值
	water_text = NULL;
	water_font = NULL;
	water_color_text = NULL;

	if(info->water_status)//如果水印功能打开了
	{

		if(info->water_type == 0)//如果为图片水印
		{
			if(file_exists((char *)info->water_image.data) == 0)//判断水印图片是否存在
			{
				water_image_from(conf);//获取水印图片信息
				if(info->water_im == NULL)//判断对象是否为空
				{
                    return;//水印文件异常
                }else{
                    water_w = info->water_im->sx;
                    water_h = info->water_im->sy;
                }
			}
			else
			{
				return;//水印图片不存在
			}
		}
		else//文字水印
		{
			water_text = (char *) info->water_text.data;
			water_color_text = (char *) info->water_color.data;
			water_font = (char *)info->water_font.data;
			if(file_exists((char *)water_font) == 0)//如果水印字体存在
			{
				int R,G,B;
				char R_str[3],G_str[3],B_str[3];
				int brect[8];
				gdImagePtr font_im;
				font_im = gdImageCreateTrueColor(info->dst_im->sx,info->dst_im->sy);
				sprintf(R_str,"%.*s",2,water_color_text+1);
				sprintf(G_str,"%.*s",2,water_color_text+3);
				sprintf(B_str,"%.*s",2,water_color_text+5);
				sscanf(R_str,"%x",&R);
				sscanf(G_str,"%x",&G);
				sscanf(B_str,"%x",&B);
				water_color = gdImageColorAllocate(info->dst_im,R,G,B);
				gdImageStringFT(font_im, &brect[0], water_color, water_font, info->water_font_size, 0.0, 0, 0,water_text/*, &strex*/);
				//water_w = abs(brect[2] - brect[6] + 10);
				water_w = abs(brect[2] - brect[6] + 10);
				water_h = abs(brect[3] - brect[7]);
				gdImageDestroy(font_im);
			}

		}
		if( (info->width < info->water_width_min) || info->height < info->water_height_min)
		{
			return;//如果图片宽度/高度比配置文件里规定的宽度/高度宽度小
		}
		if ((info->width < water_w) || (info->height < water_h))
		{
			return;//如果图片宽度/高度比水印宽度/高度宽度小
		}
		if(info->water_pos < 1 ||info->water_pos > 9)
		{
			srand((unsigned)time(NULL));
			//info->water_pos = rand() % 9 + 1;
			info->water_pos = 1+(int)(9.0*rand()/(RAND_MAX+1.0));
			//info->water_pos = rand() % 9;
		}
		switch(info->water_pos)
		{
		case 1:
			posX = 10;
			posY = 15;
			break;
		case 2:
			posX = (info->width - water_w) / 2;
			posY = 15;
			break;
		case 3:
			posX = info->width - water_w;
			posY = 15;
			break;
		case 4:
			posX = 0;
			posY = (info->height - water_h) / 2;
			break;
		case 5:
			posX = (info->width - water_w) / 2;
			posY = (info->height - water_h) / 2;
			break;
		case 6:
			posX = info->width - water_w;
			posY = (info->height - water_h) / 2;
			break;
		case 7:
			posX = 0;
			posY = (info->height - water_h);
			break;
		case 8:
			posX = (info->width - water_w) /2;
			posY = info->width - water_h;
			break;
		case 9:
			posX = info->width - water_w;
			posY = info->height - water_h;
			break;
		default:
			posX = info->width - water_w;
			posY = info->height - water_h;
			break;
		}
		if(info->water_type == 0)
		{
			gdImagePtr tmp_im;
			tmp_im = NULL;
			tmp_im = gdImageCreateTrueColor(water_w, water_h);
			gdImageCopy(tmp_im, info->dst_im, 0, 0, posX, posY, water_w, water_h);
			gdImageCopy(tmp_im, info->water_im, 0, 0, 0, 0, water_w, water_h);
			gdImageCopyMerge(info->dst_im, tmp_im,posX, posY, 0, 0, water_w,water_h,info->water_transparent);
			gdImageDestroy(tmp_im);
            gdImageDestroy(info->water_im);
		}
		else
		{
			gdImageAlphaBlending(info->dst_im,-1);
			gdImageSaveAlpha(info->dst_im,0);
			gdImageStringFT(info->dst_im,0,water_color,water_font,info->water_font_size, 0.0, posX, posY,water_text);
		}
	}
}
Exemple #26
0
static void gd_begin_graph(GVC_t * gvc, graph_t * g, box bb, point pb)
{
    char *bgcolor_str = NULL;
    char *truecolor_str;
    bool truecolor_p = FALSE;	/* try to use cheaper paletted mode */
    bool bg_transparent_p = FALSE;
    int bgcolor;

    external_surface = gvc->job->external_surface;

    init1_gd(gvc, g, bb, pb);

    if (external_surface) {
        im = (gdImagePtr)gvc->job->surface;
    } else {
        truecolor_str = agget(g, "truecolor");	/* allow user to force truecolor */
        bgcolor_str = agget(g, "bgcolor");

        if (truecolor_str && truecolor_str[0])
            truecolor_p = mapbool(truecolor_str);

        if (bgcolor_str && strcmp(bgcolor_str, "transparent") == 0) {
            bg_transparent_p = TRUE;
            if (is_format_truecolor_capable(Output_lang))
                truecolor_p = TRUE;	/* force truecolor */
        }

        if (GD_has_images(g))
            truecolor_p = TRUE;	/* force truecolor */

        if (truecolor_p) {
            if (Verbose)
                fprintf(stderr, "%s: allocating a %dK TrueColor GD image\n",
                        CmdName, ROUND(Viewport.x * Viewport.y * 4 / 1024.));
            im = gdImageCreateTrueColor(Viewport.x, Viewport.y);
        } else {
            if (Verbose)
                fprintf(stderr, "%s: allocating a %dK PaletteColor GD image\n",
                        CmdName, ROUND(Viewport.x * Viewport.y / 1024.));
            im = gdImageCreate(Viewport.x, Viewport.y);
        }
        if (!im) {
            agerr(AGERR, "gdImageCreate returned NULL. Malloc problem?\n");
            return;
        }
    }

    init2_gd(im);

    if (! external_surface) {
        if (bgcolor_str && bgcolor_str[0])
            if (bg_transparent_p)
                bgcolor = transparent;
            else
                bgcolor = gd_resolve_color(bgcolor_str);
        else
            bgcolor = white;

        cstk[0].fillcolor = bgcolor;

        /* Blending must be off to lay a transparent bgcolor.
           Nothing to blend with anyway. */
        gdImageAlphaBlending(im, FALSE);

        gdImageFill(im, im->sx / 2, im->sy / 2, bgcolor);

        /* Blend everything else together,
           especially fonts over non-transparent backgrounds */
        gdImageAlphaBlending(im, TRUE);
    }

#ifdef MYTRACE
    fprintf(stderr, "gd_begin_graph\n");
#endif
}