From: <and...@us...> - 2008-07-19 22:02:43
|
Revision: 8543 http://plplot.svn.sourceforge.net/plplot/?rev=8543&view=rev Author: andrewross Date: 2008-07-19 21:56:21 +0000 (Sat, 19 Jul 2008) Log Message: ----------- ANR for Hezekiah M. Carty. Update to plimagefr to allow an image to be plotted with a user-supplied pltr transformation function. This is an API change, but the plimagefr API has be advertised as not yet finalised and has not been included in a release. Note: this patch disables the dev_fastimg code. Tests by Hez using the xwin driver have not shown a significant time penalty on modern hardware. It may be possible to fix this if it proves an issue. Modified Paths: -------------- trunk/bindings/f77/plstubs.h trunk/bindings/f77/scstubs.c trunk/bindings/f95/plstubs.h trunk/bindings/f95/scstubs.c trunk/bindings/f95/sfstubsf95.f90 trunk/doc/docbook/src/api.xml trunk/examples/c/x20c.c trunk/include/plplot.h trunk/include/plplotP.h trunk/src/plbuf.c trunk/src/plcore.c trunk/src/plimage.c Modified: trunk/bindings/f77/plstubs.h =================================================================== --- trunk/bindings/f77/plstubs.h 2008-07-19 20:17:57 UTC (rev 8542) +++ trunk/bindings/f77/plstubs.h 2008-07-19 21:56:21 UTC (rev 8543) @@ -218,7 +218,8 @@ #define PLHLS FNAME(PLHLS,plhls) #define PLHLSRGB FNAME(PLHLSRGB,plhlsrgb) #define PLIMAGE FNAME(PLIMAGE,plimage) -#define PLIMAGEFR FNAME(PLIMAGEFR,plimagefr) +/* Commented out for now - needs fixing to use pltr */ +/*#define PLIMAGEFR FNAME(PLIMAGEFR,plimagefr)*/ #define PLINIT FNAME(PLINIT,plinit) #define PLJOIN FNAME(PLJOIN,pljoin) #define PLLAB7 FNAME(PLLAB7,pllab7) Modified: trunk/bindings/f77/scstubs.c =================================================================== --- trunk/bindings/f77/scstubs.c 2008-07-19 20:17:57 UTC (rev 8542) +++ trunk/bindings/f77/scstubs.c 2008-07-19 21:56:21 UTC (rev 8543) @@ -396,6 +396,7 @@ c_plhlsrgb(*h, *l, *s, r, g, b); } +#if 0 void PLIMAGEFR(PLFLT *idata, PLINT *nx, PLINT *ny, PLFLT *xmin, PLFLT *xmax, PLFLT *ymin, PLFLT *ymax, PLFLT *zmin, PLFLT *zmax, @@ -420,6 +421,7 @@ plFree2dGrid(pidata, *nx, *ny); } +#endif void PLIMAGE(PLFLT *idata, PLINT *nx, PLINT *ny, Modified: trunk/bindings/f95/plstubs.h =================================================================== --- trunk/bindings/f95/plstubs.h 2008-07-19 20:17:57 UTC (rev 8542) +++ trunk/bindings/f95/plstubs.h 2008-07-19 21:56:21 UTC (rev 8543) @@ -213,7 +213,8 @@ #define PLHLS FNAME(PLHLS,plhls) #define PLHLSRGB FNAME(PLHLSRGB,plhlsrgb) #define PLIMAGE FNAME(PLIMAGEF77,plimagef77) -#define PLIMAGEFR FNAME(PLIMAGEFRF77,plimagefrf77) +/* Commented out until fixed to use pltr */ +/*#define PLIMAGEFR FNAME(PLIMAGEFRF77,plimagefrf77)*/ #define PLINIT FNAME(PLINIT,plinit) #define PLJOIN FNAME(PLJOIN,pljoin) #define PLLAB7 FNAME(PLLAB7,pllab7) Modified: trunk/bindings/f95/scstubs.c =================================================================== --- trunk/bindings/f95/scstubs.c 2008-07-19 20:17:57 UTC (rev 8542) +++ trunk/bindings/f95/scstubs.c 2008-07-19 21:56:21 UTC (rev 8543) @@ -398,6 +398,7 @@ c_plhlsrgb(*h, *l, *s, r, g, b); } +#if 0 void PLIMAGEFR(PLFLT *idata, PLINT *nx, PLINT *ny, PLFLT *xmin, PLFLT *xmax, PLFLT *ymin, PLFLT *ymax, PLFLT *zmin, PLFLT *zmax, @@ -422,6 +423,7 @@ plFree2dGrid(pidata, *nx, *ny); } +#endif void PLIMAGE(PLFLT *idata, PLINT *nx, PLINT *ny, Modified: trunk/bindings/f95/sfstubsf95.f90 =================================================================== --- trunk/bindings/f95/sfstubsf95.f90 2008-07-19 20:17:57 UTC (rev 8542) +++ trunk/bindings/f95/sfstubsf95.f90 2008-07-19 21:56:21 UTC (rev 8543) @@ -940,21 +940,21 @@ call plhistf77( size(data), data, datmin, datmax, nbin, oldwin ) end subroutine plhist - subroutine plimagefr( idata, xmin, xmax, ymin, ymax, zmin, zmax, & - dxmin, dxmax, dymin, dymax, valuemin, valuemax ) - real(kind=plflt), dimension(:,:) :: idata - real(kind=plflt) :: xmin, xmax, ymin, ymax, zmin, zmax - real(kind=plflt) :: dxmin, dxmax, dymin, dymax, & - valuemin, valuemax +! subroutine plimagefr( idata, xmin, xmax, ymin, ymax, zmin, zmax, & +! dxmin, dxmax, dymin, dymax, valuemin, valuemax ) +! real(kind=plflt), dimension(:,:) :: idata +! real(kind=plflt) :: xmin, xmax, ymin, ymax, zmin, zmax +! real(kind=plflt) :: dxmin, dxmax, dymin, dymax, & +! valuemin, valuemax +! +! integer :: nx, ny +! +! nx = size(idata,1) +! ny = size(idata,2) +! call plimagefrf77( idata, nx, ny, xmin, xmax, ymin, ymax, zmin, zmax, & +! dxmin, dxmax, dymin, dymax, valuemin, valuemax ) +! end subroutine plimagefr - integer :: nx, ny - - nx = size(idata,1) - ny = size(idata,2) - call plimagefrf77( idata, nx, ny, xmin, xmax, ymin, ymax, zmin, zmax, & - dxmin, dxmax, dymin, dymax, valuemin, valuemax ) - end subroutine plimagefr - subroutine plimage( idata, xmin, xmax, ymin, ymax, zmin, zmax, & dxmin, dxmax, dymin, dymax ) real(kind=plflt), dimension(:,:) :: idata Modified: trunk/doc/docbook/src/api.xml =================================================================== --- trunk/doc/docbook/src/api.xml 2008-07-19 20:17:57 UTC (rev 8542) +++ trunk/doc/docbook/src/api.xml 2008-07-19 21:56:21 UTC (rev 8543) @@ -5538,12 +5538,10 @@ <paramdef><parameter>ymax</parameter></paramdef> <paramdef><parameter>zmin</parameter></paramdef> <paramdef><parameter>zmax</parameter></paramdef> - <paramdef><parameter>Dxmin</parameter></paramdef> - <paramdef><parameter>Dxmax</parameter></paramdef> - <paramdef><parameter>Dymin</parameter></paramdef> - <paramdef><parameter>Dymax</parameter></paramdef> <paramdef><parameter>valuemin</parameter></paramdef> <paramdef><parameter>valuemax</parameter></paramdef> + <paramdef><parameter>pltr</parameter></paramdef> + <paramdef><parameter>pltr_data</parameter></paramdef> </funcprototype> </funcsynopsis> </para> @@ -5602,18 +5600,6 @@ </varlistentry> <varlistentry> <term> - <parameter>Dxmin, Dxmax, Dymin, Dymax</parameter> - (<literal>PLFLT</literal>, input) - </term> - <listitem> - <para> - Plot only the window of points whose plot coordinates fall inside - the window of (Dxmin, Dymin) to (Dxmax, Dymax). - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> <parameter>valuemin, valuemax</parameter> (<literal>PLFLT</literal>, input) </term> @@ -5627,6 +5613,42 @@ </para> </listitem> </varlistentry> + <varlistentry> + <term> + <parameter>pltr</parameter> + (<literal>void (*) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer) + </literal>, input) + </term> + <listitem> + <para> + Pointer to function that defines transformation between indices + in array <literal><parameter>idata</parameter></literal> and the + world coordinates (C only). Transformation functions are + provided in the PLplot library: + &pltr0; for identity mapping, and &pltr1; and &pltr2; for + arbitrary mappings respectively defined by one- and + two-dimensional arrays. In addition, user-supplied routines + for the transformation can be used as well. Examples of + all of these approaches are given in + <xref linkend="contour-plots-c"/>. + The transformation function should + have the form given by any of &pltr0;, &pltr1;, or &pltr2;. + </para> + </listitem> + </varlistentry> + <varlistentry> + <term> + <parameter>pltr_data</parameter> + (<literal>PLPointer</literal>, input) + </term> + <listitem> + <para> + Extra parameter to help + pass information to &pltr0;, &pltr1;, &pltr2;, or whatever routine + that is externally supplied. + </para> + </listitem> + </varlistentry> </variablelist> <para> @@ -5637,8 +5659,7 @@ General: <function> plimagefr(idata, xmin, xmax, ymin, ymax, - zmin, zmax, Dxmin, Dxmax, Dymin, Dymax, - valuemin, valuemax) + zmin, zmax, valuemin, valuemax, pltr, pltr_data) </function> </para> </listitem> Modified: trunk/examples/c/x20c.c =================================================================== --- trunk/examples/c/x20c.c 2008-07-19 20:17:57 UTC (rev 8542) +++ trunk/examples/c/x20c.c 2008-07-19 21:56:21 UTC (rev 8543) @@ -65,6 +65,14 @@ NULL } /* long syntax */ }; +/* Transformation function */ +static void +mypltr(PLFLT x, PLFLT y, PLFLT *tx, PLFLT *ty, void *pltr_data) +{ + *tx = x + 2.0 * sin(x) + cos(y); + *ty = y + sin(x) + 2.0 * cos(y); +} + int main(int argc, const char *argv[]) { @@ -72,6 +80,8 @@ PLFLT xi, yi, xe, ye; int i, j, width, height, num_col; PLFLT **img_f; + PLFLT img_min; + PLFLT img_max; /* Bugs in plimage(): @@ -222,6 +232,22 @@ pladv(0); } + /* Base the dynamic range on the image contents. */ + plMinMax2dGrid(img_f, width, height, &img_max, &img_min); + + /* Draw a saturated version of the original image. Only use the middle 50% + of the image's full dynamic range. */ + plcol0(2); + plenv(0, width, 0, height, 1, -1); + pllab("", "", "Reduced dynamic range image example"); + plimagefr(img_f, width, height, 0., width, 0., height, 0., 0., img_min + img_max * 0.25, img_max - img_max * 0.25, NULL, NULL); + + /* Draw a distorted version of the original image, showing its full dynamic range. */ + plenv(0, width, 0, height, 1, -1); + pllab("", "", "Distorted image example"); + plimagefr(img_f, width, height, 0., width, 0., height, 0., 0., img_min, img_max, mypltr, NULL); + pladv(0); + plFree2dGrid(img_f, width, height); plend(); Modified: trunk/include/plplot.h =================================================================== --- trunk/include/plplot.h 2008-07-19 20:17:57 UTC (rev 8542) +++ trunk/include/plplot.h 2008-07-19 21:56:21 UTC (rev 8543) @@ -1463,9 +1463,10 @@ PLDLLIMPEXP void c_plimagefr(PLFLT **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, - PLFLT valuemin, PLFLT valuemax); + PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax, + PLFLT valuemin, PLFLT valuemax, + void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer), + PLPointer pltr_data); /* plots a 2d image (or a matrix too large for plshade() ) - colors automatically scaled */ Modified: trunk/include/plplotP.h =================================================================== --- trunk/include/plplotP.h 2008-07-19 20:17:57 UTC (rev 8542) +++ trunk/include/plplotP.h 2008-07-19 21:56:21 UTC (rev 8543) @@ -892,7 +892,8 @@ /* draw image */ void -plP_image(short *x, short *y, unsigned short *z, PLINT nx, PLINT ny, PLFLT xmin, PLFLT ymin, PLFLT dx, PLFLT dy, unsigned short zmin, unsigned short zmax); +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); /* End of page */ @@ -974,9 +975,10 @@ plInBuildTree(); void -plimageslow(short *x, short *y, unsigned short *data, PLINT nx, PLINT ny, - PLFLT xmin, PLFLT ymin, PLFLT dx, PLFLT dy, - unsigned short zmin, unsigned short zmax); +plimageslow(PLFLT *idata, PLINT nx, PLINT ny, + PLFLT xmin, PLFLT ymin, PLFLT dx, PLFLT dy, + void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer), + PLPointer pltr_data); typedef struct { PLFLT xmin, ymin, dx, dy;} IMG_DT; Modified: trunk/src/plbuf.c =================================================================== --- trunk/src/plbuf.c 2008-07-19 20:17:57 UTC (rev 8542) +++ trunk/src/plbuf.c 2008-07-19 21:56:21 UTC (rev 8543) @@ -659,7 +659,14 @@ rd_data(pls, dev_iy, sizeof(short) * npts); rd_data(pls, dev_z, sizeof(unsigned short) * (nptsX-1)*(nptsY-1)); - plP_image(dev_ix, dev_iy, dev_z, nptsX, nptsY, xmin, ymin, dx, dy, dev_zmin, dev_zmax); + /* + * COMMENTED OUT by Hezekiah Carty + * Commented (hopefullly temporarily) until the dev_fastimg rendering + * path can be updated to support the new plimage internals. In the + * meantime this function is not actually used so the issue of how to + * update the code to support the new interface can be ignored. + */ + /*plP_image(dev_ix, dev_iy, dev_z, nptsX, nptsY, xmin, ymin, dx, dy, dev_zmin, dev_zmax);*/ free(dev_ix); free(dev_iy); Modified: trunk/src/plcore.c =================================================================== --- trunk/src/plcore.c 2008-07-19 20:17:57 UTC (rev 8542) +++ trunk/src/plcore.c 2008-07-19 21:56:21 UTC (rev 8543) @@ -3425,13 +3425,30 @@ * * Author: Alessandro Mirone, Nov 2001 * + * Updated by Hezekiah Carty, Mar 2008. + * - Added support for pltr callback + * - Commented out the "dev_fastimg" rendering path * - * \*--------------------------------------------------------------------------*/ void -plP_image(short *x, short *y, unsigned short *z , PLINT nx, PLINT ny, PLFLT xmin, PLFLT ymin, PLFLT dx, PLFLT dy, unsigned short zmin, unsigned short zmax) +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) { + plsc->page_status = DRAWING; + + plimageslow(z, nx, ny, xmin, ymin, dx, dy, pltr, pltr_data); + + /* + * COMMENTED OUT by Hezekiah Carty, March 2008 + * The current dev_fastimg rendering method does not work as-is with + * the plimagefr coordinate transform support. + * This is hopefully temporary, until the dev_fastimg rendering + * path can be updated to work with the new plimage internals. + * Until then, all plimage* rendering is done by the plimageslow + * rendering path. + */ +#if 0 /* BEGIN dev_fastimg COMMENT */ PLINT i, npts; short *xscl, *yscl; int plbuf_write; @@ -3497,4 +3514,5 @@ grimage(x, y, z, nx, ny ); } plsc->plbuf_write = plbuf_write; +#endif /* END dev_fastimg COMMENT */ } Modified: trunk/src/plimage.c =================================================================== --- trunk/src/plimage.c 2008-07-19 20:17:57 UTC (rev 8542) +++ trunk/src/plimage.c 2008-07-19 21:56:21 UTC (rev 8543) @@ -2,6 +2,7 @@ * * Author: Alessandro Mirone, Nov 2001 * Adapted: Joao Cardoso + * Updated: Hezekiah Carty 2008 * * Copyright (C) 2004 Alan W. Irwin * @@ -24,7 +25,11 @@ #include "plplotP.h" -/* Get better names, those are too criptic! +#define COLOR_MIN 0.0 +#define COLOR_MAX 1.0 +#define COLOR_NO_PLOT (-1.0) + +/* Get better names, those are too cryptic! * * ZEROW2B: zero writing to buffer ? * ZEROW2D: zero writing to display ? @@ -70,55 +75,63 @@ +/* + * NOTE: The plshade* functions require that both pltr and pltr_data are set + * in order for pltr to be used. plimageslow does NOT require this, so it is + * up to the user to make sure pltr_data is something non-NULL if pltr + * requires it. + * Plottable values in idata must be scaled between COLOR_MIN and COLOR_MAX. + * This is an internal function, and should not be used directly. Its + * interface may change. + */ void -plimageslow(short *x, short *y, unsigned short *data, PLINT nx, PLINT ny, - PLFLT xmin, PLFLT ymin, PLFLT dx, PLFLT dy, - unsigned short zmin, unsigned short zmax) +plimageslow(PLFLT *idata, PLINT nx, PLINT ny, + PLFLT xmin, PLFLT ymin, PLFLT dx, PLFLT dy, + void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer), + PLPointer pltr_data) { + /* Indices */ PLINT ix, iy, i; + /* Float coordinates */ PLFLT xf[4], yf[4]; - short xs[5], ys[5]; + /* Translated (by pltr) coordinates */ + PLFLT tx, ty; + /* The corners of a single filled region */ int corners[4]; - unsigned short col; + /* The color to use in the fill */ + PLFLT color; for (ix = 0; ix < nx ; ix++) { for (iy = 0; iy < ny ; iy++) { + /* Only plot values within in appropriate range */ + color = idata[ix * ny + iy]; + if (color == COLOR_NO_PLOT) + continue; - col = data[ix*ny+iy]; - /* only plot points within zmin/zmax range */ - if (col < zmin || col > zmax) - continue; + /* The color value has to be scaled to 0.0 -> 1.0 plcol1 color values */ + plcol1(color / COLOR_MAX); - plcol1(col/(float)USHRT_MAX); + xf[0] = xf[1] = ix; + xf[2] = xf[3] = ix + 1; + yf[0] = yf[3] = iy; + yf[1] = yf[2] = iy + 1; - if (plsc->plbuf_read == 1) { - /* buffer read, is a replot to a slow device. */ - - corners[0] = ix*(ny+1)+iy; /* [ix][iy] */ - corners[1] = (ix+1)*(ny+1)+iy; /* [ix+1][iy] */ - corners[2] = (ix+1)*(ny+1)+iy+1; /* [ix+1][iy+1] */ - corners[3] = ix*(ny+1)+iy+1; /* [ix][iy+1] */ - - for (i = 0; i < 4; i++) { - xs[i] = x[corners[i]]; - ys[i] = y[corners[i]]; - } - xs[4] = xs[0]; ys[4] = ys[0]; - plP_fill(xs, ys, 5); - - } else { - - xf[0] = xf[1] = ix; - xf[2] = xf[3] = ix+1; - yf[0] = yf[3] = iy; - yf[1] = yf[2] = iy+1; - - for (i = 0; i < 4; i++) { - xf[i] = xmin + xf[i]*dx; - yf[i] = ymin + yf[i]*dy; - } - plfill(4, xf, yf); + if (pltr) { + for (i = 0; i < 4; i++) { + /* Translate the points */ + (*pltr) (xf[i], yf[i], &tx, &ty, pltr_data); + xf[i] = tx; + yf[i] = ty; + } } + else { + for (i = 0; i < 4; i++) { + /* Automatic translation to the specified plot area */ + xf[i] = xmin + xf[i] * dx; + yf[i] = ymin + yf[i] * dy; + } + } + plfill(4, xf, yf); } } } @@ -152,10 +165,6 @@ * only data within bounds zmin <= data <= zmax will be * plotted. If zmin == zmax, all data will be ploted. * - * Dxmin, Dxmax, Dymin, Dymax: - * plots only the window of points whose(x,y)'s fall - * inside the [Dxmin->Dxmax]X[Dymin->Dymax] window - * * valuemin, valuemax: * The minimum and maximum values to use for value -> color * mappings. A value in idata of valuemin or less will have @@ -170,118 +179,94 @@ * image content. * \*-------------------------------------------------------------------------*/ - void c_plimagefr(PLFLT **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, - PLFLT valuemin, PLFLT valuemax) + PLFLT valuemin, PLFLT valuemax, + void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer), + PLPointer pltr_data) { - PLINT nnx, nny, ix, iy, ixx, iyy, xm, ym; + PLINT ix, iy; PLFLT dx, dy; - /* Zf holds transformed image pixel values - * szmin and szmax are zmin and zmax scaled to unsigned short values */ - unsigned short *Zf, szmin, szmax; - short *Xf, *Yf; + /* z holds scaled image pixel values */ + PLFLT *z; /* This is used when looping through the image array, checking to - * make sure the values are within an acceptable range. */ + make sure the values are within an acceptable range. */ PLFLT datum; + /* Color palette 0 color in use before the plimage* call */ + PLINT init_color; if (plsc->level < 3) { - plabort("plimage: window must be set up first"); + plabort("plimagefr: window must be set up first"); return; } if (nx <= 0 || ny <= 0) { - plabort("plimage: nx and ny must be positive"); + plabort("plimagefr: nx and ny must be positive"); return; } - if (Dxmin < xmin || Dxmax > xmax || Dymin < ymin || Dymax > ymax) { - plabort("plimage: Dxmin or Dxmax or Dymin or Dymax not compatible with xmin or xmax or ymin or ymax."); - return; + if ((z = (PLFLT *) malloc(ny * nx * sizeof(PLFLT))) == NULL) { + plexit("plimagefr: Insufficient memory"); } - dx = (xmax - xmin) / (nx - 1); - dy = (ymax - ymin) / (ny - 1); - nnx = (Dxmax-Dxmin)/dx + 1; - nny = (Dymax-Dymin)/dy + 1; + /* Save the currently-in-use color. */ + init_color = plsc->icol0; - if ((Zf = (unsigned short *) malloc(nny*nnx*sizeof(unsigned short)))==NULL) - { - plexit("plimage: Insufficient memory"); - } + /* If no acceptable data range is given, then set the min/max data range + to include all of the given data. */ + if (zmin == zmax) { + /* Find the minimum and maximum values in the image */ + plMinMax2dGrid(idata, nx, ny, &zmax, &zmin); + } - xm = floor((Dxmin-xmin)/dx); ym = floor((Dymin-ymin)/dy); - - /* Go through the image values and scale them to fit in an - * unsigned short range. - * Any values greater than valuemax are set to valuemax, - * and values less than valuemin are set to valuemin. */ - ixx=-1; - for (ix=xm; ix<xm+nnx; ix++) { - ixx++; iyy=0; - for (iy=ym; iy<ym+nny; iy++) { - datum = idata[ix][iy]; - if (datum < valuemin) { - datum = valuemin; + /* Go through the image values and scale them to fit in + the COLOR_MIN to COLOR_MAX range. + Any values greater than valuemax are set to valuemax, + and values less than valuemin are set to valuemin. + Any values outside of zmin to zmax are flagged so they + are not plotted. */ + for (ix = 0; ix < nx; ix++) { + for (iy = 0; iy < ny; iy++) { + if (valuemin == valuemax) { + /* If valuemin == valuemax, avoid dividing by zero. */ + z[ix * ny + iy] = (COLOR_MAX + COLOR_MIN) / 2.0; } - else if (datum > valuemax) { - datum = valuemax; + else { + datum = idata[ix][iy]; + if (datum < zmin || datum > zmax) { + /* Set to a guaranteed-not-to-plot value */ + z[ix * ny + iy] = COLOR_NO_PLOT; + } + else { + if (datum < valuemin) { + datum = valuemin; + } + else if (datum > valuemax) { + datum = valuemax; + } + /* Set to a value scaled between COLOR_MIN and COLOR_MAX. */ + z[ix * ny + iy] = + (datum - valuemin + COLOR_MIN) / (valuemax - valuemin) * COLOR_MAX; + } } - Zf[ixx*nny+iyy++] = - (datum - valuemin) / (valuemax - valuemin) * USHRT_MAX; } } - if (zmin == zmax) { - zmin = valuemin; - zmax = valuemax; - } - else { - if (zmin < valuemin) - zmin = valuemin; - if (zmax > valuemax) - zmax = valuemax; - } + /* dx and dy are the plot-coordinates pixel sizes for an untransformed + image */ + dx = (xmax - xmin) / (PLFLT)nx; + dy = (ymax - ymin) / (PLFLT)ny; - /* The value range to plot, scaled to unsigned short values */ - szmin = (zmin - valuemin) / (valuemax - valuemin) * USHRT_MAX; - szmax = (zmax - valuemin) / (valuemax - valuemin) * USHRT_MAX; + plP_image(z, nx, ny, xmin, ymin, dx, dy, pltr, pltr_data); - xmin = Dxmin; xmax = Dxmax; - ymin = Dymin; ymax = Dymax; + plcol0(init_color); - /* The X and Y arrays has size nnx*nny */ - nnx++; nny++; - - if (((Xf = (short *) malloc(nny*nnx*sizeof(short)))==NULL)|| - ((Yf = (short *) malloc(nny*nnx*sizeof(short)))==NULL)) - { - plexit("plimage: Insufficient memory"); - } - - /* adjust the step for the X/Y arrays */ - dx = dx*(nx-1)/nx; - dy = dy*(ny-1)/ny; - - for (ix = 0; ix < nnx; ix++) { - for (iy = 0; iy < nny; iy++) { - Xf[ix*nny+iy] = plP_wcpcx(xmin + ix*dx); - Yf[ix*nny+iy] = plP_wcpcy(ymin + iy*dy); - } - } - - plP_image(Xf, Yf, Zf, nnx, nny, xmin, ymin, dx, dy, szmin, szmax); - - free(Xf); - free(Yf); - free(Zf); + free(z); } /*-------------------------------------------------------------------------*\ * plimage - * (***** SUBJECT TO CHANGE ******) * * arguments are * idata: array containing image data @@ -302,31 +287,82 @@ * inside the [Dxmin->Dxmax]X[Dymin->Dymax] window * \*-------------------------------------------------------------------------*/ - void c_plimage(PLFLT **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) + PLFLT xmin, PLFLT xmax, PLFLT ymin, PLFLT ymax, PLFLT zmin, PLFLT zmax, + PLFLT Dxmin, PLFLT Dxmax, PLFLT Dymin, PLFLT Dymax) { - PLINT ix, iy; - PLFLT data_min, data_max, iz; + PLINT ix, iy, ixx, iyy, xm, ym, nnx, nny; + PLFLT data_min, data_max, dx, dy; + /* z holds the subimage (Dxmin, Dymin) - (Dxmax, Dymax) */ + PLFLT **z; + /* Was any space allocated for z? */ + PLBOOL copied; + copied = FALSE; - /* Find the minimum and maximum values in the image, and automatically - * scale the colors scale over this range. */ - data_min = data_max = idata[0][0]; + if (nx <= 0 || ny <= 0) { + plabort("plimage: nx and ny must be positive"); + return; + } - for (ix = 0; ix < nx; ix++) { - for (iy = 0; iy < ny; iy++) { - iz = idata[ix][iy]; - if (data_max < iz) - data_max = iz; - if (data_min > iz) - data_min = iz; + if (Dxmin < xmin || Dxmax > xmax || Dymin < ymin || Dymax > ymax) { + plabort("plimage: Dxmin or Dxmax or Dymin or Dymax not compatible with xmin or xmax or ymin or ymax."); + return; + } + + if (Dxmax < Dxmin || xmax < xmin || Dymax < Dymin || ymax < ymin) { + plabort("plimage: All (Dxmin < Dxmax) and (Dymin < Dymax) and (xmin < xmax) and (ymin < ymax) must hold."); + return; + } + + /* Find the minimum and maximum values in the image. Use these values to + for the color scale range. */ + plMinMax2dGrid(idata, nx, ny, &data_max, &data_min); + + if (xmin == Dxmin && xmax == Dxmax && ymin == Dymin && ymax == Dymax) { + /* If the whole image should be shown, then no copying is needed. */ + z = idata; + nnx = nx; + nny = ny; + } + else { + /* dx and dy are the plot-coordinates pixel sizes for an untransformed + image */ + dx = (xmax - xmin) / (PLFLT)nx; + dy = (ymax - ymin) / (PLFLT)ny; + + /* Pixel dimensions of the (Dxmin, Dymin) to (Dxmax, Dymax) box */ + nnx = ceil((Dxmax - Dxmin) / dx); + nny = ceil((Dymax - Dymin) / dy); + + /* Call plimagefr with the value -> color range mapped to the minimum + Offsets for the idata indices to select + (Dxmin, Dymin) to (Dxmax, Dymax) */ + xm = floor((Dxmin - xmin) / dx); + ym = floor((Dymin - ymin) / dy); + + /* Allocate space for the sub-image */ + plAlloc2dGrid(&z, nnx, nny); + + /* Go through the image and select the pixels within the given + (Dxmin, Dymin) - (Dxmax, Dymax) window. */ + ixx = -1; + for (ix = xm; ix < xm + nnx; ix++) { + ixx++; iyy=0; + for (iy = ym; iy < ym + nny; iy++) { + z[ixx][iyy++] = idata[ix][iy]; + } } + + /* Set the appropriate values to pass in to plimagefr */ + copied = TRUE; } - /* Call plimagefr with the value -> color range mapped to the minimum - * and maximum values in idata. */ - plimagefr(idata, nx, ny, xmin, xmax, ymin, ymax, zmin, zmax, - Dxmin, Dxmax, Dymin, Dymax, data_min, data_max); + plimagefr(z, nnx, nny, Dxmin, Dxmax, Dymin, Dymax, zmin, zmax, + data_min, data_max, NULL, NULL); + + /* Only free the memory if it was allocated by us... */ + if (copied == TRUE) { + plFree2dGrid(z, nnx, nny); + } } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |