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

plimage.c

Go to the documentation of this file.
00001 // plimage()
00002 //
00003 // Author: Alessandro Mirone, Nov 2001
00004 // Adapted: Joao Cardoso
00005 // Updated: Hezekiah Carty 2008
00006 //
00007 // Copyright (C) 2004  Alan W. Irwin
00008 //
00009 // This file is part of PLplot.
00010 //
00011 // PLplot is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Library General Public License as published
00013 // by the Free Software Foundation; either version 2 of the License, or
00014 // (at your option) any later version.
00015 //
00016 // PLplot is distributed in the hope that it will be useful,
00017 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 // GNU Library General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Library General Public License
00022 // along with PLplot; if not, write to the Free Software
00023 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
00024 //
00025 
00026 #include "plplotP.h"
00027 
00028 #define COLOR_MIN        0.0
00029 #define COLOR_MAX        1.0
00030 #define COLOR_NO_PLOT    ( -1.0 )
00031 
00032 // Get better names, those are too cryptic!
00033 //
00034 // ZEROW2B: zero writing to buffer ?
00035 // ZEROW2D: zero writing to display ?
00036 // ONEW2B: set writing to buffer ?
00037 // ONEW2D: set writing to display ?
00038 //
00039 
00040 void
00041 NoBufferNoPixmap()
00042 {
00043     PLINT op = ZEROW2B;
00044 
00045     plsc->plbuf_write = 0; // TODO: store previous state
00046     plP_esc( PLESC_EXPOSE, NULL );
00047     plP_esc( PLESC_IMAGEOPS, &op );
00048 }
00049 
00050 void
00051 RestoreWrite2BufferPixmap()
00052 {
00053     PLINT op = ONEW2B;
00054 
00055     plsc->plbuf_write = 1; // TODO: revert from previous state
00056     plP_esc( PLESC_IMAGEOPS, &op );
00057 }
00058 
00059 void
00060 disabledisplay()
00061 {
00062     PLINT op = ZEROW2D;
00063 
00064     plP_esc( PLESC_IMAGEOPS, &op );
00065 }
00066 
00067 void
00068 enabledisplay()
00069 {
00070     PLINT op = ONEW2D;
00071 
00072     plP_esc( PLESC_IMAGEOPS, &op );
00073     plP_esc( PLESC_EXPOSE, NULL );
00074 }
00075 
00076 
00077 
00078 //
00079 // NOTE: The plshade* functions require that both pltr and pltr_data are set
00080 // in order for pltr to be used.  plimageslow does NOT require this, so it is
00081 // up to the user to make sure pltr_data is something non-NULL if pltr
00082 // requires it.
00083 // Plottable values in idata must be scaled between COLOR_MIN and COLOR_MAX.
00084 // This is an internal function, and should not be used directly.  Its
00085 // interface may change.
00086 //
00087 void
00088 plimageslow( PLFLT *idata, PLINT nx, PLINT ny,
00089              PLFLT xmin, PLFLT ymin, PLFLT dx, PLFLT dy,
00090              void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
00091              PLPointer pltr_data )
00092 {
00093     // Indices
00094     PLINT ix, iy, i;
00095     // Float coordinates
00096     PLFLT xf[4], yf[4];
00097     // Translated (by pltr) coordinates
00098     PLFLT tx, ty;
00099     // The corners of a single filled region
00100     // int corners[4]; - unreferenced
00101     // The color to use in the fill
00102     PLFLT color;
00103 
00104     plP_esc( PLESC_START_RASTERIZE, NULL );
00105     for ( ix = 0; ix < nx; ix++ )
00106     {
00107         for ( iy = 0; iy < ny; iy++ )
00108         {
00109             // Only plot values within in appropriate range
00110             color = idata[ix * ny + iy];
00111             if ( color == COLOR_NO_PLOT )
00112                 continue;
00113 
00114             // The color value has to be scaled to 0.0 -> 1.0 plcol1 color values
00115             plcol1( color / COLOR_MAX );
00116 
00117             xf[0] = xf[1] = ix;
00118             xf[2] = xf[3] = ix + 1;
00119             yf[0] = yf[3] = iy;
00120             yf[1] = yf[2] = iy + 1;
00121 
00122             if ( pltr )
00123             {
00124                 for ( i = 0; i < 4; i++ )
00125                 {
00126                     // Translate the points
00127                     ( *pltr )( xf[i], yf[i], &tx, &ty, pltr_data );
00128                     xf[i] = tx;
00129                     yf[i] = ty;
00130                 }
00131             }
00132             else
00133             {
00134                 for ( i = 0; i < 4; i++ )
00135                 {
00136                     // Automatic translation to the specified plot area
00137                     xf[i] = xmin + xf[i] * dx;
00138                     yf[i] = ymin + yf[i] * dy;
00139                 }
00140             }
00141             plfill( 4, xf, yf );
00142         }
00143     }
00144     plP_esc( PLESC_END_RASTERIZE, NULL );
00145 }
00146 
00147 void
00148 grimage( short *x, short *y, unsigned short *z, PLINT nx, PLINT ny )
00149 {
00150     plsc->dev_ix    = x;
00151     plsc->dev_iy    = y;
00152     plsc->dev_z     = z;
00153     plsc->dev_nptsX = nx;
00154     plsc->dev_nptsY = ny;
00155 
00156     plP_esc( PLESC_IMAGE, NULL );
00157 }
00158 
00159 //--------------------------------------------------------------------------
00160 // plimagefr
00161 //
00162 // arguments are
00163 //   idata: array containing image data
00164 //   nx: dimension of the array in the X axis.
00165 //   ny: dimension of the  array in the Y axis
00166 //   The array data is indexed like data[ix][iy]
00167 //
00168 //   xmin, xmax, ymin, ymax:
00169 //       data[0][0] corresponds to (xmin,ymin)
00170 //       data[nx-1][ny-1] to (xmax,ymax)
00171 //
00172 //   zmin, zmax:
00173 //       only data within bounds zmin <= data <= zmax will be
00174 //       plotted. If zmin == zmax, all data will be ploted.
00175 //
00176 //   valuemin, valuemax:
00177 //       The minimum and maximum values to use for value -> color
00178 //       mappings.  A value in idata of valuemin or less will have
00179 //       color 0.0 and a value in idata of valuemax or greater will
00180 //       have color 1.0.  Values between valuemin and valuemax will
00181 //       map linearly to to the colors between 0.0 and 1.0.
00182 //       If you do not want to display values outside of the
00183 //       (valuemin -> valuemax) range, then set zmin = valuemin and
00184 //       zmax = valuemax.
00185 //       This allows for multiple plots to use the same color scale
00186 //       with a consistent value -> color mapping, regardless of the
00187 //       image content.
00188 //
00189 //--------------------------------------------------------------------------
00190 void
00191 c_plimagefr( const PLFLT **idata, PLINT nx, PLINT ny,
00192              PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
00193              PLFLT valuemin, PLFLT valuemax,
00194              void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
00195              PLPointer pltr_data )
00196 {
00197     plfimagefr( plf2ops_c(), (PLPointer) idata, nx, ny,
00198         xmin, xmax, ymin, ymax, zmin, zmax,
00199         valuemin, valuemax, pltr, pltr_data );
00200 }
00201 
00202 void
00203 plfimagefr( PLF2OPS idataops, PLPointer idatap, PLINT nx, PLINT ny,
00204             PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
00205             PLFLT valuemin, PLFLT valuemax,
00206             void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
00207             PLPointer pltr_data )
00208 {
00209     PLINT ix, iy;
00210     PLFLT dx, dy;
00211     // z holds scaled image pixel values
00212     PLFLT *z;
00213     // This is used when looping through the image array, checking to
00214     // make sure the values are within an acceptable range.
00215     PLFLT datum;
00216     // Color palette 0 color in use before the plimage* call
00217     PLINT init_color;
00218     // Color range
00219     PLFLT color_min, color_max, color_range;
00220 
00221     if ( plsc->level < 3 )
00222     {
00223         plabort( "plimagefr: window must be set up first" );
00224         return;
00225     }
00226 
00227     if ( nx <= 0 || ny <= 0 )
00228     {
00229         plabort( "plimagefr: nx and ny must be positive" );
00230         return;
00231     }
00232 
00233     if ( ( z = (PLFLT *) malloc( ny * nx * sizeof ( PLFLT ) ) ) == NULL )
00234     {
00235         plexit( "plimagefr: Insufficient memory" );
00236     }
00237 
00238     // Save the currently-in-use color.
00239     init_color = plsc->icol0;
00240 
00241     // If no acceptable data range is given, then set the min/max data range
00242     // to include all of the given data.
00243     if ( zmin == zmax )
00244     {
00245         // Find the minimum and maximum values in the image
00246         idataops->minmax( idatap, nx, ny, &zmin, &zmax );
00247     }
00248 
00249     // Calculate the size of the color range to use
00250     color_min   = plsc->cmap1_min;
00251     color_max   = plsc->cmap1_max;
00252     color_range = color_max - color_min;
00253 
00254     // Go through the image values and scale them to fit in
00255     // the COLOR_MIN to COLOR_MAX range.
00256     // Any values greater than valuemax are set to valuemax,
00257     // and values less than valuemin are set to valuemin.
00258     // Any values outside of zmin to zmax are flagged so they
00259     // are not plotted.
00260     for ( ix = 0; ix < nx; ix++ )
00261     {
00262         for ( iy = 0; iy < ny; iy++ )
00263         {
00264             if ( valuemin == valuemax )
00265             {
00266                 // If valuemin == valuemax, avoid dividing by zero.
00267                 z[ix * ny + iy] = ( color_max + color_min ) / 2.0;
00268             }
00269             else
00270             {
00271                 datum = idataops->get( idatap, ix, iy );
00272                 if ( isnan( datum ) || datum < zmin || datum > zmax )
00273                 {
00274                     // Set to a guaranteed-not-to-plot value
00275                     z[ix * ny + iy] = COLOR_NO_PLOT;
00276                 }
00277                 else
00278                 {
00279                     if ( datum < valuemin )
00280                     {
00281                         datum = valuemin;
00282                     }
00283                     else if ( datum > valuemax )
00284                     {
00285                         datum = valuemax;
00286                     }
00287                     // Set to a value scaled between color_min and color_max.
00288                     z[ix * ny + iy] =
00289                         color_min + ( datum - valuemin + COLOR_MIN ) / ( valuemax - valuemin ) * COLOR_MAX * color_range;
00290                 }
00291             }
00292         }
00293     }
00294 
00295     // dx and dy are the plot-coordinates pixel sizes for an untransformed
00296     // image
00297     dx = ( xmax - xmin ) / (PLFLT) nx;
00298     dy = ( ymax - ymin ) / (PLFLT) ny;
00299 
00300     plP_image( z, nx, ny, xmin, ymin, dx, dy, pltr, pltr_data );
00301 
00302     plcol0( init_color );
00303 
00304     free( z );
00305 }
00306 
00307 //--------------------------------------------------------------------------
00308 // plimage
00309 //
00310 // arguments are
00311 //   idata: array containing image data
00312 //   nx: dimension of the array in the X axis.
00313 //   ny: dimension of the  array in the Y axis
00314 //   The array data is indexed like data[ix][iy]
00315 //
00316 //   xmin, xmax, ymin, ymax:
00317 //       data[0][0] corresponds to (xmin,ymin)
00318 //       data[nx-1][ny-1] to (xmax,ymax)
00319 //
00320 //   zmin, zmax:
00321 //       only data within bounds zmin <= data <= zmax will be
00322 //       plotted. If zmin == zmax, all data will be ploted.
00323 //
00324 //   Dxmin, Dxmax, Dymin, Dymax:
00325 //       plots only the window of points whose(x,y)'s fall
00326 //       inside the [Dxmin->Dxmax]X[Dymin->Dymax] window
00327 //
00328 //--------------------------------------------------------------------------
00329 void
00330 c_plimage( const PLFLT **idata, PLINT nx, PLINT ny,
00331            PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
00332            PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax )
00333 {
00334     plfimage( plf2ops_c(), (PLPointer) idata, nx, ny,
00335         xmin, xmax, ymin, ymax, zmin, zmax,
00336         Dxmin, Dxmax, Dymin, Dymax );
00337 }
00338 
00339 void
00340 plfimage( PLF2OPS idataops, PLPointer idatap, PLINT nx, PLINT ny,
00341           PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
00342           PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax )
00343 {
00344     PLINT   ix, iy, ixx, iyy, xm, ym, nnx, nny;
00345     PLFLT   data_min, data_max, dx, dy;
00346     // z holds the subimage (Dxmin, Dymin) - (Dxmax, Dymax)
00347     PLFLT   **z;
00348     PLF2OPS zops;
00349     // Was any space allocated for z?
00350     PLBOOL  copied;
00351     copied = FALSE;
00352 
00353     if ( nx <= 0 || ny <= 0 )
00354     {
00355         plabort( "plimage: nx and ny must be positive" );
00356         return;
00357     }
00358 
00359     if ( Dxmin < xmin || Dxmax > xmax || Dymin < ymin || Dymax > ymax )
00360     {
00361         plabort( "plimage: Dxmin or Dxmax or Dymin or Dymax not compatible with xmin or xmax or ymin or ymax." );
00362         return;
00363     }
00364 
00365     if ( Dxmax < Dxmin || xmax < xmin || Dymax < Dymin || ymax < ymin )
00366     {
00367         plabort( "plimage: All (Dxmin < Dxmax) and (Dymin < Dymax) and (xmin < xmax) and (ymin < ymax) must hold." );
00368         return;
00369     }
00370 
00371     // Find the minimum and maximum values in the image.  Use these values to
00372     // for the color scale range.
00373     idataops->minmax( idatap, nx, ny, &data_min, &data_max );
00374 
00375     if ( xmin == Dxmin && xmax == Dxmax && ymin == Dymin && ymax == Dymax )
00376     {
00377         // If the whole image should be shown, then no copying is needed.
00378         z    = (PLFLT **) idatap;
00379         zops = idataops;
00380         nnx  = nx;
00381         nny  = ny;
00382     }
00383     else
00384     {
00385         // dx and dy are the plot-coordinates pixel sizes for an untransformed
00386         // image
00387         dx = ( xmax - xmin ) / (PLFLT) nx;
00388         dy = ( ymax - ymin ) / (PLFLT) ny;
00389 
00390         // Pixel dimensions of the (Dxmin, Dymin) to (Dxmax, Dymax) box
00391         nnx = (PLINT) ceil( ( Dxmax - Dxmin ) / dx );
00392         nny = (PLINT) ceil( ( Dymax - Dymin ) / dy );
00393 
00394         // Call plimagefr with the value -> color range mapped to the minimum
00395         // Offsets for the idata indices to select
00396         // (Dxmin, Dymin) to (Dxmax, Dymax)
00397         xm = (PLINT) floor( ( Dxmin - xmin ) / dx );
00398         ym = (PLINT) floor( ( Dymin - ymin ) / dy );
00399 
00400         // Allocate space for the sub-image
00401         plAlloc2dGrid( &z, nnx, nny );
00402         zops = plf2ops_c();
00403 
00404         // Go through the image and select the pixels within the given
00405         // (Dxmin, Dymin) - (Dxmax, Dymax) window.
00406         ixx = -1;
00407         for ( ix = xm; ix < xm + nnx; ix++ )
00408         {
00409             ixx++; iyy = 0;
00410             for ( iy = ym; iy < ym + nny; iy++ )
00411             {
00412                 z[ixx][iyy++] = idataops->get( idatap, ix, iy );
00413             }
00414         }
00415 
00416         // Set the appropriate values to pass in to plimagefr
00417         copied = TRUE;
00418     }
00419 
00420     plfimagefr( zops, (PLPointer) z, nnx, nny, Dxmin, Dxmax, Dymin, Dymax, zmin, zmax,
00421         data_min, data_max, NULL, NULL );
00422 
00423     // Only free the memory if it was allocated by us...
00424     if ( copied == TRUE )
00425     {
00426         plFree2dGrid( z, nnx, nny );
00427     }
00428 }

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