PLplot  5.10.0
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 //
00060 // Unused functions - comment out
00061 //
00062 //void
00063 //disabledisplay()
00064 //{
00065 //    PLINT op = ZEROW2D;
00066 //
00067 //    plP_esc( PLESC_IMAGEOPS, &op );
00068 //}
00069 //
00070 //void
00071 //enabledisplay()
00072 //{
00073 //    PLINT op = ONEW2D;
00074 //
00075 //    plP_esc( PLESC_IMAGEOPS, &op );
00076 //    plP_esc( PLESC_EXPOSE, NULL );
00077 //}
00078 //
00079 
00080 
00081 //
00082 // NOTE: The plshade* functions require that both pltr and pltr_data are set
00083 // in order for pltr to be used.  plimageslow does NOT require this, so it is
00084 // up to the user to make sure pltr_data is something non-NULL if pltr
00085 // requires it.
00086 // Plottable values in idata must be scaled between COLOR_MIN and COLOR_MAX.
00087 // This is an internal function, and should not be used directly.  Its
00088 // interface may change.
00089 //
00090 void
00091 plimageslow( PLFLT *idata, PLINT nx, PLINT ny,
00092              PLFLT xmin, PLFLT ymin, PLFLT dx, PLFLT dy,
00093              void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
00094              PLPointer pltr_data )
00095 {
00096     // Indices
00097     PLINT ix, iy, i;
00098     // Float coordinates
00099     PLFLT xf[4], yf[4];
00100     // Translated (by pltr) coordinates
00101     PLFLT tx, ty;
00102     // The corners of a single filled region
00103     // int corners[4]; - unreferenced
00104     // The color to use in the fill
00105     PLFLT color;
00106 
00107     plP_esc( PLESC_START_RASTERIZE, NULL );
00108     for ( ix = 0; ix < nx; ix++ )
00109     {
00110         for ( iy = 0; iy < ny; iy++ )
00111         {
00112             // Only plot values within in appropriate range
00113             color = idata[ix * ny + iy];
00114             if ( color == COLOR_NO_PLOT )
00115                 continue;
00116 
00117             // The color value has to be scaled to 0.0 -> 1.0 plcol1 color values
00118             plcol1( color / COLOR_MAX );
00119 
00120             xf[0] = xf[1] = ix;
00121             xf[2] = xf[3] = ix + 1;
00122             yf[0] = yf[3] = iy;
00123             yf[1] = yf[2] = iy + 1;
00124 
00125             if ( pltr )
00126             {
00127                 for ( i = 0; i < 4; i++ )
00128                 {
00129                     // Translate the points
00130                     ( *pltr )( xf[i], yf[i], &tx, &ty, pltr_data );
00131                     xf[i] = tx;
00132                     yf[i] = ty;
00133                 }
00134             }
00135             else
00136             {
00137                 for ( i = 0; i < 4; i++ )
00138                 {
00139                     // Automatic translation to the specified plot area
00140                     xf[i] = xmin + xf[i] * dx;
00141                     yf[i] = ymin + yf[i] * dy;
00142                 }
00143             }
00144             plfill( 4, xf, yf );
00145         }
00146     }
00147     plP_esc( PLESC_END_RASTERIZE, NULL );
00148 }
00149 
00150 void
00151 grimage( short *x, short *y, unsigned short *z, PLINT nx, PLINT ny )
00152 {
00153     plsc->dev_ix    = x;
00154     plsc->dev_iy    = y;
00155     plsc->dev_z     = z;
00156     plsc->dev_nptsX = nx;
00157     plsc->dev_nptsY = ny;
00158 
00159     plP_esc( PLESC_IMAGE, NULL );
00160 }
00161 
00162 //--------------------------------------------------------------------------
00163 // plimagefr
00164 //
00165 // arguments are
00166 //   idata: array containing image data
00167 //   nx: dimension of the array in the X axis.
00168 //   ny: dimension of the  array in the Y axis
00169 //   The array data is indexed like data[ix][iy]
00170 //
00171 //   xmin, xmax, ymin, ymax:
00172 //       data[0][0] corresponds to (xmin,ymin)
00173 //       data[nx-1][ny-1] to (xmax,ymax)
00174 //
00175 //   zmin, zmax:
00176 //       only data within bounds zmin <= data <= zmax will be
00177 //       plotted. If zmin == zmax, all data will be ploted.
00178 //
00179 //   valuemin, valuemax:
00180 //       The minimum and maximum values to use for value -> color
00181 //       mappings.  A value in idata of valuemin or less will have
00182 //       color 0.0 and a value in idata of valuemax or greater will
00183 //       have color 1.0.  Values between valuemin and valuemax will
00184 //       map linearly to to the colors between 0.0 and 1.0.
00185 //       If you do not want to display values outside of the
00186 //       (valuemin -> valuemax) range, then set zmin = valuemin and
00187 //       zmax = valuemax.
00188 //       This allows for multiple plots to use the same color scale
00189 //       with a consistent value -> color mapping, regardless of the
00190 //       image content.
00191 //
00192 //--------------------------------------------------------------------------
00193 void
00194 c_plimagefr( const PLFLT * const *idata, PLINT nx, PLINT ny,
00195              PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
00196              PLFLT valuemin, PLFLT valuemax,
00197              void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
00198              PLPointer pltr_data )
00199 {
00200     plfimagefr( plf2ops_c(), (PLPointer) idata, nx, ny,
00201         xmin, xmax, ymin, ymax, zmin, zmax,
00202         valuemin, valuemax, pltr, pltr_data );
00203 }
00204 
00205 void
00206 plfimagefr( PLF2OPS idataops, PLPointer idatap, PLINT nx, PLINT ny,
00207             PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
00208             PLFLT valuemin, PLFLT valuemax,
00209             void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
00210             PLPointer pltr_data )
00211 {
00212     PLINT ix, iy;
00213     PLFLT dx, dy;
00214     // z holds scaled image pixel values
00215     PLFLT *z;
00216     // This is used when looping through the image array, checking to
00217     // make sure the values are within an acceptable range.
00218     PLFLT datum;
00219     // Color palette 0 color in use before the plimage* call
00220     PLINT init_color;
00221     // Color range
00222     PLFLT color_min, color_max, color_range;
00223 
00224     if ( plsc->level < 3 )
00225     {
00226         plabort( "plimagefr: window must be set up first" );
00227         return;
00228     }
00229 
00230     if ( nx <= 0 || ny <= 0 )
00231     {
00232         plabort( "plimagefr: nx and ny must be positive" );
00233         return;
00234     }
00235 
00236     if ( ( z = (PLFLT *) malloc( (size_t) ( ny * nx ) * sizeof ( PLFLT ) ) ) == NULL )
00237     {
00238         plexit( "plimagefr: Insufficient memory" );
00239     }
00240 
00241     // Save the currently-in-use color.
00242     init_color = plsc->icol0;
00243 
00244     // If no acceptable data range is given, then set the min/max data range
00245     // to include all of the given data.
00246     if ( zmin == zmax )
00247     {
00248         // Find the minimum and maximum values in the image
00249         idataops->minmax( idatap, nx, ny, &zmin, &zmax );
00250     }
00251 
00252     // Calculate the size of the color range to use
00253     color_min   = plsc->cmap1_min;
00254     color_max   = plsc->cmap1_max;
00255     color_range = color_max - color_min;
00256 
00257     // Go through the image values and scale them to fit in
00258     // the COLOR_MIN to COLOR_MAX range.
00259     // Any values greater than valuemax are set to valuemax,
00260     // and values less than valuemin are set to valuemin.
00261     // Any values outside of zmin to zmax are flagged so they
00262     // are not plotted.
00263     for ( ix = 0; ix < nx; ix++ )
00264     {
00265         for ( iy = 0; iy < ny; iy++ )
00266         {
00267             if ( valuemin == valuemax )
00268             {
00269                 // If valuemin == valuemax, avoid dividing by zero.
00270                 z[ix * ny + iy] = ( color_max + color_min ) / 2.0;
00271             }
00272             else
00273             {
00274                 datum = idataops->get( idatap, ix, iy );
00275                 if ( isnan( datum ) || datum < zmin || datum > zmax )
00276                 {
00277                     // Set to a guaranteed-not-to-plot value
00278                     z[ix * ny + iy] = COLOR_NO_PLOT;
00279                 }
00280                 else
00281                 {
00282                     if ( datum < valuemin )
00283                     {
00284                         datum = valuemin;
00285                     }
00286                     else if ( datum > valuemax )
00287                     {
00288                         datum = valuemax;
00289                     }
00290                     // Set to a value scaled between color_min and color_max.
00291                     z[ix * ny + iy] =
00292                         color_min + ( datum - valuemin + COLOR_MIN ) / ( valuemax - valuemin ) * COLOR_MAX * color_range;
00293                 }
00294             }
00295         }
00296     }
00297 
00298     // dx and dy are the plot-coordinates pixel sizes for an untransformed
00299     // image
00300     dx = ( xmax - xmin ) / (PLFLT) nx;
00301     dy = ( ymax - ymin ) / (PLFLT) ny;
00302 
00303     plP_image( z, nx, ny, xmin, ymin, dx, dy, pltr, pltr_data );
00304 
00305     plcol0( init_color );
00306 
00307     free( z );
00308 }
00309 
00310 //--------------------------------------------------------------------------
00311 // plimage
00312 //
00313 // arguments are
00314 //   idata: array containing image data
00315 //   nx: dimension of the array in the X axis.
00316 //   ny: dimension of the  array in the Y axis
00317 //   The array data is indexed like data[ix][iy]
00318 //
00319 //   xmin, xmax, ymin, ymax:
00320 //       data[0][0] corresponds to (xmin,ymin)
00321 //       data[nx-1][ny-1] to (xmax,ymax)
00322 //
00323 //   zmin, zmax:
00324 //       only data within bounds zmin <= data <= zmax will be
00325 //       plotted. If zmin == zmax, all data will be ploted.
00326 //
00327 //   Dxmin, Dxmax, Dymin, Dymax:
00328 //       plots only the window of points whose(x,y)'s fall
00329 //       inside the [Dxmin->Dxmax]X[Dymin->Dymax] window
00330 //
00331 //--------------------------------------------------------------------------
00332 void
00333 c_plimage( const PLFLT * const *idata, PLINT nx, PLINT ny,
00334            PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
00335            PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax )
00336 {
00337     plfimage( plf2ops_c(), (PLPointer) idata, nx, ny,
00338         xmin, xmax, ymin, ymax, zmin, zmax,
00339         Dxmin, Dxmax, Dymin, Dymax );
00340 }
00341 
00342 void
00343 plfimage( PLF2OPS idataops, PLPointer idatap, PLINT nx, PLINT ny,
00344           PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
00345           PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax )
00346 {
00347     PLINT   ix, iy, ixx, iyy, xm, ym, nnx, nny;
00348     PLFLT   data_min, data_max, dx, dy;
00349     // z holds the subimage (Dxmin, Dymin) - (Dxmax, Dymax)
00350     PLFLT   **z;
00351     PLF2OPS zops;
00352     // Was any space allocated for z?
00353     PLBOOL  copied;
00354     copied = FALSE;
00355 
00356     if ( nx <= 0 || ny <= 0 )
00357     {
00358         plabort( "plimage: nx and ny must be positive" );
00359         return;
00360     }
00361 
00362     if ( Dxmin < xmin || Dxmax > xmax || Dymin < ymin || Dymax > ymax )
00363     {
00364         plabort( "plimage: Dxmin or Dxmax or Dymin or Dymax not compatible with xmin or xmax or ymin or ymax." );
00365         return;
00366     }
00367 
00368     if ( Dxmax < Dxmin || xmax < xmin || Dymax < Dymin || ymax < ymin )
00369     {
00370         plabort( "plimage: All (Dxmin < Dxmax) and (Dymin < Dymax) and (xmin < xmax) and (ymin < ymax) must hold." );
00371         return;
00372     }
00373 
00374     // Find the minimum and maximum values in the image.  Use these values to
00375     // for the color scale range.
00376     idataops->minmax( idatap, nx, ny, &data_min, &data_max );
00377 
00378     if ( xmin == Dxmin && xmax == Dxmax && ymin == Dymin && ymax == Dymax )
00379     {
00380         // If the whole image should be shown, then no copying is needed.
00381         z    = (PLFLT **) idatap;
00382         zops = idataops;
00383         nnx  = nx;
00384         nny  = ny;
00385     }
00386     else
00387     {
00388         // dx and dy are the plot-coordinates pixel sizes for an untransformed
00389         // image
00390         dx = ( xmax - xmin ) / (PLFLT) nx;
00391         dy = ( ymax - ymin ) / (PLFLT) ny;
00392 
00393         // Pixel dimensions of the (Dxmin, Dymin) to (Dxmax, Dymax) box
00394         nnx = (PLINT) ceil( ( Dxmax - Dxmin ) / dx );
00395         nny = (PLINT) ceil( ( Dymax - Dymin ) / dy );
00396 
00397         // Call plimagefr with the value -> color range mapped to the minimum
00398         // Offsets for the idata indices to select
00399         // (Dxmin, Dymin) to (Dxmax, Dymax)
00400         xm = (PLINT) floor( ( Dxmin - xmin ) / dx );
00401         ym = (PLINT) floor( ( Dymin - ymin ) / dy );
00402 
00403         // Allocate space for the sub-image
00404         plAlloc2dGrid( &z, nnx, nny );
00405         zops = plf2ops_c();
00406 
00407         // Go through the image and select the pixels within the given
00408         // (Dxmin, Dymin) - (Dxmax, Dymax) window.
00409         ixx = -1;
00410         for ( ix = xm; ix < xm + nnx; ix++ )
00411         {
00412             ixx++; iyy = 0;
00413             for ( iy = ym; iy < ym + nny; iy++ )
00414             {
00415                 z[ixx][iyy++] = idataops->get( idatap, ix, iy );
00416             }
00417         }
00418 
00419         // Set the appropriate values to pass in to plimagefr
00420         copied = TRUE;
00421     }
00422 
00423     plfimagefr( zops, (PLPointer) z, nnx, nny, Dxmin, Dxmax, Dymin, Dymax, zmin, zmax,
00424         data_min, data_max, NULL, NULL );
00425 
00426     // Only free the memory if it was allocated by us...
00427     if ( copied == TRUE )
00428     {
00429         plFree2dGrid( z, nnx, nny );
00430     }
00431 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines