Annotation of OpenXM_contrib/gnuplot/term/png.trm, Revision 1.1
1.1 ! maekawa 1: /*
! 2: * $Id: png.trm,v 1.13 1998/06/18 14:59:23 ddenholm Exp $
! 3: *
! 4: */
! 5:
! 6: /* GNUPLOT - png.trm */
! 7:
! 8: /*[
! 9: * Copyright 1995, 1998
! 10: *
! 11: * Permission to use, copy, and distribute this software and its
! 12: * documentation for any purpose with or without fee is hereby granted,
! 13: * provided that the above copyright notice appear in all copies and
! 14: * that both that copyright notice and this permission notice appear
! 15: * in supporting documentation.
! 16: *
! 17: * Permission to modify the software is granted, but not the right to
! 18: * distribute the complete modified source code. Modifications are to
! 19: * be distributed as patches to the released version. Permission to
! 20: * distribute binaries produced by compiling modified sources is granted,
! 21: * provided you
! 22: * 1. distribute the corresponding source modifications from the
! 23: * released version in the form of a patch file along with the binaries,
! 24: * 2. add special version identification to distinguish your version
! 25: * in addition to the base release version number,
! 26: * 3. provide your name and address as the primary contact for the
! 27: * support of your modified version, and
! 28: * 4. retain our contact information in regard to use of the base
! 29: * software.
! 30: * Permission to distribute the released version of the source code along
! 31: * with corresponding source modifications in the form of a patch file is
! 32: * granted with same provisions 2 through 4 for binary distributions.
! 33: *
! 34: * This software is provided "as is" without express or implied warranty
! 35: * to the extent permitted by applicable law.
! 36: ]*/
! 37:
! 38: /*
! 39: * This file is included by ../term.c.
! 40: *
! 41: * This terminal driver supports:
! 42: * png
! 43: *
! 44: * AUTHORS
! 45: * Alexander Lehmann
! 46: * derived from pbm.trm by Russell Lang
! 47: *
! 48: * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
! 49: *
! 50: */
! 51:
! 52: /* To compile this terminal driver, you need libpng and zlib, both are
! 53: available at ftp://ftp.uu.net/graphics/png. Remember to add the
! 54: include dirs and libraries to TERMFLAGS and TERMLIBS. */
! 55:
! 56: /* The following png drivers use the generic bit mapped graphics
! 57: routines from bitmap.c to build up a bit map in memory. The driver
! 58: interchanges colomns and lines in order to access entire lines
! 59: easily and returns the lines to get bits in the right order :
! 60: (x,y) -> (y,XMAX-1-x). */
! 61: /* This interchange is done by calling b_makebitmap() with reversed
! 62: xmax and ymax, and then setting b_rastermode to TRUE. b_setpixel()
! 63: will then perform the interchange before each pixel is plotted */
! 64:
! 65: #include "driver.h"
! 66:
! 67: #ifdef TERM_REGISTER
! 68: register_term(png_driver)
! 69: #endif
! 70:
! 71: #ifdef TERM_PROTO
! 72: TERM_PUBLIC void PNGoptions __PROTO((void));
! 73: TERM_PUBLIC void PNGinit __PROTO((void));
! 74: TERM_PUBLIC void PNGreset __PROTO((void));
! 75: TERM_PUBLIC void PNGsetfont __PROTO((void));
! 76: TERM_PUBLIC void PNGgraphics __PROTO((void));
! 77: TERM_PUBLIC void PNGtext __PROTO((void));
! 78: TERM_PUBLIC void PNGlinetype __PROTO((int linetype));
! 79: TERM_PUBLIC void PNGpoint __PROTO((unsigned int x, unsigned int y, int point));
! 80: #endif /* TERM_PROTO */
! 81:
! 82: #ifdef TERM_BODY
! 83:
! 84: #include "png.h"
! 85:
! 86: /* I'm not sure exactly which is the first version we work with,
! 87: * but I know that some older ones don't define all the symbols
! 88: * we use
! 89: */
! 90:
! 91: /* png version test now in configure */
! 92:
! 93: /* From version.c */
! 94: extern char version[];
! 95: extern char patchlevel[];
! 96:
! 97: /* make XMAX and YMAX a multiple of 8 */
! 98: #define PNG_XMAX (640)
! 99: #define PNG_YMAX (480)
! 100: #define PNG_VCHAR (FNT5X9_VCHAR)
! 101: #define PNG_HCHAR (FNT5X9_VCHAR)
! 102: #define PNG_VTIC FNT5X9_HBITS
! 103: #define PNG_HTIC FNT5X9_HBITS
! 104:
! 105: static int png_font = 1; /* small font */
! 106: static int png_mode = 0; /* 0:monochrome 1:gray 2:color */
! 107:
! 108: /* 7=black, 0=white */
! 109: static int png_gray[] = { 7, 1, 6, 5, 4, 3, 2, 1, 7 }; /* grays */
! 110: /* bit3=!intensify, bit2=!red, bit1=!green, bit0=!blue */
! 111: static int png_color_table[] ={ 15, 8, 3, 5, 6, 4, 2, 1, 11, 13, 14 }; /* colors */
! 112: static png_color png_palette[16];
! 113:
! 114: void PNGoptions()
! 115: {
! 116: png_font = 1;
! 117: png_mode = 0;
! 118:
! 119: term_options[0] = NUL;
! 120:
! 121: while (!END_OF_COMMAND) {
! 122: if (almost_equals(c_token, "s$mall"))
! 123: png_font = 1;
! 124: else if (almost_equals(c_token, "me$dium"))
! 125: png_font = 2;
! 126: else if (almost_equals(c_token, "l$arge"))
! 127: png_font = 3;
! 128: else if (almost_equals(c_token, "mo$nochrome"))
! 129: png_mode = 0;
! 130: else if (almost_equals(c_token, "g$ray"))
! 131: png_mode = 1;
! 132: else if (almost_equals(c_token, "c$olor")
! 133: || almost_equals(c_token, "c$olour"))
! 134: png_mode = 2;
! 135: else {
! 136: /* reset to default, since term is already set */
! 137: png_font = 1;
! 138: png_mode = 0;
! 139: int_error("expecting: {small, medium, large} and {monochrome, gray, color}", c_token);
! 140: }
! 141: c_token++;
! 142: }
! 143:
! 144: /* setup options string */
! 145:
! 146: switch (png_font) {
! 147: case 1:
! 148: strcat(term_options, "small");
! 149: break;
! 150: case 2:
! 151: strcat(term_options, "medium");
! 152: break;
! 153: case 3:
! 154: strcat(term_options, "large");
! 155: break;
! 156: }
! 157:
! 158: switch (png_mode) {
! 159: case 0:
! 160: strcat(term_options, " monochrome");
! 161: break;
! 162: case 1:
! 163: strcat(term_options, " gray");
! 164: break;
! 165: case 2:
! 166: strcat(term_options, " color");
! 167: break;
! 168: }
! 169: }
! 170:
! 171:
! 172: void PNGinit()
! 173: {
! 174: PNGsetfont(); /* HBB 980226: do this here! */
! 175: }
! 176:
! 177:
! 178: void PNGreset()
! 179: {
! 180: #ifdef VMS
! 181: fflush_binary();
! 182: #endif /* VMS */
! 183: }
! 184:
! 185:
! 186: void PNGsetfont()
! 187: {
! 188: switch (png_font) {
! 189: case 1:
! 190: b_charsize(FNT5X9);
! 191: term->v_char = FNT5X9_VCHAR;
! 192: term->h_char = FNT5X9_HCHAR;
! 193: term->v_tic = FNT5X9_HBITS;
! 194: term->h_tic = FNT5X9_HBITS;
! 195: break;
! 196: case 2:
! 197: b_charsize(FNT9X17);
! 198: term->v_char = FNT9X17_VCHAR;
! 199: term->h_char = FNT9X17_HCHAR;
! 200: term->v_tic = FNT9X17_HBITS;
! 201: term->h_tic = FNT9X17_HBITS;
! 202: break;
! 203: case 3:
! 204: b_charsize(FNT13X25);
! 205: term->v_char = FNT13X25_VCHAR;
! 206: term->h_char = FNT13X25_HCHAR;
! 207: term->v_tic = FNT13X25_HBITS;
! 208: term->h_tic = FNT13X25_HBITS;
! 209: break;
! 210: }
! 211: }
! 212:
! 213:
! 214: void PNGgraphics()
! 215: {
! 216: int numplanes;
! 217:
! 218: switch (png_mode) {
! 219: case 0:
! 220: numplanes = 1;
! 221: break;
! 222: case 1:
! 223: numplanes = 3;
! 224: break;
! 225: case 2:
! 226: numplanes = 4;
! 227: break;
! 228: }
! 229:
! 230: /* PNGsetfont(); *//* HBB 980226: do this in init() ! */
! 231:
! 232: /* rotate plot -90 degrees by reversing XMAX and YMAX and by
! 233: setting b_rastermode to TRUE */
! 234: b_makebitmap((unsigned int) (PNG_YMAX * ysize),
! 235: (unsigned int) (PNG_XMAX * xsize), numplanes);
! 236: b_rastermode = TRUE;
! 237:
! 238: if (png_mode != 0)
! 239: b_setlinetype(0); /* solid lines */
! 240: }
! 241:
! 242: void PNGtext()
! 243: {
! 244: register int x, j, row;
! 245: png_structp png_ptr;
! 246: png_infop info_ptr;
! 247: register int i, value;
! 248: png_bytep prow;
! 249: int mask, plane1, plane2, plane3, plane4;
! 250: int red, green, blue;
! 251: png_text pngtext, *pngtext_copy;
! 252: char text[100];
! 253:
! 254: png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
! 255: if (!png_ptr) {
! 256: b_freebitmap();
! 257: return;
! 258: }
! 259: info_ptr = png_create_info_struct(png_ptr);
! 260: if (!info_ptr) {
! 261: png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
! 262: b_freebitmap();
! 263: return;
! 264: }
! 265: prow = malloc(b_ysize);
! 266: if (!prow) {
! 267: png_destroy_write_struct(&png_ptr, &info_ptr);
! 268: b_freebitmap();
! 269: return;
! 270: }
! 271: if (setjmp(png_ptr->jmpbuf)) {
! 272: png_destroy_write_struct(&png_ptr, &info_ptr);
! 273: free(prow);
! 274: b_freebitmap();
! 275: return;
! 276: }
! 277: png_info_init(info_ptr);
! 278: png_write_init(png_ptr);
! 279:
! 280: png_init_io(png_ptr, gpoutfile);
! 281:
! 282: info_ptr->width = b_ysize;
! 283: info_ptr->height = b_xsize;
! 284:
! 285: info_ptr->bit_depth = png_mode == 0 ? 1 : 4;
! 286: info_ptr->color_type = png_mode == 2 ? PNG_COLOR_TYPE_PALETTE :
! 287: PNG_COLOR_TYPE_GRAY;
! 288: if (png_mode == 2) {
! 289: info_ptr->valid |= PNG_INFO_PLTE;
! 290: info_ptr->palette = png_palette;
! 291: info_ptr->num_palette = 16;
! 292: }
! 293: if (png_mode != 0) {
! 294: info_ptr->valid |= PNG_INFO_sBIT;
! 295: if (png_mode == 1) {
! 296: info_ptr->sig_bit.gray = 3;
! 297: png_set_shift(png_ptr, &(info_ptr->sig_bit));
! 298: } else {
! 299: info_ptr->sig_bit.red = 2;
! 300: info_ptr->sig_bit.green = 2;
! 301: info_ptr->sig_bit.blue = 2;
! 302: }
! 303: }
! 304: info_ptr->interlace_type = 0;
! 305: if (png_mode == 0)
! 306: png_set_invert_mono(png_ptr);
! 307:
! 308: if (png_mode == 2)
! 309: for (i = 0; i < 16; i++) {
! 310: red = (i & 4) ? 1 : 3;
! 311: green = (i & 2) ? 1 : 3;
! 312: blue = (i & 1) ? 1 : 3;
! 313: if (i & 8) {
! 314: red--;
! 315: green--;
! 316: blue--;
! 317: }
! 318: png_palette[i].red = red * 85;
! 319: png_palette[i].green = green * 85;
! 320: png_palette[i].blue = blue * 85;
! 321: }
! 322: sprintf(text, "gnuplot %sversion %s patchlevel %s", OS, version, patchlevel);
! 323:
! 324: pngtext.compression = -1;
! 325: pngtext.key = "Software";
! 326: pngtext.text = text;
! 327: pngtext.text_length = strlen(text);
! 328:
! 329: pngtext_copy = malloc(sizeof(*pngtext_copy));
! 330: *pngtext_copy = pngtext;
! 331: info_ptr->num_text = 1;
! 332: info_ptr->text = pngtext_copy;
! 333:
! 334: png_write_info(png_ptr, info_ptr);
! 335:
! 336: info_ptr->num_text = 0;
! 337: if (info_ptr->text) free(info_ptr->text);
! 338: info_ptr->text = NULL;
! 339:
! 340: png_set_packing(png_ptr);
! 341:
! 342: /* dump bitmap in raster mode */
! 343: for (x = b_xsize - 1; x >= 0; x--) {
! 344: row = (b_ysize / 8) - 1;
! 345: for (j = row; j >= 0; j--) {
! 346: mask = 0x80;
! 347: plane1 = (*((*b_p)[j] + x));
! 348: if (png_mode != 0) {
! 349: plane2 = (*((*b_p)[j + b_psize] + x));
! 350: plane3 = (*((*b_p)[j + b_psize + b_psize] + x));
! 351: } else {
! 352: plane2 = 0;
! 353: plane3 = 0;
! 354: }
! 355: if (png_mode == 2)
! 356: plane4 = (*((*b_p)[j + b_psize + b_psize + b_psize] + x));
! 357: else
! 358: plane4 = 0;
! 359:
! 360: for (i = 0; i < 8; i++) {
! 361: value = 0;
! 362: if (plane1 & mask)
! 363: value += 1;
! 364: if (plane2 & mask)
! 365: value += 2;
! 366: if (plane3 & mask)
! 367: value += 4;
! 368: if (plane4 & mask)
! 369: value += 8;
! 370: if (png_mode == 1)
! 371: value = 7 - value;
! 372:
! 373: prow[(row - j) * 8 + i] = (png_byte) value;
! 374: mask >>= 1;
! 375: }
! 376: }
! 377: png_write_rows(png_ptr, &prow, 1);
! 378: }
! 379:
! 380: png_write_end(png_ptr, info_ptr);
! 381: png_destroy_write_struct(&png_ptr, &info_ptr);
! 382: free(prow);
! 383: b_freebitmap();
! 384: }
! 385:
! 386: void PNGlinetype(linetype)
! 387: int linetype;
! 388: {
! 389: switch (png_mode) {
! 390: case 0:
! 391: b_setlinetype(linetype);
! 392: break;
! 393: case 1:
! 394: if (linetype >= 7)
! 395: linetype %= 7;
! 396: b_setvalue(png_gray[linetype + 2]);
! 397: break;
! 398: case 2:
! 399: if (linetype >= 9)
! 400: linetype %= 9;
! 401: b_setvalue(png_color_table[linetype + 2]);
! 402: break;
! 403: }
! 404: }
! 405:
! 406: void PNGpoint(x, y, point)
! 407: unsigned int x, y;
! 408: int point;
! 409: {
! 410: if (png_mode == 0)
! 411: line_and_point(x, y, point);
! 412: else
! 413: do_point(x, y, point);
! 414: }
! 415:
! 416: #endif /* TERM_BODY */
! 417:
! 418: #ifdef TERM_TABLE
! 419:
! 420: TERM_TABLE_START(png_driver)
! 421: "png",
! 422: "Portable Network Graphics [small medium large] [monochrome gray color]",
! 423: PNG_XMAX, PNG_YMAX, PNG_VCHAR,
! 424: PNG_HCHAR, PNG_VTIC, PNG_HTIC, PNGoptions,
! 425: PNGinit, PNGreset, PNGtext, null_scale,
! 426: PNGgraphics, b_move, b_vector, PNGlinetype,
! 427: b_put_text, b_text_angle, null_justify_text, PNGpoint,
! 428: do_arrow, set_font_null,
! 429: 0, /* pointsize */
! 430: TERM_CAN_MULTIPLOT | TERM_BINARY
! 431: TERM_TABLE_END(png_driver)
! 432:
! 433: #undef LAST_TERM
! 434: #define LAST_TERM png_driver
! 435:
! 436: #endif /* TERM_TABLE */
! 437:
! 438: #ifdef TERM_HELP
! 439: START_HELP(png)
! 440: "1 png",
! 441: "?commands set terminal png",
! 442: "?set terminal png",
! 443: "?set term png",
! 444: "?terminal png",
! 445: "?term png",
! 446: "?png",
! 447: " The `png` terminal driver supports Portable Network Graphics. To compile it,",
! 448: " you will need the third-party libraries \"libpng\" and \"zlib\"; both are",
! 449: " available at ftp://ftp.uu.net/graphics/png. `png` has two options.",
! 450: "",
! 451: " Syntax:",
! 452: " set terminal png {small | medium | large}",
! 453: " {monochrome | gray | color}",
! 454: "",
! 455: " The defaults are small (fontsize) and monochrome."
! 456: END_HELP(png)
! 457: #endif /* TERM_HELP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>