int renderPixmapSymbolGD(imageObj *img, double x, double y, symbolObj *symbol, symbolStyleObj *style)
{
    gdImagePtr ip,pp;
    if(!(ip = MS_IMAGE_GET_GDIMAGEPTR(img))) return MS_FAILURE;
    assert(symbol->pixmap_buffer && symbol->pixmap_buffer->type == MS_BUFFER_GD);
    pp = symbol->pixmap_buffer->data.gd_img;
    /* gdImageAlphaBlending(ip,1); */
    /* gdImageAlphaBlending(pp,1); */

    if(symbol->transparent)
        gdImageColorTransparent(pp,symbol->transparentcolor);
    if(style->scale == 1.0 && style->rotation == 0.0) { /* don't scale */
        x -= .5*symbol->pixmap_buffer->width;
        y -= .5*symbol->pixmap_buffer->height;
        gdImageCopy(ip, pp, x, y, 0, 0, symbol->pixmap_buffer->width,symbol->pixmap_buffer->height);
    } else {
        int bRotated = MS_FALSE;
        if(style->rotation) {
            bRotated = MS_TRUE;
            pp = rotatePixmapGD(pp,style->rotation);
        }
        x -=  .5*gdImageSX(pp)*style->scale;
        y -=  .5*gdImageSY(pp)*style->scale;
        gdImageCopyResampled(ip, pp, x, y, 0, 0,
                             (int)(gdImageSX(pp) * style->scale),
                             (int)(gdImageSY(pp) * style->scale),
                             gdImageSX(pp),gdImageSY(pp));
        if(bRotated) {
            gdImageDestroy(pp);
        }
    }
    /* gdImageAlphaBlending(ip,0); */
    return MS_SUCCESS;
}
Exemple #2
0
static void crop(Cmd *cmd) {
  char *buff = cmd->data;
  int len = cmd->size;
  Gd *gd = cmd->gd;
  int index = 0;
  long width, height;
  int srcW, srcH, srcX, srcY, destX, destY, playX, playY;
  gdImagePtr destination = NULL;
  
  ei_decode_version(buff, &index, NULL);
  ei_decode_tuple_header(buff, &index, NULL);
  ei_decode_long(buff, &index, &width);
  ei_decode_long(buff, &index, &height);
  
  if (NULL == gd->image) {
    driver_failure_atom(gd->port, "null_image");
    return;
  }
  
  srcW = gdImageSX(gd->image);
  srcH = gdImageSY(gd->image);
  
  destination = gdImageCreateTrueColor(width, height);
  if (NULL == destination) {
    driver_failure_posix(gd->port, ENOMEM);
    return;
  }
  gdImageFilledRectangle(destination, 0, 0, width, height, gdImageColorAllocate(destination, 255, 255, 255));
  destX = (width - srcW) / 2;
  destY = (height - srcH) / 2;
  gdImageCopy(destination, gd->image, destX, destY, 0, 0, srcW, srcH);
  gdImageDestroy(gd->image);
  gd->image = destination;
  send_atom(gd->port, "ok");
}
Exemple #3
0
void CarGPS::draw()
{
   logger->log(DEBUG, "CarGPS::draw", "start");

   struct gpf_data data;

   if (sensor->is_connected()) {
      sensor->get_data(&data);

      if (display_type == SENSOR_READOUT)
         draw_readout(&data);
      else
         draw_map(&data);

      return;
   } 

   // sensor is not connected
   draw_string(0, 0, width, height-100, gdTrueColor(250,250,250), 
      conf->get_value("font"), 18, "GPS Receiver not connected");
   gdImageCopy(img, graphic, 0, img->sy - graphic->sy, 0, 0, graphic->sx, 
      graphic->sy);
   update();

   logger->log(DEBUG, "CarGPS::draw", "end");
}
Exemple #4
0
result_t Image::crop(int32_t x, int32_t y, 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);
    gdImageCopy(dst->m_image, m_image, 0, 0, x, y, width, height);
    gdImageAlphaBlending(dst->m_image, 1);

    retVal = dst;

    return 0;
}
Exemple #5
0
int fswc_draw_overlay(fswebcam_config_t *config, char *filename, gdImage *image){
	FILE *f;
	gdImage *overlay;
	
	if(!filename) return(-1);
	
	f = fopen(filename, "rb");
	if(!f)
	{
		ERROR("Unable to open '%s'", filename);
		ERROR("fopen: %s", strerror(errno));
		return(-1);
	}
	
	overlay = gdImageCreateFromPng(f);
	fclose(f);
	
	if(!overlay)
	{
		ERROR("Unable to read '%s'. Not a PNG image?", filename);
		return(-1);
	}
	
	gdImageCopy(image, overlay, 0, 0, 0, 0, overlay->sx, overlay->sy);
	gdImageDestroy(overlay);
	
	return(0);
}
Exemple #6
0
static void _drawBackdrop()
{
    if(backdrop == NULL)
        return;
    
    gdImageCopy(framebuffer, backdrop, 0, 0, 0, 0, backdrop->sx, backdrop->sy);
}
Exemple #7
0
void _clear_viewport(int x, int y, int w, int h, int color)
{
    if(backdrop == NULL)
        return;
    
    gdImageCopy(framebuffer, backdrop, x, y, x, y, w, h);
}
Exemple #8
0
int main()
{
	gdImagePtr im, im2;
	int error = 0;

	im = gdImageCreateTrueColor(5, 5);
	if (!im) {
		printf("can't create the src truecolor image\n");
		return 1;
	}

	gdImageFilledRectangle(im, 0, 0, 49, 49, 0x00FFFFFF);
	gdImageColorTransparent(im, 0xFFFFFF);
	gdImageFilledRectangle(im, 1, 1, 4, 4, 0xFF00FF);

	im2 = gdImageCreateTrueColor(20, 20);
	if (!im2) {
		printf("can't create the dst truecolor image\n");
		gdImageDestroy(im);
		return 1;
	}

	gdImageCopy(im2, im, 2, 2 , 0, 0, gdImageSX(im), gdImageSY(im));

	if (!gdAssertImageEqualsToFile("gdimagecopy/bug00081_exp.png", im2)) {
		error = 1;
		printf("Reference image and destination differ\n");
	}

	gdImageDestroy(im);
	gdImageDestroy(im2);
	return error;
}
Exemple #9
0
void CarModule::update()
{
   logger->log(DEBUG, "CarModule::update", "start");

   gdImageCopy(fb->img, img, app->client_offset_x, app->client_offset_y, 
      0, 0, width, height);
   fb->update();

   logger->log(DEBUG, "CarModule::update", "end");
}
Exemple #10
0
void CarModule::update(int x, int y, int w, int h)
{
   logger->log(DEBUG, "CarModule::update2", "start");

   gdImageCopy(fb->img, img, app->client_offset_x + x, 
      app->client_offset_y + y, x, y, w, h);
   fb->update(app->client_offset_x + x, app->client_offset_y + y, w, h);

   logger->log(DEBUG, "CarModule::update2", "end");
}
Exemple #11
0
gdImage* fswc_gdImageDuplicate(gdImage* src)
{
	gdImage *dst;
	
	dst = gdImageCreateTrueColor(gdImageSX(src), gdImageSY(src));
	if(!dst) return(NULL);
	
	gdImageCopy(dst, src, 0, 0, 0, 0, gdImageSX(src), gdImageSY(src));
	
	return(dst);
}
Exemple #12
0
void CarGPS::draw_map(struct gpf_data *data)
{
   logger->log(DEBUG, "CarGPS::draw_map", "start");

   char str[128], *map_data;
   int sockfd, len, bytes, tot_bytes, map_size;
   struct sockaddr_un address;

   // open a stream socket to TMRS
   sockfd = socket (AF_UNIX, SOCK_STREAM, 0);
   address.sun_family = AF_UNIX;
   strcpy (address.sun_path, "/var/tmrs_socket");

   if (connect (sockfd, (struct sockaddr *) &address, sizeof(address)) == -1)
   {
      gdImageFilledRectangle(img, 0, 0, width, height-100, gdTrueColor(0,0,0));
      gdImageCopy(img, graphic, 0, img->sy - graphic->sy, 0, 0, graphic->sx, 
         graphic->sy);
      draw_string(0, 0, width, height-100, gdTrueColor(250,250,250), 
         conf->get_value("font"), 18, "Mapping Engine is not running");
      update();
      return;
   }

   // send a 'draw map' request to TMRS
   sprintf(str, "M,RAW,%d,%d,100,27971864,-82561903\n", width, height);
   //sprintf(str, "M,RAW,%d,%d,100,27592354,-82226377\n", width, height);
   write (sockfd, str, strlen(str));

   // allocate memory to hold returned image
   map_size = width*height*4; // 4 bytes per pixel
   map_data = (char *) malloc(map_size);  

   // read in data
   tot_bytes = 0;
   do {
      bytes = read(sockfd, &map_data[tot_bytes], map_size-tot_bytes);
      tot_bytes += bytes;
   } while (bytes > 0);

   // close the socket
   close (sockfd);

   // draw the received data to screen buffer
   for (int y = 0; y < height; y++)
      memcpy(&img->tpixels[y][0], &map_data[y*width*4], width*4); 

   update();

   logger->log(DEBUG, "CarGPS::draw_map", "end");
}
Exemple #13
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 #14
0
void _bitmap_part(const void *src, int src_x, int src_y,
                  int stride, int x, int y, int width, int height)
{
    FILE *_image;
    gdImagePtr image;
    
    DEBUGF2("bitmap_part(const void *src=%s, int src_x=%d, int src_y=%d, int stride=%d, int x=%d, int y=%d, int width=%d, int height=%d\n", (char*)src, src_x, src_y, stride, x, y, width, height);
    
    _image = fopen(src, "rb");
    if(_image == NULL)
        return;
    
    image = gdImageCreateFromBmp(_image);
    fclose(_image);
    
    gdImageCopy(framebuffer, image, x, y, src_x, src_y, width, height);
    
    gdImageDestroy(image);
}
Exemple #15
0
CarGPS::CarGPS(CarApp *main, Logger *log):CarModule(main, log)
{
   logger->log(DEBUG, "CarGPS::CarGPS", "start");

   FILE *fp;

   fp = fopen("gps.jpg", "rb");
   if (fp != NULL) {
      graphic = gdImageCreateFromJpeg(fp);
      fclose(fp);
      gdImageCopy(img, graphic, 0, img->sy - graphic->sy, 0, 0, graphic->sx, 
                  graphic->sy);
   }

   sensor = new GPSSensor(logger);
   display_type = SENSOR_READOUT;
   
   logger->log(DEBUG, "CarGPS::CarGPS", "end");
}
Exemple #16
0
result_t Image::copy(Image_base *source, int32_t dstX, int32_t dstY,
                     int32_t srcX, int32_t srcY, int32_t width, int32_t height,
                     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);

    Image *src = (Image *) source;
    if (!src->m_image)
        return CHECK_ERROR(CALL_E_INVALID_CALL);

    gdImageCopy(m_image, src->m_image, dstX, dstY, srcX, srcY, width, height);
    return 0;
}
Exemple #17
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 #18
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
Exemple #19
0
void generatePuzzle()
{
	printf("Generating Puzzle:\n");
	
	size_t keyCount = 0;
	size_t targetCount = 0;
	int i = 0;
	
	// Get current image count in database
	redisReply *getReply = redisCommand(Context, "SCARD %s", GRP_TARGET_NAME);
	keyCount = getReply->integer;
	freeReplyObject(getReply);
	
	// Check if there is right amount of images
	if (keyCount >= MIN_IMAGE_TYPES) {
		
		/*
		 * Get background
		 */
		// Get background size
		redisReply *backgroundSize = redisCommand(Context, "SCARD %s", GRP_BACKGROUND_NAME);
		
		char backgroundNumber[4];
		char backgroundFileName[64];
		int randomBackgroundNumber = 1;
		
		targetCount = backgroundSize->integer;
		
		if (randomBackgroundNumber != (int)targetCount) {
			randomBackgroundNumber = generateRandomNumber(1, (int)backgroundSize->integer);
		}
		
		snprintf(backgroundNumber, 4, "%d", randomBackgroundNumber);
		strcpy(backgroundFileName, "");
		strcat(backgroundFileName, BackgroundDIR);
		strcat(backgroundFileName, "/");
		strcat(backgroundFileName, BackgroundDIR);
		strcat(backgroundFileName, backgroundNumber);
		strcat(backgroundFileName, ".jpg");
		
		printf("\nPicked %s%s as background\n", BackgroundDIR, backgroundNumber);
		
		freeReplyObject(backgroundSize);
		
		// Get a background image
		gdImagePtr background = loadImage(backgroundFileName, ".jpg");
		
		if (background == NULL) {
			// Exit out
			printf("Error opening background image\n");
			return;
		}
		
		int randomArray[MIN_IMAGE_TYPES] = {0, 0, 0, 0, 0};
		generateRandomTargetGroups(1, MIN_IMAGE_TYPES, randomArray);
		
		redisReply *targetList = redisCommand(Context, "SMEMBERS %s", GRP_TARGET_NAME);
		
		printf("\nPicked targets Below:\n");
		
		for (i = 0; i < MIN_IMAGE_TYPES; i++) {
			
			// Check if there is min amount of images
			redisReply *minImages = redisCommand(Context, "SCARD %s", targetList->element[i]->str);
			
			if (minImages->integer >= MIN_EACH_TYPE) {
				
				redisReply *currentTarget = redisCommand(Context, "SMEMBERS %s", targetList->element[i]->str);
				
				int randomTargetArray[MIN_EACH_TYPE] = {0, 0, 0};
				generateRandomTargetGroups(1, MIN_EACH_TYPE, randomTargetArray);
				
				printf("\nFor %s we are using:\n", targetList->element[i]->str);
				
				int j = 0;
				
				for (j = 0; j < MIN_EACH_TYPE; j++) {
					
					/*
					 * Get Each Target
					 */
					char targetFileName[64];
					
					strcpy(targetFileName, "");
					strcat(targetFileName, TargetDIR);
					strcat(targetFileName, "/");
					strcat(targetFileName, currentTarget->element[j]->str);
					strcat(targetFileName, ".png");
					
					printf("\t%s\n", currentTarget->element[j]->str);
					
					// Get a background image
					gdImagePtr targetImage = loadImage(targetFileName, ".png");
					
					int top = generateRandomNumber(100, (background->sx - 100));
					int bottom = top + targetImage->sy;
					int left = generateRandomNumber(100, (background->sy - 100));
					int right = left + targetImage->sx;
					
					// Write out info to file
					FILE *coords = fopen("puzzle.txt", "a");
					fprintf(coords, "%d, %d, %d, %d\n", top, bottom, left, right);
					fclose(coords);
					
					gdImageCopy(background, targetImage,
								top,
								left,
								0, 0, 100, targetImage->sy);
					
					gdImageDestroy(targetImage);
				}
				
				// Free
				freeReplyObject(currentTarget);
				
				
			} else {
				printf("Add %lld more target groups to %s\n", (MIN_EACH_TYPE - minImages->integer),
					   targetList->element[0]->str);
				break;
			}
			
			// Get random image category for user to chose
			redisReply *targetListCount = redisCommand(Context, "SCARD %s", GRP_TARGET_NAME);
			int randomTargetGroup = generateRandomNumber(1, (int)targetListCount->integer);
			freeReplyObject(targetListCount);
			
			redisReply *currentTarget = redisCommand(Context, "SMEMBERS %s", targetList->element[randomTargetGroup-1]->str);
			char *fileName = currentTarget->element[0]->str;
			
			char fileNameFinal[64];
			strcpy(fileNameFinal, "");
			strcat(fileNameFinal, TargetDIR);
			strcat(fileNameFinal, "/");
			strcat(fileNameFinal, fileName);
			strcat(fileNameFinal, ".png");
			
			// Get image of random target
			gdImagePtr lookingFor = loadImage(fileNameFinal, ".png");
			
			// Make HTML page
			generateHTML(background, lookingFor);
			
			freeReplyObject(currentTarget);
			freeReplyObject(minImages);
			
		}
		
		gdImageDestroy(background);
		freeReplyObject(targetList);
		
	} else {
		printf("Add %lu more target groups\n", (MIN_IMAGE_TYPES - keyCount));
	}
	
}
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;
}
/*
int GIFFlusht1(Metafile *mf, char *filename)
transparent, color 1 (black background)
*/
int GIFFlusht1(Metafile *mf, char *filename)
{
  mf_cgmo *cgmo	= mf->cgmo;
  GIFmetafile *meta = find_meta(cgmo);
  int status = 1;
  int tcolor;
  int white;

  /* File w/ ".gif" only are not created (Ferret hack) */
  if (strcasecmp(filename, ".gif") != 0){
    FILE *fp = fopen(filename, "w");
    if (fp != NULL && meta != 0){
      status = OK;

      gdImageGif(meta->image, fp);/*save the image as gif */
      fclose(fp);

      /* open the gif, change transparency and then save */
        FILE *inGif;
        FILE *ouGif;
        gdImagePtr gifImg;

        inGif = fopen(filename,"rb");
        gifImg = gdImageCreateFromGif(inGif);
        fclose(inGif);

        ouGif = fopen(filename,"w");

        //(1,1,1) is for black background
          tcolor = gdImageColorClosest(gifImg, 0, 0, 0);;
          gdImageColorTransparent(gifImg, tcolor);

        gdImageGif(gifImg, ouGif);

        fclose(ouGif);
        gdImageDestroy(gifImg);

/* copy logo image to an output image */
/* Set up an image the size of the Ferret plot image */

        inGif = fopen(filename,"rb");
        gifImg = gdImageCreateFromGif(inGif);
        fclose(inGif);

/* Open the image to be the background. Copy to the output image */
        FILE *inLog;
        gdImagePtr logImg;
/*        inLog = fopen("/home/users/ansley/ans_ferret/users/ansley/centered_noaa_logo.gif","rb"); */
        inLog = fopen("/home/users/ansley/Wave-3.gif","rb");
        logImg = gdImageCreateFromGif(inLog);
        fclose(inLog);

        gdImageCopy(gifImg, logImg, 0, 0, 0, 0, logImg->sx, logImg->sy); 

/* Now copy the transparent image to the output image */
        inGif = fopen(filename,"rb");
        transImg = gdImageCreateFromGif(inGif);
        fclose(inGif);

        gdImageCopy(gifImg, transImg, 0, 0, 0, 0, gifImg->sx, gifImg->sy); 

        ouGif = fopen(filename,"w"); 
        gdImageGif(gifImg, ouGif);
        fclose(ouGif);
    }
  } else {
    status = OK;
  }
  return status;
}
/*
int GIFFlusht0(Metafile *mf, char *filename)
transparent, color 0 (white background)
*/
int GIFFlusht0(Metafile *mf, char *filename)
{
  mf_cgmo *cgmo	= mf->cgmo;
  GIFmetafile *meta = find_meta(cgmo);
  int status = 1;
  int tcolor;
  int i;


     /* Load the logo image */
	 /* from Jing's email:
	 /*   
	 /* Through the function gdImageCopy, you can control the position of you logo and which
	 /* part of your logo to copy.
	 /* 
	 /*  gdImageCopy(gdImagePtr dst, gdImagePtr src, int dstX, int dstY, int srcX, int srcY, int w, int h)

	 /* The dstX and dstY arguments specify the point in the destination image to which the region will be copied.
	 /* The srcX and srcY arguments specify the upper left corner of the region in the source image.
	 /* The w and h arguments specify the width and height of the region.

	 /* more notes (ACM)
	 /* the values of the arguments to gdImageCopy are in pixels.
	 /* the upper left corner is the origin for the location on the destination image
	 /* Specifying values smaller than the size of the logo image has the effect of chopping
	 /* the image, not shrinking it.
	 
/*   To place the image 100 pixels to the right of the orig in X on the destination image,
/*   and starting at 50 pixels from the top of the source image */
/*   gdImageCopy(meta->image, logImg, 100, 0, 0, 50, logImg->sx, logImg->sy);

 */
/*   FILE *inLog;
/*   gdImagePtr logImg;
/*   inLog = fopen("/home/users/ansley/ans_ferret/users/ansley/centered_noaa_logo.gif","rb"); 
/*   inLog = fopen("/home/users/ansley/Wave-3.gif","rb");*/
/*   logImg = gdImageCreateFromGif(inLog);
/*   /* Copy the logo to your figure meta->image */
/*
/*   gdImageCopy(meta->image, logImg, 0, 0, 0, 0, logImg->sx, logImg->sy); 
/*   fclose(inLog);

  /* File w/ ".gif" only are not created (Ferret hack) */
  if (strcasecmp(filename, ".gif") != 0){
    FILE *fp = fopen(filename, "w");
    if (fp != NULL && meta != 0){
      status = OK;

      gdImageGif(meta->image, fp);/*save the image as gif */
      fclose(fp);

      /* open the gif, change transparency and then save */
      
        FILE *inGif;
        FILE *ouGif;
        gdImagePtr gifImg;
        gdImagePtr transImg;

        inGif = fopen(filename,"rb");
        gifImg = gdImageCreateFromGif(inGif);
        fclose(inGif);

        ouGif = fopen(filename,"w");

        //(0,0,0) is for white background
        tcolor   = gdImageColorClosest(gifImg, 255, 255, 255);

 for (i=0; i < 256; i+=1) {

        tcolor   = gdImageColorClosest(gifImg, i, i, i);
 }

        gdImageColorTransparent(gifImg, tcolor);

        gdImageGif(gifImg, ouGif);
        fclose(ouGif);

        gdImageDestroy(gifImg);

/* copy logo image to an output image */
/* Set up an image the size of the Ferret plot image */

        inGif = fopen(filename,"rb");
        gifImg = gdImageCreateFromGif(inGif);
        fclose(inGif);

/* Open the image to be the background. Copy to the output image */
        FILE *inLog;
        gdImagePtr logImg;
/*        inLog = fopen("/home/users/ansley/ans_ferret/users/ansley/centered_noaa_logo.gif","rb"); */
        inLog = fopen("/home/users/ansley/Wave-3.gif","rb");
        logImg = gdImageCreateFromGif(inLog);
        fclose(inLog);

        gdImageCopy(gifImg, logImg, 0, 0, 0, 0, logImg->sx, logImg->sy); 

/* Now copy the transparent image to the output image */
        inGif = fopen(filename,"rb");
        transImg = gdImageCreateFromGif(inGif);
        fclose(inGif);

        gdImageCopy(gifImg, transImg, 0, 0, 0, 0, gifImg->sx, gifImg->sy); 

        ouGif = fopen(filename,"w"); 
        gdImageGif(gifImg, ouGif);
        fclose(ouGif);

    }
  } else {
    status = OK;
  }
  return status;
}
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 #24
0
gdImage *fx_crop(gdImage *src, char *options)
{
	char arg[32];
	int w, h, x, y;
	gdImage *im;
	
	if(argncpy(arg, 32, options, ", \t", 0, 0))
	{
		WARN("Invalid area to crop: %s", arg);
		return(src);
	}
	
	w = argtol(arg, "x ", 0, 0, 10);
	h = argtol(arg, "x ", 1, 0, 10);
	
	if(w < 0 || h < 0)
	{
		WARN("Invalid area to crop: %s", arg);
		return(src);
	}
	
	/* Make sure crop area resolution is smaller than the source image. */
	if(w > gdImageSX(src) ||
	   h > gdImageSY(src))
	{
		WARN("Crop area is larger than the image!");
		return(src);
	}
	
	/* Get the offset. */
	x = -1;
	y = -1;
	
	if(!argncpy(arg, 32, options, ", \t", 1, 0))
	{
		x = argtol(arg, "x ", 0, 0, 10);
		y = argtol(arg, "x ", 1, 0, 10);
	}
	
	if(x < 0 || y < 0)
	{
		/* By default crop the center of the image. */
		x = (gdImageSX(src) - w) / 2;
		y = (gdImageSY(src) - h) / 2;
	}
	
	MSG("Cropping image from %ix%i [offset: %ix%i] -> %ix%i.",
	    gdImageSX(src), gdImageSY(src), x, y, w, h);
	
	im = gdImageCreateTrueColor(w, h);
	if(!im)
	{
		WARN("Out of memory.");
		return(src);
	}
	
	gdImageCopy(im, src, 0, 0, x, y, w, h);
	
	gdImageDestroy(src);
	
	return(im);
}
Exemple #25
0
void MapSource::generateMaps()
{
    GoogleProjection proj;
    if(tiled)
    {
        ScreenPos topLeft = (proj.fromLLToPixel(w,n,zoom_start)) ,
                  bottomRight = (proj.fromLLToPixel(e,s,zoom_start)) ;

        topLeft.x /= 256;
        topLeft.y /= 256;
        bottomRight.x /= 256;
        bottomRight.y /= 256;

		int x_fetch_freq, y_fetch_freq, x_fetches, y_fetches;

		if(multirqst)
		{
        	// Gives a value approx equal to 0.1 lat/lon in southern UK
        	x_fetch_freq = (int)(pow(2.0,zoom_start-11));
        	y_fetch_freq = (int)(pow(2.0,zoom_start-11));
        	x_fetches = ((bottomRight.x-topLeft.x) / x_fetch_freq)+1, 
            y_fetches = ((bottomRight.y-topLeft.y) / y_fetch_freq)+1; 
		}
		else
		{
			x_fetch_freq = bottomRight.x - topLeft.x;
			y_fetch_freq = bottomRight.y - topLeft.y;
			x_fetches = 1;
			y_fetches = 1;
		}

        fprintf(stderr,"topLeft: %d %d\n",topLeft.x,topLeft.y);
        fprintf(stderr,"bottomRight: %d %d\n",bottomRight.x,bottomRight.y);
        fprintf(stderr,"xfetches yfetches: %d %d\n",x_fetches, y_fetches);

        for(int xfetch=0; xfetch<x_fetches; xfetch++)
        {
               for (int yfetch=0; yfetch<y_fetches; yfetch++) 
            {
                cerr<<"XFETCH="<<xfetch<<" YFETCH="<<yfetch<<endl;
                EarthPoint bottomL_LL =
                    proj.fromPixelToLL( (topLeft.x+xfetch*x_fetch_freq)*256,
                                    ((topLeft.y+yfetch*y_fetch_freq)
                                    +y_fetch_freq)*256, zoom_start),
                           topR_LL = 
                    proj.fromPixelToLL( (
                (topLeft.x+xfetch*x_fetch_freq)+x_fetch_freq)*256,
                                        (topLeft.y+yfetch*y_fetch_freq)
                                                *256, zoom_start),
                 bottomR_LL =
                    proj.fromPixelToLL( ((topLeft.x+xfetch*x_fetch_freq)+
							x_fetch_freq)*256,
                                    ((topLeft.y+yfetch*y_fetch_freq)
                                    +y_fetch_freq)*256, zoom_start),
                           topL_LL = 
                    proj.fromPixelToLL( 
                (topLeft.x+xfetch*x_fetch_freq)*256,
                                        (topLeft.y+yfetch*y_fetch_freq)
                                                *256, zoom_start);

				double w1 = min(bottomL_LL.x-0.01,topL_LL.x-0.01),
					   s1 = min(bottomL_LL.y-0.01,bottomR_LL.y-0.01),
					   e1 = max(bottomR_LL.x+0.01,topR_LL.x+0.01),
					   n1 = max(topL_LL.y+0.01,topR_LL.y+0.01);

                parameters p;
                if(getSource()=="api")
                {
                    std::ostringstream str;
                    str<<w1<<","<<s1<<"," <<e1<<","<<n1;

                    p["url"] = url;
                    p["file"] = "";
                    p["bbox"] = str.str();
                    cerr<<"URL="<<str.str()<<endl;
                }
                else if (getSource()=="osm")
                {
                    p["file"] = osmfile;
                }
                
                Map m (width, height);
                p["type"] ="osm";
                load_map(m,xmlfile);
                setOSMLayers(m,p);
                if(srtm)
                {
                    addSRTMLayers(m,w1,s1,e1,n1);
                }

                // lonToX() and latToY() give *pixel* coordinates

                   // See email Chris Schmidt 12/02/09
                double metres_per_pixel = (20037508.34/pow(2.0,
                        7+zoom_start));

                for(int z=zoom_start; z<=zoom_end; z++)
                {
                    EarthPoint bl,tr;
            
                    int ZOOM_FCTR = (int)(pow(2.0,z-zoom_start));
                    for(int tileX=
                            (topLeft.x+xfetch*x_fetch_freq)*ZOOM_FCTR;
                        tileX<
                            (topLeft.x+xfetch*x_fetch_freq+x_fetch_freq)
                            *ZOOM_FCTR;
                        tileX++)
                    {
                        for(int tileY=(topLeft.y+yfetch*y_fetch_freq)
                                    *ZOOM_FCTR;
                            tileY<(topLeft.y+yfetch*y_fetch_freq+y_fetch_freq)
                                    *ZOOM_FCTR;
                            tileY++)
                        {
                            cerr<<"x: " << tileX << " y: " << tileY
                                <<" z: " << z << endl;

                           image_32 buf(m.width(),m.height());
                           double metres_w =( (tileX*256.0) *
                            metres_per_pixel ) -
                                20037814.088;
                           double metres_s = 20034756.658 - 
                          ((tileY*256.0) * metres_per_pixel );
                        
                           double metres_e = metres_w + (metres_per_pixel*256);
                           double metres_n = metres_s + (metres_per_pixel*256);
   
                            box2d<double> bb
                            (metres_w-32*metres_per_pixel,
                             metres_s-32*metres_per_pixel,
                             metres_e+32*metres_per_pixel,
                             metres_n+32*metres_per_pixel); 

                           m.zoom_to_box(bb);
                           agg_renderer<image_32> r(m,buf);
                           r.apply();
                
                           string filename="";
                           std::ostringstream str;
                           str<< z<< "."<<tileX<<"." << tileY << ".png";
                           save_to_file<image_data_32>(buf.data(),
                            "tmp.png","png");
                            FILE *in=fopen("tmp.png","r");
                            FILE *out=fopen(str.str().c_str(),"w");

                            gdImagePtr image, image2;
                            image=gdImageCreateTrueColor(256,256);
                            image2=gdImageCreateFromPng(in);
                            gdImageCopy(image,image2,0,0,32,32,256,256);
                            gdImagePng(image,out);
                            gdImageDestroy(image2);
                            gdImageDestroy(image);
                            fclose(out);
                            fclose(in);
                        }
                    }
                    metres_per_pixel /= 2;
                }
            }
        }
    }
    else
    {
        // standard rendering
        Map m(width,height);
        parameters p;
        p["type"] = "osm";
        p["file"] = osmfile;
        load_map(m,xmlfile);
        setOSMLayers(m,p);

        box2d<double> latlon=
            (hasBbox()) ? 
            box2d<double>(w,s,e,n):
            m.getLayer(0).envelope();
        
        EarthPoint bottomL_LL = 
            GoogleProjection::fromLLToGoog(latlon.minx(),latlon.miny()),
                   topR_LL =
            GoogleProjection::fromLLToGoog(latlon.maxx(),latlon.maxy());
        box2d<double> bb =
                box2d<double>(bottomL_LL.x,bottomL_LL.y,
                                topR_LL.x,topR_LL.y);    
        m.zoom_to_box(bb);
        image_32 buf (m.width(), m.height());
        agg_renderer<image_32> r(m,buf);
        r.apply();

        save_to_file<image_data_32>(buf.data(),outfile,"png");
    }
}
Exemple #26
0
static    gdImagePtr  graph_dibujar_posicion( Tipojuego* tj, int flags, Posicion* pos, Movida* mov ){
    int tablero_flags = ( flags & GETPNG_ROTADO );
    int i;
    gdImagePtr gdt = graph_get_tablero_png( tj, tj->tablero_actual, tablero_flags );
    if( !gdt ){
        LOGPRINT( 2, "No es posible obtener la imagen del tablero para %s", tj->nombre );
        return  0;
    }
    gdImagePtr gd = gdImageCreateTrueColor( gdImageSX( gdt ), gdImageSY( gdt ) );
    gdImageCopy( gd, gdt, 0, 0, 0, 0, gdImageSX( gdt ), gdImageSY( gdt ) );

    Tablero* tt = tipojuego_get_tablero( tj, tj->tablero_actual ); 

    // Primero las marcas en el tablero, correspondientes al ultimo movimiento
    if( GETPNG_HIGHLIGHTED( flags ) && mov ){
        int  marca ;
        int  rojo, verde, azul;
        int  posx, posy;
        rojo  = ( flags & GETPNG_HIGHLIGHT_RED ? 255 : 0 );
        verde = ( flags & GETPNG_HIGHLIGHT_GREEN ? 255 : 0 );
        azul  = ( flags & GETPNG_HIGHLIGHT_BLUE ? 255 : 0 );
        marca = gdImageColorAllocate( gd, rojo, verde, azul );
        gdImageSetThickness( gd, HIGHLIGHT_SIZE );
        int i;
        for( i = 0; i < mov->acciones->entradas; i ++ ){
            Accion* acc = mov->acciones->data[i];
            if( acc->destino ){
                if( flags & GETPNG_ROTADO ){
                    posx = ( tt->graphdef->w / tt->dimmax[0] ) * ( tt->dimmax[0] - acc->destino->posicion[0] - 1 ) +
                            tt->graphdef->ox ;
                    posy = ( tt->graphdef->h / tt->dimmax[1] ) * ( acc->destino->posicion[1] ) + 
                            tt->graphdef->oy;
                } else {
                    posx = ( tt->graphdef->w / tt->dimmax[0] ) * acc->destino->posicion[0] +
                            tt->graphdef->ox ;
                    posy = ( tt->graphdef->h / tt->dimmax[1] ) * ( acc->destino->posicion[1] + 1 ) - 
                            tt->graphdef->oy;
                    posy = tt->graphdef->h - posy ;
                }
            }
            gdImageRectangle( gd, posx + HIGHLIGHT_SIZE / 2.0, posy + HIGHLIGHT_SIZE / 2.0, 
                                  posx + ( tt->graphdef->w / tt->dimmax[0] ) - HIGHLIGHT_SIZE / 2.0, 
                                  posy + ( tt->graphdef->h / tt->dimmax[1] ) - HIGHLIGHT_SIZE / 2.0,
                                marca );
            
        }
    }

    // Ahora las piezas
    for( i = 0; i < pos->piezas_count; i ++ ){
        Pieza* p = & pos->piezas[i];
        int  posx, posy;
        if( !CASILLERO_VALIDO( p->casillero ) ) continue;
        gdImagePtr gdp = graph_tpieza_get_gd( p->tpieza, p->color );
        if( !gdp ){
          gdImageDestroy( gd );
          return 0;
        }
        // Aca tengo que entontrar la posicion relativa de la pieza
        // y colocar el dibujo. No es otra cosa que la posicion
        // relativa del casillero por el tamaño (tablero->g->w / tablero->dimmax[0])
        // mas el offset del tablero
        if( flags & GETPNG_ROTADO ){
            posx = ( tt->graphdef->w / tt->dimmax[0] ) * ( tt->dimmax[0] - p->casillero->posicion[0] - 1 ) +
                     tt->graphdef->ox ;
            posy = ( tt->graphdef->h / tt->dimmax[1] ) * ( p->casillero->posicion[1] ) + 
                    tt->graphdef->oy;
        } else {
            posx = ( tt->graphdef->w / tt->dimmax[0] ) * p->casillero->posicion[0] +
                     tt->graphdef->ox ;
            posy = ( tt->graphdef->h / tt->dimmax[1] ) * ( p->casillero->posicion[1] + 1 ) - 
                    tt->graphdef->oy;
            posy = tt->graphdef->h - posy  ;
        }
        gdImageCopy( gd, gdp, posx, posy, 0, 0, gdImageSX( gdp ), gdImageSY( gdp ) );
    }
    return gd;
}
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, 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;
}
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;
}
Exemple #30
0
gdImage *fx_flip(gdImage *src, char *options)
{
	int i;
	char d[32];
	
	i = 0;
	while(!argncpy(d, 32, options, ", \t", i++, 0))
	{
		if(*d == 'v')
		{
			int y, h;
			gdImage *line;
			
			MSG("Flipping image vertically.");
			
			line = gdImageCreateTrueColor(gdImageSX(src), 1);
			h = gdImageSY(src) / 2;
			
			for(y = 0; y < h; y++)
			{
				/* Copy bottom line into buffer. */
				gdImageCopy(line, src,
				   0, 0,
				   0, gdImageSY(src) - y - 1,
				   gdImageSX(src), 1);
				
				/* Copy the top line onto the bottom. */
				gdImageCopy(src, src,
				   0, gdImageSY(src) - y - 1,
				   0, y,
				   gdImageSX(src), 1);
				
				/* Copy the buffer into the top. */
				gdImageCopy(src, line,
				   0, y,
				   0, 0,
				   gdImageSX(src), 1);
			}
			
			gdImageDestroy(line);
		}
		else if(*d == 'h')
		{
			int x, w;
			gdImage *line;
			
			MSG("Flipping image horizontally.");
			
			line = gdImageCreateTrueColor(1, gdImageSY(src));
			w = gdImageSX(src) / 2;
			
			for(x = 0; x < w; x++)
			{
				/* Copy right line into buffer. */
				gdImageCopy(line, src,
				   0, 0,
				   gdImageSX(src) - x - 1, 0,
				   1, gdImageSY(src));
				
				/* Copy the left line onto the right. */
				gdImageCopy(src, src,
				   gdImageSX(src) - x - 1, 0,
				   x, 0,
				   1, gdImageSY(src));
				
				/* Copy the buffer into the left. */
				gdImageCopy(src, line,
				   x, 0,
				   0, 0,
				   1, gdImageSY(src));
			}
			
			gdImageDestroy(line);
		}
		else WARN("Unknown flip direction: %s", d);
	}
	
	return(src);
}