Annotation of OpenXM_contrib/gnuplot/term/png.trm, Revision 1.1.1.2
1.1 maekawa 1: /*
1.1.1.2 ! maekawa 2: * $Id: png.trm,v 1.11.2.5 1999/10/19 13:31:28 lhecking Exp $
1.1 maekawa 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
1.1.1.2 ! maekawa 45: * Alexander Lehmann original code,
! 46: * derived from pbm.trm by Russell Lang.
1.1 maekawa 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
1.1.1.2 ! maekawa 72: TERM_PUBLIC void PNG_options __PROTO((void));
! 73: TERM_PUBLIC void PNG_init __PROTO((void));
! 74: TERM_PUBLIC void PNG_reset __PROTO((void));
! 75: TERM_PUBLIC void PNG_setfont __PROTO((void));
! 76: TERM_PUBLIC void PNG_graphics __PROTO((void));
! 77: TERM_PUBLIC void PNG_text __PROTO((void));
! 78: TERM_PUBLIC void PNG_linetype __PROTO((int linetype));
! 79: TERM_PUBLIC void PNG_point __PROTO((unsigned int x, unsigned int y, int point));
1.1 maekawa 80: #endif /* TERM_PROTO */
81:
1.1.1.2 ! maekawa 82: /* make XMAX and YMAX a multiple of 8 */
! 83: #define PNG_XMAX (640)
! 84: #define PNG_YMAX (480)
! 85: #define PNG_VCHAR (FNT5X9_VCHAR)
! 86: #define PNG_HCHAR (FNT5X9_VCHAR)
! 87: #define PNG_VTIC FNT5X9_HBITS
! 88: #define PNG_HTIC FNT5X9_HBITS
! 89:
1.1 maekawa 90: #ifdef TERM_BODY
91:
92: #include "png.h"
93:
94: /* I'm not sure exactly which is the first version we work with,
95: * but I know that some older ones don't define all the symbols
96: * we use
97: */
98:
99: /* png version test now in configure */
100:
101: static int png_font = 1; /* small font */
102: static int png_mode = 0; /* 0:monochrome 1:gray 2:color */
103:
104: /* 7=black, 0=white */
105: static int png_gray[] = { 7, 1, 6, 5, 4, 3, 2, 1, 7 }; /* grays */
106: /* bit3=!intensify, bit2=!red, bit1=!green, bit0=!blue */
107: static int png_color_table[] ={ 15, 8, 3, 5, 6, 4, 2, 1, 11, 13, 14 }; /* colors */
108: static png_color png_palette[16];
109:
1.1.1.2 ! maekawa 110: TERM_PUBLIC void
! 111: PNG_options()
1.1 maekawa 112: {
1.1.1.2 ! maekawa 113: png_font = 1; /* small */
1.1 maekawa 114: png_mode = 0;
115:
116: term_options[0] = NUL;
117:
118: while (!END_OF_COMMAND) {
119: if (almost_equals(c_token, "s$mall"))
120: png_font = 1;
121: else if (almost_equals(c_token, "me$dium"))
122: png_font = 2;
123: else if (almost_equals(c_token, "l$arge"))
124: png_font = 3;
125: else if (almost_equals(c_token, "mo$nochrome"))
126: png_mode = 0;
127: else if (almost_equals(c_token, "g$ray"))
128: png_mode = 1;
129: else if (almost_equals(c_token, "c$olor")
130: || almost_equals(c_token, "c$olour"))
131: png_mode = 2;
132: else {
133: /* reset to default, since term is already set */
134: png_font = 1;
135: png_mode = 0;
1.1.1.2 ! maekawa 136: int_error("expecting: {small, medium, large}, or {monochrome, gray, color}", c_token);
1.1 maekawa 137: }
138: c_token++;
139: }
140:
141: /* setup options string */
142:
143: switch (png_font) {
1.1.1.2 ! maekawa 144: case 3:
! 145: strcat(term_options, "large");
1.1 maekawa 146: break;
147: case 2:
148: strcat(term_options, "medium");
149: break;
1.1.1.2 ! maekawa 150: case 1:
! 151: default:
! 152: strcat(term_options, "small");
1.1 maekawa 153: break;
154: }
155:
156: switch (png_mode) {
1.1.1.2 ! maekawa 157: case 2:
! 158: strcat(term_options, " color");
1.1 maekawa 159: break;
160: case 1:
161: strcat(term_options, " gray");
162: break;
1.1.1.2 ! maekawa 163: case 0:
! 164: default:
! 165: strcat(term_options, " monochrome");
1.1 maekawa 166: break;
167: }
1.1.1.2 ! maekawa 168:
1.1 maekawa 169: }
170:
171:
1.1.1.2 ! maekawa 172: TERM_PUBLIC void
! 173: PNG_init()
1.1 maekawa 174: {
1.1.1.2 ! maekawa 175: PNG_setfont(); /* HBB 980226: do this here! */
1.1 maekawa 176: }
177:
178:
1.1.1.2 ! maekawa 179: TERM_PUBLIC void
! 180: PNG_reset()
1.1 maekawa 181: {
182: #ifdef VMS
183: fflush_binary();
184: #endif /* VMS */
185: }
186:
187:
1.1.1.2 ! maekawa 188: TERM_PUBLIC void
! 189: PNG_setfont()
1.1 maekawa 190: {
191: switch (png_font) {
1.1.1.2 ! maekawa 192: case 3:
! 193: b_charsize(FNT13X25);
! 194: term->v_char = FNT13X25_VCHAR;
! 195: term->h_char = FNT13X25_HCHAR;
! 196: term->v_tic = FNT13X25_HBITS;
! 197: term->h_tic = FNT13X25_HBITS;
1.1 maekawa 198: break;
199: case 2:
200: b_charsize(FNT9X17);
201: term->v_char = FNT9X17_VCHAR;
202: term->h_char = FNT9X17_HCHAR;
203: term->v_tic = FNT9X17_HBITS;
204: term->h_tic = FNT9X17_HBITS;
205: break;
1.1.1.2 ! maekawa 206: case 1:
! 207: default:
! 208: b_charsize(FNT5X9);
! 209: term->v_char = FNT5X9_VCHAR;
! 210: term->h_char = FNT5X9_HCHAR;
! 211: term->v_tic = FNT5X9_HBITS;
! 212: term->h_tic = FNT5X9_HBITS;
1.1 maekawa 213: break;
214: }
215: }
216:
217:
1.1.1.2 ! maekawa 218: TERM_PUBLIC void
! 219: PNG_graphics()
1.1 maekawa 220: {
1.1.1.2 ! maekawa 221: int numplanes = 1;
1.1 maekawa 222:
223: switch (png_mode) {
1.1.1.2 ! maekawa 224: case 2:
! 225: numplanes = 4;
1.1 maekawa 226: break;
227: case 1:
228: numplanes = 3;
229: break;
1.1.1.2 ! maekawa 230: case 0:
! 231: default:
! 232: numplanes = 1;
1.1 maekawa 233: break;
234: }
235:
236: /* PNGsetfont(); *//* HBB 980226: do this in init() ! */
237:
238: /* rotate plot -90 degrees by reversing XMAX and YMAX and by
239: setting b_rastermode to TRUE */
240: b_makebitmap((unsigned int) (PNG_YMAX * ysize),
241: (unsigned int) (PNG_XMAX * xsize), numplanes);
242: b_rastermode = TRUE;
243:
244: if (png_mode != 0)
245: b_setlinetype(0); /* solid lines */
246: }
247:
1.1.1.2 ! maekawa 248: TERM_PUBLIC void
! 249: PNG_text()
1.1 maekawa 250: {
251: register int x, j, row;
252: png_structp png_ptr;
253: png_infop info_ptr;
254: register int i, value;
255: png_bytep prow;
256: int mask, plane1, plane2, plane3, plane4;
257: int red, green, blue;
258: png_text pngtext, *pngtext_copy;
259: char text[100];
260:
261: png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
262: if (!png_ptr) {
263: b_freebitmap();
264: return;
265: }
266: info_ptr = png_create_info_struct(png_ptr);
267: if (!info_ptr) {
268: png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
269: b_freebitmap();
270: return;
271: }
272: prow = malloc(b_ysize);
273: if (!prow) {
274: png_destroy_write_struct(&png_ptr, &info_ptr);
275: b_freebitmap();
276: return;
277: }
278: if (setjmp(png_ptr->jmpbuf)) {
279: png_destroy_write_struct(&png_ptr, &info_ptr);
280: free(prow);
281: b_freebitmap();
282: return;
283: }
1.1.1.2 ! maekawa 284:
! 285: #ifdef __OLD_PNGLIB__
! 286: /* deprecated and no longer necessary */
1.1 maekawa 287: png_info_init(info_ptr);
1.1.1.2 ! maekawa 288: png_write_init(png_ptr); */
! 289: #endif /* __OLD_PNGLIB__ */
1.1 maekawa 290:
291: png_init_io(png_ptr, gpoutfile);
292:
293: info_ptr->width = b_ysize;
294: info_ptr->height = b_xsize;
295:
296: info_ptr->bit_depth = png_mode == 0 ? 1 : 4;
297: info_ptr->color_type = png_mode == 2 ? PNG_COLOR_TYPE_PALETTE :
298: PNG_COLOR_TYPE_GRAY;
299: if (png_mode == 2) {
300: info_ptr->valid |= PNG_INFO_PLTE;
301: info_ptr->palette = png_palette;
302: info_ptr->num_palette = 16;
303: }
304: if (png_mode != 0) {
305: info_ptr->valid |= PNG_INFO_sBIT;
306: if (png_mode == 1) {
307: info_ptr->sig_bit.gray = 3;
308: png_set_shift(png_ptr, &(info_ptr->sig_bit));
309: } else {
310: info_ptr->sig_bit.red = 2;
311: info_ptr->sig_bit.green = 2;
312: info_ptr->sig_bit.blue = 2;
313: }
314: }
315: info_ptr->interlace_type = 0;
316: if (png_mode == 0)
317: png_set_invert_mono(png_ptr);
318:
319: if (png_mode == 2)
320: for (i = 0; i < 16; i++) {
321: red = (i & 4) ? 1 : 3;
322: green = (i & 2) ? 1 : 3;
323: blue = (i & 1) ? 1 : 3;
324: if (i & 8) {
325: red--;
326: green--;
327: blue--;
328: }
329: png_palette[i].red = red * 85;
330: png_palette[i].green = green * 85;
331: png_palette[i].blue = blue * 85;
332: }
1.1.1.2 ! maekawa 333: sprintf(text, "gnuplot %sversion %s patchlevel %s",
! 334: OS, version, patchlevel);
1.1 maekawa 335:
336: pngtext.compression = -1;
337: pngtext.key = "Software";
338: pngtext.text = text;
339: pngtext.text_length = strlen(text);
340:
341: pngtext_copy = malloc(sizeof(*pngtext_copy));
342: *pngtext_copy = pngtext;
343: info_ptr->num_text = 1;
344: info_ptr->text = pngtext_copy;
345:
346: png_write_info(png_ptr, info_ptr);
347:
348: info_ptr->num_text = 0;
349: if (info_ptr->text) free(info_ptr->text);
350: info_ptr->text = NULL;
351:
352: png_set_packing(png_ptr);
353:
354: /* dump bitmap in raster mode */
355: for (x = b_xsize - 1; x >= 0; x--) {
356: row = (b_ysize / 8) - 1;
357: for (j = row; j >= 0; j--) {
358: mask = 0x80;
359: plane1 = (*((*b_p)[j] + x));
360: if (png_mode != 0) {
361: plane2 = (*((*b_p)[j + b_psize] + x));
362: plane3 = (*((*b_p)[j + b_psize + b_psize] + x));
363: } else {
364: plane2 = 0;
365: plane3 = 0;
366: }
367: if (png_mode == 2)
368: plane4 = (*((*b_p)[j + b_psize + b_psize + b_psize] + x));
369: else
370: plane4 = 0;
371:
372: for (i = 0; i < 8; i++) {
373: value = 0;
374: if (plane1 & mask)
375: value += 1;
376: if (plane2 & mask)
377: value += 2;
378: if (plane3 & mask)
379: value += 4;
380: if (plane4 & mask)
381: value += 8;
382: if (png_mode == 1)
383: value = 7 - value;
384:
385: prow[(row - j) * 8 + i] = (png_byte) value;
386: mask >>= 1;
387: }
388: }
389: png_write_rows(png_ptr, &prow, 1);
390: }
391:
392: png_write_end(png_ptr, info_ptr);
393: png_destroy_write_struct(&png_ptr, &info_ptr);
394: free(prow);
395: b_freebitmap();
396: }
397:
1.1.1.2 ! maekawa 398:
! 399: TERM_PUBLIC void
! 400: PNG_linetype(linetype)
1.1 maekawa 401: int linetype;
402: {
403: switch (png_mode) {
1.1.1.2 ! maekawa 404: case 2:
! 405: if (linetype >= 9)
! 406: linetype %= 9;
! 407: b_setvalue(png_color_table[linetype + 2]);
1.1 maekawa 408: break;
409: case 1:
410: if (linetype >= 7)
411: linetype %= 7;
412: b_setvalue(png_gray[linetype + 2]);
413: break;
1.1.1.2 ! maekawa 414: case 0:
! 415: default:
! 416: b_setlinetype(linetype);
1.1 maekawa 417: break;
418: }
419: }
420:
1.1.1.2 ! maekawa 421: TERM_PUBLIC void
! 422: PNG_point(x, y, point)
1.1 maekawa 423: unsigned int x, y;
424: int point;
425: {
426: if (png_mode == 0)
427: line_and_point(x, y, point);
428: else
429: do_point(x, y, point);
430: }
431:
432: #endif /* TERM_BODY */
433:
434: #ifdef TERM_TABLE
435:
436: TERM_TABLE_START(png_driver)
437: "png",
438: "Portable Network Graphics [small medium large] [monochrome gray color]",
439: PNG_XMAX, PNG_YMAX, PNG_VCHAR,
1.1.1.2 ! maekawa 440: PNG_HCHAR, PNG_VTIC, PNG_HTIC, PNG_options,
! 441: PNG_init, PNG_reset, PNG_text, null_scale,
! 442: PNG_graphics, b_move, b_vector, PNG_linetype,
! 443: b_put_text, b_text_angle, null_justify_text, PNG_point,
1.1 maekawa 444: do_arrow, set_font_null,
445: 0, /* pointsize */
446: TERM_CAN_MULTIPLOT | TERM_BINARY
447: TERM_TABLE_END(png_driver)
448:
449: #undef LAST_TERM
450: #define LAST_TERM png_driver
451:
452: #endif /* TERM_TABLE */
453:
454: #ifdef TERM_HELP
455: START_HELP(png)
456: "1 png",
457: "?commands set terminal png",
458: "?set terminal png",
459: "?set term png",
460: "?terminal png",
461: "?term png",
462: "?png",
463: " The `png` terminal driver supports Portable Network Graphics. To compile it,",
464: " you will need the third-party libraries \"libpng\" and \"zlib\"; both are",
465: " available at ftp://ftp.uu.net/graphics/png. `png` has two options.",
466: "",
467: " Syntax:",
468: " set terminal png {small | medium | large}",
469: " {monochrome | gray | color}",
470: "",
1.1.1.2 ! maekawa 471: " The defaults are small (fontsize) and monochrome. Default size of the output",
! 472: " is 640*480 pixel."
1.1 maekawa 473: END_HELP(png)
474: #endif /* TERM_HELP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>