Summary: | reference counting problem with devices & patterns | ||
---|---|---|---|
Product: | Ghostscript | Reporter: | Ken Sharp <ken.sharp> |
Component: | Graphics Library | Assignee: | Tor Andersson <tor.andersson> |
Status: | RESOLVED FIXED | ||
Severity: | major | ||
Priority: | P2 | ||
Version: | master | ||
Hardware: | PC | ||
OS: | Windows NT | ||
Customer: | Word Size: | --- | |
Attachments: | patch to address reference counting |
Description
Ken Sharp
2009-06-24 09:25:03 UTC
Created attachment 5157 [details]
fts_01xx.xps
A file which exhibits the problem (on page 2).
How does this work with pattern fills and PS/PDF ? Seems like whatever works there should work with other parsers IF they are calling the graphics library similarly. > how does this work with pattern fills and PS/PDF ? > > Seems like whatever works there should work with other parsers IF they are > calling the graphics library similarly. postscript and pdf use the high level pattern manager, see bug #687303. AFAIK all the languages leak memory when using pdfwrite, so for now can we force the reference count to 1 and print a warning before closing the device. I think the only place we can force the device reference count is in plmain.c, pl_main_universe_dnit, line 579: if (universe->curr_device) { gs_unregister_root(universe->curr_device->memory, &device_root, "pl_main_universe_select"); /* ps allocator retain's the device, pl_alloc doesn't */ gx_device_retain(universe->curr_device, false); universe->curr_device = NULL; } We could force the reference count in gx_device_retain but I think it would be better to force it before calling gx_device_retain. Eg: if (universe->curr_device) { gs_unregister_root(universe->curr_device->memory, &device_root, "pl_main_universe_select"); if(universe->curr_device.rc.ref_count > 1) { universe->curr_device.rc.ref_count = 1; if (err_str) sprintf(err_str, "Device reference count not 1 when closing.\n"); } /* ps allocator retain's the device, pl_alloc doesn't */ gx_device_retain(universe->curr_device, false); universe->curr_device = NULL; } If that looks OK I'll make the change, it'll save me chasing the other reference counting problem as well. That seems reasonable to me for now, but are the visual brushes of XPS not being mapped into pattern fills for PDF write? I have not had a chance to look at this yet, but it would seem that is what should be done eventually. Visual brushes are indeed converted to pattern fills by a complex process. However pdfwrite cannot handle some of the visual brushes that are being used. I checked the first case that fails to write out as a fill using a /Pattern colour space (this is what leads to the reference counting), and the reason pdfwrite cannot handle it is because the pattern matrix is not orthogonal to the axes. In gdevpdfv.c, pdf_pattern, line around line 126: /* * We currently can't handle Patterns whose X/Y step isn't parallel * to the coordinate axes. */ Matrix in this case is [75 0 -37.5 0 3525 5730] Its possible (perhaps even likely) that this fallback isn't working either, since the pages cause errors in Acrobat even when the reference counting is 'fixed'. But that's a different bug, #689484, which is what I was looking at when the reference counting issue came up. I had hoped the fix I'd done for #690056 might have been the same issue, so I ran the FTS file to check, only to encounter a different problem :-( I could concentrate on fixing this problem instead, but I believe there are shadings in XPS which can't readily be handled as PDF shadings, in which case I think we would need to use this path anyway, so it needs to work. I see that the matrix you mention [75 0 -37.5 0 3525 5730] is singular. I don't see why in this XPS file we would be getting such a matrix. Well, XPS isn't my area of expertise, so I'm not exactly sure. However this is the step matrix, not the pattern matrix. Its how to transform the unit square to get to the next pattern tile (I think). PDF Patterns have an XStep and a YStep which is not independent of the Pattern Matrix, as they are measured in the pattern co-ordinate system. I think its possible to deal with this matrix and the general case, its just not done at the moment in pdfwrite. There are two areas on page 2 of the XPS file which look possible candidates for causing the issue; in the top section the image + blue hatching at the bottom right is sheared in the x-direction, in the lower section the lowest set of rectangles is sheared in the y-direction. To be honest I've concentrated rather more on the reference counting issue than any other aspects of the file. There are several patterns which work well including those on pages 3, 5 and 6. Ooops, forgot to mention also that some of the patterns are 'flipped' or mirrored in either the x or y direction, which might also be causing difficulty. OK. When I get done with this pattern transparency stuff, I am going to take a quick look at this example for myself. Anytime I see a matrix that is singular, I become a bit suspicious. Especially since I don't see where there would be any singular matrices for creating the shear in that example for an XPS visual brush or for a PDF pattern. XPS has the viewport and viewbox (along with the tile mode to do the mirroring and flipping) to define the tiling. I am pretty sure all of these should map straightforward into well behaved forms for PDF patterns. But I need to sit down and go through the math before I can be certain of that. Tor should be responsible for investigating the singular matrix and he can assign back to one of us once that part of the problem is analyzed. Raising priority since this would be a serious issue for any user. For whatever it's worth I can't find any singular matrices at that location of the code when running fts_01xx.xps. The closest matrix to the one Ken mentioned that I've found is [75 0 -37.5 75 3525 5730]. Could it be a typo that made us believe it was singular? Probably a typo on my part. I was *much* more concerned with the reference counting being wrong than the matrix contents. Who is the owner for problems involving devices ? ;-) Adding Ralph in since he should be aware of reference counting issues. Created attachment 6307 [details]
patch to address reference counting
The attached patch addresses the problem for me. In gx_dc_pattern_fill_rectangle, before calling the initialisation routine, it initialises the clip device finalize routine to NULL.
If the initialisation decides that we need to clip the pattern fill, then it will create and open a clip device, storing the device in 'state.cdev'. If we do not need to clip the pattern fill then the clip device remains untounched.
At the end of the routine the clip device finalize routine will either be NULL (not clipping) or will have been set by the open device call. If the routine is not NULL then we call the finalize routine. This then counts down the reference to the forwarded device (pdfwrite in this case).
This works for me, and a cluster test appears to be OK, the only differences being more or less expected pdfwrite ones. I believe this is safe, but I'd very much appreciate someone else (Henry ?) looking at this as well.
For me this prevents pdfwrite emitting unfinished PDF files for:
fts_01xx.xps
fts_31xx.xps
fts_32xx.xps
fts_46xx.xps
Which isn't to say that they are without problems, but they do partially work which is an improvement.
revision 11297: http://ghostscript.com/pipermail/gs-cvs/2010-May/011089.html resolves this issue for me. The other device reference counting issues noted above seem to have already been resolved by Henry's work in this area. The file now runs to completion, though there are other problems still to address. |