#include <stdlib.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/stat.h>
#include <libps/pslib.h>
#ifdef MEMORY_DEBUGGING
#include <libps/pslib-mp.h>
#endif

void errorhandler(PSDoc *p, int error, const char *str, void *data) {
	fprintf(stderr, "PSLib: %s\n", str);
}

size_t writeproc(PSDoc *p, void *data, size_t size) {
	return fwrite(data, 1, size, stdout);
}

#define LEFT_BORDER 50
#define EXAMPLE_BOX_HEIGHT 190
#define EXAMPLE_BOX_WIDTH  150
#define EXAMPLE_BOX_TITLE_HEIGHT  40

void begin_example_box(PSDoc *p, float llx, float lly, char *title, int font) {
	PS_save(p);
	PS_translate(p, llx, lly);
	PS_setcolor(p, "fill", "gray", 0.5, 0.0, 0.0, 0.0);
	PS_rect(p, 0, EXAMPLE_BOX_HEIGHT-EXAMPLE_BOX_TITLE_HEIGHT,
	           EXAMPLE_BOX_WIDTH, EXAMPLE_BOX_TITLE_HEIGHT);
	PS_fill(p);
	PS_setcolor(p, "stroke", "gray", 1.0, 0.0, 0.0, 0.0);
	PS_setfont(p, font, 12.0);
	PS_show_boxed(p, title, 10, EXAMPLE_BOX_HEIGHT-EXAMPLE_BOX_TITLE_HEIGHT-5, EXAMPLE_BOX_WIDTH-20, EXAMPLE_BOX_TITLE_HEIGHT, "left", NULL);
	PS_setlinewidth(p, 1.0);
	PS_setcolor(p, "stroke", "gray", 0.0, 0.0, 0.0, 0.0);
	PS_rect(p, 0, 0, EXAMPLE_BOX_WIDTH, EXAMPLE_BOX_HEIGHT);
	PS_stroke(p);
	PS_moveto(p, 0, EXAMPLE_BOX_HEIGHT-EXAMPLE_BOX_TITLE_HEIGHT);
	PS_lineto(p, EXAMPLE_BOX_WIDTH, EXAMPLE_BOX_HEIGHT-EXAMPLE_BOX_TITLE_HEIGHT);
	PS_stroke(p);
}

void end_example_box(PSDoc *p) {
	PS_restore(p);
}


int main() {
	PSDoc *ps;
	int psfont;
	int psimage;
	char *imagedata;
	int x, y;

	PS_boot();
#ifdef MEMORY_DEBUGGING
	PS_mp_init();
#endif

#ifdef MEMORY_DEBUGGING
	ps = PS_new2(errorhandler, PS_mp_malloc, PS_mp_realloc, PS_mp_free, NULL);
#else
	ps = PS_new();
#endif

	if (0 > PS_open_file(ps, "image.ps")) {
		printf("Cannot open PostScript file\n");
		exit(1);
	}

	PS_set_parameter(ps, "warning", "true");
	PS_set_parameter(ps, "imageencoding", "hex");

	PS_set_info(ps, "Creator", __FILE__);
	PS_set_info(ps, "Author", "Uwe Steinmann");
	PS_set_info(ps, "Title", "Image Example");
	PS_set_info(ps, "Keywords", "Image Picture PNG Jpeg");

	PS_begin_page(ps, 596, 842);
	psfont = PS_findfont(ps, "Helvetica", "", 0);
	PS_setfont(ps, psfont, 8.0);

	x = 0;
	y = 625;
	begin_example_box(ps, LEFT_BORDER+(EXAMPLE_BOX_WIDTH+30)*(x++), y, "Indexed image without alpha channel", psfont);
	psimage = PS_open_image_file(ps, "png", "indexed.png", NULL, 0);
	PS_place_image(ps, psimage, 10, 30, 1.0);
	end_example_box(ps);

	begin_example_box(ps, LEFT_BORDER+(EXAMPLE_BOX_WIDTH+30)*(x++), y, "RGB image without alpha channel", psfont);
	psimage = PS_open_image_file(ps, "png", "rgb.png", NULL, 0);
	PS_place_image(ps, psimage, 10, 30, 1.0);
	end_example_box(ps);

	begin_example_box(ps, LEFT_BORDER+(EXAMPLE_BOX_WIDTH+30)*(x++), y, "Indexed image with alpha channel", psfont);
	psimage = PS_open_image_file(ps, "png", "indexed-alpha.png", NULL, 0);
	PS_place_image(ps, psimage, 10, 30, 1.0);
	end_example_box(ps);

	x = 0;
	y = 405;
	begin_example_box(ps, LEFT_BORDER+(EXAMPLE_BOX_WIDTH+30)*(x++), y, "RGB image with alpha channel", psfont);
	psimage = PS_open_image_file(ps, "png", "rgb-alpha.png", NULL, 0);
	PS_place_image(ps, psimage, 10, 30, 1.0);
	end_example_box(ps);

	begin_example_box(ps, LEFT_BORDER+(EXAMPLE_BOX_WIDTH+30)*(x++), y, "Jpeg gray scale image", psfont);
	psimage = PS_open_image_file(ps, "jpeg", "gnu-head.jpg", NULL, 0);
	PS_place_image(ps, psimage, 10, 10, 0.45);
	end_example_box(ps);

	begin_example_box(ps, LEFT_BORDER+(EXAMPLE_BOX_WIDTH+30)*(x++), y, "", psfont);
	psimage = PS_open_image_file(ps, "jpeg", "exiftest.jpg", NULL, 0);
	PS_place_image(ps, psimage, 30, 10, 0.30);
	end_example_box(ps);

	x = 0;
	y = 185;
	begin_example_box(ps, LEFT_BORDER+(EXAMPLE_BOX_WIDTH+30)*(x++), y, "Images created in memory", psfont);
	imagedata = malloc(16);
	/* RGB */
	memset(imagedata, 0, 16);
	imagedata[0] = 255;
	imagedata[4] = 255;
	imagedata[8] = 255;
	psimage = PS_open_image(ps, "memory", "memory", imagedata, 12, 2, 2, 3, 8, NULL);
	PS_place_image(ps, psimage, 20, 20, 20.0);
	/* Gray */
	memset(imagedata, 0, 16);
	imagedata[0] = 192;
	imagedata[1] = 128;
	imagedata[2] = 64;
	imagedata[3] = 0;
	psimage = PS_open_image(ps, "memory", "memory", imagedata, 4, 2, 2, 1, 8, NULL);
	PS_place_image(ps, psimage, 90, 20, 20.0);
	/* CMYK */
	memset(imagedata, 255, 16);
	imagedata[0] = 0;
	imagedata[5] = 0;
	imagedata[10] = 0;
	imagedata[15] = 0;
	psimage = PS_open_image(ps, "memory", "memory", imagedata, 16, 2, 2, 4, 8, NULL);
	PS_place_image(ps, psimage, 20, 90, 20.0);
	PS_setfont(ps, psfont, 8.0);
	PS_show_xy(ps, "CMYK", 20, 80);
	PS_show_xy(ps, "RGB", 20, 10);
	PS_show_xy(ps, "Gray", 90, 10);

	end_example_box(ps);

	begin_example_box(ps, LEFT_BORDER+(EXAMPLE_BOX_WIDTH+30)*(x++), y, "Jpeg cmyk image, rotated", psfont);
	psimage = PS_open_image_file(ps, "jpeg", "cne-cmyk.jpg", NULL, 0);
	PS_translate(ps, 72, 10);
	PS_rotate(ps, 45);
	PS_place_image(ps, psimage, 0, 0, 0.45);
	end_example_box(ps);

	begin_example_box(ps, LEFT_BORDER+(EXAMPLE_BOX_WIDTH+30)*(x++), y, "EPS read from memory", psfont);
	{
	struct stat statbuf;
	if(0 == stat("picture.eps", &statbuf)) {
		char buffer[30];
		char *data;
		FILE *fp;
		fp = fopen("picture.eps", "r");
		data = malloc(statbuf.st_size);
		fread(data, statbuf.st_size, 1, fp);
		fclose(fp);
		psimage = PS_open_image(ps, "eps", "memory", data, statbuf.st_size, 0, 0, 0, 0, NULL);
		free(data);
		PS_place_image(ps, psimage, 15, 25, 0.45);
		sprintf(buffer, "%.0f x %.0f pixel", PS_get_value(ps, "imagewidth", (float) psimage), PS_get_value(ps, "imageheight", (float) psimage));
		PS_setfont(ps, psfont, 10.0);
		PS_show_xy(ps, buffer, EXAMPLE_BOX_WIDTH-10-PS_stringwidth(ps, buffer, psfont, 10), 10);
	}
	}
	end_example_box(ps);

	PS_end_page(ps);

	PS_begin_page(ps, 596, 842);
	psfont = PS_findfont(ps, "Helvetica", "", 0);
	PS_setfont(ps, psfont, 8.0);

	x = 0;
	y = 625;

	begin_example_box(ps, LEFT_BORDER+(EXAMPLE_BOX_WIDTH+30)*(x++), y, "Gif image", psfont);
	psimage = PS_open_image_file(ps, "gif", "debian.gif", NULL, 0);
	PS_place_image(ps, psimage, 25, 10, 2.0);
	end_example_box(ps);

	begin_example_box(ps, LEFT_BORDER+(EXAMPLE_BOX_WIDTH+30)*(x++), y, "Gif image with transparency", psfont);
	psimage = PS_open_image_file(ps, "gif", "debian-transparent.gif", NULL, 0);
	PS_place_image(ps, psimage, 25, 10, 2.0);
	end_example_box(ps);

	begin_example_box(ps, LEFT_BORDER+(EXAMPLE_BOX_WIDTH+30)*(x++), y, "Gif image, interlaced", psfont);
	psimage = PS_open_image_file(ps, "gif", "interlaced.gif", NULL, 0);
	PS_place_image(ps, psimage, 10, 10, 0.65);
	end_example_box(ps);

	x = 0;
	y = 405;
	begin_example_box(ps, LEFT_BORDER+(EXAMPLE_BOX_WIDTH+30)*(x++), y, "Tiff image", psfont);
	psimage = PS_open_image_file(ps, "tiff", "debian.tiff", NULL, 0);
	PS_place_image(ps, psimage, 25, 10, 2.0);
	end_example_box(ps);

	x = 0;
	y = 185;
	begin_example_box(ps, LEFT_BORDER+(EXAMPLE_BOX_WIDTH+30)*(x++), y, "Bmp image, indexed", psfont);
	psimage = PS_open_image_file(ps, "bmp", "debian.bmp", NULL, 0);
	PS_place_image(ps, psimage, 25, 10, 2.0);
	end_example_box(ps);

	PS_end_page(ps);

	PS_close(ps);
	PS_delete(ps);

#ifdef MEMORY_DEBUGGING 
	PS_mp_list_unfreed();
#endif  

	PS_shutdown();
	exit(0);
}
