PLplot  5.10.0
pbm.c
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines