/* * $Id: png.trm,v 1.13 1998/06/18 14:59:23 ddenholm Exp $ * */ /* GNUPLOT - png.trm */ /*[ * Copyright 1995, 1998 * * Permission to use, copy, and distribute this software and its * documentation for any purpose with or without fee is hereby granted, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. * * Permission to modify the software is granted, but not the right to * distribute the complete modified source code. Modifications are to * be distributed as patches to the released version. Permission to * distribute binaries produced by compiling modified sources is granted, * provided you * 1. distribute the corresponding source modifications from the * released version in the form of a patch file along with the binaries, * 2. add special version identification to distinguish your version * in addition to the base release version number, * 3. provide your name and address as the primary contact for the * support of your modified version, and * 4. retain our contact information in regard to use of the base * software. * Permission to distribute the released version of the source code along * with corresponding source modifications in the form of a patch file is * granted with same provisions 2 through 4 for binary distributions. * * This software is provided "as is" without express or implied warranty * to the extent permitted by applicable law. ]*/ /* * This file is included by ../term.c. * * This terminal driver supports: * png * * AUTHORS * Alexander Lehmann * derived from pbm.trm by Russell Lang * * send your comments or suggestions to (info-gnuplot@dartmouth.edu). * */ /* To compile this terminal driver, you need libpng and zlib, both are available at ftp://ftp.uu.net/graphics/png. Remember to add the include dirs and libraries to TERMFLAGS and TERMLIBS. */ /* The following png drivers use the generic bit mapped graphics routines from bitmap.c to build up a bit map in memory. The driver interchanges colomns and lines in order to access entire lines easily and returns the lines to get bits in the right order : (x,y) -> (y,XMAX-1-x). */ /* This interchange is done by calling b_makebitmap() with reversed xmax and ymax, and then setting b_rastermode to TRUE. b_setpixel() will then perform the interchange before each pixel is plotted */ #include "driver.h" #ifdef TERM_REGISTER register_term(png_driver) #endif #ifdef TERM_PROTO TERM_PUBLIC void PNGoptions __PROTO((void)); TERM_PUBLIC void PNGinit __PROTO((void)); TERM_PUBLIC void PNGreset __PROTO((void)); TERM_PUBLIC void PNGsetfont __PROTO((void)); TERM_PUBLIC void PNGgraphics __PROTO((void)); TERM_PUBLIC void PNGtext __PROTO((void)); TERM_PUBLIC void PNGlinetype __PROTO((int linetype)); TERM_PUBLIC void PNGpoint __PROTO((unsigned int x, unsigned int y, int point)); #endif /* TERM_PROTO */ #ifdef TERM_BODY #include "png.h" /* I'm not sure exactly which is the first version we work with, * but I know that some older ones don't define all the symbols * we use */ /* png version test now in configure */ /* From version.c */ extern char version[]; extern char patchlevel[]; /* make XMAX and YMAX a multiple of 8 */ #define PNG_XMAX (640) #define PNG_YMAX (480) #define PNG_VCHAR (FNT5X9_VCHAR) #define PNG_HCHAR (FNT5X9_VCHAR) #define PNG_VTIC FNT5X9_HBITS #define PNG_HTIC FNT5X9_HBITS static int png_font = 1; /* small font */ static int png_mode = 0; /* 0:monochrome 1:gray 2:color */ /* 7=black, 0=white */ static int png_gray[] = { 7, 1, 6, 5, 4, 3, 2, 1, 7 }; /* grays */ /* bit3=!intensify, bit2=!red, bit1=!green, bit0=!blue */ static int png_color_table[] ={ 15, 8, 3, 5, 6, 4, 2, 1, 11, 13, 14 }; /* colors */ static png_color png_palette[16]; void PNGoptions() { png_font = 1; png_mode = 0; term_options[0] = NUL; while (!END_OF_COMMAND) { if (almost_equals(c_token, "s$mall")) png_font = 1; else if (almost_equals(c_token, "me$dium")) png_font = 2; else if (almost_equals(c_token, "l$arge")) png_font = 3; else if (almost_equals(c_token, "mo$nochrome")) png_mode = 0; else if (almost_equals(c_token, "g$ray")) png_mode = 1; else if (almost_equals(c_token, "c$olor") || almost_equals(c_token, "c$olour")) png_mode = 2; else { /* reset to default, since term is already set */ png_font = 1; png_mode = 0; int_error("expecting: {small, medium, large} and {monochrome, gray, color}", c_token); } c_token++; } /* setup options string */ switch (png_font) { case 1: strcat(term_options, "small"); break; case 2: strcat(term_options, "medium"); break; case 3: strcat(term_options, "large"); break; } switch (png_mode) { case 0: strcat(term_options, " monochrome"); break; case 1: strcat(term_options, " gray"); break; case 2: strcat(term_options, " color"); break; } } void PNGinit() { PNGsetfont(); /* HBB 980226: do this here! */ } void PNGreset() { #ifdef VMS fflush_binary(); #endif /* VMS */ } void PNGsetfont() { switch (png_font) { case 1: b_charsize(FNT5X9); term->v_char = FNT5X9_VCHAR; term->h_char = FNT5X9_HCHAR; term->v_tic = FNT5X9_HBITS; term->h_tic = FNT5X9_HBITS; break; case 2: b_charsize(FNT9X17); term->v_char = FNT9X17_VCHAR; term->h_char = FNT9X17_HCHAR; term->v_tic = FNT9X17_HBITS; term->h_tic = FNT9X17_HBITS; break; case 3: b_charsize(FNT13X25); term->v_char = FNT13X25_VCHAR; term->h_char = FNT13X25_HCHAR; term->v_tic = FNT13X25_HBITS; term->h_tic = FNT13X25_HBITS; break; } } void PNGgraphics() { int numplanes; switch (png_mode) { case 0: numplanes = 1; break; case 1: numplanes = 3; break; case 2: numplanes = 4; break; } /* PNGsetfont(); *//* HBB 980226: do this in init() ! */ /* rotate plot -90 degrees by reversing XMAX and YMAX and by setting b_rastermode to TRUE */ b_makebitmap((unsigned int) (PNG_YMAX * ysize), (unsigned int) (PNG_XMAX * xsize), numplanes); b_rastermode = TRUE; if (png_mode != 0) b_setlinetype(0); /* solid lines */ } void PNGtext() { register int x, j, row; png_structp png_ptr; png_infop info_ptr; register int i, value; png_bytep prow; int mask, plane1, plane2, plane3, plane4; int red, green, blue; png_text pngtext, *pngtext_copy; char text[100]; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { b_freebitmap(); return; } info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, (png_infopp) NULL); b_freebitmap(); return; } prow = malloc(b_ysize); if (!prow) { png_destroy_write_struct(&png_ptr, &info_ptr); b_freebitmap(); return; } if (setjmp(png_ptr->jmpbuf)) { png_destroy_write_struct(&png_ptr, &info_ptr); free(prow); b_freebitmap(); return; } png_info_init(info_ptr); png_write_init(png_ptr); png_init_io(png_ptr, gpoutfile); info_ptr->width = b_ysize; info_ptr->height = b_xsize; info_ptr->bit_depth = png_mode == 0 ? 1 : 4; info_ptr->color_type = png_mode == 2 ? PNG_COLOR_TYPE_PALETTE : PNG_COLOR_TYPE_GRAY; if (png_mode == 2) { info_ptr->valid |= PNG_INFO_PLTE; info_ptr->palette = png_palette; info_ptr->num_palette = 16; } if (png_mode != 0) { info_ptr->valid |= PNG_INFO_sBIT; if (png_mode == 1) { info_ptr->sig_bit.gray = 3; png_set_shift(png_ptr, &(info_ptr->sig_bit)); } else { info_ptr->sig_bit.red = 2; info_ptr->sig_bit.green = 2; info_ptr->sig_bit.blue = 2; } } info_ptr->interlace_type = 0; if (png_mode == 0) png_set_invert_mono(png_ptr); if (png_mode == 2) for (i = 0; i < 16; i++) { red = (i & 4) ? 1 : 3; green = (i & 2) ? 1 : 3; blue = (i & 1) ? 1 : 3; if (i & 8) { red--; green--; blue--; } png_palette[i].red = red * 85; png_palette[i].green = green * 85; png_palette[i].blue = blue * 85; } sprintf(text, "gnuplot %sversion %s patchlevel %s", OS, version, patchlevel); pngtext.compression = -1; pngtext.key = "Software"; pngtext.text = text; pngtext.text_length = strlen(text); pngtext_copy = malloc(sizeof(*pngtext_copy)); *pngtext_copy = pngtext; info_ptr->num_text = 1; info_ptr->text = pngtext_copy; png_write_info(png_ptr, info_ptr); info_ptr->num_text = 0; if (info_ptr->text) free(info_ptr->text); info_ptr->text = NULL; png_set_packing(png_ptr); /* dump bitmap in raster mode */ for (x = b_xsize - 1; x >= 0; x--) { row = (b_ysize / 8) - 1; for (j = row; j >= 0; j--) { mask = 0x80; plane1 = (*((*b_p)[j] + x)); if (png_mode != 0) { plane2 = (*((*b_p)[j + b_psize] + x)); plane3 = (*((*b_p)[j + b_psize + b_psize] + x)); } else { plane2 = 0; plane3 = 0; } if (png_mode == 2) plane4 = (*((*b_p)[j + b_psize + b_psize + b_psize] + x)); else plane4 = 0; for (i = 0; i < 8; i++) { value = 0; if (plane1 & mask) value += 1; if (plane2 & mask) value += 2; if (plane3 & mask) value += 4; if (plane4 & mask) value += 8; if (png_mode == 1) value = 7 - value; prow[(row - j) * 8 + i] = (png_byte) value; mask >>= 1; } } png_write_rows(png_ptr, &prow, 1); } png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); free(prow); b_freebitmap(); } void PNGlinetype(linetype) int linetype; { switch (png_mode) { case 0: b_setlinetype(linetype); break; case 1: if (linetype >= 7) linetype %= 7; b_setvalue(png_gray[linetype + 2]); break; case 2: if (linetype >= 9) linetype %= 9; b_setvalue(png_color_table[linetype + 2]); break; } } void PNGpoint(x, y, point) unsigned int x, y; int point; { if (png_mode == 0) line_and_point(x, y, point); else do_point(x, y, point); } #endif /* TERM_BODY */ #ifdef TERM_TABLE TERM_TABLE_START(png_driver) "png", "Portable Network Graphics [small medium large] [monochrome gray color]", PNG_XMAX, PNG_YMAX, PNG_VCHAR, PNG_HCHAR, PNG_VTIC, PNG_HTIC, PNGoptions, PNGinit, PNGreset, PNGtext, null_scale, PNGgraphics, b_move, b_vector, PNGlinetype, b_put_text, b_text_angle, null_justify_text, PNGpoint, do_arrow, set_font_null, 0, /* pointsize */ TERM_CAN_MULTIPLOT | TERM_BINARY TERM_TABLE_END(png_driver) #undef LAST_TERM #define LAST_TERM png_driver #endif /* TERM_TABLE */ #ifdef TERM_HELP START_HELP(png) "1 png", "?commands set terminal png", "?set terminal png", "?set term png", "?terminal png", "?term png", "?png", " The `png` terminal driver supports Portable Network Graphics. To compile it,", " you will need the third-party libraries \"libpng\" and \"zlib\"; both are", " available at ftp://ftp.uu.net/graphics/png. `png` has two options.", "", " Syntax:", " set terminal png {small | medium | large}", " {monochrome | gray | color}", "", " The defaults are small (fontsize) and monochrome." END_HELP(png) #endif /* TERM_HELP */