Page 1 of 1

MagickDrawPolygonPrimitive() hanging indefinitely

Posted: 2012-06-14T09:30:26-07:00
by Caleb9849
Hello all,

I am developing an application which renders a very large number of many-vertex polygons onto a map image. I'm using ImageMagick to do the drawing, and I'm experiencing a very bizarre problem. The application has been tested to run perfectly on several Linux boxes and 32-bit Macs, but when run on 64-bit Mac OS X Lion (other 64-bit Mac OS releases have not yet been tested), the application *sometimes* finishes (with exactly the expected output) but other times hangs, apparently infinitely long (or just *extremely* long) or until forcibly killed. Judging by other tests I've done, it seems to be the case that this only happens if the polygons are complex enough; that is, they have enough vertices (or possibly the vertices are close enough together). The ImageMagick libraries are installed using MacPorts, and through the use of gdb (The GNU debugger) I've been able to determine that the application is getting stuck inside of the MagickDrawPolygonPrimitive() function. I'd like to compile the libraries with gdb symbols enabled (which, when running gdb, provides references back to the source code in the compiled code so that the developer can see much more clearly what is going on in the program being debugged). But the libraries are installed using MacPorts, and I can't seem to discern whether or not there is any way to tell MacPorts I want to do this (all it would take is a -g flag to the compiler when building the libraries).

I have tried building ImageMagick myself from source, with the -g flag. Oddly, when I do this and then build my application against the libraries, the problem of hanging in MagickDrawPolygonPrimitive() goes away entirely (making it very difficult to debug :)), but another problem is introduced, instead: after the output has been generated, I cannot seem to get it written out to any compressed image format (I've tried png, tiff, and jpg). I have gone after *that* one with gdb and found that the function call to the appropriate image compression library (e.g. libpng) is coming back false, so the data cannot be compressed. If I just write to a bitmap instead, the output shows up (every time) and is confirmed to be correct. This is despite inclusion of flags like --with-png when running the configure script.

So in a nutshell, on the MacPorts build of ImageMagick, my application *sometimes* fails to get through all polygon-drawing calls, but if it finishes, it always succeeds in writing the output file even if compressed. On my build of ImageMagick, my application always succeeds in generating the correct image data, and can always write it to a bitmap, but can never write it to a compressed format.

My question is three-fold:

1) Can anyone tell me if there is some way I could get gdb symbols compiled into the MacPorts build of ImageMagick so that I can get in there and see if I can't find out what's going on in MagickDrawPolygonPrimitive()? I'm very curious about this.
2) Does anyone have any off-the-top-of-the-head insight as to what could be causing MagickDrawPolygonPrimitive to get "stuck" but only on this particular platform, and only sometimes?
3) Any ideas as to what could be causing my build to fail in writing its output to a compressed image format? Ideally, I'd like to get question #1 answered, but if I could get my own build of ImageMagick working it would at least be a temporary solution.

Thanks very much in advance for any help!

Re: MagickDrawPolygonPrimitive() hanging indefinitely

Posted: 2012-06-15T10:46:55-07:00
by Caleb9849
Update:

Apparently the issue is connected to the OS release; I have just tested on a 64-bit Snow Leopard (Darwin 10.8) machine and did *not* get the failing behavior. Also, I have managed to narrow the cause somewhat; it seems to be the case that if you give ImageMagick polygons whose vertices have integer coordinates in pixel space that it just "doesn't like" for some reason, it can cause the bad behavior (again, it only happens *sometimes*). I have written up a short test program which demonstrates this, if anyone is interested in seeing it for themselves:

Code: Select all

#include <wand/MagickWand.h>

int main(int argc, char ** argv ) {
	MagickWandGenesis();

	PixelWand * stroke_wand = NewPixelWand();
	PixelSetRed(stroke_wand, 1);
	PixelSetGreen(stroke_wand, 1);
	PixelSetBlue(stroke_wand, 1);
	PixelSetOpacity(stroke_wand, 0);
	PixelWand * transparent_wand = NewPixelWand();
	PixelSetRed(transparent_wand, 0);
	PixelSetGreen(transparent_wand, 0);
	PixelSetBlue(transparent_wand, 0);
	PixelSetOpacity(transparent_wand, 1);

	MagickWand * magic_wand = NewMagickWand();
	MagickNewImage(magic_wand, 500, 500, transparent_wand);

	DrawingWand * line_maker = NewDrawingWand();
	DrawSetStrokeWidth(line_maker, 1);
	DrawSetStrokeColor(line_maker, stroke_wand);
	DrawSetFillColor(line_maker, transparent_wand);

	PointInfo image_coords[25];
	for (int point = 0; point < 25; point++) {
		scanf("%lf", &(image_coords[point].x));
		scanf("%lf", &(image_coords[point].y));
	}
	DrawPolygon(line_maker, 25, image_coords);
	printf("Drew the following polygon:\n");
	for (int i = 0; i < 25; i++) {
		printf("%f, %f", image_coords[i].x, image_coords[i].y);
		printf(i == 24 ? "\n" : "; ");
	}
	MagickDrawImage(magic_wand, line_maker);
	MagickSetImageCompressionQuality(magic_wand, 100);
	MagickWriteImage(magic_wand, "test.png");
	return 0;
}
This program simply takes 25 pairs of PointInfo (x, y) coordinates from stdin and asks the Magick libraries to draw a polygon through those points onto a 500x500 image. Here are two data sets which can be fed into the program, the first of which will cause the bad behavior (again, only sometimes, so you have to give it enough chances, I'd say on average it happens once out of every 5 to 10 tries), and the second of which always runs to completion.

Code: Select all


First polygon:

147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398  147  398

Second polygon:

146  398  146  398  146  398  146  398  146  398  146  398  146  398  146  398  146  398  146  397  147  397  147  397  147  397  147  397  147  397  147  397  147  397  147  397  147  397  147  397  147  397  147  398  147  398  147  398  146  398

Note that there is *very* little difference between the two sets of polygon data, basically a lot of corresponding integers simply differ by 1 from one set to the other. Also, it may be that the effect could be seen with polygons whose vertices number fewer and are more spread out; I am going to do some more testing with specific data to see if I can reproduce the issue with any such polygons.

Re: MagickDrawPolygonPrimitive() hanging indefinitely

Posted: 2012-06-15T12:29:07-07:00
by Caleb9849
Another update: I have further determined that one sure-fire way to make it (liable to) hang is with a polygon of at least 16 points, of which *all* the points have *exactly* the same coordinates. If even one single point differs from the others in either coordinate, there will be no problem. Also, if you remove at least one point so that there are 15 or less points in the polygon, you have also removed the hang.

N.B.: I am very certain that this is not the *only* configuration that can induce the hang, it's just one possible way to go about it.

Re: MagickDrawPolygonPrimitive() hanging indefinitely

Posted: 2012-06-15T16:38:09-07:00
by magick
Unfortunately we cannot reproduce the problem. We're using Linux / ImageMagick 6.7.7-7, the current release. We tried 16 points at (147, 398) all the same with the code you provided. Any other suggestions to cause the rendering methods to hang?

Re: MagickDrawPolygonPrimitive() hanging indefinitely

Posted: 2012-06-15T21:34:11-07:00
by Caleb9849
I'm not surprised that you get it to run correctly on Linux, since that has been my experience as well:
Caleb9849 wrote: The application has been tested to run perfectly on several Linux boxes and 32-bit Macs, but when run on 64-bit Mac OS X Lion (other 64-bit Mac OS releases have not yet been tested), the application *sometimes* finishes (with exactly the expected output) but other times hangs, apparently infinitely long (or just *extremely* long) or until forcibly killed.
Later:
Caleb9849 wrote: Apparently the issue is connected to the OS release; I have just tested on a 64-bit Snow Leopard (Darwin 10.8) machine and did *not* get the failing behavior.
To recap, I have done extensive testing on various Mac and Linux boxes and have thus far only seen the problem occur on Mac OS X Lion. I'll grant, of course, that the problem could easily be internal to Lion itself, and manifesting itself noticeably in ImageMagick, rather than the problem being inherent to ImageMagick. In either case I would very much like to be able to dive in (to the MacPorts build) with gdb and see if I can't discern what the problem is, for curiosity's sake if nothing else.

Re: MagickDrawPolygonPrimitive() hanging indefinitely

Posted: 2012-08-29T08:01:03-07:00
by GeorgeP
I also have this issue. Having run the command through gdb I can also see it stuck in DrawPolygonPrimitive I'm on 64 bit OS X 10.8

Did it get looked into? It's making development a real pain having to kill it off every 5/6 image generations

Re: MagickDrawPolygonPrimitive() hanging indefinitely

Posted: 2012-08-29T09:07:26-07:00
by magick
Can you provide a small code set or drawing command we can use to reproduce the problem? So far we have been unable to reproduce this problem.

Re: MagickDrawPolygonPrimitive() hanging indefinitely

Posted: 2012-08-29T13:43:34-07:00
by GeorgeP
magick wrote:Can you provide a small code set or drawing command we can use to reproduce the problem? So far we have been unable to reproduce this problem.
I've reduced it down to this:

Code: Select all

convert -size 256x256 xc:transparent -draw "path 'M 248,163 248,163'" tmp/test.png
Whether that is valid or not, ie should work to start with, I'm unsure. The paths come from an external data provider so whilst we don't have any control over them we could check for the same point twice in a line. The biggest issue is imagemagick is inconsistent in how it handles this - ie sometimes it works, sometimes it doesn't. I find it varies between hanging once every 5 times to once every 10 times.

Some further examples to help you debug the issue:

Also causes the issue:

Code: Select all

convert -size 256x256 xc:transparent -draw "path 'M 248,163 248,163 248,163'" tmp/test-test123456-19.png
Does not cause the issue:

Code: Select all

convert -size 256x256 xc:transparent -draw "path 'M 248,163 247,163 248,163'" tmp/test-test123456-19.png
Does not cause the issue:

Code: Select all

convert -size 256x256 xc:transparent -draw "path 'M 247,163 248,163 248,163'" tmp/test-test123456-19.png
So it seems it's only when all the points are the same. Version is 6.7.7-6 as installed by brew on Mac OS X 10.8

Re: MagickDrawPolygonPrimitive() hanging indefinitely

Posted: 2012-08-29T15:18:23-07:00
by magick
We ran your command 10,000 times under Mountain Lion and ImageMagick 6.7.9-2. It ran without complaint. We'll keep trying but this bug is illusive

Re: MagickDrawPolygonPrimitive() hanging indefinitely

Posted: 2012-08-29T23:24:06-07:00
by GeorgeP
OK thanks for trying. I guess the only other thing is the version difference. When brew release an updated version we'll upgrade and feedback if we still get the issue. I did check the changelog but didn't see anything obvious that could effect the issue