PLplot
5.10.0
|
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 }