Exemplo n.º 1
0
int32_t my_replacer(gdImagePtr im, int32_t src)
{
    if (src == gdImageGetTransparent(im))
        return gdTrueColor(255, 255, 255);

    return gdAlphaBlend(gdTrueColor(255, 255, 255), src);
}
Exemplo n.º 2
0
static void gdImageBrushApply(gdImagePtr im, int x, int y)
{
	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;
	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)) {
				gdImageSetPixel(im, lx, ly,
					im->brushColorMap[p]);
			}
			srcx++;
		}
		srcy++;
	}	
}		
Exemplo n.º 3
0
result_t Image::get_transparent(int32_t &retVal)
{
    if (!m_image)
        return CHECK_ERROR(CALL_E_INVALID_CALL);

    retVal = gdImageGetTransparent(m_image);
    return 0;
}
Exemplo n.º 4
0
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;
}
void
PrintGIFInfo
	(
	gdImagePtr image
	)
{
	cout << endl;
	cout << "Index\tRed\tGreen\tBlue" << endl;

	const JSize colorCount = gdImageColorsTotal(image);
	for (JIndex i=0; i<colorCount; i++)
		{
		cout << i;
		cout << '\t' << gdImageRed  (image, i);
		cout << '\t' << gdImageGreen(image, i);
		cout << '\t' << gdImageBlue (image, i);
		cout << endl;
		}

	cout << endl;

	cout << "Number of colors:        " << colorCount << endl;

	const int transparentColor = gdImageGetTransparent(image);
	cout << "Transparent color index: ";
	if (transparentColor == kNoTransparentColor)
		{
		cout << "none";
		}
	else
		{
		cout << transparentColor;
		}
	cout << endl;

	cout << endl;

	cout << "Width:      " << gdImageSX(image) << endl;
	cout << "Height:     " << gdImageSY(image) << endl;
	cout << "Interlaced: ";
	if (gdImageGetInterlaced(image))
		{
		cout << "yes";
		}
	else
		{
		cout << "no";
		}
	cout << endl;

	cout << endl;
}
Exemplo n.º 6
0
static int gd_resolve_color(char* name)
{
	color_t	color;
 
	if (!(strcmp(name,"transparent"))) {
	    	/* special case for "transparent" color */
		return gdImageGetTransparent(im);
	} 
	else {
		colorxlate(name,&color,RGBA_BYTE);
		return gdImageColorResolve(im,color.u.rgba[0],color.u.rgba[1],color.u.rgba[2]);
	}
}
Exemplo n.º 7
0
static int color_index(gdImagePtr im, gvcolor_t color)
{
    int alpha;

    /* convert alpha (normally an "opacity" value) to gd's "transparency" */
    alpha = (255 - color.u.rgba[3]) * gdAlphaMax / 255;

    if(alpha == gdAlphaMax)
        return (gdImageGetTransparent(im));
    else
        return (gdImageColorResolveAlpha(im,
		    color.u.rgba[0],
		    color.u.rgba[1],
		    color.u.rgba[2],
		    alpha));
}
Exemplo n.º 8
0
static void gdImageTileApply(gdImagePtr im, int x, int y)
{
	int srcx, srcy;
	int p;
	if (!im->tile) {
		return;
	}
	srcx = x % gdImageSX(im->tile);
	srcy = y % gdImageSY(im->tile);
	p = gdImageGetPixel(im->tile, srcx, srcy);
	/* Allow for transparency */
	if (p != gdImageGetTransparent(im->tile)) {
		gdImageSetPixel(im, x, y,
			im->tileColorMap[p]);
	}
}		
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
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;
}
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);
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
/**
 * Function: gdImageCropAuto
 *
 * Crop an image automatically
 *
 * This function detects the cropping area according to the given _mode_.
 *
 * Parameters:
 *   im   - The image.
 *   mode - The cropping mode, see <gdCropMode>.
 *
 * Returns:
 *   The newly created cropped image, or NULL on failure.
 *
 * See also:
 *   - <gdImageCrop>
 *   - <gdImageCropThreshold>
 */
BGD_DECLARE(gdImagePtr) gdImageCropAuto(gdImagePtr im, const unsigned int mode)
{
	const int width = gdImageSX(im);
	const int height = gdImageSY(im);

	int x,y;
	int color, match;
	gdRect crop;

	crop.x = 0;
	crop.y = 0;
	crop.width = 0;
	crop.height = 0;

	switch (mode) {
	case GD_CROP_TRANSPARENT:
		color = gdImageGetTransparent(im);
		break;

	case GD_CROP_BLACK:
		color = gdImageColorClosestAlpha(im, 0, 0, 0, 0);
		break;

	case GD_CROP_WHITE:
		color = gdImageColorClosestAlpha(im, 255, 255, 255, 0);
		break;

	case GD_CROP_SIDES:
		gdGuessBackgroundColorFromCorners(im, &color);
		break;

	case GD_CROP_DEFAULT:
	default:
		color = gdImageGetTransparent(im);
		break;
	}

	/* TODO: Add gdImageGetRowPtr and works with ptr at the row level
	 * for the true color and palette images
	 * new formats will simply work with ptr
	 */
	match = 1;
	for (y = 0; match && y < height; y++) {
		for (x = 0; match && x < width; x++) {
			match = (color == gdImageGetPixel(im, x,y));
		}
	}

	/* Whole image would be cropped > bye */
	if (match) {
		return NULL;
	}

	crop.y = y - 1;

	match = 1;
	for (y = height - 1; match && y >= 0; y--) {
		for (x = 0; match && x < width; x++) {
			match = (color == gdImageGetPixel(im, x,y));
		}
	}
	crop.height = y - crop.y + 2;

	match = 1;
	for (x = 0; match && x < width; x++) {
		for (y = 0; match && y < crop.y + crop.height; y++) {
			match = (color == gdImageGetPixel(im, x,y));
		}
	}
	crop.x = x - 1;

	match = 1;
	for (x = width - 1; match && x >= 0; x--) {
		for (y = 0; match &&  y < crop.y + crop.height; y++) {
			match = (color == gdImageGetPixel(im, x,y));
		}
	}
	crop.width = x - crop.x + 2;

	return gdImageCrop(im, &crop);
}
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;
}
Exemplo n.º 15
0
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 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;
}
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;
}
Exemplo n.º 18
0
int main(int argc, char **argv)
{
	FILE *in;
	FILE *out;
	char outFn[20];
	int useStdinStdout=0;

	/* Declare our image pointer */
	gdImagePtr im = 0;
	int i;
       /* We'll clear 'no' once we know the user has made a
		reasonable request. */
	int no = 1;
	/* We'll set 'write' once we know the user's request
		requires that the image be written back to disk. */
	int write = 0;
	/* C programs always get at least one argument; we want at
		least one more (the image), more in practice. */
	if (argc < 2 || !strcmp(argv[1], "--help")) {
		no = 1;	
		goto usage;
	}

	/* The last argument should be the image. Open the file. */
	if (strcmp("-", argv[argc-1])==0) { /* - is synonymous with STDIN */
	  useStdinStdout = 1;
	  in = stdin;
	} else {
	  in = fopen(argv[argc-1], "rb");	
	}
	if (!in) {
		fprintf(stderr,
			"Error: can't open file %s.\n", argv[argc-1]);
		exit(1);
	}
	/* Now load the image. */	
	im = gdImageCreateFromPng(in);
	fclose(in);
	/* If the load failed, it must not be a PNG file. */
	if (!im) {
		fprintf(stderr,
			"Error: %s is not a valid PNG file.\n", argv[argc-1]);
		exit(1);	
	}
	/* Consider each argument in turn. */
	for (i=1; (i < (argc-1)); i++) {
		/* -i turns on and off interlacing. */
		if (!strcmp(argv[i], "--help")) { 
		  /* Every program should use this for help! :) */
		  no = 1;
		  goto usage;
		} else if (!strcmp(argv[i], "-i")) {
			if (i == (argc-2)) {
				fprintf(stderr, 
				"Error: -i specified without y or n.\n");
				no = 1;
				goto usage;
			}
			if (!strcmp(argv[i+1], "y")) {
				/* Set interlace. */
				gdImageInterlace(im, 1);
			} else if (!strcmp(argv[i+1], "n")) {
				/* Clear interlace. */
				gdImageInterlace(im, 0);
			} else {
				fprintf(stderr,
				"Error: -i specified without y or n.\n");
				no = 1;
				goto usage;
			}
			i++;
			no = 0;
			write = 1;
		} else if (!strcmp(argv[i], "-t")) {
			/* Set transparent index (or none). */
			int index;
			if (i == (argc-2)) {
				fprintf(stderr,
		"Error: -t specified without a color table index.\n");
				no = 1;
				goto usage;
			}
			if (!strcmp(argv[i+1], "none")) {
				/* -1 means not transparent. */
				gdImageColorTransparent(im, -1);
			} else {
				/* OK, get an integer and set the index. */
				index = atoi(argv[i+1]);
				gdImageColorTransparent(im, index);
			}
			i++;
			write = 1;
			no = 0;
		} else if (!strcmp(argv[i], "-l")) {
			/* List the colors in the color table. */
			int j;
			/* Tabs used below. */
			printf("Index	Red	Green	Blue\n");
			for (j=0; (j < gdImageColorsTotal(im)); j++) {
				/* Use access macros to learn colors. */
				printf("%d	%d	%d	%d\n",
					j, 
					gdImageRed(im, j),
					gdImageGreen(im, j),
					gdImageBlue(im, j));
			}
			no = 0;
		} else if (!strcmp(argv[i], "-d")) {
			/* Output dimensions, etc. */
			int t;
			printf("Width: %d Height: %d Colors: %d\n",
				gdImageSX(im), gdImageSY(im),
				gdImageColorsTotal(im));
			t = gdImageGetTransparent(im);
			if (t != (-1)) {
				printf("Transparent index: %d\n", t);
			} else {
				/* -1 means the image is not transparent. */
				printf("Transparent index: none\n");
			}
			if (gdImageGetInterlaced(im)) {
				printf("Interlaced: yes\n");	
			} else {
				printf("Interlaced: no\n");	
			}
			no = 0;
		} else {
			fprintf(stderr, "Unknown argument: %s\n", argv[i]);
			break;	
		}
	}
usage:
	if (no) {
		/* If the command failed, output an explanation. */
		fprintf(stderr, 
"Usage: webpng [-i y|n ] [-l] [-t index|none ] [-d] pngname.png\n"

"  -i [y|n]   Turns on/off interlace\n"
"  -l         Prints the table of color indexes\n"
"  -t [index] Set the transparent color to the specified index (0-255 or \"none\")\n"
"  -d         Reports the dimensions and other characteristics of the image.\n"
"\n"
"If you specify '-' as the input file, stdin/stdout will be used input/output.\n"
);
	} 
	if (write) {
	  if (useStdinStdout) {
	    out = stdout;
	  } else {
	    /* Open a temporary file. */

	    /* "temp.tmp" is not good temporary filename. */
	    sprintf(outFn, "webpng.tmp%d", getpid());
	    out = fopen(outFn, "wb"); 

	    if (!out) {
	      fprintf(stderr,
		      "Unable to write to %s -- exiting\n", outFn);
	      exit(1);
	    }
	  }

	  /* Write the new PNG. */
	  gdImagePng(im, out);

	  if (!useStdinStdout) {
	    fclose(out);
	    /* Erase the old PNG. */
	    unlink(argv[argc-1]);
	    /* Rename the new to the old. */
	    if (rename(outFn, argv[argc-1])!=0) {
	      perror("rename");
	      exit(1);
	    }
	  }
	}
	/* Delete the image from memory. */
	if (im) {
		gdImageDestroy(im);
	}
	/* All's well that ends well. */
	return 0;
}
Exemplo n.º 19
0
/**
 * Function: gdImageAutoCrop
 *  Automatic croping of the src image using the given mode
 *  (see <gdCropMode>)
 *
 *
 * Parameters:
 * 	im - Source image
 *  mode - crop mode
 *
 * Returns:
 *  <gdImagePtr> on success or NULL
 *
 * See also:
 *  <gdCropMode>
 */
gdImagePtr gdImageCropAuto(gdImagePtr im, const unsigned int mode)
{
	const int width = gdImageSX(im);
	const int height = gdImageSY(im);

	int x,y;
	int color, corners, match;
	gdRect crop;

	crop.x = 0;
	crop.y = 0;
	crop.width = 0;
	crop.height = 0;

	switch (mode) {
		case GD_CROP_TRANSPARENT:
			color = gdImageGetTransparent(im);
			break;

		case GD_CROP_BLACK:
			color = gdImageColorClosestAlpha(im, 0, 0, 0, 0);
			break;

		case GD_CROP_WHITE:
			color = gdImageColorClosestAlpha(im, 255, 255, 255, 0);
			break;

		case GD_CROP_SIDES:
			corners = gdGuessBackgroundColorFromCorners(im, &color);
			break;

		case GD_CROP_DEFAULT:
		default:
			color = gdImageGetTransparent(im);
			if (color == -1) {
				corners = gdGuessBackgroundColorFromCorners(im, &color);
			}
			break;
	}

	/* TODO: Add gdImageGetRowPtr and works with ptr at the row level
	 * for the true color and palette images
	 * new formats will simply work with ptr
	 */
	match = 1;
	for (y = 0; match && y < height; y++) {
		for (x = 0; match && x < width; x++) {
			int c2 = gdImageGetPixel(im, x, y);
			match = (color == c2);
		}
	}

	/* Nothing to do > bye
	 * Duplicate the image?
	 */
	if (y == height - 1) {
		return NULL;
	}

	crop.y = y -1;
	match = 1;
	for (y = height - 1; match && y >= 0; y--) {
		for (x = 0; match && x < width; x++) {
			match = (color == gdImageGetPixel(im, x,y));
		}
	}

	if (y == 0) {
		crop.height = height - crop.y + 1;
	} else {
		crop.height = y - crop.y + 2;
	}

	match = 1;
	for (x = 0; match && x < width; x++) {
		for (y = 0; match && y < crop.y + crop.height - 1; y++) {
			match = (color == gdImageGetPixel(im, x,y));
		}
	}
	crop.x = x - 1;

	match = 1;
	for (x = width - 1; match && x >= 0; x--) {
		for (y = 0; match &&  y < crop.y + crop.height - 1; y++) {
			match = (color == gdImageGetPixel(im, x,y));
		}
	}
	crop.width = x - crop.x + 2;
	if (crop.x <= 0 || crop.y <= 0 || crop.width <= 0 || crop.height <= 0) {
		return NULL;
	}
	return gdImageCrop(im, &crop);
}
Exemplo n.º 20
0
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;
}
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;
}
Exemplo n.º 22
0
int msSaveImageGDAL( mapObj *map, imageObj *image, char *filename )

{
  int  bFileIsTemporary = MS_FALSE;
  GDALDatasetH hMemDS, hOutputDS;
  GDALDriverH  hMemDriver, hOutputDriver;
  int          nBands = 1;
  int          iLine;
  GByte       *pabyAlphaLine = NULL;
  char        **papszOptions = NULL;
  outputFormatObj *format = image->format;
  rasterBufferObj rb;
  GDALDataType eDataType = GDT_Byte;
  int bUseXmp = MS_FALSE;

  msGDALInitialize();
  memset(&rb,0,sizeof(rasterBufferObj));

#ifdef USE_EXEMPI
  if( map != NULL ) {
    bUseXmp = msXmpPresent(map);
  }
#endif


  /* -------------------------------------------------------------------- */
  /*      Identify the proposed output driver.                            */
  /* -------------------------------------------------------------------- */
  msAcquireLock( TLOCK_GDAL );
  hOutputDriver = GDALGetDriverByName( format->driver+5 );
  if( hOutputDriver == NULL ) {
    msReleaseLock( TLOCK_GDAL );
    msSetError( MS_MISCERR, "Failed to find %s driver.",
                "msSaveImageGDAL()", format->driver+5 );
    return MS_FAILURE;
  }

  /* -------------------------------------------------------------------- */
  /*      We will need to write the output to a temporary file and        */
  /*      then stream to stdout if no filename is passed.  If the         */
  /*      driver supports virtualio then we hold the temporary file in    */
  /*      memory, otherwise we try to put it in a reasonable temporary    */
  /*      file location.                                                  */
  /* -------------------------------------------------------------------- */
  if( filename == NULL ) {
    const char *pszExtension = format->extension;
    if( pszExtension == NULL )
      pszExtension = "img.tmp";

    if( bUseXmp == MS_FALSE && GDALGetMetadataItem( hOutputDriver, GDAL_DCAP_VIRTUALIO, NULL )
        != NULL ) {
      CleanVSIDir( "/vsimem/msout" );
      filename = msTmpFile(map, NULL, "/vsimem/msout/", pszExtension );
    }

    if( filename == NULL && map != NULL)
      filename = msTmpFile(map, map->mappath,NULL,pszExtension);
    else if( filename == NULL ) {
      filename = msTmpFile(map, NULL, NULL, pszExtension );
    }

    bFileIsTemporary = MS_TRUE;
  }

  /* -------------------------------------------------------------------- */
  /*      Establish the characteristics of our memory, and final          */
  /*      dataset.                                                        */
  /* -------------------------------------------------------------------- */

  if( format->imagemode == MS_IMAGEMODE_RGB ) {
    nBands = 3;
    assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer );
    format->vtable->getRasterBufferHandle(image,&rb);
  } else if( format->imagemode == MS_IMAGEMODE_RGBA ) {
    pabyAlphaLine = (GByte *) calloc(image->width,1);
    if (pabyAlphaLine == NULL) {
      msReleaseLock( TLOCK_GDAL );
      msSetError( MS_MEMERR, "Out of memory allocating %u bytes.\n", "msSaveImageGDAL()", image->width);
      return MS_FAILURE;
    }
    nBands = 4;
    assert( MS_RENDERER_PLUGIN(format) && format->vtable->supports_pixel_buffer );
    format->vtable->getRasterBufferHandle(image,&rb);
  } else if( format->imagemode == MS_IMAGEMODE_INT16 ) {
    nBands = format->bands;
    eDataType = GDT_Int16;
  } else if( format->imagemode == MS_IMAGEMODE_FLOAT32 ) {
    nBands = format->bands;
    eDataType = GDT_Float32;
  } else if( format->imagemode == MS_IMAGEMODE_BYTE ) {
    nBands = format->bands;
    eDataType = GDT_Byte;
  } else {
#ifdef USE_GD
    assert( format->imagemode == MS_IMAGEMODE_PC256
            && format->renderer == MS_RENDER_WITH_GD );
#else
    {
      msReleaseLock( TLOCK_GDAL );
      msSetError( MS_MEMERR, "GD not compiled in. This is a bug.", "msSaveImageGDAL()");
      return MS_FAILURE;
    }
#endif

  }

  /* -------------------------------------------------------------------- */
  /*      Create a memory dataset which we can use as a source for a      */
  /*      CreateCopy().                                                   */
  /* -------------------------------------------------------------------- */
  hMemDriver = GDALGetDriverByName( "MEM" );
  if( hMemDriver == NULL ) {
    msReleaseLock( TLOCK_GDAL );
    msSetError( MS_MISCERR, "Failed to find MEM driver.",
                "msSaveImageGDAL()" );
    return MS_FAILURE;
  }

  hMemDS = GDALCreate( hMemDriver, "msSaveImageGDAL_temp",
                       image->width, image->height, nBands,
                       eDataType, NULL );
  if( hMemDS == NULL ) {
    msReleaseLock( TLOCK_GDAL );
    msSetError( MS_MISCERR, "Failed to create MEM dataset.",
                "msSaveImageGDAL()" );
    return MS_FAILURE;
  }

  /* -------------------------------------------------------------------- */
  /*      Copy the gd image into the memory dataset.                      */
  /* -------------------------------------------------------------------- */
  for( iLine = 0; iLine < image->height; iLine++ ) {
    int iBand;

    for( iBand = 0; iBand < nBands; iBand++ ) {
      GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 );

      if( format->imagemode == MS_IMAGEMODE_INT16 ) {
        GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                      image->img.raw_16bit + iLine * image->width
                      + iBand * image->width * image->height,
                      image->width, 1, GDT_Int16, 2, 0 );

      } else if( format->imagemode == MS_IMAGEMODE_FLOAT32 ) {
        GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                      image->img.raw_float + iLine * image->width
                      + iBand * image->width * image->height,
                      image->width, 1, GDT_Float32, 4, 0 );
      } else if( format->imagemode == MS_IMAGEMODE_BYTE ) {
        GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                      image->img.raw_byte + iLine * image->width
                      + iBand * image->width * image->height,
                      image->width, 1, GDT_Byte, 1, 0 );
      }
#ifdef USE_GD
      else if(format->renderer == MS_RENDER_WITH_GD) {
        gdImagePtr img = (gdImagePtr)image->img.plugin;
        GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                      img->pixels[iLine],
                      image->width, 1, GDT_Byte, 0, 0 );
      }
#endif
      else {
        GByte *pabyData;
        unsigned char *pixptr = NULL;
        assert( rb.type == MS_BUFFER_BYTE_RGBA );
        switch(iBand) {
          case 0:
            pixptr = rb.data.rgba.r;
            break;
          case 1:
            pixptr = rb.data.rgba.g;
            break;
          case 2:
            pixptr = rb.data.rgba.b;
            break;
          case 3:
            pixptr = rb.data.rgba.a;
            break;
        }
        assert(pixptr);
        if( pixptr == NULL ) {
          msReleaseLock( TLOCK_GDAL );
          msSetError( MS_MISCERR, "Missing RGB or A buffer.\n",
                      "msSaveImageGDAL()" );
          return MS_FAILURE;
        }

        pabyData = (GByte *)(pixptr + iLine*rb.data.rgba.row_step);

        if( rb.data.rgba.a == NULL || iBand == 3 ) {
          GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                        pabyData, image->width, 1, GDT_Byte,
                        rb.data.rgba.pixel_step, 0 );
        } else { /* We need to un-pre-multiple RGB by alpha. */
          GByte *pabyUPM = (GByte*) malloc(image->width);
          GByte *pabyAlpha= (GByte *)(rb.data.rgba.a + iLine*rb.data.rgba.row_step);
          int i;

          for( i = 0; i < image->width; i++ ) {
            int alpha = pabyAlpha[i*rb.data.rgba.pixel_step];

            if( alpha == 0 )
              pabyUPM[i] = 0;
            else {
              int result = (pabyData[i*rb.data.rgba.pixel_step] * 255) / alpha;

              if( result > 255 )
                result = 255;

              pabyUPM[i] = result;
            }
          }

          GDALRasterIO( hBand, GF_Write, 0, iLine, image->width, 1,
                        pabyUPM, image->width, 1, GDT_Byte, 1, 0 );
          free( pabyUPM );
        }
      }
    }
  }

  if( pabyAlphaLine != NULL )
    free( pabyAlphaLine );

  /* -------------------------------------------------------------------- */
  /*      Attach the palette if appropriate.                              */
  /* -------------------------------------------------------------------- */
#ifdef USE_GD
  if( format->renderer == MS_RENDER_WITH_GD ) {
    GDALColorEntry sEntry;
    int  iColor;
    GDALColorTableH hCT;
    gdImagePtr img = (gdImagePtr)image->img.plugin;
    hCT = GDALCreateColorTable( GPI_RGB );

    for( iColor = 0; iColor < img->colorsTotal; iColor++ ) {
      sEntry.c1 = img->red[iColor];
      sEntry.c2 = img->green[iColor];
      sEntry.c3 = img->blue[iColor];

      if( iColor == gdImageGetTransparent( img ) )
        sEntry.c4 = 0;
      else if( iColor == 0
               && gdImageGetTransparent( img ) == -1
               && format->transparent )
        sEntry.c4 = 0;
      else
        sEntry.c4 = 255;

      GDALSetColorEntry( hCT, iColor, &sEntry );
    }

    GDALSetRasterColorTable( GDALGetRasterBand( hMemDS, 1 ), hCT );

    GDALDestroyColorTable( hCT );
  } else
#endif
    if( format->imagemode == MS_IMAGEMODE_RGB ) {
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand );
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand );
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand );
    } else if( format->imagemode == MS_IMAGEMODE_RGBA ) {
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 1 ), GCI_RedBand );
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 2 ), GCI_GreenBand );
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 3 ), GCI_BlueBand );
      GDALSetRasterColorInterpretation(
        GDALGetRasterBand( hMemDS, 4 ), GCI_AlphaBand );
    }

  /* -------------------------------------------------------------------- */
  /*      Assign the projection and coordinate system to the memory       */
  /*      dataset.                                                        */
  /* -------------------------------------------------------------------- */

  if( map != NULL ) {
    char *pszWKT;

    GDALSetGeoTransform( hMemDS, map->gt.geotransform );

    pszWKT = msProjectionObj2OGCWKT( &(map->projection) );
    if( pszWKT != NULL ) {
      GDALSetProjection( hMemDS, pszWKT );
      msFree( pszWKT );
    }
  }

  /* -------------------------------------------------------------------- */
  /*      Possibly assign a nodata value.                                 */
  /* -------------------------------------------------------------------- */
  if( msGetOutputFormatOption(format,"NULLVALUE",NULL) != NULL ) {
    int iBand;
    const char *nullvalue = msGetOutputFormatOption(format,
                            "NULLVALUE",NULL);

    for( iBand = 0; iBand < nBands; iBand++ ) {
      GDALRasterBandH hBand = GDALGetRasterBand( hMemDS, iBand+1 );
      GDALSetRasterNoDataValue( hBand, atof(nullvalue) );
    }
  }

  /* -------------------------------------------------------------------- */
  /*  Try to save resolution in the output file.                          */
  /* -------------------------------------------------------------------- */
  if( image->resolution > 0 ) {
    char res[30];

    sprintf( res, "%lf", image->resolution );
    GDALSetMetadataItem( hMemDS, "TIFFTAG_XRESOLUTION", res, NULL );
    GDALSetMetadataItem( hMemDS, "TIFFTAG_YRESOLUTION", res, NULL );
    GDALSetMetadataItem( hMemDS, "TIFFTAG_RESOLUTIONUNIT", "2", NULL );
  }

  /* -------------------------------------------------------------------- */
  /*      Create a disk image in the selected output format from the      */
  /*      memory image.                                                   */
  /* -------------------------------------------------------------------- */
  papszOptions = (char**)calloc(sizeof(char *),(format->numformatoptions+1));
  if (papszOptions == NULL) {
    msReleaseLock( TLOCK_GDAL );
    msSetError( MS_MEMERR, "Out of memory allocating %u bytes.\n", "msSaveImageGDAL()",
                (unsigned int)(sizeof(char *)*(format->numformatoptions+1)));
    return MS_FAILURE;
  }

  memcpy( papszOptions, format->formatoptions,
          sizeof(char *) * format->numformatoptions );

  hOutputDS = GDALCreateCopy( hOutputDriver, filename, hMemDS, FALSE,
                              papszOptions, NULL, NULL );

  free( papszOptions );

  if( hOutputDS == NULL ) {
    GDALClose( hMemDS );
    msReleaseLock( TLOCK_GDAL );
    msSetError( MS_MISCERR, "Failed to create output %s file.\n%s",
                "msSaveImageGDAL()", format->driver+5,
                CPLGetLastErrorMsg() );
    return MS_FAILURE;
  }

  /* closing the memory DS also frees all associated resources. */
  GDALClose( hMemDS );

  GDALClose( hOutputDS );
  msReleaseLock( TLOCK_GDAL );


  /* -------------------------------------------------------------------- */
  /*      Are we writing license info into the image?                     */
  /*      If so, add it to the temp file on disk now.                     */
  /* -------------------------------------------------------------------- */
#ifdef USE_EXEMPI
  if ( bUseXmp == MS_TRUE ) {
    if( msXmpWrite(map, filename) == MS_FAILURE ) {
      /* Something bad happened. */
      msSetError( MS_MISCERR, "XMP write to %s failed.\n",
                  "msSaveImageGDAL()", filename);
      return MS_FAILURE;
    }
  }
#endif

  /* -------------------------------------------------------------------- */
  /*      Is this supposed to be a temporary file?  If so, stream to      */
  /*      stdout and delete the file.                                     */
  /* -------------------------------------------------------------------- */
  if( bFileIsTemporary ) {
    FILE *fp;
    unsigned char block[4000];
    int bytes_read;

    if( msIO_needBinaryStdout() == MS_FAILURE )
      return MS_FAILURE;

    /* We aren't sure how far back GDAL exports the VSI*L API, so
       we only use it if we suspect we need it.  But we do need it if
       holding temporary file in memory. */
    fp = VSIFOpenL( filename, "rb" );
    if( fp == NULL ) {
      msSetError( MS_MISCERR,
                  "Failed to open %s for streaming to stdout.",
                  "msSaveImageGDAL()", filename );
      return MS_FAILURE;
    }

    while( (bytes_read = VSIFReadL(block, 1, sizeof(block), fp)) > 0 )
      msIO_fwrite( block, 1, bytes_read, stdout );

    VSIFCloseL( fp );

    VSIUnlink( filename );
    CleanVSIDir( "/vsimem/msout" );

    free( filename );
  }

  return MS_SUCCESS;
}
Exemplo n.º 23
0
// Generates the count image from the count string, returns true if all ok
bool CreateImage(const char *pcCount, const char *pcFont, int iDigits) {
	// Set the spare value 
	int iCountLen = strlen(pcCount);
	if (iDigits < iCountLen)
		iDigits = iCountLen;
	int iSpare = 0;
	if (iDigits > iCountLen)
		iSpare = iDigits - iCountLen;
	// Loop vars
	char pcDigitName[STR_SIZE] = "";
	gdImagePtr pImg = NULL;
	FILE *pPic = NULL;
	// Load the zero digit image
	sprintf(pcDigitName, COUNTER_ZERO, pcFont);
	pPic = fopen(pcDigitName, "rb+");
	if (pPic == NULL)
		return false;
	pImg = gdImageCreateFromGif(pPic);
	fclose(pPic);
	if (pImg == NULL)
		return false;
	// Create the output image
	gdImagePtr pOutImg = NULL;
	pOutImg = gdImageCreate(iDigits * pImg->sx, pImg->sy);
	if (pOutImg == NULL) {
		gdImageDestroy(pImg);
		return false;
	}
	// Copy the palette info from one to the other...
	int iColTotal = gdImageColorsTotal(pImg);
	for (int i = 0; i < iColTotal; i++) {
		gdImageColorAllocate(pOutImg, gdImageRed(pImg, i), gdImageGreen(pImg, i), gdImageBlue(pImg, i));
	}
	int iTransCol = gdImageGetTransparent(pImg);
	if (iTransCol >= 0) {
		gdImageColorTransparent(pOutImg, iTransCol);
		gdImageFill(pOutImg, 0, 0, iTransCol);
	}
	// Loop through each leading zero
	int iPos = 0;
	while (iSpare-- > 0) {
		// paste in the image
		gdImageCopy(pOutImg, pImg, iPos, 0, 0, 0, pImg->sx, pImg->sy);
		iPos += pImg->sx;
	}
	// Delete the zero image
	gdImageDestroy(pImg);
	// Loop through each counter character
	const char *pcPos = pcCount;
	while (*pcPos != '\0') {
		sprintf(pcDigitName, COUNTER_PIC, pcFont, *pcPos);
		// Load the image
		pPic = fopen(pcDigitName, "rb+");
		if (pPic == NULL) {
			gdImageDestroy(pOutImg);
			return false;
		}
		pImg = gdImageCreateFromGif(pPic);
		if (pImg == NULL) {
			gdImageDestroy(pOutImg);
			return false;
		}
		// Paste in the image
		gdImageCopy(pOutImg, pImg, iPos, 0, 0, 0, pImg->sx, pImg->sy);
		iPos += pImg->sx;
		// Delete the image
		gdImageDestroy(pImg);
		// Update the position counter
		pcPos++;
	}
	// Write out the output image
	if (g_oCGI.Debug()) {
		char pcGIFName[STR_SIZE] = COUNTER_ROOT;
		strcat(pcGIFName, "out.gif");
		FILE *pGIFFile = NULL;
		pGIFFile = fopen(pcGIFName, "wb");
		if (pGIFFile) {
			gdImageGif(pOutImg, pGIFFile);
			fclose(pGIFFile);
		}
	}
	else {
		gdImageInterlace(pOutImg, 1);
#ifdef WIN32
		_setmode(_fileno(stdout), _O_BINARY);
#endif
		printf("Content-type: image/gif\n\n");
		gdImageGif(pOutImg, stdout);
	}
	// Destroy the image
	gdImageDestroy(pOutImg);

	return true;
} // CreateImage
Exemplo n.º 24
0
int main(int argc, char **argv)
{
	FILE *in;
	FILE *out;
	/* Declare our image pointer */
	gdImagePtr im = 0;
	int i;
       /* We'll clear 'no' once we know the user has made a
		reasonable request. */
	int no = 1;
	/* We'll set 'write' once we know the user's request
		requires that the image be written back to disk. */
	int write = 0;
	/* C programs always get at least one argument; we want at
		least one more (the image), more in practice. */
	if (argc < 2) {
		no = 1;	
		goto usage;
	}
	/* The last argument should be the image. Open the file. */
	in = fopen(argv[argc-1], "rb");	
	if (!in) {
		fprintf(stderr,
			"Error: can't open file %s.\n", argv[argc-1]);
	}
	/* Now load the image. */	
	im = gdImageCreateFromGif(in);
	fclose(in);
	/* If the load failed, it must not be a GIF file. */
	if (!im) {
		fprintf(stderr,
			"Error: %s is not a valid gif file.\n", argv[1]);
		exit(1);	
	}
	/* Consider each argument in turn. */
	for (i=1; (i < (argc-1)); i++) {
		/* -i turns on and off interlacing. */
		if (!strcmp(argv[i], "-i")) {
			if (i == (argc-2)) {
				fprintf(stderr, 
				"Error: -i specified without y or n.\n");
				no = 1;
				goto usage;
			}
			if (!strcmp(argv[i+1], "y")) {
				/* Set interlace. */
				gdImageInterlace(im, 1);
			} else if (!strcmp(argv[i+1], "n")) {
				/* Clear interlace. */
				gdImageInterlace(im, 0);
			} else {
				fprintf(stderr,
				"Error: -i specified without y or n.\n");
				no = 1;
				goto usage;
			}
			i++;
			no = 0;
			write = 1;
		} else if (!strcmp(argv[i], "-t")) {
			/* Set transparent index (or none). */
			int index;
			if (i == (argc-2)) {
				fprintf(stderr,
		"Error: -t specified without a color table index.\n");
				no = 1;
				goto usage;
			}
			if (!strcmp(argv[i+1], "none")) {
				/* -1 means not transparent. */
				gdImageColorTransparent(im, -1);
			} else {
				/* OK, get an integer and set the index. */
				index = atoi(argv[i+1]);
				gdImageColorTransparent(im, index);
			}
			i++;
			write = 1;
			no = 0;
		} else if (!strcmp(argv[i], "-l")) {
			/* List the colors in the color table. */
			int j;
			/* Tabs used below. */
			printf("Index	Red	Green	Blue\n");
			for (j=0; (j < gdImageColorsTotal(im)); j++) {
				/* Use access macros to learn colors. */
				printf("%d	%d	%d	%d\n",
					j, 
					gdImageRed(im, j),
					gdImageGreen(im, j),
					gdImageBlue(im, j));
			}
			no = 0;
		} else if (!strcmp(argv[i], "-d")) {
			/* Output dimensions, etc. */
			int t;
			printf("Width: %d Height: %d Colors: %d\n",
				gdImageSX(im), gdImageSY(im),
				gdImageColorsTotal(im));
			t = gdImageGetTransparent(im);
			if (t != (-1)) {
				printf("Transparent index: %d\n", t);
			} else {
				/* -1 means the image is not transparent. */
				printf("Transparent index: none\n");
			}
			if (gdImageGetInterlaced(im)) {
				printf("Interlaced: yes\n");	
			} else {
				printf("Interlaced: no\n");	
			}
			no = 0;
		} else {
			fprintf(stderr, "Unknown argument: %s\n", argv[i]);
			break;	
		}
	}
usage:
	if (no) {
		/* If the command failed, output an explanation. */
		fprintf(stderr, 
	"Usage: webgif [-i y|n ] [-l] [-t index|off ] [-d] gifname.gif\n");
		fprintf(stderr, 
	"Where -i controls interlace (specify y or n for yes or no),\n");
		fprintf(stderr, 
	"-l outputs a table of color indexes, -t sets the specified\n");
		fprintf(stderr, 
	"color index (0-255 or none) to be the transparent color, and\n");
		fprintf(stderr,
	"-d reports the dimensions and other characteristics of the image.\n");
		fprintf(stderr, 
	"Note: you may wish to pipe to \"more\" when using the -l option.\n");
	} 
	if (write) {
		/* Open a temporary file. */
		out = fopen("temp.tmp", "wb");
		if (!out) {
			fprintf(stderr,
				"Unable to write to temp.tmp -- exiting\n");
			exit(1);
		}
		/* Write the new gif. */
		gdImageGif(im, out);
		fclose(out);
		/* Erase the old gif. */
		unlink(argv[argc-1]);
		/* Rename the new to the old. */
		rename("temp.tmp", argv[argc-1]);
	}
	/* Delete the image from memory. */
	if (im) {
		gdImageDestroy(im);
	}
	/* All's well that ends well. */
	return 0;
}
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;
}
Exemplo n.º 26
0
Arquivo: gdxpm.c Projeto: johlim/study
BGD_DECLARE(gdImagePtr) gdImageCreateFromXpm(char *filename)
{
	XpmInfo info;
	XpmImage image;
	unsigned int i, j, k, number, len;
	char buf[5];
	gdImagePtr im = 0;
	int *pointer;
	int red = 0, green = 0, blue = 0;
	int *colors;
	int ret;

	ret = XpmReadFileToXpmImage(filename, &image, &info);
	if(ret != XpmSuccess) {
		return 0;
	}

	number = image.ncolors;
	if(overflow2(sizeof(int), number)) {
		goto done;
	}

	colors = (int *)gdMalloc(sizeof(int) * number);
	if(colors == NULL) {
		goto done;
	}

	if(!(im = gdImageCreate(image.width, image.height))) {
		gdFree(colors);
		goto done;
	}

	for(i = 0; i < number; i++) {
		char *c_color = image.colorTable[i].c_color;
		if(strcmp(c_color, "None") == 0) {
		  colors[i] = gdImageGetTransparent(im);
		  if(colors[i] == -1) colors[i] = gdImageColorAllocate(im, 0, 0, 0);
		  if(colors[i] != -1) gdImageColorTransparent(im, colors[i]);
		  continue;
		}
		len = strlen(c_color);
		if(len < 1) continue;
		if(c_color[0] == '#') {
			switch(len) {
			case 4:
				buf[2] = '\0';
				buf[0] = buf[1] = c_color[1];
				red = strtol(buf, NULL, 16);

				buf[0] = buf[1] = c_color[2];
				green = strtol(buf, NULL, 16);

				buf[0] = buf[1] = c_color[3];
				blue = strtol(buf, NULL, 16);
				break;

			case 7:
				buf[2] = '\0';
				buf[0] = c_color[1];
				buf[1] = c_color[2];
				red = strtol(buf, NULL, 16);

				buf[0] = c_color[3];
				buf[1] = c_color[4];
				green = strtol(buf, NULL, 16);

				buf[0] = c_color[5];
				buf[1] = c_color[6];
				blue = strtol(buf, NULL, 16);
				break;

			case 10:
				buf[3] = '\0';
				buf[0] = c_color[1];
				buf[1] = c_color[2];
				buf[2] = c_color[3];
				red = strtol(buf, NULL, 16);
				red /= 64;

				buf[0] = c_color[4];
				buf[1] = c_color[5];
				buf[2] = c_color[6];
				green = strtol(buf, NULL, 16);
				green /= 64;

				buf[0] = c_color[7];
				buf[1] = c_color[8];
				buf[2] = c_color[9];
				blue = strtol(buf, NULL, 16);
				blue /= 64;
				break;

			case 13:
				buf[4] = '\0';
				buf[0] = c_color[1];
				buf[1] = c_color[2];
				buf[2] = c_color[3];
				buf[3] = c_color[4];
				red = strtol(buf, NULL, 16);
				red /= 256;

				buf[0] = c_color[5];
				buf[1] = c_color[6];
				buf[2] = c_color[7];
				buf[3] = c_color[8];
				green = strtol(buf, NULL, 16);
				green /= 256;

				buf[0] = c_color[9];
				buf[1] = c_color[10];
				buf[2] = c_color[11];
				buf[3] = c_color[12];
				blue = strtol(buf, NULL, 16);
				blue /= 256;
				break;
			}
		} else if(!gdColorMapLookup(GD_COLOR_MAP_X11, c_color, &red, &green, &blue)) {
			continue;
		}

		colors[i] = gdImageColorResolve(im, red, green, blue);
	}

	pointer = (int *)image.data;

	for(i = 0; i < image.height; i++) {
		for(j = 0; j < image.width; j++) {
			k = *pointer++;
			gdImageSetPixel(im, j, i, colors[k]);
		}
	}

	gdFree(colors);

 done:
	XpmFreeXpmImage(&image);
	XpmFreeXpmInfo(&info);
	return im;
}