irplib_plot.c

00001 /* $Id: irplib_plot.c,v 1.27 2006/12/13 11:29:48 jmlarsen Exp $
00002  *
00003  * This file is part of the irplib package
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: jmlarsen $
00023  * $Date: 2006/12/13 11:29:48 $
00024  * $Revision: 1.27 $
00025  * $Name:  $
00026  */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 /*-----------------------------------------------------------------------------
00033                                    Includes
00034  -----------------------------------------------------------------------------*/
00035 
00036 #include <stdio.h>
00037 #include <unistd.h>
00038 #include <sys/types.h>
00039 #include <string.h>
00040 #include <stdlib.h>
00041 #include <assert.h>
00042 #include <float.h>
00043 
00044 /* Needed to get irplib_sprintf() */
00045 #include "irplib_utils.h"
00046 #include "irplib_plot.h"
00047 
00048 /*-----------------------------------------------------------------------------
00049                                    Define
00050  -----------------------------------------------------------------------------*/
00051 
00052 /* The IRPLIB-based application may have checked for the availability of popen() 
00053    and pclose() in which case the macros are defined to either 0 or 1. Without
00054    checks it is assumed that the functions are available. With a suitable
00055    version of autoconf the two macros can be defined with this entry in
00056    configure.ac:
00057    AC_CHECK_DECLS([popen, pclose])
00058 */
00059 
00060 #if defined HAVE_DECL_POPEN && !HAVE_DECL_POPEN
00061 #define HAS_PROCESS_IO 0
00062 #elif defined HAVE_DECL_PCLOSE && !HAVE_DECL_PCLOSE
00063 #define HAS_PROCESS_IO 0
00064 #else
00065 #define HAS_PROCESS_IO 1
00066 #endif
00067 
00068 #define LINE_SIZE 80
00069 
00070 /*----------------------------------------------------------------------------*/
00080 /*----------------------------------------------------------------------------*/
00081 
00082 /*-----------------------------------------------------------------------------
00083                                    Type definition
00084  -----------------------------------------------------------------------------*/
00085 
00086 typedef struct _irplib_plot_ irplib_plot;
00087 
00088 struct _irplib_plot_ {
00089     /* Pipe to plotting process */
00090     FILE * pipe;
00091 };
00092 
00093 /*-----------------------------------------------------------------------------
00094                         Private function prototypes
00095  -----------------------------------------------------------------------------*/
00096 
00097 static cpl_error_code irplib_mplot_puts(irplib_plot *, const char *);
00098 static cpl_error_code irplib_mplot_write(irplib_plot *, const char *, size_t);
00099 static irplib_plot * irplib_mplot_open(const char *);
00100 static irplib_plot * irplib_image_open(const char *);
00101 static cpl_error_code irplib_mplot_close(irplib_plot *, const char *);
00102 static const char * irplib_mplot_plotter(void);
00103 static const char * irplib_mplot_imager(void);
00104 
00105 /*-----------------------------------------------------------------------------
00106                                    Functions code
00107  -----------------------------------------------------------------------------*/
00110 /*----------------------------------------------------------------------------*/
00146 /*----------------------------------------------------------------------------*/
00147 cpl_error_code irplib_vector_plot_macro(const char          *   pre, 
00148                                         const char          *   options,
00149                                         const char          *   post, 
00150                                         const cpl_vector    *   vector,
00151                                         const char          *   file, 
00152                                         const unsigned          line) 
00153 {
00154     char           snumber[LINE_SIZE];
00155     const double * pvec      = cpl_vector_get_data(vector);
00156     const int      n         = cpl_vector_get_size(vector);
00157     cpl_error_code error     = CPL_ERROR_NONE;
00158     int            i;
00159     irplib_plot * plot;
00160 
00161 
00162     cpl_ensure_code(n > 0 , cpl_error_get_code());
00163 
00164     plot = irplib_mplot_open(pre);
00165 
00166     cpl_ensure_code(plot != NULL, cpl_error_get_code());
00167 
00168     error |= irplib_mplot_puts(plot, "plot '-' ");
00169 
00170     if (options != NULL) {
00171         error |= irplib_mplot_puts(plot, options);
00172     } else {
00173         char * myoptions = irplib_sprintf("t '%d-vector (%p) in "
00174                                                          "file %s line %u'",
00175                                                          n, (void*)vector, file,
00176                                                          line);
00177         assert(myoptions != NULL);
00178         error |= irplib_mplot_puts(plot, myoptions);
00179         cpl_free(myoptions);
00180     }
00181 
00182     error |= irplib_mplot_puts(plot, ";\n");
00183 
00184     for (i = 0; i < n; i++) {
00185         const int nlen = snprintf(snumber, LINE_SIZE, "%g\n", pvec[i]);
00186 
00187         assert(nlen > 0);
00188         error |= irplib_mplot_puts(plot, snumber);
00189         if (error) break;
00190     }
00191 
00192     error |= irplib_mplot_puts(plot, "e\n");
00193     error |= irplib_mplot_close(plot, post);
00194 
00195     return error ? cpl_error_get_code() : CPL_ERROR_NONE;
00196 }
00197 
00198 /*----------------------------------------------------------------------------*/
00224 /*----------------------------------------------------------------------------*/
00225 cpl_error_code irplib_bivector_plot_macro(const char          *   pre, 
00226                                           const char          *   options,
00227                                           const char          *   post,
00228                                           const cpl_bivector  *   bivector,
00229                                           const char          *   file, 
00230                                           const unsigned          line) 
00231 {
00232     char           snumber[LINE_SIZE];
00233     const int      n         = cpl_bivector_get_size(bivector);
00234     const double * pvecx     = cpl_bivector_get_x_data(bivector);
00235     const double * pvecy     = cpl_bivector_get_y_data(bivector);
00236     cpl_error_code error     = CPL_ERROR_NONE;
00237     irplib_plot  * plot;
00238     int            i;
00239 
00240 
00241     cpl_ensure_code(n > 0, cpl_error_get_code());
00242 
00243     plot = irplib_mplot_open(pre);
00244 
00245     cpl_ensure_code(plot != NULL, cpl_error_get_code());
00246 
00247     error |= irplib_mplot_puts(plot, "plot '-' ");
00248 
00249     if (options != NULL) {
00250         error |= irplib_mplot_puts(plot, options);
00251     } else {
00252         char * myoptions = irplib_sprintf("t '%d-bivector (%p) "
00253                                                          "in file %s line %u'",
00254                                                          n, (void*)bivector,
00255                                                          file, line);
00256 
00257         assert(myoptions != NULL);
00258         error |= irplib_mplot_puts(plot, myoptions);
00259         cpl_free(myoptions);
00260     }
00261 
00262     error |= irplib_mplot_puts(plot, ";\n");
00263 
00264     for (i = 0; i < n; i++) {
00265         const int nlen = snprintf(snumber, LINE_SIZE, "%g %g\n",
00266                                   pvecx[i], pvecy[i]);
00267 
00268         assert(nlen > 0);
00269         error |= irplib_mplot_puts(plot, snumber);
00270         if (error) break;
00271     }
00272 
00273     error |= irplib_mplot_puts(plot, "e\n");
00274     error |= irplib_mplot_close(plot, post);
00275 
00276     return error ? cpl_error_get_code() : CPL_ERROR_NONE;
00277 }
00278 
00279 /*----------------------------------------------------------------------------*/
00305 /*----------------------------------------------------------------------------*/
00306 cpl_error_code irplib_vectors_plot_macro(const char          *   pre, 
00307                                          const char          *   options,
00308                                          const char          *   post,
00309                                          const cpl_vector    **  vectors,
00310                                          int                     nvec)
00311 {
00312     double      *   pvecx ;
00313     double      *   pvecy ;
00314     int             vec_size = 0; /* Avoid uninit warning */
00315     char        **  names ;
00316     char            snumber[LINE_SIZE];
00317     char        *   sval;
00318     FILE        *   tmpfd ;
00319     irplib_plot *   plot ;
00320     int             i, j ;
00321     
00322     /* Check entries */
00323     cpl_ensure_code(vectors != NULL, CPL_ERROR_NULL_INPUT);
00324     cpl_ensure_code(nvec>=3, CPL_ERROR_NULL_INPUT);
00325     for (i=1 ; i<nvec ; i++) {
00326         cpl_ensure_code(vectors[i] != NULL, CPL_ERROR_NULL_INPUT);
00327         if (i==1) vec_size = cpl_vector_get_size(vectors[i]) ;
00328         else cpl_ensure_code(vec_size==cpl_vector_get_size(vectors[i]), 
00329                     CPL_ERROR_ILLEGAL_INPUT);
00330     }
00331     if (vectors[0] != NULL) {
00332         cpl_ensure_code(vec_size==cpl_vector_get_size(vectors[0]), 
00333                     CPL_ERROR_ILLEGAL_INPUT);
00334     }
00335 
00336     /* Get the X axis if passed */
00337     if (vectors[0] == NULL) pvecx = NULL ;
00338     else pvecx = cpl_vector_get_data(vectors[0]) ;
00339     
00340     /* Hold the files names */
00341     names = cpl_malloc((nvec-1)*sizeof(char*)) ;
00342     for (i=1 ; i<nvec ; i++)
00343     names[i-1] = irplib_sprintf("irplib_plot-%d", i) ;
00344     
00345     /* Open the plot */
00346     plot = irplib_mplot_open(pre);
00347 
00348     /* Loop on the signals to plot */
00349     for (i=1 ; i<nvec ; i++) {
00350         
00351         /* Get the current Y axis */
00352         pvecy = cpl_vector_get_data(vectors[i]) ;
00353 
00354         /* Open temporary file for output   */
00355     if ((tmpfd=fopen(names[i-1], "w"))==NULL) {
00356             irplib_mplot_close(plot, post);
00357             for (i=1 ; i<nvec ; i++) remove(names[i-1]) ; 
00358             for (i=1 ; i<nvec ; i++) cpl_free(names[i-1]) ; 
00359             cpl_free(names); 
00360             return CPL_ERROR_FILE_IO ;
00361         }
00362 
00363         /* Write data to this file  */
00364         for (j=0 ; j<vec_size ; j++) {
00365             int nlen;
00366 
00367             if (pvecx == NULL) {
00368                 nlen = snprintf(snumber, LINE_SIZE, "%g %g\n", (double)(j+1),
00369                                 pvecy[j]);
00370             } else {
00371                 nlen = snprintf(snumber, LINE_SIZE, "%g %g\n", pvecx[j],
00372                                 pvecy[j]);
00373             }
00374             assert(nlen > 0);
00375             if (fputs(snumber, tmpfd) < 0) break;
00376         }
00377         if (fclose(tmpfd) != 0) break;
00378         if (j != vec_size) break;
00379 
00380         /* Plot the file */
00381         if (i==1) {
00382             /* Plot the first signal */
00383             sval = irplib_sprintf("plot '%s' %s ;\n", names[i-1],
00384                                                  options);
00385         } else {
00386             sval = irplib_sprintf("replot '%s' t 'Vector %d' w "
00387                                                  "lines ;\n", names[i-1], i);
00388         }
00389         irplib_mplot_puts(plot, sval);
00390         cpl_free(sval);
00391     }
00392     irplib_mplot_close(plot, post);
00393     for (i=1 ; i<nvec ; i++) remove(names[i-1]) ; 
00394     for (i=1 ; i<nvec ; i++) cpl_free(names[i-1]) ; 
00395     cpl_free(names); 
00396     return cpl_error_get_code();
00397 }
00398 
00399 /*----------------------------------------------------------------------------*/
00428 /*----------------------------------------------------------------------------*/
00429 cpl_error_code irplib_bivectors_plot_macro(const char          *   pre, 
00430                        const char          **  options,
00431                        const char          *   post,
00432                        const cpl_bivector  **  bivectors,
00433                        int                     nbvec)
00434 {
00435     double      *   pvecx ;
00436     double      *   pvecy ;
00437     char        **  names ;
00438     char            snumber[LINE_SIZE];
00439     char        *   sval;
00440     FILE        *   tmpfd ;
00441     irplib_plot *   plot ;
00442     int             i, j ;
00443     
00444     /* Check entries */
00445     cpl_ensure_code(bivectors != NULL, CPL_ERROR_NULL_INPUT);
00446     cpl_ensure_code(options != NULL, CPL_ERROR_NULL_INPUT);
00447     cpl_ensure_code(nbvec>=1, CPL_ERROR_DATA_NOT_FOUND);
00448     for (i=0 ; i<nbvec ; i++) {
00449         cpl_ensure_code(bivectors[i] != NULL, CPL_ERROR_NULL_INPUT);
00450         cpl_ensure_code(  options[i] != NULL, CPL_ERROR_NULL_INPUT);
00451     }
00452 
00453     /* Hold the files names */
00454     names = cpl_malloc((nbvec)*sizeof(char*)) ;
00455     for (i=0 ; i<nbvec ; i++)
00456     names[i] = irplib_sprintf("irplib_plot-%d", i+1);
00457     
00458     /* Open the plot */
00459     plot = irplib_mplot_open(pre);
00460 
00461     /* Loop on the signals to plot */
00462     for (i=0 ; i<nbvec ; i++) {
00463     int vec_size;
00464         
00465         /* Get current vectors */
00466         pvecx = cpl_bivector_get_x_data(bivectors[i]) ;
00467         pvecy = cpl_bivector_get_y_data(bivectors[i]) ;
00468     vec_size = cpl_bivector_get_size(bivectors[i]) ;
00469 
00470         /* Open temporary file for output */
00471     if ((tmpfd=fopen(names[i], "w"))==NULL) {
00472             irplib_mplot_close(plot, post);
00473             for (i=0 ; i<nbvec ; i++) remove(names[i]) ;
00474             for (i=0 ; i<nbvec ; i++) cpl_free(names[i]) ;
00475             cpl_free(names);
00476             return CPL_ERROR_FILE_IO ;
00477         }
00478 
00479         /* Write data to this file  */
00480         for (j=0 ; j<vec_size ; j++) {
00481         const int nlen = snprintf(snumber, LINE_SIZE, "%g %g\n", pvecx[j],
00482                                       pvecy[j]);
00483             assert(nlen > 0);
00484             if (fputs(snumber, tmpfd) < 0) break;
00485         }
00486         if (fclose(tmpfd) != 0) break;
00487         if (j != vec_size) break;
00488 
00489     /* Plot the file using 'plot' the first time,
00490        otherwise use 'replot' */
00491     sval = irplib_sprintf("%splot '%s' %s ;\n", 
00492         i==0 ? "" : "re", names[i], options[i]);
00493     irplib_mplot_puts(plot, sval);
00494         cpl_free(sval);
00495     }
00496     irplib_mplot_close(plot, post);
00497     for (i=0 ; i<nbvec ; i++) remove(names[i]) ;
00498     for (i=0 ; i<nbvec ; i++) cpl_free(names[i]) ;
00499     cpl_free(names);
00500     return cpl_error_get_code();
00501 }
00502 
00503 /*----------------------------------------------------------------------------*/
00547 /*----------------------------------------------------------------------------*/
00548 cpl_error_code irplib_image_plot_macro(const char      *   pre, 
00549                                        const char      *   options,
00550                                        const char      *   post,
00551                                        const cpl_image *   image,
00552                                        const char      *   file, 
00553                                        const unsigned      line) 
00554 {
00555     char snumber[LINE_SIZE];
00556     const char    * irplib_plot_exe = irplib_mplot_imager();
00557     const int       nx = cpl_image_get_size_x(image);
00558     const int       ny = cpl_image_get_size_y(image);
00559     irplib_plot   * plot;
00560     cpl_image     * temp;
00561     const double  * pimage;
00562     unsigned char * raster = NULL;
00563     char          * dvi_options = (char *)options;
00564     char          * myoptions   = (char *)options;
00565     cpl_error_code  error = CPL_ERROR_NONE;
00566     int             i, j;
00567 
00568 
00569     cpl_ensure_code( nx > 0, cpl_error_get_code());
00570 
00571     plot = irplib_image_open(pre);
00572 
00573     cpl_ensure_code(plot != NULL, cpl_error_get_code());
00574 
00575     if (options == NULL || strlen(options) < 1) {
00576         dvi_options = irplib_sprintf("%dX%d-image-(%d) (%p) "
00577                                                     "in file %s line %u",
00578                                                     nx, ny, (int)
00579                                                     cpl_image_get_type(image),
00580                                                     (void*)image,
00581                                                     file, line);
00582         assert( dvi_options != NULL);
00583     }
00584 
00585     if (strstr(irplib_plot_exe, "gnuplot")) {
00586 
00587         if (cpl_image_get_type(image) == CPL_TYPE_DOUBLE) {
00588             temp = NULL;
00589             pimage = cpl_image_get_data_double(image);
00590         } else {
00591             temp = cpl_image_cast(image, CPL_TYPE_DOUBLE);
00592             pimage = cpl_image_get_data_double(temp);
00593         }
00594 
00595         error |= irplib_mplot_puts(plot, "splot '-' matrix ");
00596 
00597         if (myoptions == NULL || strlen(myoptions) < 1) {
00598 
00599             myoptions = irplib_sprintf("t '%s';",
00600                                                       dvi_options);
00601             assert( myoptions != NULL);
00602         }
00603         error |= irplib_mplot_puts(plot, myoptions);
00604         error |= irplib_mplot_puts(plot, ";\n");
00605 
00606         for (j = 0; j < ny; j++) {
00607             for (i = 0; i < nx; i++) {
00608                 const int nlen = snprintf(snumber, LINE_SIZE, "%g ",
00609                                           pimage[j*nx + i]);
00610 
00611                 assert(nlen > 0);
00612                 error |= irplib_mplot_puts(plot, snumber);
00613                 if (error) break;
00614             }
00615             error |= irplib_mplot_puts(plot, "\n");
00616             if (error) break;
00617         }
00618         error |= irplib_mplot_puts(plot, "e\n");
00619 
00620     } else {
00621         const size_t bsize = (size_t)(ny * nx); /* Octets in raster */
00622         int          nlen;
00623         const double tmin = cpl_image_get_min(image);
00624         double       tmax;
00625 
00626 
00627         /* Convert the image to one in the range [0; 256[ */
00628         if (cpl_image_get_type(image) == CPL_TYPE_DOUBLE)  {
00629             temp = cpl_image_subtract_scalar_create(image, tmin);
00630         } else {
00631             temp = cpl_image_cast(image, CPL_TYPE_DOUBLE);
00632             error |= cpl_image_subtract_scalar(temp, tmin);
00633         }
00634 
00635         tmax = cpl_image_get_max(temp);
00636 
00637         if (tmax > 0.0)
00638             error |= cpl_image_multiply_scalar(temp, 256.0*(1.0-DBL_EPSILON)
00639                                                /tmax);
00640 
00641         pimage = cpl_image_get_data_double(temp);
00642         assert(pimage != NULL);
00643 
00644         /* Create a PGM P5 header - with a maxval of 255 */
00645         nlen = snprintf(snumber, LINE_SIZE, "P5\n%d %d\n", nx, ny);
00646         assert(nlen > 0);
00647         error |= irplib_mplot_puts(plot, snumber);
00648 
00649         myoptions = irplib_sprintf("# True Value Range: "
00650                                                   "[%g;%g]\n",
00651                                                   tmin, tmin+tmax);
00652         assert( myoptions != NULL);
00653 
00654         error |= irplib_mplot_puts(plot, myoptions);
00655         cpl_free(myoptions);
00656 
00657         myoptions = irplib_sprintf("# %s\n255\n",
00658                                                   dvi_options);
00659 
00660         error |= irplib_mplot_puts(plot, myoptions);
00661 
00662         raster = (unsigned char *)cpl_malloc(bsize);
00663         for (j = 0; j < ny; j++) for (i = 0; i < nx; i++)
00664             raster[(ny-j-1)*nx + i] = (unsigned char) pimage[j*nx + i];
00665 
00666         error |= irplib_mplot_write(plot, (const char *) raster, bsize);
00667 
00668     }
00669 
00670 
00671     if (dvi_options != options) cpl_free(dvi_options);
00672     if (myoptions   != options) cpl_free(myoptions);
00673     cpl_free(raster);
00674     cpl_image_delete(temp);
00675 
00676     error |= irplib_mplot_close(plot, post);
00677 
00678     return error ? cpl_error_get_code() : CPL_ERROR_NONE;
00679 }
00680 
00681 /*----------------------------------------------------------------------------*/
00723 /*----------------------------------------------------------------------------*/
00724 cpl_error_code irplib_image_row_plot_macro(const char      *   pre,
00725                                            const char      *   options,
00726                                            const char      *   post,
00727                                            const cpl_image *   image,
00728                                            int                 firstrow, 
00729                                            int                 lastrow,
00730                                            int                 rowstep,
00731                                            const char      *   file,
00732                                            const unsigned      line) 
00733 {
00734     int nx, ny;
00735 
00736     cpl_ensure_code(image != NULL, CPL_ERROR_NULL_INPUT);
00737 
00738     nx = cpl_image_get_size_x(image);
00739     ny = cpl_image_get_size_y(image);
00740 
00741     cpl_ensure_code( nx > 0, CPL_ERROR_ILLEGAL_INPUT);
00742     cpl_ensure_code( ny > 0, CPL_ERROR_ILLEGAL_INPUT);
00743 
00744     cpl_ensure_code( rowstep > 0, CPL_ERROR_ILLEGAL_INPUT);
00745 
00746     cpl_ensure_code( firstrow > 0,    CPL_ERROR_ACCESS_OUT_OF_RANGE);
00747     cpl_ensure_code( firstrow <= lastrow, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00748     cpl_ensure_code( lastrow  <= ny,  CPL_ERROR_ACCESS_OUT_OF_RANGE);
00749    
00750     do {
00751 
00752         char snumber[LINE_SIZE];
00753         double * pimage;
00754         cpl_image * temp = NULL;
00755         char * myoptions = (char *)options;
00756         int i, j;
00757 
00758         irplib_plot * plot = irplib_mplot_open(pre);
00759 
00760         do {
00761             if (cpl_error_get_code()) break;
00762 
00763             if (irplib_mplot_puts(plot, "plot")) break;
00764             for (j = firstrow-1; j < lastrow; j += rowstep) {
00765                 if (j > firstrow-1 && irplib_mplot_puts(plot, ",")) break;
00766                 if (irplib_mplot_puts(plot, " '-' ")) break;
00767 
00768                 if (myoptions == NULL || strlen(myoptions) < 1) {
00769 
00770                     myoptions = (j == firstrow-1)
00771                         ? irplib_sprintf("t 'Row %d %dX%d-image-"
00772                                                  "(%d) (%p) in file %s "
00773                                                  "line %u'", j, nx, ny,
00774                                                  (int)cpl_image_get_type(image),
00775                                                  (void*)image, file, line)
00776                         : irplib_sprintf("t 'Row %d of the same "
00777                                                         "image'", j);
00778 
00779                         assert( myoptions != NULL);
00780 
00781                 }
00782                 if (irplib_mplot_puts(plot, myoptions    )) break;
00783                 if (myoptions != options) {
00784                     cpl_free(myoptions);
00785                     myoptions = NULL;
00786                 }
00787             }
00788             if (irplib_mplot_puts(plot, ";\n      ")) break;
00789 
00790             if (cpl_image_get_type(image) == CPL_TYPE_DOUBLE) {
00791                 pimage = cpl_image_get_data_double(image);
00792             } else {
00793                 temp = cpl_image_cast(image, CPL_TYPE_DOUBLE);
00794                 pimage = cpl_image_get_data_double(temp);
00795             }
00796 
00797             assert(pimage != NULL);
00798 
00799             for (j = firstrow-1; j < lastrow; j += rowstep) {
00800                 for (i = 0; i < nx; i++) {
00801                     const int nlen = snprintf(snumber, LINE_SIZE, "%g\n",
00802                                               pimage[j * nx + i]);
00803 
00804                     assert(nlen > 0);
00805                     if (irplib_mplot_puts(plot, snumber)) break;
00806                 }
00807                 if (i != nx) break;
00808                 if (irplib_mplot_puts(plot, "e\n")) break;
00809             }
00810             if (j != lastrow) break;
00811 
00812         } while (0);
00813 
00814         if (myoptions != options) cpl_free(myoptions);
00815         cpl_image_delete(temp);
00816 
00817         irplib_mplot_close(plot, post);
00818 
00819     } while (0);
00820 
00821     return cpl_error_get_code();
00822 }
00823 
00824 /*----------------------------------------------------------------------------*/
00866 /*----------------------------------------------------------------------------*/
00867 cpl_error_code irplib_image_col_plot_macro(const char      *   pre,
00868                                            const char      *   options,
00869                                            const char      *   post,
00870                                            const cpl_image *   image,
00871                                            int                 firstcol, 
00872                                            int                 lastcol,
00873                                            int                 colstep,
00874                                            const char      *   file,
00875                                            const unsigned      line) 
00876 {
00877     int nx, ny;
00878     cpl_ensure_code(image != NULL, CPL_ERROR_NULL_INPUT);
00879 
00880     nx = cpl_image_get_size_x(image);
00881     ny = cpl_image_get_size_y(image);
00882 
00883     cpl_ensure_code( nx > 0, CPL_ERROR_ILLEGAL_INPUT);
00884     cpl_ensure_code( ny > 0, CPL_ERROR_ILLEGAL_INPUT);
00885 
00886     cpl_ensure_code( colstep > 0, CPL_ERROR_ILLEGAL_INPUT);
00887 
00888     cpl_ensure_code( firstcol > 0,    CPL_ERROR_ACCESS_OUT_OF_RANGE);
00889     cpl_ensure_code( firstcol <= lastcol, CPL_ERROR_ACCESS_OUT_OF_RANGE);
00890     cpl_ensure_code( lastcol  <= nx,  CPL_ERROR_ACCESS_OUT_OF_RANGE);
00891    
00892     do {
00893 
00894         char snumber[LINE_SIZE];
00895         double * pimage;
00896         cpl_image * temp = NULL;
00897         char * myoptions = (char *)options;
00898         int i, j;
00899 
00900         irplib_plot * plot = irplib_mplot_open(pre);
00901 
00902         do {
00903             if (cpl_error_get_code()) break;
00904 
00905             if (irplib_mplot_puts(plot, "plot")) break;
00906             for (i = firstcol-1; i < lastcol; i += colstep) {
00907                 if (i > firstcol-1 && irplib_mplot_puts(plot, ",")) break;
00908                 if (irplib_mplot_puts(plot, " '-' ")) break;
00909                 if (myoptions == NULL || strlen(myoptions) < 1) {
00910 
00911                     myoptions = (i == firstcol-1)
00912                         ? irplib_sprintf("t 'Column %d of a "
00913                                                  "%dX%d-image-(%d) (%p) "
00914                                                  "in file %s line %u'",
00915                                                  i, nx, ny,
00916                                                  (int)cpl_image_get_type(image),
00917                                                  (void*)image, file, line)
00918                         : irplib_sprintf("t 'Column %d of the "
00919                                                         "same image'", i);
00920                     assert( myoptions != NULL);
00921 
00922                 }
00923                 if (irplib_mplot_puts(plot, myoptions  )) break;
00924                 if (myoptions != options) {
00925                     cpl_free(myoptions);
00926                     myoptions = NULL;
00927                 }
00928             }
00929             if (irplib_mplot_puts(plot, ";\n      ")) break;
00930 
00931             if (cpl_image_get_type(image) == CPL_TYPE_DOUBLE) {
00932                 pimage = cpl_image_get_data_double(image);
00933             } else {
00934                 temp = cpl_image_cast(image, CPL_TYPE_DOUBLE);
00935                 pimage = cpl_image_get_data_double(temp);
00936             }
00937 
00938             for (i = firstcol-1; i < lastcol; i += colstep) {
00939                 for (j = 0; j < ny; j++) {
00940                     const int nlen = snprintf(snumber, LINE_SIZE, "%g\n",
00941                                               pimage[j * nx + i]);
00942 
00943                     assert(nlen > 0);
00944                     if (irplib_mplot_puts(plot, snumber)) break;
00945                 }
00946                 if (j != ny) break;
00947                 if (irplib_mplot_puts(plot, "e\n")) break;
00948             }
00949             if (i != lastcol) break;
00950 
00951         } while (0);
00952 
00953         if (myoptions != options) cpl_free(myoptions);
00954 
00955         cpl_image_delete(temp);
00956 
00957         irplib_mplot_close(plot, post);
00958 
00959     } while (0);
00960 
00961     return cpl_error_get_code();
00962 }
00963 
00964 /*----------------------------------------------------------------------------*/
00990 /*----------------------------------------------------------------------------*/
00991 cpl_error_code irplib_table_plot_macro(const char      *   pre, 
00992                                        const char      *   options,
00993                                        const char      *   post,
00994                                        const cpl_table *   tab,
00995                                        const char      *   xlab, 
00996                                        const char      *   ylab,
00997                                        const char      *   file, 
00998                                        const unsigned      line) 
00999 {
01000     int                 n;
01001     cpl_table       *   temp;
01002     cpl_bivector    *   bivect;
01003     cpl_vector      *   xvec;
01004     cpl_vector      *   yvec;
01005     cpl_type            type_x;
01006     cpl_type            type_y;
01007     int                 invalid_x;
01008     int                 invalid_y;
01009 
01010     /* Check input */
01011     cpl_ensure_code(tab, CPL_ERROR_NULL_INPUT);
01012     cpl_ensure_code(xlab, CPL_ERROR_NULL_INPUT);
01013     cpl_ensure_code(ylab, CPL_ERROR_NULL_INPUT);
01014     n = cpl_table_get_nrow(tab);
01015     cpl_ensure_code(n>0, CPL_ERROR_ILLEGAL_INPUT);
01016 
01017     cpl_ensure_code(cpl_table_has_column(tab, xlab), CPL_ERROR_DATA_NOT_FOUND);
01018     cpl_ensure_code(cpl_table_has_column(tab, ylab), CPL_ERROR_DATA_NOT_FOUND);
01019 
01020     type_x = cpl_table_get_column_type(tab, xlab);
01021     type_y = cpl_table_get_column_type(tab, ylab);
01022 
01023     cpl_ensure_code(type_x == CPL_TYPE_INT ||
01024             type_x == CPL_TYPE_FLOAT ||
01025             type_x == CPL_TYPE_DOUBLE, CPL_ERROR_INVALID_TYPE);
01026     cpl_ensure_code(type_y == CPL_TYPE_INT ||
01027             type_y == CPL_TYPE_FLOAT ||
01028             type_y == CPL_TYPE_DOUBLE, CPL_ERROR_INVALID_TYPE);
01029         
01030     invalid_x = cpl_table_count_invalid(tab, xlab);
01031     invalid_y = cpl_table_count_invalid(tab, ylab);
01032 
01033     if (invalid_x == n || invalid_y == n) return cpl_error_get_code();
01034 
01035     /* Cast columns to CPL_TYPE_DOUBLE and remove invalid entries */
01036     if (type_x != CPL_TYPE_DOUBLE || invalid_x > 0 ||
01037     type_y != CPL_TYPE_DOUBLE || invalid_y > 0)
01038     {
01039         temp = cpl_table_new(n);
01040         
01041         cpl_table_duplicate_column(temp, "X", (cpl_table*)tab, xlab);
01042         cpl_table_cast_column(temp, "X", "Xdouble", CPL_TYPE_DOUBLE);
01043         
01044         cpl_table_duplicate_column(temp, "Y", (cpl_table*)tab, ylab);
01045         cpl_table_cast_column(temp, "Y", "Ydouble", CPL_TYPE_DOUBLE);
01046         
01047         /* Remove rows with one or more invalid elements.
01048            No columns will be removed because each column
01049            contains at least one valid element. */
01050 
01051         cpl_table_erase_invalid(temp);
01052         
01053         xvec = cpl_vector_wrap(cpl_table_get_nrow(temp),
01054                    cpl_table_get_data_double(temp, "Xdouble"));
01055         
01056         yvec = cpl_vector_wrap(cpl_table_get_nrow(temp),
01057                    cpl_table_get_data_double(temp, "Ydouble"));
01058     }
01059     else
01060     {
01061         temp = NULL;
01062         
01063         xvec = cpl_vector_wrap(n, cpl_table_get_data_double((cpl_table*)tab,
01064                                                                 xlab));
01065         yvec = cpl_vector_wrap(n, cpl_table_get_data_double((cpl_table*)tab,
01066                                                                 ylab));
01067     }
01068     
01069     bivect = cpl_bivector_wrap_vectors(xvec, yvec);
01070     irplib_bivector_plot_macro(pre, options, post, bivect, file, line);
01071     
01072     cpl_bivector_unwrap_vectors(bivect);
01073     cpl_vector_unwrap(xvec);
01074     cpl_vector_unwrap(yvec);
01075     if (temp != NULL) cpl_table_delete(temp);
01076 
01077     return cpl_error_get_code();
01078 }
01079 
01082 /*----------------------------------------------------------------------------*/
01091 /*----------------------------------------------------------------------------*/
01092 static const char * irplib_mplot_plotter(void)
01093 {
01094     return getenv("IRPLIB_PLOTTER") ? getenv("IRPLIB_PLOTTER")
01095         : "gnuplot -persist";
01096 }
01097 
01098 /*----------------------------------------------------------------------------*/
01111 /*----------------------------------------------------------------------------*/
01112 static const char * irplib_mplot_imager(void)
01113 {
01114     return getenv("IRPLIB_IMAGER") ? getenv("IRPLIB_IMAGER")
01115         : irplib_mplot_plotter();
01116 }
01117 
01118 /*----------------------------------------------------------------------------*/
01142 /*----------------------------------------------------------------------------*/
01143 static irplib_plot * irplib_mplot_open(const char * options)
01144 {
01145     const char * irplib_plot_exe = irplib_mplot_plotter();
01146     irplib_plot * plot = NULL;
01147 
01148     if (irplib_plot_exe == NULL) return NULL;
01149 
01150     cpl_ensure(strstr(irplib_plot_exe, "gnuplot"), CPL_ERROR_UNSUPPORTED_MODE,
01151                NULL);
01152 
01153 #if HAS_PROCESS_IO
01154     /* FIXME: The getuid() call should have its own HAVE_GETUID */
01155     /* Disallow popen() calls when running as a different user */
01156     cpl_ensure(getuid() == geteuid(), CPL_ERROR_UNSUPPORTED_MODE, NULL);
01157 
01158     plot = cpl_calloc(1, sizeof(irplib_plot));
01159 
01160     plot->pipe = popen(irplib_plot_exe, "w");
01161 
01162     cpl_ensure(plot->pipe != NULL, CPL_ERROR_FILE_NOT_FOUND, NULL);
01163 
01164 #else
01165     cpl_ensure(0, CPL_ERROR_UNSUPPORTED_MODE, NULL);
01166 #endif
01167 
01168     if (irplib_mplot_puts(plot, options)) {
01169         (void)irplib_mplot_close(plot, "");
01170         cpl_ensure(0, cpl_error_get_code(), NULL);
01171     }
01172 
01173     return plot;
01174 }
01175 
01176 /*----------------------------------------------------------------------------*/
01201 /*----------------------------------------------------------------------------*/
01202 static irplib_plot * irplib_image_open(const char * options)
01203 {
01204     const char  * irplib_plot_exe = irplib_mplot_imager();
01205     irplib_plot * plot;
01206 
01207 
01208     if (irplib_plot_exe == NULL) return NULL;
01209 
01210 #if HAS_PROCESS_IO
01211     plot = cpl_calloc(1, sizeof(irplib_plot));
01212 
01213     plot->pipe = popen(irplib_plot_exe, "w");
01214 #else
01215     cpl_ensure(0, CPL_ERROR_UNSUPPORTED_MODE, NULL);
01216 #endif
01217 
01218     cpl_ensure(plot->pipe != NULL, CPL_ERROR_FILE_NOT_FOUND, NULL);
01219 
01220     if (irplib_mplot_puts(plot, options)) {
01221         (void)irplib_mplot_close(plot, "");
01222         cpl_ensure(0, cpl_error_get_code(), NULL);
01223     }
01224 
01225     return plot;
01226 }
01227 
01228 /*----------------------------------------------------------------------------*/
01240 /*----------------------------------------------------------------------------*/
01241 static cpl_error_code irplib_mplot_close(irplib_plot * plot,
01242                                          const char  * options)
01243 {
01244     cpl_error_code error;
01245 
01246 
01247     cpl_ensure_code(plot != NULL, CPL_ERROR_NULL_INPUT);
01248 
01249     error = irplib_mplot_puts(plot, options);
01250 
01251 #if HAS_PROCESS_IO
01252     if (pclose(plot->pipe) == -1 && !error) error = CPL_ERROR_FILE_IO;
01253 #else
01254     if (!error) error = CPL_ERROR_UNSUPPORTED_MODE;
01255 #endif
01256 
01257     cpl_free(plot);
01258 
01259     cpl_ensure_code(!error, error);
01260 
01261     return CPL_ERROR_NONE;
01262 }
01263 
01264 /*----------------------------------------------------------------------------*/
01276 /*----------------------------------------------------------------------------*/
01277 static cpl_error_code irplib_mplot_puts(irplib_plot * plot, const char * cmd)
01278 {
01279 
01280     cpl_ensure_code(plot != NULL, CPL_ERROR_NULL_INPUT);
01281 
01282     if (cmd == NULL || strlen(cmd) == 0) return CPL_ERROR_NONE;
01283 
01284     assert(plot->pipe != NULL);
01285 
01286     cpl_ensure_code(fputs(cmd, plot->pipe) >= 0, CPL_ERROR_FILE_IO);
01287 
01288     return CPL_ERROR_NONE;
01289 }
01290 
01291 /*----------------------------------------------------------------------------*/
01304 /*----------------------------------------------------------------------------*/
01305 static cpl_error_code irplib_mplot_write(irplib_plot     *   plot, 
01306                                          const char      *   buffer,
01307                                          size_t              length)
01308 {
01309     cpl_ensure_code(plot   != NULL, CPL_ERROR_NULL_INPUT);
01310     cpl_ensure_code(buffer != NULL, CPL_ERROR_NULL_INPUT);
01311     cpl_ensure_code(length > 0,     CPL_ERROR_ILLEGAL_INPUT);
01312 
01313     assert(plot->pipe != NULL);
01314 
01315     cpl_ensure_code(fwrite(buffer, 1, length, plot->pipe) == length,
01316                     CPL_ERROR_FILE_IO);
01317 
01318     return CPL_ERROR_NONE;
01319 }

Generated on Wed Jan 17 08:33:41 2007 for SINFONI Pipeline Reference Manual by  doxygen 1.4.4