PLplot
5.10.0
|
00001 // PLplot PBM (PPM) device driver. 00002 // 00003 // Contributed by John C. Atkinson and Zulfi Cumali. 00004 // Slightly modified by Geoffrey Furnish. 00005 // 00006 #include "plDevs.h" 00007 00008 #ifdef PLD_pbm 00009 00010 #include "plplotP.h" 00011 #include "drivers.h" 00012 00013 // Device info 00014 PLDLLIMPEXP_DRIVER const char* plD_DEVICE_INFO_pbm = "pbm:PDB (PPM) Driver:0:pbm:38:pbm\n"; 00015 00016 00017 void plD_dispatch_init_pbm( PLDispatchTable *pdt ); 00018 00019 void plD_init_pbm( PLStream * ); 00020 void plD_line_pbm( PLStream *, short, short, short, short ); 00021 void plD_polyline_pbm( PLStream *, short *, short *, PLINT ); 00022 void plD_eop_pbm( PLStream * ); 00023 void plD_bop_pbm( PLStream * ); 00024 void plD_tidy_pbm( PLStream * ); 00025 void plD_state_pbm( PLStream *, PLINT ); 00026 void plD_esc_pbm( PLStream *, PLINT, void * ); 00027 00028 #undef PIXELS_X 00029 #undef PIXELS_Y 00030 #define PIXELS_X 640 00031 #define PIXELS_Y 480 00032 00033 static char *cmap; 00034 00035 #undef MAX 00036 #undef ABS 00037 #define MAX( a, b ) ( ( a > b ) ? a : b ) 00038 #define ABS( a ) ( ( a < 0 ) ? -a : a ) 00039 00040 #define MAX_INTENSITY 255 00041 00042 void plD_dispatch_init_pbm( PLDispatchTable *pdt ) 00043 { 00044 #ifndef ENABLE_DYNDRIVERS 00045 pdt->pl_MenuStr = "PDB (PPM) Driver"; 00046 pdt->pl_DevName = "pbm"; 00047 #endif 00048 pdt->pl_type = plDevType_FileOriented; 00049 pdt->pl_seq = 38; 00050 pdt->pl_init = (plD_init_fp) plD_init_pbm; 00051 pdt->pl_line = (plD_line_fp) plD_line_pbm; 00052 pdt->pl_polyline = (plD_polyline_fp) plD_polyline_pbm; 00053 pdt->pl_eop = (plD_eop_fp) plD_eop_pbm; 00054 pdt->pl_bop = (plD_bop_fp) plD_bop_pbm; 00055 pdt->pl_tidy = (plD_tidy_fp) plD_tidy_pbm; 00056 pdt->pl_state = (plD_state_fp) plD_state_pbm; 00057 pdt->pl_esc = (plD_esc_fp) plD_esc_pbm; 00058 } 00059 00060 //-------------------------------------------------------------------------- 00061 // plD_init_pbm() 00062 // 00063 // Initialize device (terminal). 00064 //-------------------------------------------------------------------------- 00065 00066 void 00067 plD_init_pbm( PLStream *pls ) 00068 { 00069 #if 1 00070 00071 // Initialize family file info 00072 00073 plFamInit( pls ); 00074 00075 plP_setpxl( (PLFLT) 5.905, (PLFLT) 5.905 ); 00076 00077 #endif 00078 00079 pls->color = 1; // Is a color device 00080 pls->dev_fill0 = 0; // Handle solid fills 00081 pls->dev_fill1 = 0; // Use PLplot core fallback for pattern fills 00082 pls->nopause = 1; // Don't pause between frames 00083 00084 // Prompt for a file name if not already set 00085 00086 plOpenFile( pls ); 00087 pls->pdfs = pdf_finit( pls->OutFile ); 00088 00089 // Allocate and initialize device-specific data 00090 00091 pls->dev = NULL; 00092 00093 // Set up device parameters 00094 00095 if ( pls->xlength <= 0 || pls->ylength <= 0 ) 00096 { 00097 plspage( 0., 0., PIXELS_X, PIXELS_Y, 0, 0 ); 00098 } 00099 00100 plP_setphy( 0, pls->xlength, 0, pls->ylength ); 00101 } 00102 00103 #if 0 00104 void 00105 plD_line_pbm( PLStream *pls, short x1a, short y1a, short x2a, short y2a ) 00106 { 00107 int steps, i, dx, dy; 00108 double x_off, y_off, dx_step, dy_step; 00109 00110 // This algoritm is by Steven Harrington 00111 // From "Computer Graphics: A Proogramming Approach 00112 00113 dx = x2a - x1a; 00114 dy = y2a - y1a; 00115 steps = MAX( ABS( dx ), ABS( dy ) ) + 1; 00116 steps *= 2; 00117 dx_step = dx / steps; 00118 dy_step = dy / steps; 00119 x_off = x1a + 0.5; 00120 y_off = y1a + 0.5; 00121 00122 for ( i = 0; i < steps; i++ ) 00123 { 00124 cmap[(int) y_off][(int) x_off][0] = pls->curcolor.r; 00125 cmap[(int) y_off][(int) x_off][1] = pls->curcolor.g; 00126 cmap[(int) y_off][(int) x_off][2] = pls->curcolor.b; 00127 x_off += dx_step; 00128 y_off += dy_step; 00129 } 00130 00131 cmap[(int) y_off][(int) x_off][0] = pls->curcolor.r; 00132 cmap[(int) y_off][(int) x_off][1] = pls->curcolor.g; 00133 cmap[(int) y_off][(int) x_off][2] = pls->curcolor.b; 00134 00135 return; 00136 } 00137 #endif 00138 00139 #define sign( a ) ( ( a < 0 ) ? -1 : ( ( a == 0 ) ? 0 : 1 ) ) 00140 00141 #if 0 00142 #define plot( x, y, c ) { cmap[y - 1][x - 1][0] = ( c )->curcolor.r; \ 00143 cmap[y - 1][x - 1][1] = ( c )->curcolor.g; \ 00144 cmap[y - 1][x - 1][2] = ( c )->curcolor.b; } 00145 00146 // Bresnham's algorithm for line plotting on a scan lines 00147 00148 void 00149 plD_line_pbm( PLStream *pls, short x1a, short y1a, short x2a, short y2a ) 00150 { 00151 int e, x, y, dx, dy, s1, s2, temp, change, i; 00152 00153 x = x1a; 00154 y = y1a; 00155 00156 dx = ABS( x2a - x1a ); 00157 dy = ABS( y2a - y1a ); 00158 s1 = sign( x2a - x1a ); 00159 s2 = sign( y2a - y1a ); 00160 00161 if ( dy > dx ) 00162 { 00163 temp = dx; 00164 dx = dy; 00165 dy = temp; 00166 change = 1; 00167 } 00168 else 00169 { 00170 change = 0; 00171 } 00172 e = 2 * dy - dx; 00173 00174 for ( i = 1; i < dx; i++ ) 00175 { 00176 plot( x, y, pls ); 00177 while ( e >= 0 ) 00178 { 00179 if ( change == 1 ) 00180 x += s1; 00181 else 00182 y += s2; 00183 e = e - 2 * dx; 00184 } 00185 if ( change == 1 ) 00186 y += s2; 00187 else 00188 x += s1; 00189 e = e + 2 * dy; 00190 } 00191 } 00192 #else 00193 #define plot( x, y, c ) { int i = 3 * ( ( y ) * ( c )->xlength + ( x ) ); \ 00194 cmap[i + 0] = ( c )->curcolor.r; \ 00195 cmap[i + 1] = ( c )->curcolor.g; \ 00196 cmap[i + 2] = ( c )->curcolor.b; } 00197 00198 // Modified version of the ljii routine (see ljii.c) 00199 void 00200 plD_line_pbm( PLStream *pls, short x1a, short y1a, short x2a, short y2a ) 00201 { 00202 int i; 00203 int x1 = x1a, y1 = y1a, x2 = x2a, y2 = y2a; 00204 PLINT x1b, y1b, x2b, y2b; 00205 PLFLT length, fx, fy, dx, dy; 00206 00207 // Take mirror image, since PCL expects (0,0) to be at top left 00208 00209 y1 = pls->ylength - ( y1 - 0 ); 00210 y2 = pls->ylength - ( y2 - 0 ); 00211 00212 x1b = x1, x2b = x2, y1b = y1, y2b = y2; 00213 length = (PLFLT) sqrt( (double) 00214 ( ( x2b - x1b ) * ( x2b - x1b ) + ( y2b - y1b ) * ( y2b - y1b ) ) ); 00215 00216 if ( length == 0. ) 00217 length = 1.; 00218 dx = ( x2 - x1 ) / length; 00219 dy = ( y2 - y1 ) / length; 00220 00221 fx = x1; 00222 fy = y1; 00223 plot( (PLINT) x1, (PLINT) y1, pls ); 00224 plot( (PLINT) x2, (PLINT) y2, pls ); 00225 00226 for ( i = 1; i <= (int) length; i++ ) 00227 { 00228 fx += dx; fy += dy; 00229 plot( (PLINT) fx, (PLINT) fy, pls ); 00230 } 00231 } 00232 #endif 00233 00234 void 00235 plD_polyline_pbm( PLStream *pls, short *xa, short *ya, PLINT npts ) 00236 { 00237 int i; 00238 for ( i = 0; i < npts - 1; i++ ) 00239 plD_line_pbm( pls, xa[i], ya[i], xa[i + 1], ya[i + 1] ); 00240 } 00241 00242 void 00243 plD_eop_pbm( PLStream *pls ) 00244 { 00245 FILE *fp = pls->OutFile; 00246 size_t im_size, nwrite; 00247 00248 if ( fp != NULL ) 00249 { 00250 fprintf( fp, "%s\n", "P6" ); 00251 fprintf( fp, "%d %d\n", pls->xlength, pls->ylength ); 00252 fprintf( fp, "%d\n", MAX_INTENSITY ); 00253 // 00254 // { 00255 // int i, j, k; 00256 // for (i=0; i<PIXELS_Y; i++) 00257 // for (j=0; j<PIXELS_X; j++) 00258 // for (k=0; k<3; k++) 00259 // fprintf(fp, "%c", cmap[i][j][k]); 00260 // } 00261 // 00262 im_size = pls->xlength * pls->ylength * 3; 00263 nwrite = fwrite( cmap, 1, im_size, fp ); 00264 if ( nwrite != im_size ) 00265 plabort( "pbm driver: Error writing pbm file" ); 00266 00267 plCloseFile( pls ); 00268 } 00269 free( cmap ); 00270 cmap = 0; 00271 } 00272 00273 void 00274 plD_bop_pbm( PLStream *pls ) 00275 { 00276 int i, j, k; 00277 cmap = (char *) malloc( pls->xlength * pls->ylength * 3 ); 00278 for ( i = 0; i < pls->ylength; i++ ) 00279 for ( j = 0; j < pls->xlength; j++ ) 00280 { 00281 k = ( i * pls->xlength + j ) * 3; 00282 cmap[k + 0] = pls->cmap0[0].r; 00283 cmap[k + 1] = pls->cmap0[0].g; 00284 cmap[k + 2] = pls->cmap0[0].b; 00285 } 00286 } 00287 00288 void 00289 plD_tidy_pbm( PLStream *pls ) 00290 { 00291 // Nothing to do here 00292 } 00293 00294 void 00295 plD_state_pbm( PLStream *pls, PLINT op ) 00296 { 00297 // Nothing to do here 00298 } 00299 00300 void 00301 plD_esc_pbm( PLStream *pls, PLINT op, void *ptr ) 00302 { 00303 // Nothing to do here 00304 } 00305 00306 #else 00307 int 00308 pldummy_pbm() 00309 { 00310 return 0; 00311 } 00312 00313 #endif // PLD_pbm 00314 00315