PLplot 5.9.6
|
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 General Library 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( 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 00219 if ( plsc->level < 3 ) 00220 { 00221 plabort( "plimagefr: window must be set up first" ); 00222 return; 00223 } 00224 00225 if ( nx <= 0 || ny <= 0 ) 00226 { 00227 plabort( "plimagefr: nx and ny must be positive" ); 00228 return; 00229 } 00230 00231 if ( ( z = (PLFLT *) malloc( ny * nx * sizeof ( PLFLT ) ) ) == NULL ) 00232 { 00233 plexit( "plimagefr: Insufficient memory" ); 00234 } 00235 00236 /* Save the currently-in-use color. */ 00237 init_color = plsc->icol0; 00238 00239 /* If no acceptable data range is given, then set the min/max data range 00240 * to include all of the given data. */ 00241 if ( zmin == zmax ) 00242 { 00243 /* Find the minimum and maximum values in the image */ 00244 idataops->minmax( idatap, nx, ny, &zmin, &zmax ); 00245 } 00246 00247 /* Go through the image values and scale them to fit in 00248 * the COLOR_MIN to COLOR_MAX range. 00249 * Any values greater than valuemax are set to valuemax, 00250 * and values less than valuemin are set to valuemin. 00251 * Any values outside of zmin to zmax are flagged so they 00252 * are not plotted. */ 00253 for ( ix = 0; ix < nx; ix++ ) 00254 { 00255 for ( iy = 0; iy < ny; iy++ ) 00256 { 00257 if ( valuemin == valuemax ) 00258 { 00259 /* If valuemin == valuemax, avoid dividing by zero. */ 00260 z[ix * ny + iy] = ( COLOR_MAX + COLOR_MIN ) / 2.0; 00261 } 00262 else 00263 { 00264 datum = idataops->get( idatap, ix, iy ); 00265 if ( isnan( datum ) || datum < zmin || datum > zmax ) 00266 { 00267 /* Set to a guaranteed-not-to-plot value */ 00268 z[ix * ny + iy] = COLOR_NO_PLOT; 00269 } 00270 else 00271 { 00272 if ( datum < valuemin ) 00273 { 00274 datum = valuemin; 00275 } 00276 else if ( datum > valuemax ) 00277 { 00278 datum = valuemax; 00279 } 00280 /* Set to a value scaled between COLOR_MIN and COLOR_MAX. */ 00281 z[ix * ny + iy] = 00282 ( datum - valuemin + COLOR_MIN ) / ( valuemax - valuemin ) * COLOR_MAX; 00283 } 00284 } 00285 } 00286 } 00287 00288 /* dx and dy are the plot-coordinates pixel sizes for an untransformed 00289 * image */ 00290 dx = ( xmax - xmin ) / (PLFLT) nx; 00291 dy = ( ymax - ymin ) / (PLFLT) ny; 00292 00293 plP_image( z, nx, ny, xmin, ymin, dx, dy, pltr, pltr_data ); 00294 00295 plcol0( init_color ); 00296 00297 free( z ); 00298 } 00299 00300 /*-------------------------------------------------------------------------*\ 00301 * plimage 00302 * 00303 * arguments are 00304 * idata: array containing image data 00305 * nx: dimension of the array in the X axis. 00306 * ny: dimension of the array in the Y axis 00307 * The array data is indexed like data[ix][iy] 00308 * 00309 * xmin, xmax, ymin, ymax: 00310 * data[0][0] corresponds to (xmin,ymin) 00311 * data[nx-1][ny-1] to (xmax,ymax) 00312 * 00313 * zmin, zmax: 00314 * only data within bounds zmin <= data <= zmax will be 00315 * plotted. If zmin == zmax, all data will be ploted. 00316 * 00317 * Dxmin, Dxmax, Dymin, Dymax: 00318 * plots only the window of points whose(x,y)'s fall 00319 * inside the [Dxmin->Dxmax]X[Dymin->Dymax] window 00320 * 00321 \*-------------------------------------------------------------------------*/ 00322 void 00323 c_plimage( PLFLT **idata, PLINT nx, PLINT ny, 00324 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax, 00325 PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax ) 00326 { 00327 plfimage( plf2ops_c(), (PLPointer) idata, nx, ny, 00328 xmin, xmax, ymin, ymax, zmin, zmax, 00329 Dxmin, Dxmax, Dymin, Dymax ); 00330 } 00331 00332 void 00333 plfimage( PLF2OPS idataops, PLPointer idatap, 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 PLINT ix, iy, ixx, iyy, xm, ym, nnx, nny; 00338 PLFLT data_min, data_max, dx, dy; 00339 /* z holds the subimage (Dxmin, Dymin) - (Dxmax, Dymax) */ 00340 PLFLT **z; 00341 PLF2OPS zops; 00342 /* Was any space allocated for z? */ 00343 PLBOOL copied; 00344 copied = FALSE; 00345 00346 if ( nx <= 0 || ny <= 0 ) 00347 { 00348 plabort( "plimage: nx and ny must be positive" ); 00349 return; 00350 } 00351 00352 if ( Dxmin < xmin || Dxmax > xmax || Dymin < ymin || Dymax > ymax ) 00353 { 00354 plabort( "plimage: Dxmin or Dxmax or Dymin or Dymax not compatible with xmin or xmax or ymin or ymax." ); 00355 return; 00356 } 00357 00358 if ( Dxmax < Dxmin || xmax < xmin || Dymax < Dymin || ymax < ymin ) 00359 { 00360 plabort( "plimage: All (Dxmin < Dxmax) and (Dymin < Dymax) and (xmin < xmax) and (ymin < ymax) must hold." ); 00361 return; 00362 } 00363 00364 /* Find the minimum and maximum values in the image. Use these values to 00365 * for the color scale range. */ 00366 idataops->minmax( idatap, nx, ny, &data_min, &data_max ); 00367 00368 if ( xmin == Dxmin && xmax == Dxmax && ymin == Dymin && ymax == Dymax ) 00369 { 00370 /* If the whole image should be shown, then no copying is needed. */ 00371 z = (PLFLT **) idatap; 00372 zops = idataops; 00373 nnx = nx; 00374 nny = ny; 00375 } 00376 else 00377 { 00378 /* dx and dy are the plot-coordinates pixel sizes for an untransformed 00379 * image */ 00380 dx = ( xmax - xmin ) / (PLFLT) nx; 00381 dy = ( ymax - ymin ) / (PLFLT) ny; 00382 00383 /* Pixel dimensions of the (Dxmin, Dymin) to (Dxmax, Dymax) box */ 00384 nnx = (PLINT) ceil( ( Dxmax - Dxmin ) / dx ); 00385 nny = (PLINT) ceil( ( Dymax - Dymin ) / dy ); 00386 00387 /* Call plimagefr with the value -> color range mapped to the minimum 00388 * Offsets for the idata indices to select 00389 * (Dxmin, Dymin) to (Dxmax, Dymax) */ 00390 xm = (PLINT) floor( ( Dxmin - xmin ) / dx ); 00391 ym = (PLINT) floor( ( Dymin - ymin ) / dy ); 00392 00393 /* Allocate space for the sub-image */ 00394 plAlloc2dGrid( &z, nnx, nny ); 00395 zops = plf2ops_c(); 00396 00397 /* Go through the image and select the pixels within the given 00398 * (Dxmin, Dymin) - (Dxmax, Dymax) window. */ 00399 ixx = -1; 00400 for ( ix = xm; ix < xm + nnx; ix++ ) 00401 { 00402 ixx++; iyy = 0; 00403 for ( iy = ym; iy < ym + nny; iy++ ) 00404 { 00405 z[ixx][iyy++] = idataops->get( idatap, ix, iy ); 00406 } 00407 } 00408 00409 /* Set the appropriate values to pass in to plimagefr */ 00410 copied = TRUE; 00411 } 00412 00413 plfimagefr( zops, (PLPointer) z, nnx, nny, Dxmin, Dxmax, Dymin, Dymax, zmin, zmax, 00414 data_min, data_max, NULL, NULL ); 00415 00416 /* Only free the memory if it was allocated by us... */ 00417 if ( copied == TRUE ) 00418 { 00419 plFree2dGrid( z, nnx, nny ); 00420 } 00421 }