• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

pbm.c

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

Generated on Wed Oct 12 2011 20:42:22 for PLplot by  doxygen 1.7.1