PLplot  5.12.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
plimage.c
Go to the documentation of this file.
1 // plimage()
2 //
3 // Author: Alessandro Mirone, Nov 2001
4 // Adapted: Joao Cardoso
5 // Updated: Hezekiah Carty 2008
6 //
7 // Copyright (C) 2004 Alan W. Irwin
8 //
9 // This file is part of PLplot.
10 //
11 // PLplot is free software; you can redistribute it and/or modify
12 // it under the terms of the GNU Library General Public License as published
13 // by the Free Software Foundation; either version 2 of the License, or
14 // (at your option) any later version.
15 //
16 // PLplot is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Library General Public License for more details.
20 //
21 // You should have received a copy of the GNU Library General Public License
22 // along with PLplot; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 //
25 
26 #include "plplotP.h"
27 
28 #define COLOR_MIN 0.0
29 #define COLOR_MAX 1.0
30 #define COLOR_NO_PLOT ( -1.0 )
31 
32 // Get better names, those are too cryptic!
33 //
34 // ZEROW2B: zero writing to buffer ?
35 // ZEROW2D: zero writing to display ?
36 // ONEW2B: set writing to buffer ?
37 // ONEW2D: set writing to display ?
38 //
39 
40 void
42 {
43  PLINT op = ZEROW2B;
44 
45  plsc->plbuf_write = 0; // TODO: store previous state
46  plP_esc( PLESC_EXPOSE, NULL );
47  plP_esc( PLESC_IMAGEOPS, &op );
48 }
49 
50 void
52 {
53  PLINT op = ONEW2B;
54 
55  plsc->plbuf_write = 1; // TODO: revert from previous state
56  plP_esc( PLESC_IMAGEOPS, &op );
57 }
58 
59 //
60 // Unused functions - comment out
61 //
62 //void
63 //disabledisplay()
64 //{
65 // PLINT op = ZEROW2D;
66 //
67 // plP_esc( PLESC_IMAGEOPS, &op );
68 //}
69 //
70 //void
71 //enabledisplay()
72 //{
73 // PLINT op = ONEW2D;
74 //
75 // plP_esc( PLESC_IMAGEOPS, &op );
76 // plP_esc( PLESC_EXPOSE, NULL );
77 //}
78 //
79 
80 
81 //
82 // NOTE: The plshade* functions require that both pltr and pltr_data are set
83 // in order for pltr to be used. plimageslow does NOT require this, so it is
84 // up to the user to make sure pltr_data is something non-NULL if pltr
85 // requires it.
86 // Plottable values in idata must be scaled between COLOR_MIN and COLOR_MAX.
87 // This is an internal function, and should not be used directly. Its
88 // interface may change.
89 //
90 void
91 plimageslow( PLFLT *idata, PLINT nx, PLINT ny,
92  PLFLT xmin, PLFLT ymin, PLFLT dx, PLFLT dy,
93  PLTRANSFORM_callback pltr, PLPointer pltr_data )
94 {
95  // Indices
96  PLINT ix, iy, i;
97  // Float coordinates
98  PLFLT xf[4], yf[4];
99  // Translated (by pltr) coordinates
100  PLFLT tx, ty;
101  // The corners of a single filled region
102  // int corners[4]; - unreferenced
103  // The color to use in the fill
104  PLFLT color;
105 
107  for ( ix = 0; ix < nx; ix++ )
108  {
109  for ( iy = 0; iy < ny; iy++ )
110  {
111  // Only plot values within in appropriate range
112  color = idata[ix * ny + iy];
113  if ( color == COLOR_NO_PLOT )
114  continue;
115 
116  // The color value has to be scaled to 0.0 -> 1.0 plcol1 color values
117  plcol1( color / COLOR_MAX );
118 
119  xf[0] = xf[1] = ix;
120  xf[2] = xf[3] = ix + 1;
121  yf[0] = yf[3] = iy;
122  yf[1] = yf[2] = iy + 1;
123 
124  if ( pltr )
125  {
126  for ( i = 0; i < 4; i++ )
127  {
128  // Translate the points
129  ( *pltr )( xf[i], yf[i], &tx, &ty, pltr_data );
130  xf[i] = tx;
131  yf[i] = ty;
132  }
133  }
134  else
135  {
136  for ( i = 0; i < 4; i++ )
137  {
138  // Automatic translation to the specified plot area
139  xf[i] = xmin + xf[i] * dx;
140  yf[i] = ymin + yf[i] * dy;
141  }
142  }
143  plfill( 4, xf, yf );
144  }
145  }
146  plP_esc( PLESC_END_RASTERIZE, NULL );
147 }
148 
149 void
150 grimage( short *x, short *y, unsigned short *z, PLINT nx, PLINT ny )
151 {
152  plsc->dev_ix = x;
153  plsc->dev_iy = y;
154  plsc->dev_z = z;
155  plsc->dev_nptsX = nx;
156  plsc->dev_nptsY = ny;
157 
158  plP_esc( PLESC_IMAGE, NULL );
159 }
160 
161 //--------------------------------------------------------------------------
162 // plimagefr_null
163 //
164 // arguments are
165 // idata: array containing image data
166 // nx: dimension of the array in the X axis.
167 // ny: dimension of the array in the Y axis
168 // The array data is indexed like data[ix][iy]
169 //
170 // xmin, xmax, ymin, ymax:
171 // data[0][0] corresponds to (xmin,ymin)
172 // data[nx-1][ny-1] to (xmax,ymax)
173 //
174 // zmin, zmax:
175 // only data within bounds zmin <= data <= zmax will be
176 // plotted. If zmin == zmax, all data will be ploted.
177 //
178 // valuemin, valuemax:
179 // The minimum and maximum values to use for value -> color
180 // mappings. A value in idata of valuemin or less will have
181 // color 0.0 and a value in idata of valuemax or greater will
182 // have color 1.0. Values between valuemin and valuemax will
183 // map linearly to to the colors between 0.0 and 1.0.
184 // If you do not want to display values outside of the
185 // (valuemin -> valuemax) range, then set zmin = valuemin and
186 // zmax = valuemax.
187 // This allows for multiple plots to use the same color scale
188 // with a consistent value -> color mapping, regardless of the
189 // image content.
190 //
191 //--------------------------------------------------------------------------
192 
193 // N.B. This routine only needed by the Fortran interface to distinguish
194 // the case where pltr and pltr_data are NULL. So don't put declaration in
195 // header which might encourage others to use this in some other context.
196 PLDLLIMPEXP void
198  PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
199  PLFLT valuemin, PLFLT valuemax )
200 {
201  plfimagefr( plf2ops_c(), (PLPointer) idata, nx, ny,
202  xmin, xmax, ymin, ymax, zmin, zmax,
203  valuemin, valuemax, NULL, NULL );
204 }
205 
206 //--------------------------------------------------------------------------
207 // plimagefr
208 //
209 // arguments are
210 // idata: array containing image data
211 // nx: dimension of the array in the X axis.
212 // ny: dimension of the array in the Y axis
213 // The array data is indexed like data[ix][iy]
214 //
215 // xmin, xmax, ymin, ymax:
216 // data[0][0] corresponds to (xmin,ymin)
217 // data[nx-1][ny-1] to (xmax,ymax)
218 //
219 // zmin, zmax:
220 // only data within bounds zmin <= data <= zmax will be
221 // plotted. If zmin == zmax, all data will be ploted.
222 //
223 // valuemin, valuemax:
224 // The minimum and maximum values to use for value -> color
225 // mappings. A value in idata of valuemin or less will have
226 // color 0.0 and a value in idata of valuemax or greater will
227 // have color 1.0. Values between valuemin and valuemax will
228 // map linearly to to the colors between 0.0 and 1.0.
229 // If you do not want to display values outside of the
230 // (valuemin -> valuemax) range, then set zmin = valuemin and
231 // zmax = valuemax.
232 // This allows for multiple plots to use the same color scale
233 // with a consistent value -> color mapping, regardless of the
234 // image content.
235 //
236 //--------------------------------------------------------------------------
237 void
239  PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
240  PLFLT valuemin, PLFLT valuemax,
241  PLTRANSFORM_callback pltr, PLPointer pltr_data )
242 {
243  plfimagefr( plf2ops_c(), (PLPointer) idata, nx, ny,
244  xmin, xmax, ymin, ymax, zmin, zmax,
245  valuemin, valuemax, pltr, pltr_data );
246 }
247 
248 void
249 plfimagefr( PLF2OPS idataops, PLPointer idatap, PLINT nx, PLINT ny,
250  PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
251  PLFLT valuemin, PLFLT valuemax,
252  PLTRANSFORM_callback pltr, PLPointer pltr_data )
253 {
254  PLINT ix, iy;
255  PLFLT dx, dy;
256  // z holds scaled image pixel values
257  PLFLT *z;
258  // This is used when looping through the image array, checking to
259  // make sure the values are within an acceptable range.
260  PLFLT datum;
261  // Color palette 0 color in use before the plimage* call
262  PLINT init_color;
263  // Color range
264  PLFLT color_min, color_max, color_range;
265 
266  if ( plsc->level < 3 )
267  {
268  plabort( "plimagefr: window must be set up first" );
269  return;
270  }
271 
272  if ( nx <= 0 || ny <= 0 )
273  {
274  plabort( "plimagefr: nx and ny must be positive" );
275  return;
276  }
277 
278  if ( ( z = (PLFLT *) malloc( (size_t) ( ny * nx ) * sizeof ( PLFLT ) ) ) == NULL )
279  {
280  plexit( "plimagefr: Insufficient memory" );
281  }
282 
283  // Save the currently-in-use color.
284  init_color = plsc->icol0;
285 
286  // If no acceptable data range is given, then set the min/max data range
287  // to include all of the given data.
288  if ( zmin == zmax )
289  {
290  // Find the minimum and maximum values in the image
291  idataops->minmax( idatap, nx, ny, &zmin, &zmax );
292  }
293 
294  // Calculate the size of the color range to use
295  color_min = plsc->cmap1_min;
296  color_max = plsc->cmap1_max;
297  color_range = color_max - color_min;
298 
299  // Go through the image values and scale them to fit in
300  // the COLOR_MIN to COLOR_MAX range.
301  // Any values greater than valuemax are set to valuemax,
302  // and values less than valuemin are set to valuemin.
303  // Any values outside of zmin to zmax are flagged so they
304  // are not plotted.
305  for ( ix = 0; ix < nx; ix++ )
306  {
307  for ( iy = 0; iy < ny; iy++ )
308  {
309  if ( valuemin == valuemax )
310  {
311  // If valuemin == valuemax, avoid dividing by zero.
312  z[ix * ny + iy] = ( color_max + color_min ) / 2.0;
313  }
314  else
315  {
316  datum = idataops->get( idatap, ix, iy );
317  if ( isnan( datum ) || datum < zmin || datum > zmax )
318  {
319  // Set to a guaranteed-not-to-plot value
320  z[ix * ny + iy] = COLOR_NO_PLOT;
321  }
322  else
323  {
324  if ( datum < valuemin )
325  {
326  datum = valuemin;
327  }
328  else if ( datum > valuemax )
329  {
330  datum = valuemax;
331  }
332  // Set to a value scaled between color_min and color_max.
333  z[ix * ny + iy] =
334  color_min + ( datum - valuemin + COLOR_MIN ) / ( valuemax - valuemin ) * COLOR_MAX * color_range;
335  }
336  }
337  }
338  }
339 
340  // dx and dy are the plot-coordinates pixel sizes for an untransformed
341  // image
342  dx = ( xmax - xmin ) / (PLFLT) ( nx - 1 );
343  dy = ( ymax - ymin ) / (PLFLT) ( ny - 1 );
344 
345  plP_image( z, nx, ny, xmin, ymin, dx, dy, pltr, pltr_data );
346 
347  plcol0( init_color );
348 
349  free( z );
350 }
351 
352 //--------------------------------------------------------------------------
353 // plimage
354 //
355 // arguments are
356 // idata: array containing image data
357 // nx: dimension of the array in the X axis.
358 // ny: dimension of the array in the Y axis
359 // The array data is indexed like data[ix][iy]
360 //
361 // xmin, xmax, ymin, ymax:
362 // data[0][0] corresponds to (xmin,ymin)
363 // data[nx-1][ny-1] to (xmax,ymax)
364 //
365 // zmin, zmax:
366 // only data within bounds zmin <= data <= zmax will be
367 // plotted. If zmin == zmax, all data will be ploted.
368 //
369 // Dxmin, Dxmax, Dymin, Dymax:
370 // plots only the window of points whose(x,y)'s fall
371 // inside the [Dxmin->Dxmax]X[Dymin->Dymax] window
372 //
373 //--------------------------------------------------------------------------
374 void
376  PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
377  PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax )
378 {
379  plfimage( plf2ops_c(), (PLPointer) idata, nx, ny,
380  xmin, xmax, ymin, ymax, zmin, zmax,
381  Dxmin, Dxmax, Dymin, Dymax );
382 }
383 
384 void
385 plfimage( PLF2OPS idataops, PLPointer idatap, PLINT nx, PLINT ny,
386  PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
387  PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax )
388 {
389  PLINT ix, iy, ixx, iyy, xm, ym, nnx, nny;
390  PLFLT data_min, data_max, dx, dy;
391  // z holds the subimage (Dxmin, Dymin) - (Dxmax, Dymax)
392  PLFLT **z;
393  PLF2OPS zops;
394  // Was any space allocated for z?
395  PLBOOL copied;
396  copied = FALSE;
397 
398  if ( nx <= 0 || ny <= 0 )
399  {
400  plabort( "plimage: nx and ny must be positive" );
401  return;
402  }
403 
404  if ( Dxmin < xmin || Dxmax > xmax || Dymin < ymin || Dymax > ymax )
405  {
406  plabort( "plimage: Dxmin or Dxmax or Dymin or Dymax not compatible with xmin or xmax or ymin or ymax." );
407  return;
408  }
409 
410  if ( Dxmax < Dxmin || xmax < xmin || Dymax < Dymin || ymax < ymin )
411  {
412  plabort( "plimage: All (Dxmin < Dxmax) and (Dymin < Dymax) and (xmin < xmax) and (ymin < ymax) must hold." );
413  return;
414  }
415 
416  // Find the minimum and maximum values in the image. Use these values to
417  // for the color scale range.
418  idataops->minmax( idatap, nx, ny, &data_min, &data_max );
419 
420  if ( xmin == Dxmin && xmax == Dxmax && ymin == Dymin && ymax == Dymax )
421  {
422  // If the whole image should be shown, then no copying is needed.
423  z = (PLFLT **) idatap;
424  zops = idataops;
425  nnx = nx;
426  nny = ny;
427  }
428  else
429  {
430  // dx and dy are the plot-coordinates pixel sizes for an untransformed
431  // image
432  dx = ( xmax - xmin ) / (PLFLT) ( nx - 1 );
433  dy = ( ymax - ymin ) / (PLFLT) ( ny - 1 );
434 
435  // Pixel dimensions of the (Dxmin, Dymin) to (Dxmax, Dymax) box
436  nnx = (PLINT) ceil( ( Dxmax - Dxmin ) / dx ) + 1;
437  nny = (PLINT) ceil( ( Dymax - Dymin ) / dy ) + 1;
438 
439  // Call plimagefr with the value -> color range mapped to the minimum
440  // Offsets for the idata indices to select
441  // (Dxmin, Dymin) to (Dxmax, Dymax)
442  xm = (PLINT) floor( ( Dxmin - xmin ) / dx );
443  ym = (PLINT) floor( ( Dymin - ymin ) / dy );
444 
445  // Allocate space for the sub-image
446  plAlloc2dGrid( &z, nnx, nny );
447  zops = plf2ops_c();
448 
449  // Go through the image and select the pixels within the given
450  // (Dxmin, Dymin) - (Dxmax, Dymax) window.
451  ixx = -1;
452  for ( ix = xm; ix < xm + nnx; ix++ )
453  {
454  ixx++; iyy = 0;
455  for ( iy = ym; iy < ym + nny; iy++ )
456  {
457  z[ixx][iyy++] = idataops->get( idatap, ix, iy );
458  }
459  }
460 
461  // Set the appropriate values to pass in to plimagefr
462  copied = TRUE;
463  }
464 
465  plfimagefr( zops, (PLPointer) z, nnx, nny, Dxmin, Dxmax, Dymin, Dymax, zmin, zmax,
466  data_min, data_max, NULL, NULL );
467 
468  // Only free the memory if it was allocated by us...
469  if ( copied == TRUE )
470  {
471  plFree2dGrid( z, nnx, nny );
472  }
473 }
void(* PLTRANSFORM_callback)(PLFLT x, PLFLT y, PLFLT_NC_SCALAR xp, PLFLT_NC_SCALAR yp, PL_GENERIC_POINTER data)
Definition: plplot.h:258
void plexit(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1948
void plP_esc(PLINT op, void *ptr)
Definition: plcore.c:265
void NoBufferNoPixmap()
Definition: plimage.c:41
#define COLOR_MIN
Definition: plimage.c:28
PL_NC_GENERIC_POINTER PLPointer
Definition: plplot.h:211
const PLFLT *const * PLFLT_MATRIX
Definition: plplot.h:254
#define plfill
Definition: plplot.h:713
PLFLT(* get)(PL_GENERIC_POINTER p, PLINT ix, PLINT iy)
Definition: plplot.h:599
#define isnan(x)
Definition: plplotP.h:262
void plfimage(PLF2OPS idataops, PLPointer idatap, PLINT nx, PLINT ny, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax, PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax)
Definition: plimage.c:385
void plfimagefr(PLF2OPS idataops, PLPointer idatap, PLINT nx, PLINT ny, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax, PLFLT valuemin, PLFLT valuemax, PLTRANSFORM_callback pltr, PLPointer pltr_data)
Definition: plimage.c:249
void plabort(PLCHAR_VECTOR errormsg)
Definition: plctrl.c:1884
void plimageslow(PLFLT *idata, PLINT nx, PLINT ny, PLFLT xmin, PLFLT ymin, PLFLT dx, PLFLT dy, PLTRANSFORM_callback pltr, PLPointer pltr_data)
Definition: plimage.c:91
int PLINT
Definition: plplot.h:174
PLINT PLBOOL
Definition: plplot.h:197
PLDLLIMPEXP void plimagefr_null(PLFLT_MATRIX idata, PLINT nx, PLINT ny, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax, PLFLT valuemin, PLFLT valuemax)
Definition: plimage.c:197
void plFree2dGrid(PLFLT **f, PLINT nx, PLINT PL_UNUSED(ny))
Definition: plmem.c:85
#define TRUE
Definition: plplotP.h:176
void c_plimagefr(PLFLT_MATRIX idata, PLINT nx, PLINT ny, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax, PLFLT valuemin, PLFLT valuemax, PLTRANSFORM_callback pltr, PLPointer pltr_data)
Definition: plimage.c:238
#define FALSE
Definition: plplotP.h:177
#define PLESC_END_RASTERIZE
Definition: plplot.h:304
void RestoreWrite2BufferPixmap()
Definition: plimage.c:51
void plP_image(PLFLT *z, PLINT nx, PLINT ny, PLFLT xmin, PLFLT ymin, PLFLT dx, PLFLT dy, void(*pltr)(PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer), PLPointer pltr_data)
Definition: plcore.c:4354
#define plcol1
Definition: plplot.h:699
void grimage(short *x, short *y, unsigned short *z, PLINT nx, PLINT ny)
Definition: plimage.c:150
void(* minmax)(PL_GENERIC_POINTER p, PLINT nx, PLINT ny, PLFLT_NC_SCALAR zmin, PLFLT_NC_SCALAR zmax)
Definition: plplot.h:606
void c_plimage(PLFLT_MATRIX idata, PLINT nx, PLINT ny, PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax, PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax)
Definition: plimage.c:375
float PLFLT
Definition: plplot.h:157
#define PLESC_START_RASTERIZE
Definition: plplot.h:303
void plAlloc2dGrid(PLFLT ***f, PLINT nx, PLINT ny)
Definition: plmem.c:60
#define plcol0
Definition: plplot.h:698
PLF2OPS plf2ops_c()
Definition: plf2ops.c:126
#define PLESC_IMAGE
Definition: plplot.h:292
#define COLOR_NO_PLOT
Definition: plimage.c:30
#define PLESC_IMAGEOPS
Definition: plplot.h:293
#define PLDLLIMPEXP
Definition: pldll.h:49
#define COLOR_MAX
Definition: plimage.c:29
#define PLESC_EXPOSE
Definition: plplot.h:275
#define ZEROW2B
Definition: plplot.h:323
#define ONEW2B
Definition: plplot.h:325