Exemple #1
0
void makeMeme(char *input, char *output, char *text)
{
    FILE *in, *out;
    gdImagePtr im;
    int black;
    int white;
    in = fopen(input, "r");
   // if (in == NULL) return 1;

    //im = gdImageCreateFromPng(in);
    im = gdImageCreateFromJpeg(in);
    fclose(in);

    black = gdImageColorAllocate(im, 0, 0, 0);
    white = gdImageColorAllocate(im, 255, 255, 255);

    gdImageString(im, gdFontGetLarge(),
                  im->sx / 2 - (strlen(text) * gdFontGetLarge()->w / 2),
                  im->sy - im->sy / 10,
                  text, black);

    //gdImagePng(im, out);
    out = fopen(output, "w");
//    printf("Meme created!\n");
    gdImageJpeg(im, out, 95);
    gdImageDestroy(im);
    //if (out == NULL) return 1;
    fclose(out);
    //return 0;
}
Exemple #2
0
static void gd_end_graph_to_file(void)
{
/*
 * Windows will do \n -> \r\n  translations on stdout unless told otherwise.
 */
#ifdef HAVE_SETMODE
#ifdef O_BINARY
	setmode(fileno(Output_file), O_BINARY);
#endif
#endif

/*
 * Write IM to OUTFILE as a JFIF-formatted JPEG image, using quality
 * JPEG_QUALITY.  If JPEG_QUALITY is in the range 0-100, increasing values
 * represent higher quality but also larger image size.  If JPEG_QUALITY is
 * negative, the IJG JPEG library's default quality is used (which
 * should be near optimal for many applications).  See the IJG JPEG
 * library documentation for more details.  */

#define JPEG_QUALITY -1

	if (Output_lang == GD) {
		gdImageGd(im, Output_file);
#ifdef HAVE_LIBZ
	} else if (Output_lang == GD2) {
#define GD2_CHUNKSIZE 128
#define GD2_RAW 1
#define GD2_COMPRESSED 2
		gdImageGd2(im, Output_file, GD2_CHUNKSIZE, GD2_COMPRESSED);
#endif
#ifdef WITH_GIF
	} else if (Output_lang == GIF) {
		gdImageGif(im, Output_file);
#endif
#ifdef HAVE_LIBPNG
#ifdef HAVE_LIBZ
	} else if (Output_lang == PNG) {
		gdImagePng(im, Output_file);
#endif
#endif
#ifdef HAVE_LIBJPEG
	} else if (Output_lang == JPEG) {
		gdImageJpeg(im, Output_file, JPEG_QUALITY);
#endif
	} else if (Output_lang == WBMP) {
        	/* Use black for the foreground color for the B&W wbmp image. */
		gdImageWBMP(im, black, Output_file);
#ifdef HAVE_LIBXPM
	} else if (Output_lang == XBM) {
		gdImageXbm(im, Output_file);
#endif
	}
	if (ImageDict) {
		dtclose(ImageDict); ImageDict = 0;
	}
	gdImageDestroy(im);
#ifdef MYTRACE
fprintf(stderr,"gd_end_graph_to_file\n");
#endif
}
Exemple #3
0
void
dotest (char *font, int w, int h, char *string, const char *filename)
{
  gdImagePtr im;
  FILE *out;
  int bg;
  int fc;

  im = gdImageCreate (w, h);
  bg = gdImageColorAllocate (im, 0, 0, 0);

  gdImageFilledRectangle (im, 1, 1, w - 1, h - 1, bg);

  fc = gdImageColorAllocate (im, 255, 192, 192);

  out = fopen (filename, "wb");

  dosizes (im, fc, font, 20, 20, string);

#if defined(HAVE_LIBPNG)
  gdImagePng (im, out);
#elif defined(HAVE_LIBJPEG)
  gdImageJpeg (im, out, -1);
#endif
  fclose (out);
}
Exemple #4
0
int
main( int argc, char **argv )
{
	FILE *fp;
	gdImagePtr original, cropped,resized;
	if( argc != 3 ) {
		printf( "usage: %s in-jpeg out-jpeg\n", argv[0] );
		exit( 1 );
	}

	if( !(fp = fopen( argv[1], "r" )) ) {
		printf( "unable to open \"%s\"\n", argv[1] );
		exit( 1 );
	}
	if( !(original = gdImageCreateFromJpeg( fp )) ) {
		printf( "unable to load \"%s\"\n", argv[1] );
		exit( 1 );
	}
	fclose( fp );


  gdRect crop;
  crop.x = 100;
  crop.y = 100;
  crop.width = original->sx - 200;
  crop.height = original->sy - 200;
  cropped = gdImageCrop(original, &crop);
  gdImageDestroy( original );
  original = 0;

  if( !(cropped) ) {
    printf( "unable to crop image\n" ); 
    exit( 1 );
  }
  

  resized = gdImageScale(cropped, crop.width * 0.9, crop.height * 0.9);
  gdImageDestroy( cropped );
  cropped = 0;

  if( !(resized) ) {
    printf( "unable to resize image\n" ); 
    exit( 1 );
  }

  //gdImageSharpen is extremely slow
	//gdImageSharpen( resized, 75 );

	if( !(fp = fopen( argv[2], "w" )) ) {
		printf( "unable to open \"%s\"\n", argv[2] );
		exit( 1 );
	}
	gdImageJpeg( resized, fp, -1 );
	fclose( fp );

	gdImageDestroy( resized );

	return( 0 ); 
}
Exemple #5
0
value ImageJpeg(value img,value filename,value quality) {
	int _quality = val_int(quality);
	ImageData _img = getImage(img);
	FILE *_file = openFileWrite(filename);
	gdImageJpeg(imageImage(_img),_file,_quality);
	fclose(_file);	
	return val_null;
}
Exemple #6
0
int
graphicsGdImageSaveAsJpeg(gdImage *im, const char *path, int quality)
{
#ifdef GD_JPEG
  CALL_WITH_F4(path, "wb", F_WRLCK, gdImageJpeg(im, f, quality));
#else
  graphicsGdRaiseCondition("unsupported format: %s", "Jpeg");
  return -1;
#endif /* GD_JPEG */
}
Exemple #7
0
int main (int argc, char *argv[]) {
	FILE *fp;
	gdImagePtr in, out;
	int w, h;

	/* Help */
	if (argc<=4) {
		printf("%s  input.jpg  output.jpg  width  height\n", argv[0]);
		return 1;
	}

	/* Size */
	w = atoi(argv[3]);
	h = atoi(argv[4]);
	if (w<=0 || h<=0) {
		fprintf(stderr, "Bad size %dx%d\n", h, w);
		return 2;
	}

	/* Input */
	fp = fopen(argv[1], "rb");
	if (!fp) {
		fprintf(stderr, "Can't read image %s\n", argv[1]);
		return 3;
	}
	in = gdImageCreateFromJpeg(fp);
	fclose(fp);
	if (!in) {
		fprintf(stderr, "Can't create image from %s\n", argv[1]);
		return 4;
	}

	/* Resize */
	gdImageSetInterpolationMethod(in, GD_BILINEAR_FIXED);
	out = gdImageScale(in, w, h);
	if (!out) {
		fprintf(stderr, "gdImageScale fails\n");
		return 5;
	}

	/* Output */
	fp = fopen(argv[2], "wb");
	if (!fp) {
		fprintf(stderr, "Can't save image %s\n", argv[2]);
		return 6;
	}
	gdImageJpeg(out, fp, 90);
	fclose(fp);

	/* Cleanups */
	gdImageDestroy(in);
	gdImageDestroy(out);

	return 0;
}
Exemple #8
0
void piechart_write(FILE *pieoutf, char *filename, logical jpegcharts) {
#ifdef HAVE_GD
  if (jpegcharts)
    gdImageJpeg(im, pieoutf, 100);
  else
#endif
  gdImagePng(im, pieoutf);
  debug('F', "Closing %s", filename);
  fclose(pieoutf);
  gdImageDestroy(im);
}
Exemple #9
0
/*
 * Save float luminance image to JPEG via gd
 * return -1 on error, 0 otherwise
 */
uint32_t y_float_save( float *data, uint32_t w, uint32_t h, char *name )
{
	FILE *f;
	gdImage *image;
	uint32_t i, j, g, color;
	float *dat, d, max;
	
	if(!name)
		return(-1);
	
	f = fopen(name, "wb");
	
	if(!f)
	{
		ERROR("Error opening file for output: %s", name);
		ERROR("fopen: %s", strerror(errno));
		return(-1);
	}
	
	image = gdImageCreateTrueColor(w,h);
	if(!image)
	{
		ERROR("Cannot create image");
		fclose(f);
		return(-1);
	}

	max=0;
	dat=data;
	for(j=0;j<h;j++)
		for(i=0;i<w;i++)
		{
			d = *(dat++);
			if(d>max) max=d;
		}		
	
	
	dat = data;
	for(j=0; j<h; j++){
		for(i=0; i<w; i++)
		{
			d = *(dat++);
			g = 0xff * d/max;
			color = g + (g<<8) + (g<<16);
			color &= 0xffffff; 
			gdImageSetPixel(image,i,j,color);
		}
	}
	
	gdImageJpeg(image, f, 255);

	gdImageDestroy(image);
	return(0);
}
Exemple #10
0
int main() {
  /* Declare the image */
  gdImagePtr im;

  /* Declare output files */
  FILE *pngout, *jpegout;

  /* Declare color indexes */
  int black;  int white; int cyan; int orange;

  /* Allocate the image: 64 pixels across by 64 pixels tall */
  im = gdImageCreate(64, 64);

   /* Allocate the color black (red, green and blue all minimum).
      Since this is the first color in a new image, it will
      be the background color. */
  black = gdImageColorAllocate(im, 0, 0, 0);

  /* Allocate the color white (red, green and blue all maximum). */
  white = gdImageColorAllocate(im, 255, 255, 255);

  /* Allocate the color cyan and orange. */
  cyan    = gdImageColorAllocate(im, 0, 192, 255);
  orange  = gdImageColorAllocate(im, 255, 128, 0);

  /* Draw a line from the upper left to the lower right,
     using white color index. */
  gdImageLine(im, 0, 0, 63, 63, white);
  gdImageLine(im, 15, 0, 15, 63, cyan);
  gdImageLine(im, 31, 0, 31, 63, orange);

  /* Open a file for writing. "wb" means "write binary", important
     under MSDOS, harmless under Unix. */
  pngout = fopen("test.png", "wb");

  /* Do the same for a JPEG-format file. */
  jpegout = fopen("test.jpg", "wb");

  /* Output the image to the disk file in PNG format. */
  gdImagePng(im, pngout);

  /* Output the same image in JPEG format, using the default
     JPEG quality setting. */
  gdImageJpeg(im, jpegout, -1);

  /* Close the files. */
  fclose(pngout);
  fclose(jpegout);

  /* Destroy the image in memory. */
  gdImageDestroy(im);

  return(0);
}
Exemple #11
0
void
MessageEncryption::encrypt(std::string imgpath,std::string outpath){
    std::default_random_engine rand (this->key);
    int currand; int i, j;
    int width, height;
    FILE* in, *out; gdImagePtr img;
    printf("o\n");
    int ext = getexten(imgpath);

    printf("a\n");
    
    in = fopen(imgpath.c_str(),"rb");
    if(ext==0){
        img=gdImageCreateFromJpeg(in);
    } else if(ext==1){
        img=gdImageCreateFromPng(in);
    } else{
        exit(1);
    }
    fclose(in);

    printf("b\n");

    width = gdImageSX(img); height = gdImageSY(img);
    
    for(i=0;i<ITER_COUNT;i++){
        currand = rand()%FLIP_CHANCE;
        if(currand==0){ // flip horizontally
            fliphoriz(img);
        } else if(currand==1){ // flip vertically
            flipvert(img);
        } else if(currand<=1+FLIP_CHANCE/2){ // shift some rows
            for(j=0;j<=(currand%(width/3));j++){
                shiftcol(img,(3*i+j)%width,(7*currand+4*i)%height);
            }
        } else{  // shift some columns
            for(j=0;j<=(currand%(height/3));j++){
                shiftrow(img,(3*i+j)%height,(7*currand+4*i)%width);
            }
        }
    }
    printf("c\n");
    ext = getexten(outpath);
    out = fopen(outpath.c_str(),"wb");
    if(ext==0){
        gdImageJpeg(img,out,-1);
    } else if(ext==1){
        gdImagePng(img,out);
    } else{
        exit(1);
    }
    fclose(out); gdImageDestroy(img);
}
Exemple #12
0
/* ------------------------------------------------------------------------ */
void
out_err( int			IMGWIDTH,
		 int			IMGHEIGHT,
		 FILE			*fptr,
		 unsigned long	BGColor,
		 unsigned long	LineColor,
		 char			*err_str )
{

	gdImagePtr	im;
	int			lineclr;
	int			bgclr;


	if( (GDC_hold_img & GDC_REUSE_IMAGE) &&
		GDC_image != (void*)NULL )
		im = GDC_image;
	else
		im = gdImageCreate( IMGWIDTH, IMGHEIGHT );

	bgclr    = gdImageColorAllocate( im, l2gdcal(BGColor) );
	lineclr  = gdImageColorAllocate( im, l2gdcal(LineColor) );

	gdImageString( im,
				   gdFontMediumBold,
				   IMGWIDTH/2 - GDC_fontc[GDC_MEDBOLD].w*strlen(err_str)/2,
				   IMGHEIGHT/3,
				   (unsigned char*)err_str,
				   lineclr );

	/* usually GDC_generate_img is used in conjunction with hard or hold options */
	if( GDC_generate_img )
		{
		fflush(fptr);			/* clear anything buffered  */
		switch( GDC_image_type )
			{
#ifdef HAVE_JPEG
			case GDC_JPEG:	gdImageJpeg( im, fptr, GDC_jpeg_quality );	break;
#endif
			case GDC_WBMP:	gdImageWBMP( im, lineclr, fptr );			break;
			case GDC_GIF:	gdImageGif( im, fptr);						break;
			case GDC_PNG:
			default:		gdImagePng( im, fptr );
			}
		}

	if( GDC_hold_img & GDC_EXPOSE_IMAGE )
		GDC_image = (void*)im;
	else
		gdImageDestroy(im);
	return;
}
Exemple #13
0
int
create_im (char * name,
		   char * string,
		   int * res,
		   int * sub,
		   rgb backg,
		   rgb foreg)
{
	gdImagePtr	im;
	FILE		* background;
	int			act[2];

	int			back;
	int			fore;

	char		* buf;
	int			y = 0;
    size_t      i;

	act[0] = res[0] / 2 - (sub[0] * gdFontGetLarge ()->w) / 2;
	act[1] = res[1] / 2 - (sub[1] * gdFontGetLarge ()->h) / 2;

	buf = (char *) malloc (((int) get_screen_dims ()[1] / gdFontGetLarge ()->w) * sizeof (char));

	im = gdImageCreate (res[0], res[1]);

	back = gdImageColorAllocate (im, backg.r, backg.g, backg.b);
	fore = gdImageColorAllocate (im, foreg.r, foreg.g, foreg.b);

	for (i = 0; i < strlen (string); i++)
	{
		if (string[i] != '\n')
			buf[y++] = string[i];
		else
		{
			buf[y] = '\0';
			y = 0;
			gdImageString (im, gdFontGetLarge (), act[0], act[1], (unsigned char *) buf, fore);
			act[1] += gdFontGetLarge ()->h;
		}
	}

	buf[y] = '\0';
	gdImageString (im, gdFontGetLarge (), act[0], act[1], (unsigned char *) buf, fore);

	background = fopen (name, "wb");
	gdImageJpeg (im, background, -1);
	fclose (background);
	gdImageDestroy (im);
	return 1;
}
Exemple #14
0
int main(int argc, char *argv[]) {

	// Output directory
	mkdir("results", S_IRWXU | S_IRWXG | S_IRWXO);

	// Directory for reading and file entry
	DIR *directory;
	struct dirent *entry;

	// Main loop
	for(directory = opendir("."); (entry = readdir(directory)) != 0;) {
		if(strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue;
		if(strstr(entry->d_name, ".jpg") != entry->d_name + strlen(entry->d_name) - 4) continue;
		if(strstr(entry->d_name, ".resized.jpg") == entry->d_name + strlen(entry->d_name) - 12) continue;

		printf("Processing <%s>\n", entry->d_name);

		FILE *file = fopen(entry->d_name, "r");
		gdImagePtr source = gdImageCreateFromJpeg(file);

		int source_width = gdImageSX(source);
		int source_height = gdImageSY(source);

		int destination_width = 1024;
		int destination_height = 768;

		gdImagePtr destination = gdImageCreateTrueColor(destination_width, destination_height);

		gdImageCopyResampled(destination, source, 0, 0, 0, 0, destination_width, destination_height, source_width, source_height);

		sprintf(destination_filename, "results/%s.resized.jpg", entry->d_name);

		FILE *destination_file = fopen(destination_filename, "w");
		fseek(destination_file, 0, SEEK_SET);
		gdImageJpeg(destination, destination_file, 90);
		fclose(destination_file);

		gdImageDestroy(destination);
		gdImageDestroy(source);

		fclose(file);
	}
	closedir(directory);

	printf("Job done!\n");

	return 0;
}
Exemple #15
0
int main(int argc, char** argv) {
	if (argc < 3) return 1;
	const char* thumb = argv[1];
	const char* outname = argv[2];
	int thudim = argc < 4 ? 0 : strtol(argv[3], NULL, 0);
	if (thudim < 8) thudim = 150;
	int qual = argc < 5 ? 0 : strtol(argv[4], NULL, 0);
	if (qual < 10) qual = 80;
	//fprintf(stderr, "%s -> %s %d %d\n", thumb, outname, thudim, qual);

	int fd = -1;
	unsigned char* map = NULL;
	size_t len = 0;

	try {
		struct stat st;
		if ((fd = open(thumb, O_RDONLY)) == -1 || fstat(fd, &st) ||
				(map = (unsigned char*)mmap(NULL, len = st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED)
			throw imgdb::io_errno(errno);

		if (map[0] == 'B' && map[1] == 'M') {
			fprintf(stderr, "Bitmap file, ignoring.\n");
			exit(64);
		}

		AutoGDImage thu(resize_image_data(map, len, thudim, 0, 12*thudim));

		FILE *out = fopen(outname, "wb");
		if (!out) throw imgdb::io_errno(errno);

		gdImageJpeg(thu, out, qual);
		fclose(out);


	} catch (std::exception& e) {
		fprintf(stderr, "Resizer caught exception, what=%s.\n", e.what());
		return 1;
	}

	if (map) munmap(map, len);
	if (fd != -1) close(fd);

	return 0;
}
Exemple #16
0
void storeImageBackground(gdImagePtr image, const char *fileExtension,
				const char *dir, const char *fileName, const char *groupName)
{
	char directoryFinal[64];
	char redisIndex[4];
	long long index;
	
	strcpy(directoryFinal, "");
	strcat(directoryFinal, dir);
	strcat(directoryFinal, "/");
	strcat(directoryFinal, dir);
	
	// Get current image count in database
	redisReply *getReply = redisCommand(Context, "SCARD %s", groupName);
	
	index = getReply->integer;
	
	// Get the next
	index++;
	
	snprintf(redisIndex, 4, "%lld", index);
	
	freeReplyObject(getReply);
	
	// Regardless store the filename
	redisReply *setReply = redisCommand(Context, "SADD %s %s", groupName, fileName);
	freeReplyObject(setReply);
	
	strcat(directoryFinal, redisIndex);
	strcat(directoryFinal, fileExtension);
	
	// Scale the image
	double imageHeight = BACKGROUND_WIDTH*((double)image->sx/(double)image->sy);
	int imageHeightRounded = (int)imageHeight;
	image = gdImageScale(image, BACKGROUND_WIDTH, imageHeightRounded);
	
	FILE *output = fopen(directoryFinal, "w");
	gdImageJpeg(image, output, 100);
	fclose(output);
}
Exemple #17
0
static bool picNote(const char *path, char *text)
{
	FILE *fp;
	int c;
	int x, y, w, h;
	int rect[8] = { 0 };
	gdImagePtr im;

	if ((fp = fopen(path, "rb")) == NULL) {
		return false;
	}

	im = gdImageCreateFromJpeg(fp);
	fclose(fp);
	if (im == NULL) {
		return false;
	}

	c = gdImageColorAllocate(im, 255, 255, 255);
	w = gdImageSX(im);
	h = gdImageSY(im);

	memset(rect, 0x00, sizeof(rect));
	gdImageStringFT(NULL, rect, c, "SimHei", 13, 0.0, 0, 0, text);
	x = w - rect[4] - 5;
	y = h - 10;
	gdImageStringFT(im, NULL, c, "SimHei", 13, 0.0, x, y, text);

	if ((fp = fopen(path, "wb")) == NULL) {
		gdImageDestroy(im);
		return false;
	}

	gdImageJpeg(im, fp, -1);
	fclose(fp);

	gdImageDestroy(im);

	return true;
}
void
dotest (char *font, int size, double incr,
        int w, int h, char *string, const char *filename)
{
	gdImagePtr im;
	FILE *out;
	int bg;
	int fc;
#if 0
	int lc;
#endif
	int xc = w / 2;
	int yc = h / 2;

	im = gdImageCreate (w, h);
	bg = gdImageColorAllocate (im, 0, 0, 0);

	gdImageFilledRectangle (im, 1, 1, w - 1, h - 1, bg);

	fc = gdImageColorAllocate (im, 255, 192, 192);
#if 0
	lc = gdImageColorAllocate (im, 192, 255, 255);
#endif

	out = fopen (filename, "wb");

	dowheel (im, fc, font, size, incr, xc, yc, 20, string);
#if 0
	dolines (im, lc, incr, xc, yc, 20, 120);
#endif

#if defined(HAVE_LIBPNG)
	gdImagePng (im, out);
#elif defined(HAVE_LIBJPEG)
	gdImageJpeg (im, out, -1);
#endif

	fclose (out);
}
bool WriteGDImage(const char * filepath, gdImagePtr gdImg, u8 format, u8 compression)
{
	if(gdImg == 0)
		return false;

	FILE * file = fopen(filepath, "wb");
	if(!file)
		return false;

	switch(format)
	{
		default:
		case IMAGE_PNG:
			gdImagePng(gdImg, file);
			break;
		case IMAGE_JPEG:
			gdImageJpeg(gdImg, file, LIMIT(100-compression, 0, 100));
			break;
		case IMAGE_GIF:
			gdImageGif(gdImg, file);
			break;
		case IMAGE_TIFF:
			gdImageTiff(gdImg, file);
			break;
		case IMAGE_BMP:
			gdImageBmp(gdImg, file, compression > 9 ? 9 : compression);
			break;
		case IMAGE_GD:
			gdImageGd(gdImg, file);
			break;
		case IMAGE_GD2:
			gdImageGd2(gdImg, file, 0, LIMIT(compression+1, 1, 2));
			break;
	}

	fclose(file);

	return true;
}
Exemple #20
0
int main(int argc, char** argv) {
	if (argc < 3) exit(1);
	const char* thumb = argv[1];
	const char* outname = argv[2];
	int thudim = strtol(argv[3], NULL, 0);

	int fd = -1;
	unsigned char* map = NULL;
	size_t len = 0;

	try {
		struct stat st;
		if ((fd = open(thumb, O_RDONLY)) == -1 || fstat(fd, &st) ||
				(map = (unsigned char*)mmap(NULL, len = st.st_size, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED)
			throw imgdb::io_errno(errno);

		fprintf(stderr, "Mapped %s at %p:%zd.\n", thumb, map, len);
		AutoGDImage thu(resize_image_data(map, len, thudim, 0, 12*thudim));

		FILE *out = fopen(outname, "wb");
		if (!out) throw imgdb::io_errno(errno);

		gdImageJpeg(thu, out, 95);
		fclose(out);

		fprintf(stderr, "OK:%d %d\n", thu->sx, thu->sy);

	} catch (std::exception& e) {
		fprintf(stderr, "Resizer caught exception, what=%s.\n", e.what());
	}

	if (map) munmap(map, len);
	if (fd != -1) close(fd);

	return 0;
}
Exemple #21
0
NEOERR* mimg_zoomout(int ftype, FILE *dst, FILE*src, int width, int height)
{
    MCS_NOT_NULLB(dst, src);

    int ow, oh;
    gdImagePtr im;
    FILE *gdin, *gdout;

    if (width <= 0 && height <= 0) return STATUS_OK;

    gdin = mfile_get_std_from_safe(src);
    gdout = mfile_get_std_from_safe(dst);

    fseek(src, 0, SEEK_SET);
    fseek(dst, 0, SEEK_SET);

    switch (ftype) {
    case MIMG_TYPE_JPEG:
        im = gdImageCreateFromJpeg(gdin);
        break;
    case MIMG_TYPE_PNG:
        im = gdImageCreateFromPng(gdin);
        break;
    case MIMG_TYPE_GIF:
        im = gdImageCreateFromGif(gdin);
        break;
    case MIMG_TYPE_BMP:
        im = gdImageCreateFromWBMP(gdin);
        break;
    default:
        return nerr_raise(NERR_ASSERT, "file type %d not support", ftype);
    }
    if (!im) return nerr_raise(NERR_ASSERT, "读取图片出错,文件格式错误?");

    ow = gdImageSX(im);
    oh = gdImageSY(im);

    if ((width > 0 && ow > width) ||
        (height > 0 && oh > height)) {
        if (width <= 0) width = (float)height / oh * ow;
        if (height <= 0) height = (float)width / ow * oh;
        
        gdImagePtr dim = gdImageCreateTrueColor(width, height);
        gdImageCopyResized(dim, im, 0, 0, 0, 0, width, height, ow, oh);

        if (dim) {
            switch (ftype) {
            case MIMG_TYPE_JPEG:
                gdImageJpeg(dim, gdout, 70);
                break;
            case MIMG_TYPE_PNG:
                gdImagePng(dim, gdout);
                break;
            case MIMG_TYPE_GIF:
                gdImageGif(dim, gdout);
                break;
            case MIMG_TYPE_BMP:
                gdImageWBMP(dim, 0, gdout);
                break;
            default:
                return nerr_raise(NERR_ASSERT, "file type %d not suport", ftype);
            }
            
        } else return nerr_raise(NERR_ASSERT, "resize image error");
    } else {
        mfile_copy(dst, src);
    }

    return STATUS_OK;
}
Exemple #22
0
int SVimage2file(char *directory, char *RENDERfilename, int rendertype, int woffset, int width, int hoffset, int height){

  FILE *RENDERfile;
  char *renderfile=NULL;
  GLubyte *OpenGLimage, *p;
  gdImagePtr RENDERimage;
  unsigned int r, g, b;
  int i,j,rgb_local;
  int width_beg, width_end, height_beg, height_end;
  int width2, height2;

  width_beg=woffset;
  width_end=width+woffset;
  height_beg=hoffset;
  height_end=hoffset+height;
  if(clip_rendered_scene==1){
    width_beg+=render_clip_left;
    width_end-=render_clip_right;
    height_beg+=render_clip_bottom;
    height_end-=render_clip_top;
  }
  width2 = width_end-width_beg;
  height2 = height_end-height_beg;

  if(directory==NULL){
    renderfile=get_filename(smokeviewtempdir,RENDERfilename,tempdir_flag);
  }
  else{
    renderfile=get_filename(directory,RENDERfilename,1);
  }
  if(renderfile == NULL){
    fprintf(stderr,"*** Error: Unable to write to %s\n",RENDERfilename);
    return 1;
  }
  RENDERfile = fopen(renderfile, "wb");
  if(RENDERfile == NULL){
    fprintf(stderr,"*** Error: Unable to write to %s\n",renderfile);
    return 1;
  }
  NewMemory((void **)&OpenGLimage,width2 * height2 * sizeof(GLubyte) * 3);
  if(OpenGLimage == NULL){
    fprintf(stderr,"*** Error allocating memory buffer for render file:%s\n",renderfile);
    fclose(RENDERfile);
    return 1;
  }
  PRINTF("Rendering to: %s .",renderfile);
  glPixelStorei(GL_PACK_ALIGNMENT, 1);

  /* get the image from the OpenGL frame buffer */

  glReadPixels(width_beg, height_beg, width2, height2, GL_RGB, GL_UNSIGNED_BYTE, OpenGLimage);

  /* copy the image from OpenGL memory to GIF memory */

  p = OpenGLimage;

  RENDERimage = gdImageCreateTrueColor(width2,height2);

  for (i = height2-1 ; i>=0; i--){
    for(j=0;j<width2;j++){
      r=*p++; g=*p++; b=*p++;
      rgb_local = (r<<16)|(g<<8)|b;
      gdImageSetPixel(RENDERimage,j,i,rgb_local);
    }
  }

  if(test_smokesensors==1&&active_smokesensors==1&&show_smokesensors!=0){
    int idev;

    for(idev=0;idev<ndeviceinfo;idev++){
      devicedata *devicei;
      int idev_col, idev_row;
      int col_offset, row_offset;
      unsigned int red=255<<16;

      devicei = deviceinfo + idev;

      if(devicei->object->visible==0)continue;
      if(strcmp(devicei->object->label,"smokesensor")!=0)continue;
      idev_row = devicei->screenijk[0];
      idev_col = devicei->screenijk[1];
      for(col_offset=-3;col_offset<4;col_offset++){
        for(row_offset=-3;row_offset<4;row_offset++){
          int irow, icol;

          irow = idev_row+row_offset;
          if(irow<0)irow=0;
          if(irow>width-1)irow=width-1;

          icol = height - 1 - (idev_col+col_offset);
          if(icol<0)icol=0;
          if(icol>height-1)icol=height-1;

          gdImageSetPixel(RENDERimage,irow,icol,red);
        }
      }
    }
  }

  /* output the gif image */

  switch(rendertype){
  case PNG:
    gdImagePng(RENDERimage,RENDERfile);
    break;
  case JPEG:
    gdImageJpeg(RENDERimage,RENDERfile,-1);
    break;
  default:
    ASSERT(FFALSE);
    break;
  }

  /* free up memory used by both OpenGL and GIF images */

  fclose(RENDERfile);
  FREEMEMORY(renderfile);

  gdImageDestroy(RENDERimage);
  FREEMEMORY(OpenGLimage);
  PRINTF(" Completed.\n");
  return 0;
}
Exemple #23
0
int
main (int argc, char **argv)
{
#ifdef HAVE_LIBPNG
  gdImagePtr im, ref, im2, im3;
  FILE *in, *out;
  void *iptr;
  int sz;
  char of[256];
  int colRed, colBlu;
  gdSource imgsrc;
  gdSink imgsnk;
  int foreground;
  int i;
  if (argc != 2)
    {
      fprintf (stderr, "Usage: gdtest filename.png\n");
      exit (1);
    }
  in = fopen (argv[1], "rb");
  if (!in)
    {
      fprintf (stderr, "Input file does not exist!\n");
      exit (1);
    }
  im = gdImageCreateFromPng (in);

  rewind (in);
  ref = gdImageCreateFromPng (in);

  fclose (in);

  printf ("Reference File has %d Palette entries\n", ref->colorsTotal);

  CompareImages ("Initial Versions", ref, im);


  /* */
  /* Send to PNG File then Ptr */
  /* */
#ifdef VMS
  sprintf (of, "%s-png", argv[1]);
#else
  sprintf (of, "%s.png", argv[1]);
#endif
  out = fopen (of, "wb");
  gdImagePng (im, out);
  fclose (out);

  in = fopen (of, "rb");
  if (!in)
    {
      fprintf (stderr, "PNG Output file does not exist!\n");
      exit (1);
    }
  im2 = gdImageCreateFromPng (in);
  fclose (in);

  CompareImages ("GD->PNG File->GD", ref, im2);

  unlink (of);
  gdImageDestroy (im2);

  /* 2.0.21: use the new From*Ptr functions */
  iptr = gdImagePngPtr (im, &sz);
  im2 = gdImageCreateFromPngPtr (sz, iptr);
  gdFree (iptr);
  CompareImages ("GD->PNG ptr->GD", ref, im2);

  gdImageDestroy (im2);

  /* */
  /* Send to GD2 File then Ptr */
  /* */
#ifdef VMS
  sprintf (of, "%s-gd2", argv[1]);
#else
  sprintf (of, "%s.gd2", argv[1]);
#endif
  out = fopen (of, "wb");
  gdImageGd2 (im, out, 128, 2);
  fclose (out);

  in = fopen (of, "rb");
  if (!in)
    {
      fprintf (stderr, "GD2 Output file does not exist!\n");
      exit (1);
    }
  im2 = gdImageCreateFromGd2 (in);
  fclose (in);

  CompareImages ("GD->GD2 File->GD", ref, im2);

  unlink (of);
  gdImageDestroy (im2);

  iptr = gdImageGd2Ptr (im, 128, 2, &sz);
  /*printf("Got ptr %d (size %d)\n",iptr, sz); */
  im2 = gdImageCreateFromGd2Ptr (sz, iptr);
  gdFree (iptr);
  /*printf("Got img2 %d\n",im2); */

  CompareImages ("GD->GD2 ptr->GD", ref, im2);

  gdImageDestroy (im2);

  /* */
  /* Send to GD File then Ptr */
  /* */
#ifdef VMS
  sprintf (of, "%s-gd", argv[1]);
#else
  sprintf (of, "%s.gd", argv[1]);
#endif
  out = fopen (of, "wb");
  gdImageGd (im, out);
  fclose (out);

  in = fopen (of, "rb");
  if (!in)
    {
      fprintf (stderr, "GD Output file does not exist!\n");
      exit (1);
    }
  im2 = gdImageCreateFromGd (in);
  fclose (in);

  CompareImages ("GD->GD File->GD", ref, im2);

  unlink (of);
  gdImageDestroy (im2);

  iptr = gdImageGdPtr (im, &sz);
  /*printf("Got ptr %d (size %d)\n",iptr, sz); */
  im2 = gdImageCreateFromGdPtr (sz, iptr);
  gdFree (iptr);
  /*printf("Got img2 %d\n",im2); */

  CompareImages ("GD->GD ptr->GD", ref, im2);

  gdImageDestroy (im2);

  /*
   * Test gdImageCreateFromPngSource'
   */

  in = fopen (argv[1], "rb");

  imgsrc.source = freadWrapper;
  imgsrc.context = in;
  im2 = gdImageCreateFromPngSource (&imgsrc);
  fclose (in);

  if (im2 == NULL)
    {
      printf
	("GD Source: ERROR Null returned by gdImageCreateFromPngSource\n");
    }
  else
    {
      CompareImages ("GD Source", ref, im2);
      gdImageDestroy (im2);
    };


  /*
   * Test gdImagePngToSink'
   */
#ifdef VMS
  sprintf (of, "%s-snk", argv[1]);
#else
  sprintf (of, "%s.snk", argv[1]);
#endif
  out = fopen (of, "wb");
  imgsnk.sink = fwriteWrapper;
  imgsnk.context = out;
  gdImagePngToSink (im, &imgsnk);
  fclose (out);
  in = fopen (of, "rb");
  if (!in)
    {
      fprintf (stderr,
	       "GD Sink: ERROR - GD Sink Output file does not exist!\n");
    }
  else
    {
      im2 = gdImageCreateFromPng (in);
      fclose (in);

      CompareImages ("GD Sink", ref, im2);
      gdImageDestroy (im2);
    };

  unlink (of);

  /* */
  /*  Test Extraction */
  /* */
  in = fopen ("test/gdtest_200_300_150_100.png", "rb");
  if (!in)
    {
      fprintf (stderr, "gdtest_200_300_150_100.png does not exist!\n");
      exit (1);
    }
  im2 = gdImageCreateFromPng (in);
  fclose (in);


  in = fopen ("test/gdtest.gd2", "rb");
  if (!in)
    {
      fprintf (stderr, "gdtest.gd2 does not exist!\n");
      exit (1);
    }
  im3 = gdImageCreateFromGd2Part (in, 200, 300, 150, 100);
  fclose (in);

  CompareImages ("GD2Part (gdtest_200_300_150_100.png, gdtest.gd2(part))",
		 im2, im3);

  gdImageDestroy (im2);
  gdImageDestroy (im3);

  /* */
  /*  Copy Blend */
  /* */
  in = fopen ("test/gdtest.png", "rb");
  if (!in)
    {
      fprintf (stderr, "gdtest.png does not exist!\n");
      exit (1);
    }
  im2 = gdImageCreateFromPng (in);
  fclose (in);

  im3 = gdImageCreate (100, 60);
  colRed = gdImageColorAllocate (im3, 255, 0, 0);
  colBlu = gdImageColorAllocate (im3, 0, 0, 255);
  gdImageFilledRectangle (im3, 0, 0, 49, 30, colRed);
  gdImageFilledRectangle (im3, 50, 30, 99, 59, colBlu);

  gdImageCopyMerge (im2, im3, 150, 200, 10, 10, 90, 50, 50);
  gdImageCopyMerge (im2, im3, 180, 70, 10, 10, 90, 50, 50);

  gdImageCopyMergeGray (im2, im3, 250, 160, 10, 10, 90, 50, 50);
  gdImageCopyMergeGray (im2, im3, 80, 70, 10, 10, 90, 50, 50);

  gdImageDestroy (im3);

  in = fopen ("test/gdtest_merge.png", "rb");
  if (!in)
    {
      fprintf (stderr, "gdtest_merge.png does not exist!\n");
      exit (1);
    }
  im3 = gdImageCreateFromPng (in);
  fclose (in);

  printf ("[Merged Image has %d colours]\n", im2->colorsTotal);
  CompareImages ("Merged (gdtest.png, gdtest_merge.png)", im2, im3);

  gdImageDestroy (im2);
  gdImageDestroy (im3);

#ifdef HAVE_LIBJPEG
  out = fopen ("test/gdtest.jpg", "wb");
  if (!out)
    {
      fprintf (stderr, "Can't create file test/gdtest.jpg.\n");
      exit (1);
    }
  gdImageJpeg (im, out, -1);
  fclose (out);
  in = fopen ("test/gdtest.jpg", "rb");
  if (!in)
    {
      fprintf (stderr, "Can't open file test/gdtest.jpg.\n");
      exit (1);
    }
  im2 = gdImageCreateFromJpeg (in);
  fclose (in);
  if (!im2)
    {
      fprintf (stderr, "gdImageCreateFromJpeg failed.\n");
      exit (1);
    }
  gdImageDestroy (im2);
  printf ("Created test/gdtest.jpg successfully. Compare this image\n"
	  "to the input image manually. Some difference must be\n"
	  "expected as JPEG is a lossy file format.\n");
#endif /* HAVE_LIBJPEG */
  /* Assume the color closest to black is the foreground
     color for the B&W wbmp image. */
  fprintf (stderr,
	   "NOTE: the WBMP output image will NOT match the original unless the original\n"
	   "is also black and white. This is OK!\n");
  foreground = gdImageColorClosest (im, 0, 0, 0);
  fprintf (stderr, "Foreground index is %d\n", foreground);
  if (foreground == -1)
    {
      fprintf (stderr, "Source image has no colors, skipping wbmp test.\n");
    }
  else
    {
      out = fopen ("test/gdtest.wbmp", "wb");
      if (!out)
	{
	  fprintf (stderr, "Can't create file test/gdtest.wbmp.\n");
	  exit (1);
	}
      gdImageWBMP (im, foreground, out);
      fclose (out);
      in = fopen ("test/gdtest.wbmp", "rb");
      if (!in)
	{
	  fprintf (stderr, "Can't open file test/gdtest.wbmp.\n");
	  exit (1);
	}
      im2 = gdImageCreateFromWBMP (in);
      fprintf (stderr, "WBMP has %d colors\n", gdImageColorsTotal (im2));
      fprintf (stderr, "WBMP colors are:\n");
      for (i = 0; (i < gdImageColorsTotal (im2)); i++)
	{
	  fprintf (stderr, "%02X%02X%02X\n",
		   gdImageRed (im2, i),
		   gdImageGreen (im2, i), gdImageBlue (im2, i));
	}
      fclose (in);
      if (!im2)
	{
	  fprintf (stderr, "gdImageCreateFromWBMP failed.\n");
	  exit (1);
	}
      CompareImages ("WBMP test (gdtest.png, gdtest.wbmp)", ref, im2);
      out = fopen ("test/gdtest_wbmp_to_png.png", "wb");
      if (!out)
	{
	  fprintf (stderr,
		   "Can't create file test/gdtest_wbmp_to_png.png.\n");
	  exit (1);
	}
      gdImagePng (im2, out);
      fclose (out);
      gdImageDestroy (im2);
    }
  gdImageDestroy (im);
  gdImageDestroy (ref);
#else
  fprintf (stderr, "No PNG library support.\n");
#endif /* HAVE_LIBPNG */

  return 0;
}
Exemple #24
0
void graficotorta(int n, long cantidad[], int estado[]) {

    gdImagePtr imagen;
    FILE *archivo;
    char titulo[513];
    char etiqueta[512];
    int blanco, negro, color;
    gdFontPtr fuente = gdFontGetSmall();
    
    imagen = gdImageCreateTrueColor(IMG_WIDTH, IMG_HEIGHT);

    int i;
    int angEtiqueta, xEtiqueta, yEtiqueta;
    float eqgrados;
    int iniciotrozo, fintrozo;
    long suma = 0;
    int aprox;
    for (i=0; i<n; i++) {    
        suma = suma + cantidad[i];
    }
    eqgrados = 360.0/suma;
    
    if (imagen) {
        blanco = gdImageColorAllocate(imagen, 255, 255, 255);
        negro = gdImageColorAllocate(imagen, 0, 0, 0);
        // Pintamos el fondo Blanco
        gdImageFill(imagen, 0, 0, blanco);
        iniciotrozo = 0;
        for (i=0; i<n; i++) {
            fintrozo = (int) iniciotrozo+cantidad[i]*eqgrados;
            angEtiqueta = (iniciotrozo + fintrozo) / 2;
            xEtiqueta = cos(angEtiqueta*PI/180) * 220 + 400;
            yEtiqueta = sin(angEtiqueta*PI/180) * 220 + 290;
            // Color
            color = gdImageColorAllocate(imagen, color_aleatoreo(), color_aleatoreo(), color_aleatoreo());
            //Pintamos fondo el trozo
            gdImageFilledArc(imagen, 400, 300, 400, 400, iniciotrozo, fintrozo, color, gdArc);       
            //Etiqueta de peticion
            memset(etiqueta, 0, 513);
            snprintf(etiqueta, 512, "peticion %s",intStr(estado[i]));
            gdImageString(imagen, fuente, xEtiqueta-25, yEtiqueta, (unsigned char *) etiqueta, negro);
            //Correccion de aproximacion para el porcentaje
            aprox = cantidad[i] * 1000 / suma;
            aprox = aprox%10;
            if (aprox>=5)
                aprox = 1;
            else
                aprox = 0;
            //Etiqueta de porcentaje
            memset(etiqueta, 0, 513);
            snprintf(etiqueta, 512, "%s%%",longStr(cantidad[i]*100/suma+aprox));
            if (cantidad[i]*100/suma<3){      //Para que la etiqueta sea legible
                xEtiqueta = xEtiqueta + 52;
                yEtiqueta = yEtiqueta - 15;
            }
            gdImageString(imagen, fuente, xEtiqueta, yEtiqueta+15, (unsigned char *) etiqueta, negro);
            iniciotrozo = (int) iniciotrozo+cantidad[i]*eqgrados;
        }

        //Pintamos borde del circulo
        gdImageArc(imagen, 400, 300, 400, 400, 0, 360, negro);
        // Coloco el título
        memset(titulo, 0, 513);
        snprintf(titulo, 512, "Peticiones Por Estado");
        gdImageString(imagen, fuente, (int) IMG_WIDTH * 0.4, 25, (unsigned char *) titulo, negro);
        // Pintamos Borde
        gdImageLine(imagen, BORDE_ANCHO, BORDE_ALTO, (IMG_WIDTH - BORDE_ANCHO), BORDE_ALTO, negro); //linea horiz superior
        gdImageLine(imagen, BORDE_ANCHO, (IMG_HEIGHT - BORDE_ALTO), (IMG_WIDTH - BORDE_ANCHO), (IMG_HEIGHT - BORDE_ALTO), negro); //linea horiz inferior
        gdImageLine(imagen, BORDE_ANCHO, BORDE_ALTO, BORDE_ANCHO, (IMG_HEIGHT - BORDE_ALTO), negro); //linea vertical izquierda
        gdImageLine(imagen, (IMG_WIDTH - BORDE_ANCHO), BORDE_ALTO, (IMG_WIDTH - BORDE_ANCHO), (IMG_HEIGHT - BORDE_ALTO), negro); //linea horiz derecha
        // Guardar imagen
        archivo = fopen("graficot.jpg", "wb");
        if (archivo != NULL) {
            gdImageJpeg(imagen, archivo, 100);
            fclose(archivo);
        }
        gdImageDestroy(imagen);
    }
 
}
Exemple #25
0
/* ======================================================= *\ 
 * PIE
 * 
 * Notes:
 *  always drawn from 12:00 position clockwise
 *  'missing' slices don't get labels
 *  sum(val[0], ... val[num_points-1]) is assumed to be 100%
\* ======================================================= */
void
GDC_out_pie( short			IMGWIDTH,
			 short			IMGHEIGHT,
			 FILE			*img_fptr,			/* open file pointer */
			 GDCPIE_TYPE	type,
			 int			num_points,
			 char			*lbl[],				/* data labels */
			 float			val[] )				/* data */
{
	int			i;

	gdImagePtr	im;
	int			BGColor,
				LineColor,
				PlotColor,
				EdgeColor,
				EdgeColorShd;
	CREATE_ARRAY1( SliceColor, int, num_points );		/* int SliceColor[num_points] */
	CREATE_ARRAY1( SliceColorShd, int, num_points );	/* int SliceColorShd[num_points] */

	float		rad = 0.0;					/* radius */
	float		ellipsex = 1.0;
	float		ellipsey = 1.0 - (float)GDCPIE_perspective/100.0;
	float		tot_val = 0.0;
	float		pscl;
	int			cx,							/* affects PX() */
				cy;							/* affects PY() */
								/* ~ 1% for a size of 100 pixs */
								/* label sizes will more dictate this */
	float		min_grphable = ( GDCPIE_other_threshold < 0?
								  100.0/(float)MIN(IMGWIDTH,IMGHEIGHT):
								  (float)GDCPIE_other_threshold )/100.0;
	short		num_slices1 = 0,
				num_slices2 = 0;
	char		any_too_small = FALSE;
	CREATE_ARRAY1( others, char, num_points );			/* char others[num_points] */
	CREATE_ARRAY2( slice_angle, float, 3, num_points );	/* float slice_angle[3][num_points] */
														/* must be used with others[] */
	char		threeD = ( type == GDC_3DPIE );

	int			xdepth_3D      = 0,			/* affects PX() */
				ydepth_3D      = 0;			/* affects PY() */
	int			do3Dx = 0,					/* reserved for macro use */
				do3Dy = 0;

	CREATE_ARRAY2( pct_lbl, char, num_points, 16 );			/* sizeof or strlen (GDCPIE_percent_fmt)? */
	CREATE_ARRAY1( pct_ftsz, struct fnt_sz_t, num_points );	/* struct fnt_sz_t lbl_ftsz[num_points] */
	CREATE_ARRAY1( lbl_ftsz, struct fnt_sz_t, num_points );	/* struct fnt_sz_t lbl_ftsz[num_points] */


#ifdef HAVE_LIBFREETYPE
	char			*gdcpie_title_font  = GDCPIE_title_font;
	char			*gdcpie_label_font  = GDCPIE_label_font;
	double			gdcpie_title_ptsize = GDCPIE_title_ptsize;
	double			gdcpie_label_ptsize = GDCPIE_label_ptsize;
#else
	char			*gdcpie_title_font  = NULL;
	char			*gdcpie_label_font  = NULL;
	double			gdcpie_title_ptsize = 0.0;
	double			gdcpie_label_ptsize = 0.0;
#endif

/*	GDCPIE_3d_angle = MOD_360(90-GDCPIE_3d_angle+360); */
	pie_3D_rad = TO_RAD( GDCPIE_3d_angle );

	xdepth_3D      = threeD? (int)( cos((double)MOD_2PI(M_PI_2-pie_3D_rad+2.0*M_PI)) * GDCPIE_3d_depth ): 0;
	ydepth_3D      = threeD? (int)( sin((double)MOD_2PI(M_PI_2-pie_3D_rad+2.0*M_PI)) * GDCPIE_3d_depth ): 0;
/*	xdepth_3D      = threeD? (int)( cos(pie_3D_rad) * GDCPIE_3d_depth ): 0; */
/*	ydepth_3D      = threeD? (int)( sin(pie_3D_rad) * GDCPIE_3d_depth ): 0; */

	load_font_conversions();

	/* ----- get total value ----- */
	for( i=0; i<num_points; ++i )
		tot_val += val[i];

	/* ----- pie sizing ----- */
	/* ----- make width room for labels, depth, etc.: ----- */
	/* ----- determine pie's radius ----- */
	{
	int		title_hgt  = GDCPIE_title? 1			/*  title? horizontal text line */
									   + GDCfnt_sz( GDCPIE_title,
													GDCPIE_title_size,
													gdcpie_title_font, gdcpie_title_ptsize, 0.0, NULL ).h

									   + 2:
									   0;
	float	last = 0.0;
	float	label_explode_limit = 0.0;
	int		cheight,
			cwidth;

	/* maximum: no labels, explosions */
	/* gotta start somewhere */
	rad = (float)MIN( (IMGWIDTH/2)/ellipsex-(1+ABS(xdepth_3D)), (IMGHEIGHT/2)/ellipsey-(1+ABS(ydepth_3D))-title_hgt );

	/* ok fix center, i.e., no floating re labels, explosion, etc. */
	cx = IMGWIDTH/2 /* - xdepth_3D */ ;
	cy = (IMGHEIGHT-title_hgt)/2 + title_hgt /* + ydepth_3D */ ;

	cheight = (IMGHEIGHT- title_hgt)/2 /* - ydepth_3D */ ;
	cwidth  = cx;

	/* walk around pie. determine spacing to edge */
	for( i=0; i<num_points; ++i )
		{
		float	this_pct = val[i]/tot_val;						/* should never be > 100% */
		float	this = this_pct*(2.0*M_PI);						/* pie-portion */
		if( (this_pct > min_grphable) ||						/* too small */
			(!GDCPIE_missing || !GDCPIE_missing[i]) )			/* still want angles */
			{
			int this_explode = GDCPIE_explode? GDCPIE_explode[i]: 0;
			double	this_sin;
			double	this_cos;
			slice_angle[0][i] = this/2.0+last;				/* mid-point on full pie */
			slice_angle[1][i] = last;						/* 1st on full pie */
			slice_angle[2][i] = this+last;					/* 2nd on full pie */
			this_sin        = ellipsex*sin( (double)slice_angle[0][i] );
			this_cos        = ellipsey*cos( (double)slice_angle[0][i] );

			if( !GDCPIE_missing || !(GDCPIE_missing[i]) )
				{
				short	lbl_wdth = 0,
						lbl_hgt  = 0;
				float	this_y_explode_limit,
						this_x_explode_limit;

				/* start slice label height, width     */
				/*  accounting for PCT placement, font */
				pct_ftsz[i].h = 0;
				pct_ftsz[i].w = 0;
				if( GDCPIE_percent_fmt &&
					GDCPIE_percent_labels != GDCPIE_PCT_NONE )
					{
					sprintf( pct_lbl[i], GDCPIE_percent_fmt, this_pct * 100.0 );
					pct_ftsz[i] = GDCfnt_sz( pct_lbl[i],
											 GDCPIE_label_size,
											 gdcpie_label_font, gdcpie_label_ptsize, 0.0, NULL );
					lbl_wdth = pct_ftsz[i].w;
					lbl_hgt  = pct_ftsz[i].h;
					}

				if( lbl && lbl[i] )
					{
					lbl_ftsz[i] = GDCfnt_sz( lbl[i],
											 GDCPIE_label_size,
											 gdcpie_label_font, gdcpie_label_ptsize, 0.0, NULL );

					if( GDCPIE_percent_labels == GDCPIE_PCT_ABOVE ||
						GDCPIE_percent_labels == GDCPIE_PCT_BELOW )
						{
						lbl_wdth = MAX( pct_ftsz[i].w, lbl_ftsz[i].w );
						lbl_hgt  = pct_ftsz[i].h + lbl_ftsz[i].h + 1;
						}
					else
					if( GDCPIE_percent_labels == GDCPIE_PCT_RIGHT ||
						GDCPIE_percent_labels == GDCPIE_PCT_LEFT )
						{
						lbl_wdth = pct_ftsz[i].w + lbl_ftsz[i].w + 1;
						lbl_hgt  = MAX( pct_ftsz[i].h, lbl_ftsz[i].h );
						}
					else /* GDCPIE_PCT_NONE */
						{
						lbl_wdth = lbl_ftsz[i].w;
						lbl_hgt  = lbl_ftsz[i].h;
						}
					}
				else
					lbl_wdth = lbl_hgt = 0;
				/* end label height, width */
				
				/* diamiter limited by this point's: explosion, label                 */
				/* (radius to box @ slice_angle) - (explode) - (projected label size) */
				/* radius constraint due to labels */
				this_y_explode_limit = (float)this_cos==0.0? FLT_MAX:
										(	(float)( (double)cheight/ABS(this_cos) ) - 
											(float)( this_explode + (lbl&&lbl[i]? GDCPIE_label_dist: 0) ) -
											(float)( lbl_hgt/2 ) / (float)ABS(this_cos)	);
				this_x_explode_limit = (float)this_sin==0.0? FLT_MAX:
										(	(float)( (double)cwidth/ABS(this_sin) ) - 
											(float)( this_explode + (lbl&&lbl[i]? GDCPIE_label_dist: 0) ) -
											(float)( lbl_wdth ) / (float)ABS(this_sin)	);

				rad = MIN( rad, this_y_explode_limit );
				rad = MIN( rad, this_x_explode_limit );

				/* ok at this radius (which is most likely larger than final) */
				/* adjust for inter-label spacing */
/*				if( lbl[i] && *lbl[i] ) */
/*					{ */
/*					char which_edge = slice_angle[0][i] > M_PI? +1: -1;		// which semi */
/*					last_label_yedge = cheight - (int)( (rad +				// top or bottom of label */
/*														(float)(this_explode + */
/*														(float)GDCPIE_label_dist)) * (float)this_cos ) + */
/*											     ( (GDC_fontc[GDCPIE_label_size].h+1)/2 + */
/*													GDC_label_spacing )*which_edge; */
/*					} */

				/* radius constriant due to exploded depth */
				/* at each edge of the slice, and the middle */
				/* this is really stupid */
				/*  this section uses a different algorithm then above, but does the same thing */
				/*  could be combined, but each is ugly enough! */
/* PROTECT /0 */
				if( threeD )
					{
					short	j;
					int		this_y_explode_pos;
					int		this_x_explode_pos;

					/* first N E S W (actually no need for N) */
					if( (slice_angle[1][i] < M_PI_2 && M_PI_2 < slice_angle[2][i]) &&				/* E */
						(this_x_explode_pos=OX(i,M_PI_2,1)) > cx+cwidth )
						rad -= (float)ABS( (double)(1+this_x_explode_pos-(cx+cwidth))/sin(M_PI_2) );
					if( (slice_angle[1][i] < 3.0*M_PI_2 && 3.0*M_PI_2 < slice_angle[2][i]) &&		/* W */
						(this_x_explode_pos=OX(i,3.0*M_PI_2,1)) < cx-cwidth )
						rad -= (float)ABS( (double)(this_x_explode_pos-(cx+cwidth))/sin(3.0*M_PI_2) );
					if( (slice_angle[1][i] < M_PI && M_PI < slice_angle[2][i]) &&					/* S */
						(this_y_explode_pos=OY(i,M_PI,1)) > cy+cheight )
						rad -= (float)ABS( (double)(1+this_y_explode_pos-(cy+cheight))/cos(M_PI) );

					for( j=0; j<3; ++j )
						{
						this_y_explode_pos = IY(i,j,1);
						if( this_y_explode_pos < cy-cheight )
							rad -= (float)ABS( (double)((cy-cheight)-this_y_explode_pos)/cos((double)slice_angle[j][i]) );
						if( this_y_explode_pos > cy+cheight )
							rad -= (float)ABS( (double)(1+this_y_explode_pos-(cy+cheight))/cos((double)slice_angle[j][i]) );

						this_x_explode_pos = IX(i,j,1);
						if( this_x_explode_pos < cx-cwidth )
							rad -= (float)ABS( (double)((cx-cwidth)-this_x_explode_pos)/sin((double)slice_angle[j][i]) );
						if( this_x_explode_pos > cx+cwidth )
							rad -= (float)ABS( (double)(1+this_x_explode_pos-(cx+cwidth))/sin((double)slice_angle[j][i]) );
						}
					}
				}
			others[i] = FALSE;
			}
		else
			{
			others[i] = TRUE;
			slice_angle[0][i] = -FLT_MAX;
			}
		last += this;
		}
	}

	/* ----- go ahead and start the image ----- */
	im = gdImageCreate( IMGWIDTH, IMGHEIGHT );

	/* --- allocate the requested colors --- */
	BGColor   = clrallocate( im, GDCPIE_BGColor );
	LineColor = clrallocate( im, GDCPIE_LineColor );
	PlotColor = clrallocate( im, GDCPIE_PlotColor );
	if( GDCPIE_EdgeColor != GDC_NOCOLOR )
	 {
	 EdgeColor = clrallocate( im, GDCPIE_EdgeColor );
	 if( threeD )
	  EdgeColorShd = clrshdallocate( im, GDCPIE_EdgeColor );
	 }

	/* --- set color for each slice --- */
	for( i=0; i<num_points; ++i )
		if( GDCPIE_Color )
			{
			unsigned long	slc_clr = GDCPIE_Color[i];

			SliceColor[i]     = clrallocate( im, slc_clr );
			if( threeD )
			 SliceColorShd[i] = clrshdallocate( im, slc_clr );
			}
		else
			{
			SliceColor[i]     = PlotColor;
			if( threeD )
			 SliceColorShd[i] = clrshdallocate( im, GDCPIE_PlotColor );
			}

	pscl = (2.0*M_PI)/tot_val;
	
	/* ----- calc: smallest a slice can be ----- */
	/* 1/2 circum / num slices per side. */
	/*              determined by number of labels that'll fit (height) */
	/* scale to user values */
	/* ( M_PI / (IMGHEIGHT / (SFONTHGT+1)) ) */
/*	min_grphable = tot_val / */
/*				   ( 2.0 * (float)IMGHEIGHT / (float)(SFONTHGT+1+TFONTHGT+2) ); */


	if( threeD )
		{
		/* draw background shaded pie */
		{
		float	rad1 = rad * 3.0/4.0;
		for( i=0; i<num_points; ++i )
			if( !(others[i]) &&
				(!GDCPIE_missing || !GDCPIE_missing[i]) )
				{
				int		edge_color = GDCPIE_EdgeColor == GDC_NOCOLOR? SliceColorShd[i]:
				                                                      EdgeColorShd;

				gdImageLine( im, CX(i,1), CY(i,1), IX(i,1,1), IY(i,1,1), edge_color );
				gdImageLine( im, CX(i,1), CY(i,1), IX(i,2,1), IY(i,2,1), edge_color );
				gdImageArc( im, CX(i,1), CY(i,1),
								(int)(rad*ellipsex*2.0), (int)(rad*ellipsey*2.0),
								TO_INT_DEG_FLOOR(slice_angle[1][i])+270,
								TO_INT_DEG_CEIL(slice_angle[2][i])+270,
								edge_color );
					
/*				gdImageFilledArc( im, CX(i,1), CY(i,1), */
/*									  rad*ellipsex*2, rad*ellipsey*2, */
/*									  TO_INT_DEG_FLOOR(slice_angle[1][i])+270, */
/*									  TO_INT_DEG_CEIL(slice_angle[2][i])+270, */
/*									  SliceColorShd[i], */
/*									  gdPie ); */
				/* attempt to fill, if slice is wide enough */
				if( (ABS(IX(i,1,1)-IX(i,2,1)) + ABS(IY(i,1,1)-IY(i,2,1))) > 2 )
					{
					float	rad = rad1;										/* local override */
					gdImageFillToBorder( im, IX(i,0,1), IY(i,0,1), edge_color, SliceColorShd[i] );
					}
				}
		}
		/* fill in connection to foreground pie */
		/* this is where we earn our keep */
		{
		int					t,
							num_slice_angles = 0;
		CREATE_ARRAY1( tmp_slice, struct tmp_slice_t, 4*num_points+4 );		/* should only need 2*num_points+2 */

		for( i=0; i<num_points; ++i )
			if( !GDCPIE_missing || !GDCPIE_missing[i] )
				{
				if( RAD_DIST1(slice_angle[1][i]) < RAD_DIST2(slice_angle[0][i]) )
					tmp_slice[num_slice_angles].hidden = FALSE;
				else
					tmp_slice[num_slice_angles].hidden = TRUE;
				tmp_slice[num_slice_angles].i       = i;
				tmp_slice[num_slice_angles].slice   = slice_angle[0][i];
				tmp_slice[num_slice_angles++].angle = slice_angle[1][i];
				if( RAD_DIST1(slice_angle[2][i]) < RAD_DIST2(slice_angle[0][i]) )
					tmp_slice[num_slice_angles].hidden = FALSE;
				else
					tmp_slice[num_slice_angles].hidden = TRUE;
				tmp_slice[num_slice_angles].i       = i;
				tmp_slice[num_slice_angles].slice   = slice_angle[0][i];
				tmp_slice[num_slice_angles++].angle = slice_angle[2][i];
				/* identify which 2 slices (i) have a tangent parallel to depth angle  */
				if( slice_angle[1][i]<MOD_2PI(pie_3D_rad+M_PI_2) && slice_angle[2][i]>MOD_2PI(pie_3D_rad+M_PI_2) )
					{
					tmp_slice[num_slice_angles].i       = i;
					tmp_slice[num_slice_angles].hidden  = FALSE;
					tmp_slice[num_slice_angles].slice   = slice_angle[0][i];
					tmp_slice[num_slice_angles++].angle = MOD_2PI( pie_3D_rad+M_PI_2 );
					}
				if( slice_angle[1][i]<MOD_2PI(pie_3D_rad+3.0*M_PI_2) && slice_angle[2][i]>MOD_2PI(pie_3D_rad+3.0*M_PI_2) )
					{
					tmp_slice[num_slice_angles].i       = i;
					tmp_slice[num_slice_angles].hidden  = FALSE;
					tmp_slice[num_slice_angles].slice   = slice_angle[0][i];
					tmp_slice[num_slice_angles++].angle = MOD_2PI( pie_3D_rad+3.0*M_PI_2 );
					}
				}

		qsort( tmp_slice, num_slice_angles, sizeof(struct tmp_slice_t), ocmpr );
		for( t=0; t<num_slice_angles; ++t )
			{
			gdPoint	gdp[4];

			i = tmp_slice[t].i;

			gdp[0].x  = CX(i,0);					gdp[0].y = CY(i,0);
			gdp[1].x  = CX(i,1);					gdp[1].y = CY(i,1);
			gdp[2].x  = OX(i,tmp_slice[t].angle,1);	gdp[2].y = OY(i,tmp_slice[t].angle,1);
			gdp[3].x  = OX(i,tmp_slice[t].angle,0);	gdp[3].y = OY(i,tmp_slice[t].angle,0);

			if( !(tmp_slice[t].hidden) )
				gdImageFilledPolygon( im, gdp, 4, SliceColorShd[i] );
			else
				{
				rad -= 2.0;										/* no peeking */
				gdp[0].x  = OX(i,slice_angle[0][i],0);	gdp[0].y = OY(i,slice_angle[0][i],0);
				gdp[1].x  = OX(i,slice_angle[0][i],1);	gdp[1].y = OY(i,slice_angle[0][i],1);
				rad += 2.0;
				gdp[2].x  = OX(i,slice_angle[1][i],1);	gdp[2].y = OY(i,slice_angle[1][i],1);
				gdp[3].x  = OX(i,slice_angle[1][i],0);	gdp[3].y = OY(i,slice_angle[1][i],0);
				gdImageFilledPolygon( im, gdp, 4, SliceColorShd[i] );
				gdp[2].x  = OX(i,slice_angle[2][i],1);	gdp[2].y = OY(i,slice_angle[2][i],1);
				gdp[3].x  = OX(i,slice_angle[2][i],0);	gdp[3].y = OY(i,slice_angle[2][i],0);
				gdImageFilledPolygon( im, gdp, 4, SliceColorShd[i] );
				}
				

			if( GDCPIE_EdgeColor != GDC_NOCOLOR )
				{
				gdImageLine( im, CX(i,0), CY(i,0), CX(i,1), CY(i,1), EdgeColorShd );
				gdImageLine( im, OX(i,tmp_slice[t].angle,0), OY(i,tmp_slice[t].angle,0),
								 OX(i,tmp_slice[t].angle,1), OY(i,tmp_slice[t].angle,1),
								 EdgeColorShd );
				}
			}
		FREE_ARRAY1( tmp_slice );
		}
		}


	/* ----- pie face ----- */
	{
	/* float	last = 0.0; */
	float	rad1 = rad * 3.0/4.0;
	for( i=0; i<num_points; ++i )
		if( !others[i] &&
			(!GDCPIE_missing || !GDCPIE_missing[i]) )
			{
			int		edge_color = GDCPIE_EdgeColor == GDC_NOCOLOR? SliceColor[i]:
																  EdgeColorShd;
			/* last += val[i]; */
			/* EXPLODE_CX_CY( slice_angle[0][i], i ); */
			gdImageLine( im, CX(i,0), CY(i,0), IX(i,1,0), IY(i,1,0), edge_color );
			gdImageLine( im, CX(i,0), CY(i,0), IX(i,2,0), IY(i,2,0), edge_color );
			gdImageArc( im, CX(i,0), CY(i,0), 
							(int)(rad*ellipsex*2.0), (int)(rad*ellipsey*2.0),
							(TO_INT_DEG_FLOOR(slice_angle[1][i])+270)%360,
							(TO_INT_DEG_CEIL(slice_angle[2][i])+270)%360,
							edge_color );
			/* antialiasing here */
			/* likely only on the face? */
/* bugs in gd2.0.0 */
/*	arc doesn't honor deg>360 */
/*	arcs from gdImageFilledArc() don't match with gdImageArc() */
/*	angles are off */
/*	doesn't always fill completely */
/*			gdImageFilledArc( im, CX(i,0), CY(i,0),  */
/*								  (int)(rad*ellipsex*2.0), (int)(rad*ellipsey*2.0), */
/*								  (TO_INT_DEG_FLOOR(slice_angle[1][i])+270)%360, */
/*								  (TO_INT_DEG_CEIL(slice_angle[2][i])+270)%360, */
/*								  SliceColor[i], */
/*								  gdPie ); */
			/* attempt to fill, if slice is wide enough */
			{
			float	rad = rad1;										/* local override */
			if( (ABS(IX(i,1,1)-IX(i,2,1)) + ABS(IY(i,1,1)-IY(i,2,1))) > 2 )
				{
				gdImageFillToBorder( im, IX(i,0,0), IY(i,0,0), edge_color, SliceColor[i] );
				}
			/* catch missed pixels on narrow slices */
			gdImageLine( im, CX(i,0), CY(i,0), IX(i,0,0), IY(i,0,0), SliceColor[i] );
			}
			}
	}

	if( GDCPIE_title )
		{
		struct fnt_sz_t	tftsz      = GDCfnt_sz( GDCPIE_title,
												GDCPIE_title_size,
												gdcpie_title_font, gdcpie_title_ptsize, 0.0, NULL );
		GDCImageStringNL( im,
						  &GDC_fontc[GDCPIE_title_size],
						  gdcpie_title_font, gdcpie_title_ptsize,
						  0.0,
						  IMGWIDTH/2 - tftsz.w/2,
						  1,
						  GDCPIE_title,
						  LineColor,
						  GDC_JUSTIFY_CENTER,
						  NULL );
		}

	/* labels */
	if( lbl )
		{
		float	liner = rad;

		rad += GDCPIE_label_dist;
		for( i=0; i<num_points; ++i )
			{
			if( !others[i] &&
				(!GDCPIE_missing || !GDCPIE_missing[i]) )
				{
				int		lblx,  pctx,
						lbly,  pcty,
						linex, liney;

				lbly = (liney = IY(i,0,0))-lbl_ftsz[i].h / 2;
				lblx = pctx = linex = IX(i,0,0);

				if( slice_angle[0][i] > M_PI )								/* which semicircle */
					{
					lblx -= lbl_ftsz[i].w;
					pctx = lblx;
					++linex;
					}
				else
					--linex;

				switch( GDCPIE_percent_labels )
					{
					case GDCPIE_PCT_LEFT:	if( slice_angle[0][i] > M_PI )
												pctx -= lbl_ftsz[i].w-1;
											else
												lblx += pct_ftsz[i].w+1;
											pcty = IY(i,0,0) - ( 1+pct_ftsz[i].h ) / 2;
											break;
					case GDCPIE_PCT_RIGHT:	if( slice_angle[0][i] > M_PI )
												lblx -= pct_ftsz[i].w-1;
											else
												pctx += lbl_ftsz[i].w+1;
											pcty = IY(i,0,0) - ( 1+pct_ftsz[i].h ) / 2;
											break;
					case GDCPIE_PCT_ABOVE:	lbly += (1+pct_ftsz[i].h) / 2;
											pcty = lbly - pct_ftsz[i].h;
											break;
					case GDCPIE_PCT_BELOW:	lbly -= (1+pct_ftsz[i].h) / 2;
											pcty = lbly + lbl_ftsz[i].h;
											break;
					case GDCPIE_PCT_NONE:
					default:;
					}

				if( GDCPIE_percent_labels != GDCPIE_PCT_NONE )
					GDCImageStringNL( im,
									  &GDC_fontc[GDCPIE_label_size],
									  gdcpie_label_font, gdcpie_label_ptsize,
									  0.0,
									  slice_angle[0][i] <= M_PI? pctx:
																 pctx+lbl_ftsz[i].w-pct_ftsz[i].w,
									  pcty,
									  pct_lbl[i],
									  LineColor,
									  GDC_JUSTIFY_CENTER,
									  NULL );
				if( lbl[i] )
					GDCImageStringNL( im,
									  &GDC_fontc[GDCPIE_label_size],
									  gdcpie_label_font, gdcpie_label_ptsize,
									  0.0,
									  lblx,
									  lbly,
									  lbl[i],
									  LineColor,
									  slice_angle[0][i] <= M_PI? GDC_JUSTIFY_LEFT:
																 GDC_JUSTIFY_RIGHT,
									  NULL );
				if( GDCPIE_label_line )
					{
					float	rad = liner;
					gdImageLine( im, linex, liney, IX(i,0,0), IY(i,0,0), LineColor );
					}
				}
			}
		rad -= GDCPIE_label_dist;
		}

		fflush( img_fptr );
		switch( GDC_image_type )
			{
#ifdef HAVE_JPEG
			case GDC_JPEG:	gdImageJpeg( im, img_fptr, GDC_jpeg_quality );	break;
#endif
			case GDC_WBMP:	gdImageWBMP( im, PlotColor, img_fptr );			break;
			case GDC_GIF:	gdImageGif( im, img_fptr);						break;
			case GDC_PNG:
			default:		gdImagePng( im, img_fptr );
			}

	FREE_ARRAY1( lbl_ftsz );
	FREE_ARRAY1( pct_ftsz );
	FREE_ARRAY2( pct_lbl );

	FREE_ARRAY2( slice_angle );
	FREE_ARRAY1( others );

	FREE_ARRAY1( SliceColorShd );
	FREE_ARRAY1( SliceColor );
	gdImageDestroy(im);
	return;
}
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;
}
Exemple #27
0
int main(int argc, char *argv[])
{
#ifndef HAVE_LIBFREETYPE
	(void)argc;
	(void)argv;

	/* 2.0.12 */
	fprintf(stderr, "annotate is not useful without freetype.\n"
	         "Install freetype, then './configure; make clean; make install'\n"
	         "the gd library again.\n"
	        );
	return 1;
#else
	gdImagePtr im;
	char *iin, *iout;
	FILE *in, *out;
	char s[1024];
	int bounds[8];
	int lines = 1;
	int color = gdTrueColor(0, 0, 0);
	char font[1024];
	int size = 12;
	int align = left;
	int x = 0, y = 0;
	char *fontError;

	strcpy(font, "times");

	if(argc != 3) {
		fprintf(stderr, "Usage: annotate imagein.jpg imageout.jpg\n\n");
		fprintf(stderr, "Standard input should consist of\n");
		fprintf(stderr, "lines in the following formats:\n");
		fprintf(stderr, "color r g b (0-255 each) [a (0-127, 0 is opaque)]\n");
		fprintf(stderr, "font fontname (max name length 1024)\n");
		fprintf(stderr, "size pointsize\n");
		fprintf(stderr, "align (left|right|center)\n");
		fprintf(stderr, "move x y\n");
		fprintf(stderr, "text actual-output-text\n\n");
		fprintf(stderr,
		        "If the file 'paris.ttf' exists in /usr/share/fonts/truetype or in a\n");
		fprintf(stderr,
		        "location specified in the GDFONTPATH environment variable, 'font paris' is\n");
		fprintf(stderr,
		        "sufficient. You may also specify the full, rooted path of a font file.\n");
		exit(1);
	}

	iin = argv[1];
	iout = argv[2];

	in = fopen(iin, "rb");
	if(!in) {
		fprintf(stderr, "Couldn't open %s\n", iin);
		exit(2);
	}

#ifdef HAVE_LIBJPEG
	im = gdImageCreateFromJpeg(in);
#else
	fprintf(stderr, "No JPEG library support available.\n");
	exit(1);
#endif

	fclose(in);

	if(!im) {
		fprintf(stderr, "%s did not load properly\n", iin);
		exit(3);
	}

	while(fgets(s, sizeof(s), stdin)) {
		char *st;
		char *text;

		st = strtok(s, " \t\r\n");
		if(!st) {
			/* Be nice about blank lines */
			continue;
		}

		if(!strcmp(st, "font")) {
			char *st = strtok(0, " \t\r\n");
			if(!st) {
				goto badLine;
			} else {
				const unsigned int font_len = strlen(st);
				if (font_len >= 1024) {
					fprintf(stderr, "Font maximum length is 1024, %d given\n", font_len);
					goto badLine;
				}
				strncpy(font, st, font_len);
			}
		} else if(!strcmp(st, "align")) {
			char *st = strtok(0, " \t\r\n");

			if(!st) {
				goto badLine;
			}

			if(!strcmp(st, "left")) {
				align = 0;
			} else if(!strcmp(st, "center")) {
				align = 1;
			} else if(!strcmp(st, "right")) {
				align = 2;
			}
		} else if(!strcmp(st, "size")) {
			char *st = strtok(0, " \t\r\n");

			if(!st) {
				goto badLine;
			}

			size = atoi(st);
		} else if(!strcmp(st, "color")) {
			char *st = strtok(0, "\r\n");
			int r, g, b, a = 0;

			if(!st) {
				goto badLine;
			}

			if(sscanf(st, "%d %d %d %d", &r, &g, &b, &a) < 3) {
				fprintf(stderr, "Bad color at line %d\n", lines);
				exit(2);
			}

			color = gdTrueColorAlpha(r, g, b, a);
		} else if(!strcmp(st, "move")) {
			char *st = strtok(0, "\r\n");

			if(!st) {
				goto badLine;
			}

			if(sscanf(st, "%d %d", &x, &y) != 2) {
				fprintf(stderr, "Missing coordinates at line %d\n", lines);
				exit(3);
			}
		} else if(!strcmp(st, "text")) {
			int rx = x;

			text = strtok(0, "\r\n");
			if(!text) {
				text = "";
			}

			gdImageStringFT(0, bounds, color, font, size, 0, x, y, text);

			switch(align) {
			case left:
				break;

			case center:
				rx -= (bounds[2] - bounds[0]) / 2;
				break;

			case right:
				rx -= (bounds[2] - bounds[0]);
				break;
			}

			fontError = gdImageStringFT(im, 0, color, font, size, 0, rx, y, text);
			if(fontError) {
				fprintf(stderr, "font error at line %d: %s\n", lines, fontError);
				exit(7);
			}

			y -= (bounds[7] - bounds[1]);
		} else {
			goto badLine;
		}

		lines++;
		continue;

badLine:
		fprintf(stderr, "Bad syntax, line %d\n", lines);
		exit(4);
	}

	out = fopen(iout, "wb");
	if(!out) {
		fprintf(stderr, "Cannot create %s\n", iout);
		exit(5);
	}
#ifdef HAVE_LIBJPEG
	gdImageJpeg(im, out, 95);
#else
	fprintf(stderr, "No JPEG library support available.\n");
#endif
	gdImageDestroy(im);
	fclose(out);
	return 0;
#endif /* HAVE_LIBFREETYPE */
}
Exemple #28
0
int fswc_output(fswebcam_config_t *config, char *name, gdImage *image)
{
	char filename[FILENAME_MAX];
	gdImage *im;
	FILE *f;
	
	if(!name) return(-1);
	if(!strncmp(name, "-", 2) && config->background)
	{
		ERROR("stdout is unavailable in background mode.");
		return(-1);
	}
	
	fswc_strftime(filename, FILENAME_MAX, name,
	              config->start, config->gmt);
	
	/* Create a temporary image buffer. */
	im = fswc_gdImageDuplicate(image);
	if(!im)
	{
		ERROR("Out of memory.");
		return(-1);
	}
	
	/* Draw the underlay. */
	fswc_draw_overlay(config, config->underlay, im);
	
	/* Draw the banner. */
	if(config->banner != NO_BANNER)
	{
		char *err;
		
		/* Check if drawing text works */
		err = gdImageStringFT(NULL, NULL, 0, config->font, config->fontsize, 0.0, 0, 0, "");
		
		if(!err) fswc_draw_banner(config, im);
		else
		{
			/* Can't load the font - display a warning */
			WARN("Unable to load font '%s': %s", config->font, err);
			WARN("Disabling the the banner.");
		}
	}
	
	/* Draw the overlay. */
	fswc_draw_overlay(config, config->overlay, im);
	
	/* Write to a file if a filename was given, otherwise stdout. */
	if(strncmp(name, "-", 2)) f = fopen(filename, "wb");
	else f = stdout;
	
	if(!f)
	{
		ERROR("Error opening file for output: %s", filename);
		ERROR("fopen: %s", strerror(errno));
		gdImageDestroy(im);
		return(-1);
	}
	
	/* Write the compressed image. */
	switch(config->format)
	{
	case FORMAT_JPEG:
		MSG("Writing JPEG image to '%s'.", filename);
		gdImageJpeg(im, f, config->compression);
		break;
	case FORMAT_PNG:
		MSG("Writing PNG image to '%s'.", filename);
		gdImagePngEx(im, f, config->compression);
		break;
	}
	
	if(f != stdout) fclose(f);
	
	gdImageDestroy(im);
	
	return(0);
}
Exemple #29
0
/*********************************************************************//*!
 * @brief Query the current state of the application and see what else
 * we need to get from it
 *
 * Depending on the current state of the application, other additional
 * parameters may be queried.
 *
 * @return SUCCESS or an appropriate error code otherwise
 *//*********************************************************************/
static OSC_ERR QueryApp()
{
	OSC_ERR err;

	/* First, get the current state of the algorithm. */
	err = OscIpcGetParam(cgi.ipcChan, &cgi.appState, GET_APP_STATE, sizeof(struct APPLICATION_STATE));
	if (err != SUCCESS)
	{
		/* This request is defined in all states, and thus must succeed. */
		OscLog(ERROR, "CGI: Error querying application! (%d)\n", err);
		return err;
	}

	switch(cgi.appState.enAppMode)
	{
	case APP_OFF:
		/* Algorithm is off, nothing else to do. */
		break;
	case APP_CAPTURE_ON:
		if (cgi.appState.bNewImageReady)
		{
			FILE* F;
			uint16 r,c;
			uint8* pData;
			uint32 dataSiz, i;
			uint16 oType;

			/* If there is a new image ready, request it from the application. */
			/* We get TWICE the size of an image because metadata might be available */
			err = OscIpcGetParam(cgi.ipcChan, cgi.imgBuf, GET_NEW_IMG, NUM_COLORS*nc*nr*2);
			if (err != SUCCESS)
			{
				OscLog(DEBUG, "CGI: Getting new image failed! (%d)\n", err);
				return err;
			}
//we have to take care of the different ways gdlib treats gray and color data
#if NUM_COLORS == 1
			//create gd image and ...
			gdImagePtr im_out =  gdImageCreate(nc, nr);
			//initialize with sensor image
			for(r = 0; r < nr; r++)
			{
				//in case the original image should not be modified replace the following loop by the memcpy statement
				//memcpy(im_out->pixels[r], cgi.imgBuf+r*nc, nc*sizeof(uint8));
				for(c = 0; c < nc; c++)
				{
					im_out->pixels[r][c] = (*(cgi.imgBuf+r*nc+c) & 0xfe);//mask out first bit -> only even gray values
				}
			}
			//allocate color palette (255 is red -> we did not change the sensor image!! should rather use a LUT)
			for(c = 0; c < 256; c++)
			{
				if((c%2) && c > 255-2*MAX_NUM_COLORS){
					i = (255-c)/2;
					gdImageColorAllocate (im_out, colorLUT[i][0], colorLUT[i][1], colorLUT[i][2]);
				} else {
					gdImageColorAllocate (im_out, c, c, c);
				}
			}
#else
			//create gd image and ...
			gdImagePtr im_out =  gdImageCreateTrueColor(nc, nr);
			//initialize with sensor image
			for(r = 0; r < nr; r++)
			{
				for(c = 0; c < nc; c++)
				{
					uint8* p = (cgi.imgBuf+r*3*nc+3*c);
					im_out->tpixels[r][c] = gdTrueColor(p[2], p[1], p[0]);
				}
			}


#endif
			//there might be additional data to be written to image
			pData = (uint8*) (cgi.imgBuf+NUM_COLORS*nc*nr);
			memcpy(&dataSiz, pData, sizeof(uint32));
			//OscLog(DEBUG, "received %d number of bytes\n", dataSiz);
			pData += sizeof(uint32);//skip dataSiz
			if(dataSiz)
			{
				i = 0;
				while(i < dataSiz)
				{
					memcpy(&oType, pData+i, sizeof(uint16));
					i += sizeof(uint16);
					switch(oType) {
						case OBJ_LINE:
						{
							struct IMG_LINE imgLine;
							memcpy(&imgLine, pData+i, sizLine);
							i += sizLine;
							//OscLog(DEBUG, "received line (%d,%d)-(%d,%d), color(%d)\n", imgLine.x1, imgLine.y1, imgLine.x2, imgLine.y2, (int) imgLine.color);
							gdImageLine(im_out, imgLine.x1, imgLine.y1, imgLine.x2, imgLine.y2, colorLoolUp(imgLine.color));
							break;
						}
						case OBJ_RECT:
						{
							struct IMG_RECT imgRect;
							memcpy(&imgRect, pData+i, sizRect);
							i += sizRect;
							//OscLog(DEBUG, "received rect (%d,%d)-(%d,%d), %s, color(%d)\n", imgRect.left, imgRect.bottom, imgRect.right, imgRect.top, imgRect.recFill ? "fill" : "not fill", (int) imgRect.color);
							if(imgRect.recFill) {
								gdImageFilledRectangle(im_out, imgRect.left, imgRect.bottom, imgRect.right, imgRect.top, colorLoolUp(imgRect.color));
							} else {
								gdImageRectangle(im_out, imgRect.left, imgRect.bottom, imgRect.right, imgRect.top, colorLoolUp(imgRect.color));
							}
							break;
						}
						case OBJ_STRING:
						{
							gdFontPtr font = gdFontSmall;
							struct IMG_STRING imgString;
							memcpy(&imgString, pData+i, sizString);
							i += sizString;
							//OscLog(DEBUG, "received string (%d,%d), font %d, %s, color(%d)\n", imgString.xPos, imgString.yPos, imgString.font, pData+i, imgString.color);
							switch(imgString.font)
							{
								case GIANT:
									font = gdFontGiant;
									break;
								case LARGE:
									font = gdFontLarge;
									break;
								case MEDIUMBOLD:
									font = gdFontMediumBold;
									break;
								case SMALL:
									font = gdFontSmall;
									break;
								case TINY:
									font = gdFontTiny;
									break;
								default:
									break;//set in definition of font
							}
							gdImageString(im_out, font, imgString.xPos, imgString.yPos, pData+i, colorLoolUp(imgString.color));
							i += imgString.len;
						}
					}
				}
			}

			F = fopen(IMG_FN, "wb");
			//gdImageGif(im_out, F);
			gdImageJpeg(im_out, F, 80);
			fclose(F);
			gdImageDestroy(im_out);

			return SUCCESS;
		}
		break;
	default:
		OscLog(ERROR, "%s: Invalid application mode (%d)!\n", __func__, cgi.appState.enAppMode);
		break;
	}
	return SUCCESS;
}
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;
}