/* png driver for sddsplot by M. Borland using gd1.2 routines * by Thomas Boutell */ #include "gd.h" #include "sddsplot.h" #if defined(_WIN32) #include #include #if defined(__BORLANDC__) #define _setmode(handle, amode) setmode(handle, amode) #endif #endif #define PNG_XMAX 656 #define PNG_YMAX 506 #define MPNG_XMAX ((long)(PNG_XMAX/0.80)) #define MPNG_YMAX ((long)(PNG_YMAX/0.80)) #define LPNG_XMAX ((long)(MPNG_XMAX/0.75)) #define LPNG_YMAX ((long)(MPNG_YMAX/0.75)) #define HPNG_XMAX ((long)(LPNG_XMAX*2)) #define HPNG_YMAX ((long)(LPNG_YMAX*2)) #define GPNG_XMAX ((long)(HPNG_XMAX*2)) #define GPNG_YMAX ((long)(HPNG_YMAX*2)) #define SPNG_XMAX ((long)(PNG_XMAX*0.80)) #define SPNG_YMAX ((long)(PNG_YMAX*0.80)) #define TPNG_XMAX ((long)(SPNG_XMAX*0.75)) #define TPNG_YMAX ((long)(SPNG_YMAX*0.75)) #define PDAPNG_XMAX 230 #define PDAPNG_YMAX 230 static long png_xlast, png_ylast, png_xmax, png_ymax; static unsigned long pngFlags; #define PNG_ON_WHITE 0x0001 #define PNG_ON_BLACK 0x0002 #define PNG_TEMPLATE 0x0004 #define PNG_ROOTNAME 0x0008 #define PNG_LINE_TABLE 0x0010 #define PNG_USEDASHES 0x0020 static gdImagePtr pngImage; static int pngBlack, pngWhite; #define PNG_LINETYPES 16 static int pngLinetype[PNG_LINETYPES], png_linetype; static int png_line_thickness = 1; static char *pngTemplate = NULL; static long pngGeneration = 1, doPngGenerations = 0; static FILE *pngOutfile = NULL; int png_color_index = 0; int png_color_maxindex = 0; MotifColor *png_colors = NULL; int *png_colorList = NULL; int ncolors_png=101; int spectralpng=0; int customspectralpng=0; unsigned short r0_png=0, g0_png=0, b0_png=0, r1_png=1, g1_png=1, b1_png=1; BOOLEAN is_forced_color; int png_force_color; #define PNG_DASHTYPES 10 static char png_dashes[PNG_DASHTYPES][5] = { {0}, {4,2,0}, {2,3,0}, {1,2,0}, {5,2,1,2,0}, {3,3,1,4,0}, {2,5,0}, {4,4,4,1,0}, {8,2,0}, {1,4,0}, }; static int png_dashtype = 0 ; char **getDeviceArgv(long *argc); int PNG_initCommon() { char **argv, *pngRootname = NULL; long argc; pngFlags = PNG_ON_WHITE; if ((argv = getDeviceArgv(&argc))) { if (!scanItemList(&pngFlags, argv, &argc, 0, "rootname", SDDS_STRING, &pngRootname, 1, PNG_ROOTNAME, "template", SDDS_STRING, &pngTemplate, 1, PNG_TEMPLATE, "onwhite", -1, NULL, 0, PNG_ON_WHITE, "onblack", -1, NULL, 0, PNG_ON_BLACK, "dashes", -1, NULL, 0, PNG_USEDASHES, "linetypetable", SDDS_STRING, &LineTableFile, 1, PNG_LINE_TABLE, "linecolortable", SDDS_STRING, &LineTableFile, 1, PNG_LINE_TABLE, /* for backward compatibility only */ NULL) || (pngFlags&PNG_ROOTNAME && !pngRootname) || (pngFlags&PNG_TEMPLATE && !pngTemplate) || (pngFlags&PNG_LINE_TABLE && !LineTableFile)) { bomb("error scanning device arguments for PNG", NULL); } if (pngRootname && pngTemplate) { bomb("give either rootname or template for png device, not both", NULL); } if (pngRootname || pngTemplate) { if (pngRootname) { pngTemplate = (char*)malloc(sizeof(*pngTemplate)*1024); sprintf(pngTemplate, "%s.%%03ld", pngRootname); } doPngGenerations = 1; pngGeneration = 1; pngOutfile = NULL; } } if (LineTableFile) { long i; if (!SDDS_ReadLineTypeTable(&lineTypeTable, LineTableFile)) { SDDS_PrintErrors(stderr, SDDS_VERBOSE_PrintErrors); bomb("problem reading line-type table", NULL); } if (lineTypeTable.typeFlag&LINE_TABLE_DEFINE_COLOR) { for (i=0; i= 1000) linetype-=1000; png_linetype = linetype%lineTypeTable.nEntries; } else if ((png_color_index == 0) || (linetype < 1000)) { png_linetype = linetype%PNG_LINETYPES; if ( pngFlags&PNG_USEDASHES) png_dashtype = linetype%PNG_DASHTYPES; } else { png_linetype = linetype; } png_line_thickness = 1; is_forced_color = FALSE; return 0; } static int png_xposition, png_yposition; int PNG_move(int x, int y) { y = png_ylast - y; png_xposition = x; png_yposition = y; return 0; } int PNG_dot(int x, int y, int number) { y = png_ylast - y; if (lineTypeTable.nEntries && png_color_index) { gdImageSetPixel(pngImage, x, y, png_colorList[png_linetype%lineTypeTable.nEntries]); } else if ((png_color_index == 0) || (png_linetype < 1000)) { gdImageSetPixel(pngImage, x, y, pngLinetype[png_linetype]); } else { gdImageSetPixel(pngImage, x, y, png_colorList[(png_linetype - 1000)%png_color_index]); } png_xposition = x; png_yposition = y; return 0; } int PNG_vector(int x, int y) { gdImagePtr brush; int i, j,n,color, npts=0 ; int *styledash=NULL; int use_line_thickness, use_line_color; char *use_line_dash =NULL; y = png_ylast - y; if (lineTypeTable.nEntries) { if ( lineTypeTable.typeFlag&LINE_TABLE_DEFINE_THICKNESS) use_line_thickness = (int) lineTypeTable.thickness[png_linetype]; else use_line_thickness = png_line_thickness; if( (lineTypeTable.typeFlag&LINE_TABLE_DEFINE_COLOR) && png_color_index) use_line_color = png_colorList[png_color_index-lineTypeTable.nEntries+png_linetype]; else use_line_color = pngWhite; if ( lineTypeTable.typeFlag & LINE_TABLE_DEFINE_DASH ) use_line_dash = lineTypeTable.dash[png_linetype].dashArray; } else if ((png_color_index == 0) || (png_linetype < 1000)) { use_line_thickness = png_line_thickness; if(is_forced_color) use_line_color = png_force_color; else use_line_color = pngLinetype[png_linetype]; use_line_dash = png_dashes[png_dashtype]; } else { use_line_thickness = png_line_thickness; use_line_color = png_colorList[(png_linetype-1000)%png_color_index]; if(pngFlags&PNG_USEDASHES) use_line_dash = png_dashes[(png_linetype-1000)%PNG_DASHTYPES]; } brush = gdImageCreateTrueColor(use_line_thickness,use_line_thickness); gdImagePaletteCopy(brush, pngImage); gdImageFilledRectangle(brush, 0,0,use_line_thickness-1, use_line_thickness-1, use_line_color); if ( ((pngFlags&PNG_USEDASHES) && (!lineTypeTable.nEntries)) || (lineTypeTable.typeFlag&LINE_TABLE_DEFINE_DASH) ) { for (i=0; i<5; i++) { n = ((int) use_line_dash[i])*use_line_thickness; if ( n == 0 ) { break; } else { npts += n; if ( !styledash) { styledash = tmalloc(sizeof(int)*n); for (j=0; j 1 ? shade/(ncolors_png - 1.0) : 0); else if (spectralpng == 2) Spectral_BGR_values(&r, &g, &b, ncolors_png > 1 ? shade/(ncolors_png - 1.0) : 0); else if (customspectralpng) Custom_RGB_values(&r, &g, &b, r0_png, g0_png, b0_png, r1_png, g1_png, b1_png, ncolors_png > 1 ? shade/(ncolors_png - 1.0) : 0); else RGB_values(&r, &g, &b, ncolors_png > 1 ? shade/(ncolors_png - 1.0) : 0); if (r >= 1) r = .99999; if (g >= 1) g = .99999; if (b >= 1) b = .99999; red = (unsigned short)(65536 * r); green = (unsigned short)(65536 * g); blue = (unsigned short)(65536 * b); PNG_color(red, green, blue); n = xl - xh; if (n >= 0) { while (n >= 0) { gdImageLine(pngImage, xl+n, png_ylast - yl, xl+n, png_ylast - yh, /*png_colorList[png_color_index - 1]*/ png_force_color); n--; } } else { while (n <= 0) { gdImageLine(pngImage, xh+n, png_ylast - yl, xh+n, png_ylast - yh, /*png_colorList[png_color_index - 1]*/ png_force_color); n++; } } png_xposition = xl; png_yposition = png_ylast - yh; return 0; } int PNG_add_color(unsigned short red, unsigned short green, unsigned short blue) { if (png_color_index >= png_color_maxindex) { png_color_maxindex += 100; if (png_color_index == 0) { png_colors = tmalloc(sizeof(*png_colors)*png_color_maxindex); } else { png_colors = trealloc(png_colors, sizeof(*png_colors)*(++png_color_maxindex)); } } png_colors[png_color_index].red = red; png_colors[png_color_index].green = green; png_colors[png_color_index].blue = blue; png_color_index++; return 0; } int PNG_line_thickness(int lt) { if (lt < 1) lt = 1; if (lt > 9) lt = 9; png_line_thickness = lt; return 0; } int PNG_color(unsigned short red, unsigned short green, unsigned short blue) { is_forced_color = TRUE; png_force_color = gdImageColorAllocate(pngImage, red / 256, green / 256, blue / 256); return 0; } int PNG_spectral(long num, int spec, unsigned short red0, unsigned short green0, unsigned short blue0, unsigned short red1, unsigned short green1, unsigned short blue1) { ncolors_png = num > 101 ? 101 : num; if (spec == 0) { spectralpng = 0; customspectralpng = 1; r0_png = red0; g0_png = green0; b0_png = blue0; r1_png = red1; g1_png = green1; b1_png = blue1; } else if (spec == 1){ spectralpng = 1; customspectralpng = 0; } else if (spec == 2){ spectralpng = 2; customspectralpng = 0; } else { spectralpng = 0; customspectralpng = 0; } return 0; }