PLplot: pbm.c Source File

PLplot 5.10.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pbm.c
Go to the documentation of this file.
1 //
2 // $Id: pbm.c 11760 2011-06-01 19:29:11Z airwin $
3 //
4 // PLplot PBM (PPM) device driver.
5 //
6 // Contributed by John C. Atkinson and Zulfi Cumali.
7 // Slightly modified by Geoffrey Furnish.
8 //
9 #include "plDevs.h"
10
11 #ifdef PLD_pbm
12
13 #include "plplotP.h"
14 #include "drivers.h"
15
16 // Device info
17 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_pbm = "pbm:PDB (PPM) Driver:0:pbm:38:pbm\n";
18
19
20 void plD_dispatch_init_pbm( PLDispatchTable *pdt );
21
22 void plD_init_pbm( PLStream * );
23 void plD_line_pbm( PLStream *, short, short, short, short );
24 void plD_polyline_pbm( PLStream *, short *, short *, PLINT );
25 void plD_eop_pbm( PLStream * );
26 void plD_bop_pbm( PLStream * );
27 void plD_tidy_pbm( PLStream * );
28 void plD_state_pbm( PLStream *, PLINT );
29 void plD_esc_pbm( PLStream *, PLINT, void * );
30
31 #undef PIXELS_X
32 #undef PIXELS_Y
33 #define PIXELS_X 640
34 #define PIXELS_Y 480
35
36 static char *cmap;
37
38 #undef MAX
39 #undef ABS
40 #define MAX( a, b ) ( ( a > b ) ? a : b )
41 #define ABS( a ) ( ( a < 0 ) ? -a : a )
42
43 #define MAX_INTENSITY 255
44
45 void plD_dispatch_init_pbm( PLDispatchTable *pdt )
46 {
47 #ifndef ENABLE_DYNDRIVERS
48 pdt->pl_MenuStr = "PDB (PPM) Driver";
49 pdt->pl_DevName = "pbm";
50 #endif
51 pdt->pl_type = plDevType_FileOriented;
52 pdt->pl_seq = 38;
53 pdt->pl_init = (plD_init_fp) plD_init_pbm;
54 pdt->pl_line = (plD_line_fp) plD_line_pbm;
55 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_pbm;
56 pdt->pl_eop = (plD_eop_fp) plD_eop_pbm;
57 pdt->pl_bop = (plD_bop_fp) plD_bop_pbm;
58 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_pbm;
59 pdt->pl_state = (plD_state_fp) plD_state_pbm;
60 pdt->pl_esc = (plD_esc_fp) plD_esc_pbm;
61 }
62
63 //--------------------------------------------------------------------------
64 // plD_init_pbm()
65 //
66 // Initialize device (terminal).
67 //--------------------------------------------------------------------------
68
69 void
70 plD_init_pbm( PLStream *pls )
71 {
72 #if 1
73
74 // Initialize family file info
75
76 plFamInit( pls );
77
78 plP_setpxl( (PLFLT) 5.905, (PLFLT) 5.905 );
79
80 #endif
81
82 pls->color = 1; // Is a color device
83 pls->dev_fill0 = 0; // Handle solid fills
84 pls->dev_fill1 = 0; // Use PLplot core fallback for pattern fills
85 pls->nopause = 1; // Don't pause between frames
86
87 // Prompt for a file name if not already set
88
89 plOpenFile( pls );
90 pls->pdfs = pdf_finit( pls->OutFile );
91
92 // Allocate and initialize device-specific data
93
94 pls->dev = NULL;
95
96 // Set up device parameters
97
98 if ( pls->xlength <= 0 || pls->ylength <= 0 )
99 {
100 plspage( 0., 0., PIXELS_X, PIXELS_Y, 0, 0 );
101 }
102
103 plP_setphy( 0, pls->xlength, 0, pls->ylength );
104 }
105
106 #if 0
107 void
108 plD_line_pbm( PLStream *pls, short x1a, short y1a, short x2a, short y2a )
109 {
110 int steps, i, dx, dy;
111 double x_off, y_off, dx_step, dy_step;
112
113 // This algoritm is by Steven Harrington
114 // From "Computer Graphics: A Proogramming Approach
115
116 dx = x2a - x1a;
117 dy = y2a - y1a;
118 steps = MAX( ABS( dx ), ABS( dy ) ) + 1;
119 steps *= 2;
120 dx_step = dx / steps;
121 dy_step = dy / steps;
122 x_off = x1a + 0.5;
123 y_off = y1a + 0.5;
124
125 for ( i = 0; i < steps; i++ )
126 {
127 cmap[(int) y_off][(int) x_off][0] = pls->curcolor.r;
128 cmap[(int) y_off][(int) x_off][1] = pls->curcolor.g;
129 cmap[(int) y_off][(int) x_off][2] = pls->curcolor.b;
130 x_off += dx_step;
131 y_off += dy_step;
132 }
133
134 cmap[(int) y_off][(int) x_off][0] = pls->curcolor.r;
135 cmap[(int) y_off][(int) x_off][1] = pls->curcolor.g;
136 cmap[(int) y_off][(int) x_off][2] = pls->curcolor.b;
137
138 return;
139 }
140 #endif
141
142 #define sign( a ) ( ( a < 0 ) ? -1 : ( ( a == 0 ) ? 0 : 1 ) )
143
144 #if 0
145 #define plot( x, y, c ) { cmap[y - 1][x - 1][0] = ( c )->curcolor.r; \
146 cmap[y - 1][x - 1][1] = ( c )->curcolor.g; \
147 cmap[y - 1][x - 1][2] = ( c )->curcolor.b; }
148
149 // Bresnham's algorithm for line plotting on a scan lines
150
151 void
152 plD_line_pbm( PLStream *pls, short x1a, short y1a, short x2a, short y2a )
153 {
154 int e, x, y, dx, dy, s1, s2, temp, change, i;
155
156 x = x1a;
157 y = y1a;
158
159 dx = ABS( x2a - x1a );
160 dy = ABS( y2a - y1a );
161 s1 = sign( x2a - x1a );
162 s2 = sign( y2a - y1a );
163
164 if ( dy > dx )
165 {
166 temp = dx;
167 dx = dy;
168 dy = temp;
169 change = 1;
170 }
171 else
172 {
173 change = 0;
174 }
175 e = 2 * dy - dx;
176
177 for ( i = 1; i < dx; i++ )
178 {
179 plot( x, y, pls );
180 while ( e >= 0 )
181 {
182 if ( change == 1 )
183 x += s1;
184 else
185 y += s2;
186 e = e - 2 * dx;
187 }
188 if ( change == 1 )
189 y += s2;
190 else
191 x += s1;
192 e = e + 2 * dy;
193 }
194 }
195 #else
196 #define plot( x, y, c ) { int i = 3 * ( ( y ) * ( c )->xlength + ( x ) ); \
197 cmap[i + 0] = ( c )->curcolor.r; \
198 cmap[i + 1] = ( c )->curcolor.g; \
199 cmap[i + 2] = ( c )->curcolor.b; }
200
201 // Modified version of the ljii routine (see ljii.c)
202 void
203 plD_line_pbm( PLStream *pls, short x1a, short y1a, short x2a, short y2a )
204 {
205 int i;
206 int x1 = x1a, y1 = y1a, x2 = x2a, y2 = y2a;
207 PLINT x1b, y1b, x2b, y2b;
208 PLFLT length, fx, fy, dx, dy;
209
210 // Take mirror image, since PCL expects (0,0) to be at top left
211
212 y1 = pls->ylength - ( y1 - 0 );
213 y2 = pls->ylength - ( y2 - 0 );
214
215 x1b = x1, x2b = x2, y1b = y1, y2b = y2;
216 length = (PLFLT) sqrt( (double)
217 ( ( x2b - x1b ) * ( x2b - x1b ) + ( y2b - y1b ) * ( y2b - y1b ) ) );
218
219 if ( length == 0. )
220 length = 1.;
221 dx = ( x2 - x1 ) / length;
222 dy = ( y2 - y1 ) / length;
223
224 fx = x1;
225 fy = y1;
226 plot( (PLINT) x1, (PLINT) y1, pls );
227 plot( (PLINT) x2, (PLINT) y2, pls );
228
229 for ( i = 1; i <= (int) length; i++ )
230 {
231 fx += dx; fy += dy;
232 plot( (PLINT) fx, (PLINT) fy, pls );
233 }
234 }
235 #endif
236
237 void
238 plD_polyline_pbm( PLStream *pls, short *xa, short *ya, PLINT npts )
239 {
240 int i;
241 for ( i = 0; i < npts - 1; i++ )
242 plD_line_pbm( pls, xa[i], ya[i], xa[i + 1], ya[i + 1] );
243 }
244
245 void
246 plD_eop_pbm( PLStream *pls )
247 {
248 FILE *fp = pls->OutFile;
249 size_t im_size, nwrite;
250
251 if ( fp != NULL )
252 {
253 fprintf( fp, "%s\n", "P6" );
254 fprintf( fp, "%d %d\n", pls->xlength, pls->ylength );
255 fprintf( fp, "%d\n", MAX_INTENSITY );
256 //
257 // {
258 // int i, j, k;
259 // for (i=0; i<PIXELS_Y; i++)
260 // for (j=0; j<PIXELS_X; j++)
261 // for (k=0; k<3; k++)
262 // fprintf(fp, "%c", cmap[i][j][k]);
263 // }
264 //
265 im_size = pls->xlength * pls->ylength * 3;
266 nwrite = fwrite( cmap, 1, im_size, fp );
267 if ( nwrite != im_size )
268 plabort( "pbm driver: Error writing pbm file" );
269
270 plCloseFile( pls );
271 }
272 free( cmap );
273 cmap = 0;
274 }
275
276 void
277 plD_bop_pbm( PLStream *pls )
278 {
279 int i, j, k;
280 cmap = (char *) malloc( pls->xlength * pls->ylength * 3 );
281 for ( i = 0; i < pls->ylength; i++ )
282 for ( j = 0; j < pls->xlength; j++ )
283 {
284 k = ( i * pls->xlength + j ) * 3;
285 cmap[k + 0] = pls->cmap0[0].r;
286 cmap[k + 1] = pls->cmap0[0].g;
287 cmap[k + 2] = pls->cmap0[0].b;
288 }
289 }
290
291 void
292 plD_tidy_pbm( PLStream *pls )
293 {
294 // Nothing to do here
295 }
296
297 void
298 plD_state_pbm( PLStream *pls, PLINT op )
299 {
300 // Nothing to do here
301 }
302
303 void
304 plD_esc_pbm( PLStream *pls, PLINT op, void *ptr )
305 {
306 // Nothing to do here
307 }
308
309 #else
310 int
311 pldummy_pbm()
312 {
313 return 0;
314 }
315
316 #endif // PLD_pbm
317
318