PLplot: plimage.c Source File

PLplot 5.10.0

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

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
41 NoBufferNoPixmap()
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
51 RestoreWrite2BufferPixmap()
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 void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
94 PLPointer pltr_data )
95 {
96 // Indices
97 PLINT ix, iy, i;
98 // Float coordinates
99 PLFLT xf[4], yf[4];
100 // Translated (by pltr) coordinates
101 PLFLT tx, ty;
102 // The corners of a single filled region
103 // int corners[4]; - unreferenced
104 // The color to use in the fill
105 PLFLT color;
106
107 plP_esc( PLESC_START_RASTERIZE, NULL );
108 for ( ix = 0; ix < nx; ix++ )
109 {
110 for ( iy = 0; iy < ny; iy++ )
111 {
112 // Only plot values within in appropriate range
113 color = idata[ix * ny + iy];
114 if ( color == COLOR_NO_PLOT )
115 continue;
116
117 // The color value has to be scaled to 0.0 -> 1.0 plcol1 color values
118 plcol1( color / COLOR_MAX );
119
120 xf[0] = xf[1] = ix;
121 xf[2] = xf[3] = ix + 1;
122 yf[0] = yf[3] = iy;
123 yf[1] = yf[2] = iy + 1;
124
125 if ( pltr )
126 {
127 for ( i = 0; i < 4; i++ )
128 {
129 // Translate the points
130 ( *pltr )( xf[i], yf[i], &tx, &ty, pltr_data );
131 xf[i] = tx;
132 yf[i] = ty;
133 }
134 }
135 else
136 {
137 for ( i = 0; i < 4; i++ )
138 {
139 // Automatic translation to the specified plot area
140 xf[i] = xmin + xf[i] * dx;
141 yf[i] = ymin + yf[i] * dy;
142 }
143 }
144 plfill( 4, xf, yf );
145 }
146 }
147 plP_esc( PLESC_END_RASTERIZE, NULL );
148 }
149
150 void
151 grimage( short *x, short *y, unsigned short *z, PLINT nx, PLINT ny )
152 {
153 plsc->dev_ix = x;
154 plsc->dev_iy = y;
155 plsc->dev_z = z;
156 plsc->dev_nptsX = nx;
157 plsc->dev_nptsY = ny;
158
159 plP_esc( PLESC_IMAGE, NULL );
160 }
161
162 //--------------------------------------------------------------------------
163 // plimagefr
164 //
165 // arguments are
166 // idata: array containing image data
167 // nx: dimension of the array in the X axis.
168 // ny: dimension of the array in the Y axis
169 // The array data is indexed like data[ix][iy]
170 //
171 // xmin, xmax, ymin, ymax:
172 // data[0][0] corresponds to (xmin,ymin)
173 // data[nx-1][ny-1] to (xmax,ymax)
174 //
175 // zmin, zmax:
176 // only data within bounds zmin <= data <= zmax will be
177 // plotted. If zmin == zmax, all data will be ploted.
178 //
179 // valuemin, valuemax:
180 // The minimum and maximum values to use for value -> color
181 // mappings. A value in idata of valuemin or less will have
182 // color 0.0 and a value in idata of valuemax or greater will
183 // have color 1.0. Values between valuemin and valuemax will
184 // map linearly to to the colors between 0.0 and 1.0.
185 // If you do not want to display values outside of the
186 // (valuemin -> valuemax) range, then set zmin = valuemin and
187 // zmax = valuemax.
188 // This allows for multiple plots to use the same color scale
189 // with a consistent value -> color mapping, regardless of the
190 // image content.
191 //
192 //--------------------------------------------------------------------------
193 void
194 c_plimagefr( const PLFLT * const *idata, PLINT nx, PLINT ny,
195 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
196 PLFLT valuemin, PLFLT valuemax,
197 void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
198 PLPointer pltr_data )
199 {
200 plfimagefr( plf2ops_c(), (PLPointer) idata, nx, ny,
201 xmin, xmax, ymin, ymax, zmin, zmax,
202 valuemin, valuemax, pltr, pltr_data );
203 }
204
205 void
206 plfimagefr( PLF2OPS idataops, PLPointer idatap, PLINT nx, PLINT ny,
207 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
208 PLFLT valuemin, PLFLT valuemax,
209 void ( *pltr )( PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer ),
210 PLPointer pltr_data )
211 {
212 PLINT ix, iy;
213 PLFLT dx, dy;
214 // z holds scaled image pixel values
215 PLFLT *z;
216 // This is used when looping through the image array, checking to
217 // make sure the values are within an acceptable range.
218 PLFLT datum;
219 // Color palette 0 color in use before the plimage* call
220 PLINT init_color;
221 // Color range
222 PLFLT color_min, color_max, color_range;
223
224 if ( plsc->level < 3 )
225 {
226 plabort( "plimagefr: window must be set up first" );
227 return;
228 }
229
230 if ( nx <= 0 || ny <= 0 )
231 {
232 plabort( "plimagefr: nx and ny must be positive" );
233 return;
234 }
235
236 if ( ( z = (PLFLT *) malloc( (size_t) ( ny * nx ) * sizeof ( PLFLT ) ) ) == NULL )
237 {
238 plexit( "plimagefr: Insufficient memory" );
239 }
240
241 // Save the currently-in-use color.
242 init_color = plsc->icol0;
243
244 // If no acceptable data range is given, then set the min/max data range
245 // to include all of the given data.
246 if ( zmin == zmax )
247 {
248 // Find the minimum and maximum values in the image
249 idataops->minmax( idatap, nx, ny, &zmin, &zmax );
250 }
251
252 // Calculate the size of the color range to use
253 color_min = plsc->cmap1_min;
254 color_max = plsc->cmap1_max;
255 color_range = color_max - color_min;
256
257 // Go through the image values and scale them to fit in
258 // the COLOR_MIN to COLOR_MAX range.
259 // Any values greater than valuemax are set to valuemax,
260 // and values less than valuemin are set to valuemin.
261 // Any values outside of zmin to zmax are flagged so they
262 // are not plotted.
263 for ( ix = 0; ix < nx; ix++ )
264 {
265 for ( iy = 0; iy < ny; iy++ )
266 {
267 if ( valuemin == valuemax )
268 {
269 // If valuemin == valuemax, avoid dividing by zero.
270 z[ix * ny + iy] = ( color_max + color_min ) / 2.0;
271 }
272 else
273 {
274 datum = idataops->get( idatap, ix, iy );
275 if ( isnan( datum ) || datum < zmin || datum > zmax )
276 {
277 // Set to a guaranteed-not-to-plot value
278 z[ix * ny + iy] = COLOR_NO_PLOT;
279 }
280 else
281 {
282 if ( datum < valuemin )
283 {
284 datum = valuemin;
285 }
286 else if ( datum > valuemax )
287 {
288 datum = valuemax;
289 }
290 // Set to a value scaled between color_min and color_max.
291 z[ix * ny + iy] =
292 color_min + ( datum - valuemin + COLOR_MIN ) / ( valuemax - valuemin ) * COLOR_MAX * color_range;
293 }
294 }
295 }
296 }
297
298 // dx and dy are the plot-coordinates pixel sizes for an untransformed
299 // image
300 dx = ( xmax - xmin ) / (PLFLT) nx;
301 dy = ( ymax - ymin ) / (PLFLT) ny;
302
303 plP_image( z, nx, ny, xmin, ymin, dx, dy, pltr, pltr_data );
304
305 plcol0( init_color );
306
307 free( z );
308 }
309
310 //--------------------------------------------------------------------------
311 // plimage
312 //
313 // arguments are
314 // idata: array containing image data
315 // nx: dimension of the array in the X axis.
316 // ny: dimension of the array in the Y axis
317 // The array data is indexed like data[ix][iy]
318 //
319 // xmin, xmax, ymin, ymax:
320 // data[0][0] corresponds to (xmin,ymin)
321 // data[nx-1][ny-1] to (xmax,ymax)
322 //
323 // zmin, zmax:
324 // only data within bounds zmin <= data <= zmax will be
325 // plotted. If zmin == zmax, all data will be ploted.
326 //
327 // Dxmin, Dxmax, Dymin, Dymax:
328 // plots only the window of points whose(x,y)'s fall
329 // inside the [Dxmin->Dxmax]X[Dymin->Dymax] window
330 //
331 //--------------------------------------------------------------------------
332 void
333 c_plimage( const PLFLT * const *idata, PLINT nx, PLINT ny,
334 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
335 PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax )
336 {
337 plfimage( plf2ops_c(), (PLPointer) idata, nx, ny,
338 xmin, xmax, ymin, ymax, zmin, zmax,
339 Dxmin, Dxmax, Dymin, Dymax );
340 }
341
342 void
343 plfimage( PLF2OPS idataops, PLPointer idatap, PLINT nx, PLINT ny,
344 PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax,
345 PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax )
346 {
347 PLINT ix, iy, ixx, iyy, xm, ym, nnx, nny;
348 PLFLT data_min, data_max, dx, dy;
349 // z holds the subimage (Dxmin, Dymin) - (Dxmax, Dymax)
350 PLFLT **z;
351 PLF2OPS zops;
352 // Was any space allocated for z?
353 PLBOOL copied;
354 copied = FALSE;
355
356 if ( nx <= 0 || ny <= 0 )
357 {
358 plabort( "plimage: nx and ny must be positive" );
359 return;
360 }
361
362 if ( Dxmin < xmin || Dxmax > xmax || Dymin < ymin || Dymax > ymax )
363 {
364 plabort( "plimage: Dxmin or Dxmax or Dymin or Dymax not compatible with xmin or xmax or ymin or ymax." );
365 return;
366 }
367
368 if ( Dxmax < Dxmin || xmax < xmin || Dymax < Dymin || ymax < ymin )
369 {
370 plabort( "plimage: All (Dxmin < Dxmax) and (Dymin < Dymax) and (xmin < xmax) and (ymin < ymax) must hold." );
371 return;
372 }
373
374 // Find the minimum and maximum values in the image. Use these values to
375 // for the color scale range.
376 idataops->minmax( idatap, nx, ny, &data_min, &data_max );
377
378 if ( xmin == Dxmin && xmax == Dxmax && ymin == Dymin && ymax == Dymax )
379 {
380 // If the whole image should be shown, then no copying is needed.
381 z = (PLFLT **) idatap;
382 zops = idataops;
383 nnx = nx;
384 nny = ny;
385 }
386 else
387 {
388 // dx and dy are the plot-coordinates pixel sizes for an untransformed
389 // image
390 dx = ( xmax - xmin ) / (PLFLT) nx;
391 dy = ( ymax - ymin ) / (PLFLT) ny;
392
393 // Pixel dimensions of the (Dxmin, Dymin) to (Dxmax, Dymax) box
394 nnx = (PLINT) ceil( ( Dxmax - Dxmin ) / dx );
395 nny = (PLINT) ceil( ( Dymax - Dymin ) / dy );
396
397 // Call plimagefr with the value -> color range mapped to the minimum
398 // Offsets for the idata indices to select
399 // (Dxmin, Dymin) to (Dxmax, Dymax)
400 xm = (PLINT) floor( ( Dxmin - xmin ) / dx );
401 ym = (PLINT) floor( ( Dymin - ymin ) / dy );
402
403 // Allocate space for the sub-image
404 plAlloc2dGrid( &z, nnx, nny );
405 zops = plf2ops_c();
406
407 // Go through the image and select the pixels within the given
408 // (Dxmin, Dymin) - (Dxmax, Dymax) window.
409 ixx = -1;
410 for ( ix = xm; ix < xm + nnx; ix++ )
411 {
412 ixx++; iyy = 0;
413 for ( iy = ym; iy < ym + nny; iy++ )
414 {
415 z[ixx][iyy++] = idataops->get( idatap, ix, iy );
416 }
417 }
418
419 // Set the appropriate values to pass in to plimagefr
420 copied = TRUE;
421 }
422
423 plfimagefr( zops, (PLPointer) z, nnx, nny, Dxmin, Dxmax, Dymin, Dymax, zmin, zmax,
424 data_min, data_max, NULL, NULL );
425
426 // Only free the memory if it was allocated by us...
427 if ( copied == TRUE )
428 {
429 plFree2dGrid( z, nnx, nny );
430 }
431 }