|
From: V. <gae...@no...> - 2005-08-16 18:03:16
|
I have found a strange behaviour of the image code.=20
Here is a minimal example :
set xrange [-10:137]
set yrange [-10:157]
unset colorbox
plot 'blutux.rgb' binary array=3D128x128 flip xy \
format=3D'%uchar%uchar%uchar' every 64:16 using ($1+$2+$3) with image
With the standard terminal drivers (x11, post, png) this works without a
flaw, but while working on the povray terminal, on the image code, I note=
d
that corner[0].x ends up being negative ! But it is a unsigned int !!
The other terminals use it by calling it "(int) corner[0].x", thus
forcing the conversion to a negativ integer. However if I put a=20
"fprintf(gpoutfile, "corner[0].x : %u\n",corner[0].x)" I get a
ridiculously high value printed. Printing it as an integer solves the
problem, and this is how I worked around this.
I suspect this problem is lying around in other places (I think I
might have seen it elsewhere, but it is hard to trick gnuplot into
making a negative value for a coordinate). Maybe those "(int)" casts in
many of the terminal drivers are just hiding more bug.
I just had a look at the way the post terminal calls this :
line 3777 : fprintf(gppsfile, "%d %d translate\n", corner[0].x, corner[0]=
.y);
Why %d and not %u ?
I am wrong or is there a problem here ? Maybe these should not
be unsigned ints, but ints ? Checking for there sign seems a bit
complicated.
--
Ga=EBl
|
|
From: Daniel J S. <dan...@ie...> - 2005-08-16 18:52:32
|
You may have found a bug. OK, let's see. I haven't looked at any data or examples, but my initial suspicion is tha= t although the following > line 3777 : fprintf(gppsfile, "%d %d translate\n", corner[0].x, corner[= 0].y); >=20 > Why %d and not %u ? is a conflict, unless corner[0].x is very large (i.e., the highest bit ch= anges from 0 to 1) it will not print an incorrect value. I do notice that corner.x and corner.y are unsigned int as part of gpiPoi= nt. In 'graphics.c' there is map_x() used to assign a value to corner.x = . However, map_x() is #define map_x(x) AXIS_MAP(x_axis, x) #define AXIS_MAP(axis, variable) \ (int) ((axis_array[axis].term_lower) \ + ((variable) - axis_array[axis].min) \ * axis_array[axis].term_scale + 0.5) I.e., not unsigned. So there may be a problem here. I think it wouldn't= be unlikely that somehow this could be a negative value, if only due to = rounding or whatnot. So the question here may be What world should corner.x and corner.y live = in? Signed or unsigned? I'm not sure I put too much thought into this o= riginally. I may have just patterned the function after that for filled = polygons _filled_polygon(int points, gpiPoint *corners) I'll have to look at this when I have more time. Thanks, Dan Ga=EBl Varoquaux wrote: > I have found a strange behaviour of the image code.=20 > Here is a minimal example : >=20 > set xrange [-10:137] > set yrange [-10:157] >=20 > unset colorbox > plot 'blutux.rgb' binary array=3D128x128 flip xy \ > format=3D'%uchar%uchar%uchar' every 64:16 using ($1+$2+$3) with image >=20 >=20 > With the standard terminal drivers (x11, post, png) this works without = a > flaw, but while working on the povray terminal, on the image code, I no= ted > that corner[0].x ends up being negative ! But it is a unsigned int !! > The other terminals use it by calling it "(int) corner[0].x", thus > forcing the conversion to a negativ integer. However if I put a=20 > "fprintf(gpoutfile, "corner[0].x : %u\n",corner[0].x)" I get a > ridiculously high value printed. Printing it as an integer solves the > problem, and this is how I worked around this. > I suspect this problem is lying around in other places (I think I > might have seen it elsewhere, but it is hard to trick gnuplot into > making a negative value for a coordinate). Maybe those "(int)" casts in > many of the terminal drivers are just hiding more bug. > I just had a look at the way the post terminal calls this : > line 3777 : fprintf(gppsfile, "%d %d translate\n", corner[0].x, corner[= 0].y); >=20 > Why %d and not %u ? >=20 > I am wrong or is there a problem here ? Maybe these should not > be unsigned ints, but ints ? Checking for there sign seems a bit > complicated. >=20 > -- > Ga=EBl >=20 >=20 > ------------------------------------------------------- > SF.Net email is Sponsored by the Better Software Conference & EXPO > September 19-22, 2005 * San Francisco, CA * Development Lifecycle Pract= ices > Agile & Plan-Driven Development * Managing Projects & Teams * Testing &= QA > Security * Process Improvement & Measurement * http://www.sqe.com/bsce5= sf > _______________________________________________ > gnuplot-beta mailing list > gnu...@li... > https://lists.sourceforge.net/lists/listinfo/gnuplot-beta >=20 >=20 --=20 Dan Sebald phone: 608 256 7718 email: daniel DOT sebald AT ieee DOT org URL: http://acer-access DOT com/~dsebald AT acer-access DOT com/ |
|
From: Daniel J S. <dan...@ie...> - 2005-08-16 18:59:47
|
Ga=EBl,
For your povray terminal, what is the value of axis_array[axis].term_lowe=
r? Perhaps on other terminals these are large values (i.e., the terminal=
axis has a noticable offset compared to its base coordinate system) and =
the int/unsigned issue becomes a non-issue.
#define AXIS_MAP(axis, variable) \
(int) ((axis_array[axis].term_lower) \
+ ((variable) - axis_array[axis].min) \
* axis_array[axis].term_scale + 0.5)
Dan
|
|
From: V. <gae...@no...> - 2005-08-17 12:00:27
|
> For your povray terminal, what is the value of axis_array[axis].term_lo=
wer?=20
> Perhaps on other terminals these are large values (i.e., the terminal a=
xis=20
> has a noticable offset compared to its base coordinate system) and the=20
> int/unsigned issue becomes a non-issue.
I didn't define any ! I wasn't even aware that such a thing existed
(I still don"t know gnuplot's code terribly well). However, grepping the
term directory seems to show me that only the x11 and the tkcanvas use
it, and only to read values out of it, not to assign anything to it.
I tried to see how this "axis_array[axis].term_lower" was assigned.
It is assigned in axis.c, line 1314, by axis_graphical_range, and this
function is called in graph3d.c and graphics.c with argument alike
"xleft", itself defined, for instance by :
xleft =3D (int) (xoffset * t->xmax
+ t->h_char * (lmargin >=3D 0 ? lmargin : 2));
So what your are telling me is indeed that my t->xmax, and t->h_char
are ill defined ?
Povray terminal has :
#define POVRAY_XMAX (4096)
#define POVRAY_YMAX (4096)
and=20
#define POVRAY_HCHAR (POVRAY_XMAX/60)
And, as a comparison, postscript terminal has :
#define PS_XMAX (10*720)
#define PS_HCHAR (14*PS_SC*6/10)
where PS_SC is given by :
#define PS_SC 10
So t->xmax =3D 4096 for povray, 7200 for postscript,
t->h_char ~ 68 for povray, 84 for postscript.
I don't see any obvious difference, but I think I have missed your
point. I don't really understand where axis_array[axis].term_lower comes
from, and what it is supposed to be.
--
Ga=EBl
|
|
From: Hans-Bernhard B. <br...@ph...> - 2005-08-17 12:25:25
|
Ga=EBl Varoquaux wrote: > I don't see any obvious difference, but I think I have missed your > point. I don't really understand where axis_array[axis].term_lower come= s > from, and what it is supposed to be. It's the lower border of the graph box, in terminal coordinates. In=20 other words, for axis=3DFIRST_Y_AXIS, this is where the x axis will be (i= n=20 a 2D plot). It must be non-negative, and smaller than term->ymax.=20 Similarly, axis_array[FIRST_X_AXIS].term_lower is the position of the y=20 axis, and must be between zero and term->xmax - 1, inclusive. The values of these variables are computed in graphics.c:boundary() and=20 graph3d.c:boundary3d(), respectively, and used heavily by macros and=20 functions in the 'axis' module, like AXIS_MAP(), and its callers map_x() = and map_y(). Signed vs. unsigned issues plague the gnuplot source quite a bit. It's=20 so bad that I've long since given up trying to enable gcc's=20 -Wsign-compare even in my "picky mode" CFLAGS. You have to tread=20 carefully there. And try to remember that we have at least some drivers = where INT_MAX < term->xmax < UINT_MAX. so no, casting isn't generally going to help. |
|
From: Daniel J S. <dan...@ie...> - 2005-08-17 14:49:40
|
Ga=EBl Varoquaux wrote: > Povray terminal has : > #define POVRAY_XMAX (4096) > #define POVRAY_YMAX (4096) >=20 > and=20 > #define POVRAY_HCHAR (POVRAY_XMAX/60) >=20 > And, as a comparison, postscript terminal has : > #define PS_XMAX (10*720) >=20 > #define PS_HCHAR (14*PS_SC*6/10) >=20 > where PS_SC is given by : > #define PS_SC 10 >=20 > So t->xmax =3D 4096 for povray, 7200 for postscript, > t->h_char ~ 68 for povray, 84 for postscript. These numbers don't look unreasonable, I guess. > I don't see any obvious difference, but I think I have missed your > point. I don't really understand where axis_array[axis].term_lower come= s > from, and what it is supposed to be. All I'm saying is use a printf(...) or fprintf(stdout,...) to print out t= he values to perhaps pinpoint where the negative number is occurring. (W= hich you did.) Is POV-Ray v3.7.beta.8 on the web page http://www.povray.= org/ what we are talking about to utilize the povray patch? (Could you p= ut the patch on the SourceForge page?) Dan |
|
From: V. <gae...@no...> - 2005-08-17 15:47:51
|
On Wed, Aug 17, 2005 at 09:54:16AM -0500, Daniel J Sebald wrote: > Is POV-Ray v3.7.beta.8 on the web page http://www.povray.org/ > what we are talking about to utilize the povray patch?=20 Any povray above or including 3.5 would do the trick.=20 =20 > (Could you put the patch on the SourceForge page?) I feel really stupid : I do not know how to do a "patch". I think it involves the "diff" program, but I have not been succesfull at make it give the right kind of output : I get something that look like : """""""""""""""""""""""""""""""""""""""""""""""""""""" diff -r gnuplot/src/makefile.all gnuplot-patch/src/makefile.all 29c29 < $(T)win.trm $(T)x11.trm $(T)xlib.trm --- > $(T)win.trm $(T)x11.trm $(T)xlib.trm $(T)povray.trm diff -r gnuplot/src/makefile.awc gnuplot-patch/src/makefile.awc 29c29 < $(T)win.trm $(T)x11.trm $(T)xlib.trm --- > $(T)win.trm $(T)x11.trm $(T)xlib.trm $(T)povray.trm Only in gnuplot-patch/term: povray.trm """""""""""""""""""""""""""""""""""""""""""""""""""""" and that does not look like the patches I download from sourceforge. -- Ga=EBl |
|
From: Hans-Bernhard B. <br...@ph...> - 2005-08-17 16:05:54
|
Ga=EBl Varoquaux wrote: > I feel really stupid : I do not know how to do a "patch". I think i= t > involves the "diff" program, but I have not been succesfull at make it > give the right kind of output=20 > and that does not look like the patches I download from sourceforge= =2E You want to use something like diff -urp old_directory new_directory instead. If you have added any files (like 'povray.trm'), also check=20 out options -N and --unidirectional-new-file in the 'diff'=20 documentation. For diffs that are made not for patching, but just for=20 looking at what you did, it often helps to use options -w and -B, too,=20 so unimportant re-indentations of source code don't show up in the output= : diff -uwBrp old new |
|
From: V. <gae...@no...> - 2005-08-17 16:25:21
|
It's on sourceforge !
--
Ga=EBl
|
|
From: Hans-Bernhard B. <br...@ph...> - 2005-08-17 12:45:03
|
Ga=EBl Varoquaux wrote:
> With the standard terminal drivers (x11, post, png) this works without =
a
> flaw, but while working on the povray terminal, on the image code, I no=
ted
> that corner[0].x ends up being negative ! But it is a unsigned int !!
I.e. it's not really negative. It'll just look negative if you somewhat
incorrectly cast it to a signed value, which is what a printf("%d") will =
do behind your back.
Such a value being presented to the terminal driver is plain and simply=20
*wrong*, and the error was introduced by the core code: it computed a=20
pixel position that is outside the page boundaries and tried to draw=20
there. That's a bug. There are some areas where we can't really help=20
it, like with parts of text that may end up outside the page because we=20
don't really know how large they'll be in the output. For pixel=20
positions passed to term->vector() or similar functions, it's unacceptabl=
e.
> ridiculously high value printed. Printing it as an integer solves the
> problem,=20
No, it doesn't. It just obfuscates it. A POVray driver may not=20
actually care if you try to draw outside the page --- other drivers do,=20
and the core code must never assume it can step outside that border.
|
|
From: Ethan M. <merritt@u.washington.edu> - 2005-08-17 16:25:38
|
On Wednesday 17 August 2005 05:27 am, Hans-Bernhard Broeker wrote: > > Signed vs. unsigned issues plague the gnuplot source quite a bit. Yes. It's really a nightmare. Although you raise a possible issue below, my inclination is that we should never be using unsigned coordinates. Wrapping around to a large positive number is far worse than going negative. > And try to remember that we have at least some drivers > where > > INT_MAX < term->xmax < UINT_MAX. Are you sure? Which ones? -- Ethan A Merritt merritt@u.washington.edu Biomolecular Structure Center Mailstop 357742 University of Washington, Seattle, WA 98195 |
|
From: Hans-Bernhard B. <br...@ph...> - 2005-08-17 18:05:07
|
Ethan Merritt wrote: > Yes. It's really a nightmare. Although you raise a possible > issue below, my inclination is that we should never be using > unsigned coordinates. Wrapping around to a large positive number > is far worse than going negative. Not really. It's the same problem in a different dress. Terminal coordinates are really only valid in some interval. That interval always has one endpoint at zero, by design, so it makes sense for the coordinates to be unsigned. It being unsigned even helps generate faster code: a single test for (x < term->xmax) will detect points that are off to the right or the left. Any case of a coordinate outside that range being passed to the driver is a bug in the core: it's a clear sign that somebody forgot to do proper clipping. An extension to the debug.trm that checks each and every coordinate passed to it (plus options that let you change the sizes it reports to the core) might be in order, to ease testing of such things a bit. >>And try to remember that we have at least some drivers >>where >> >> INT_MAX < term->xmax < UINT_MAX. > > > Are you sure? Which ones? All the 16-bit platforms easily have this potential, 32-bit ones can be driven there. Win16 always is close to behaving like that by default during copy-to-clipboard (24000x18000 pixels). Many others, including postscript, can be made to, if you only 'set size' high enough before 'set term' or use the driver's own 'size' option. |
|
From: Daniel J S. <dan...@ie...> - 2005-08-18 19:42:38
|
Hans-Bernhard Broeker wrote: > Ethan Merritt wrote: > >> Yes. It's really a nightmare. Although you raise a possible issue >> below, my inclination is that we should never be using >> unsigned coordinates. Wrapping around to a large positive number >> is far worse than going negative. > > > Not really. It's the same problem in a different dress. Terminal > coordinates are really only valid in some interval. That interval > always has one endpoint at zero, by design, so it makes sense for the > coordinates to be unsigned. It being unsigned even helps generate > faster code: a single test for (x < term->xmax) will detect points that > are off to the right or the left. > > Any case of a coordinate outside that range being passed to the driver > is a bug in the core: it's a clear sign that somebody forgot to do > proper clipping. I wouldn't rule out any such oversight on my part. There could be half a pixel extending past the "wrap-around" border in some circumstances. Then again, should it be the core's responsibility to deal with boundary checks if ultimately these terminal parameters come from the terminal driver? If yes, then where should the boundary checks be placed? As part of map_x() and map_y()? That would seem to be the logical place for good code reuse. Dan |
|
From: Hans-Bernhard B. <br...@ph...> - 2005-08-18 20:27:18
|
Daniel J Sebald wrote: > Then again, should it be the core's responsibility to deal with boundary > checks if ultimately these terminal parameters come from the terminal > driver? The parameters come from the driver, but the data being plotted don't. By the time they arrive in the driver, they should be usable by it, i.e. within the terminal coordinate range. > If yes, then where should the boundary checks be placed? As > part of map_x() and map_y()? No. Clipping depends on the primitive being drawn, so it can't be done by just clipping individual coordinates. We already have quite a collection of special clipping functions, for that reason: cliptorange clip_point clip_line clip_move / clip_vector clip_put_text clip_put_text_just edge_intersect edge_intersect_steps edge_intersect_fsteps two_edge_intersect two_edge_intersect_steps two_edge_intersect_fsteps bound_intersect edge3d_intersect two_edge3d_intersect Some of those are misnomers, but they all handle clipping either to the graph box interior, or to the page, for various primitives or plotting styles. But clipping should indeed typically happen closely before map_x() is called, because that's where data get transformed from doubles to terminal coordinates. I.e. searching for calls of map_x() can help locate the positions that need to be checked if clipping is being handled correctly. The traditional plot style handlers (plot_lines() & friends) handle clipping by checking input data a couple of processing steps before they ever reach map_x() --- that's what INRANGE/OUTRANGE are about. plot_image_...() doesn't. The problem is that different graphical primitives need different clipping techniques. |
|
From: Ethan M. <merritt@u.washington.edu> - 2005-08-18 21:26:31
|
On Wednesday 17 August 2005 11:06 am, Hans-Bernhard Broeker wrote: > Ethan Merritt wrote: > > > Yes. It's really a nightmare. Although you raise a possible > > issue below, my inclination is that we should never be using > > unsigned coordinates. Wrapping around to a large positive number > > is far worse than going negative. > > Not really. It's the same problem in a different dress. Terminal > coordinates are really only valid in some interval. That interval > always has one endpoint at zero, by design, so it makes sense for the > coordinates to be unsigned. It being unsigned even helps generate > faster code: a single test for (x < term->xmax) will detect points that > are off to the right or the left. Detect, yes. But it does not allow you to clip the line segment. For that you need the "true" negative coordinate so that you can interpolate the intersections with the plot borders. > Any case of a coordinate outside that range being passed to the driver > is a bug in the core: it's a clear sign that somebody forgot to do > proper clipping. We are somewhat talking at cross-purposes. I agree that the core routines should clip before sending to the drivers. Fine. The problem is that the core routines *themselves* use unsigned integers, which they should not. And once the arithmetic has started using unsigned ints, clipping becomes much, much harder. > >>And try to remember that we have at least some drivers > >>where > >> > >> INT_MAX < term->xmax < UINT_MAX. > > Are you sure? Which ones? > > All the 16-bit platforms easily have this potential, 32-bit ones can be > driven there. But only if the terminal claims to have > 32768 pixels. Is that in fact the case? > Win16 always is close to behaving like that by default during > copy-to-clipboard (24000x18000 pixels). Many others, including > postscript, can be made to, if you only 'set size' high enough before > 'set term' or use the driver's own 'size' option. 'set size' is itself highly problematic. I'll make the provocative assertion that size > 1.0 should not be allowed. Or allowed only with the caveat "if you set size > 1.0 then do not complain if your terminal overflows or segfaults". -- Ethan A Merritt merritt@u.washington.edu Biomolecular Structure Center Mailstop 357742 University of Washington, Seattle, WA 98195 |
|
From: Hans-Bernhard B. <br...@ph...> - 2005-08-18 04:06:36
|
Ethan Merritt wrote:
> On Wednesday 17 August 2005 11:06 am, Hans-Bernhard Broeker wrote:
>>Not really. It's the same problem in a different dress. Terminal
>>coordinates are really only valid in some interval. That interval
>>always has one endpoint at zero, by design, so it makes sense for the
>>coordinates to be unsigned. It being unsigned even helps generate
>>faster code: a single test for (x < term->xmax) will detect points that
>>are off to the right or the left.
> Detect, yes. But it does not allow you to clip the line segment.
That's OK --- clipping should not be done in the terminal driver anyway.
> For that you need the "true" negative coordinate so that you
> can interpolate the intersections with the plot borders.
More to the point, you need the original input, i.e. the floating-point
numbers that the plot elements are all specified in.
> I agree that the core routines should clip before sending to the
> drivers. Fine. The problem is that the core routines *themselves*
> use unsigned integers, which they should not.
Agreed, up to a point --- the key issue is that they have to clip
before converting any coordinates to integers, be those signed or
unsigned. For the classic plot styles, it's done by checking the data
points' validity flags (INRANGE/OUTRANGE/UNDEFINED). The 'with image'
implementation, in particular, never checks these flags. Odds are
that's exactly the root of the bug the OP found.
> But only if the terminal claims to have > 32768 pixels.
> Is that in fact the case?
Not by default, but it can be made to be.
>>Win16 always is close to behaving like that by default during
>>copy-to-clipboard (24000x18000 pixels). Many others, including
>>postscript, can be made to, if you only 'set size' high enough before
>>'set term' or use the driver's own 'size' option.
> 'set size' is itself highly problematic.
That's a side issue. 'set term png size 40000,30000' will fail just as
spectacularly ('test' on that one just crashed this machine) ;->
> I'll make the provocative assertion that size > 1.0 should not
> be allowed. Or allowed only with the caveat "if you set size > 1.0
> then do not complain if your terminal overflows or segfaults".
The docs already hint that it may not be the best of all imaginable
ideas to set size to something larger than 1.0. But I don't think that
it should be forbidden.
|
|
From: Daniel J S. <dan...@ie...> - 2005-08-18 18:48:51
|
Hans-Bernhard Broeker wrote: > Ethan Merritt wrote: > >> On Wednesday 17 August 2005 11:06 am, Hans-Bernhard Broeker wrote: > > >>> Not really. It's the same problem in a different dress. Terminal >>> coordinates are really only valid in some interval. That interval >>> always has one endpoint at zero, by design, so it makes sense for the >>> coordinates to be unsigned. It being unsigned even helps generate >>> faster code: a single test for (x < term->xmax) will detect points >>> that are off to the right or the left. > > >> Detect, yes. But it does not allow you to clip the line segment. > > > That's OK --- clipping should not be done in the terminal driver anyway. > >> For that you need the "true" negative coordinate so that you >> can interpolate the intersections with the plot borders. > > > More to the point, you need the original input, i.e. the floating-point > numbers that the plot elements are all specified in. > >> I agree that the core routines should clip before sending to the >> drivers. Fine. The problem is that the core routines *themselves* >> use unsigned integers, which they should not. > > > Agreed, up to a point --- the key issue is that they have to clip > before converting any coordinates to integers, be those signed or > unsigned. For the classic plot styles, it's done by checking the data > points' validity flags (INRANGE/OUTRANGE/UNDEFINED). The 'with image' > implementation, in particular, never checks these flags. Odds are > that's exactly the root of the bug the OP found. The image drawing routine does not use INRANGE. Originally I intended that. There is an in range test in a way, however. Here is the issue. When we speak of a *point* being in range, that is one thing. But consider that the pixel of an image has a non-negligible width. So, there can be pixels for which its centers are just outside the viewable border. They'd be classified as OUTRANGE, but really a portion of the pixel would be visible. Agreed? When pixels are very small, it is not a big deal to leave out a portion of a pixel. But when resolution is low, it's noticeable. But, unlike pm3d, there is no easy way for the core to create portions of a pixel because of the nature of image data. I think that clipping has to be done at the terminal level because every utility has it's own way of handling a portion of an image being viewable. (For example, the X11 code I wrote has as part of its algorithm something that creates portions of a pixel.) In summary, the image code tosses out all pixels that are clearly out of the viewable range, but keeps those just on the exterior of the boundary if they exist. This is why I said a portion of a pixel might be extending off the viewable boundary. Also it's why I'm asking whether the terminal should take care of boundary checking. Have I just given an argument why a signed number passed to the terminal driver, as Ethan suggests, would prove better than unsigned? (Not sure myself.) That is, this may be a case where it is worth being able to tell in which direction something has gone out of range, rather than being able to test out of range with a single unsigned test? Dan |
|
From: Hans-Bernhard B. <br...@ph...> - 2005-08-18 16:47:18
|
Daniel J Sebald wrote: > The image drawing routine does not use INRANGE. Originally I intended > that. There is an in range test in a way, however. > > Here is the issue. When we speak of a *point* being in range, that is > one thing. But consider that the pixel of an image has a non-negligible > width. So, there can be pixels for which its centers are just outside > the viewable border. Well, nobody ever promised doing proper clipping would be easy. It rather certainly is not --- as you can see by looking at the existing code. You didn't believe plot_lines() is a 50-line function just for fun, did you? The fact that it's hard is all the more reason to do it in the core, where we only have to get it right once, instead of re-inventing this for every terminal driver. > They'd be classified as OUTRANGE, but really a > portion of the pixel would be visible. Agreed? If you refer to pixels only by their center (and a globally fixed size), then yes, that can be OUTRANGE without the pixel itself being completely obscured. But exactly because it may be quite large, it's dangerous to assume you can just plot it and expect the terminal driver to resolve this peacefully. The bug we're discussing demonstrates quite nicely just how wrong that can go. > But, unlike pm3d, there is no easy way for the core to create portions > of a pixel because of the nature of image data. Then maybe that nature of image data has to be re-thought. > This is why I said a portion of a pixel might be extending off the > viewable boundary. That may still be fine. What's definitely not fine is if the coordinate of the pixel that you output to the driver is not just outside the graph box, but actually off the page. |
|
From: Daniel J S. <dan...@ie...> - 2005-08-18 17:01:32
|
Hans-Bernhard Broeker wrote: > Daniel J Sebald wrote: > >> The image drawing routine does not use INRANGE. Originally I intended >> that. There is an in range test in a way, however. >> >> Here is the issue. When we speak of a *point* being in range, that is >> one thing. But consider that the pixel of an image has a >> non-negligible width. So, there can be pixels for which its centers >> are just outside the viewable border. > > > Well, nobody ever promised doing proper clipping would be easy. It > rather certainly is not --- as you can see by looking at the existing > code. You didn't believe plot_lines() is a 50-line function just for > fun, did you? To quote the Monkees, I'm a believer. > > The fact that it's hard is all the more reason to do it in the core, > where we only have to get it right once, instead of re-inventing this > for every terminal driver. I think it can't, but let's continue to hash this out... Image data sent to a plotting device, like a PostScript interpretter, is a rectangular matrix--essentially a uniform sampling of intensity (light, field strength, temperature, etc.). There is no way to include in that data individual information about a pixel, say, pixel 25 should be only 0.67 the size of the uniform sampling interval. Rather, I think the only control is to specify an overall visible range for the image. The driver can then stop drawing the pixel once outside the viewable range. This scenario arises when the viewer's resolution is higher than the image data itself, i.e., when an image pixel actually occupies 30 screen pixels, say, in X11. Dan |
|
From: Ethan M. <merritt@u.washington.edu> - 2005-08-18 17:13:32
|
On Thursday 18 August 2005 09:04 am, Daniel J Sebald wrote: > > I think it can't, but let's continue to hash this out... > Image data sent to a plotting device, like a PostScript interpretter, > is a rectangular matrix--essentially a uniform sampling of intensity > (light, field strength, temperature, etc.). > There is no way to include in that data individual information about > a pixel, say, pixel 25 should be only 0.67 the size of the uniform > sampling interval. Bad example. PostScript support for explicit clipping is very straightforward. You set the clipping boundary first, and then draw your big "pixels" without any special processing. PostScript itself will clip them to fit within the requested clipping boundary. The real problem comes from the drivers with external libraries that are too stupid to clip -- libpdf being the prime offender. -- Ethan A Merritt merritt@u.washington.edu Biomolecular Structure Center Mailstop 357742 University of Washington, Seattle, WA 98195 |
|
From: Daniel J S. <dan...@ie...> - 2005-08-18 17:25:50
|
Ethan Merritt wrote: > On Thursday 18 August 2005 09:04 am, Daniel J Sebald wrote: > >>I think it can't, but let's continue to hash this out... >>Image data sent to a plotting device, like a PostScript interpretter, >>is a rectangular matrix--essentially a uniform sampling of intensity >>(light, field strength, temperature, etc.). >>There is no way to include in that data individual information about >>a pixel, say, pixel 25 should be only 0.67 the size of the uniform >>sampling interval. > > > Bad example. PostScript support for explicit clipping is very straightforward. > You set the clipping boundary first, and then draw your big "pixels" without > any special processing. PostScript itself will clip them to fit within the > requested clipping boundary. > > The real problem comes from the drivers with external libraries that are > too stupid to clip -- libpdf being the prime offender. That is my point. PostScript is very capable of dealing with this, just as you describe. It effectively draws a portion of a pixel. And as you point out with libpdf, there appears to be no universal solution to this. I'm arguing that we should not limit the PostScript or X11 drivers because other less-intelligent drivers have no good solution. If libpdf is incapable, then it should be at the driver level that a decision is made to toss out some pixels that partially extend outside the viewable range, i.e., further refinement by possible shrinking the image by one pixel per edge. You agree that PostScript should be allowed to have negative numbers for an image location then? (Or does PostScript always have a greater than zero offset for the origin of the plot area?) Dan |
|
From: Ethan M. <merritt@u.washington.edu> - 2005-08-18 22:36:21
|
On Thursday 18 August 2005 10:26 am, Daniel J Sebald wrote: > > You agree that PostScript should be allowed to have negative numbers for > an image location then? The PostScript language itself allows negative numbers, if that's what you're asking. Whether the gnuplot core routines should ever send negative coordinates to a terminal driver is a rather different question. > (Or does PostScript always have a greater than zero offset for the origin of the plot area?) Zero offset is a legal origin. The result of zero offset and negative coordinates is probably device-dependent. I do not recall ever seeing a printer either crash or wrap around for this reason, but then again one doesn't normally construct such cases on purpose. -- Ethan A Merritt merritt@u.washington.edu Biomolecular Structure Center Mailstop 357742 University of Washington, Seattle, WA 98195 |
|
From: Daniel J S. <dan...@ie...> - 2005-08-18 18:03:40
|
Ethan Merritt wrote:
> On Thursday 18 August 2005 10:26 am, Daniel J Sebald wrote:
>
>>You agree that PostScript should be allowed to have negative numbers for
>>an image location then?
>
>
> The PostScript language itself allows negative numbers, if that's what you're
> asking.
Yeah, I suppose that is why I used a %d rather than a %u in the fprintf() for the PostScript driver. If the core only sends "small" unsigned numbers, having %d there shouldn't hurt anything.
> Whether the gnuplot core routines should ever send negative coordinates
> to a terminal driver is a rather different question.
Actually it is a rather similar question. As far as a frame of reference, it seems to me that when laying out a plot (as with drawing on a piece of paper) you want to leave room on all sides to work with. The following would be equivalent:
1) allow signed coordinates, choose plot area origin near 0
2) allow unsigned coordinates, choose plot area origin way out (halfway?) in the allowable number range
By going with option 2 and then setting axis_array[axis].term_lower to zero in the following formula
#define AXIS_MAP(axis, variable) \
(int) ((axis_array[axis].term_lower) \
+ ((variable) - axis_array[axis].min) \
* axis_array[axis].term_scale + 0.5)
it is like starting a drawing on the corner edge of one's piece of paper.
Dan
|