GNOME Bugzilla – Bug 142074
Paste into 1x1 pixel image from buffer crashes GIMP 2.01
Last modified: 2004-12-11 01:24:57 UTC
1) Load Knoppix 3.4 2) Start GIMP v2.0 from the menu. K-> The GIMP (v2.0) 3) Take a screenshot using (GIMP) File->Acquire->Screenshot (whole screen option) 4) Click screen to capture. I only did this to get something into the buffer 5) Select some of the screenshot using the select tool 6) IMPORTANT BIT -> Edit >> Copy the selection 7) IMPORTANT BIT -> File >> New (open a new image) 8) IMPORTANT BIT -> Set the height and width of the new image to 1pixel by 1pixel 9) IMPORTANT BIT -> Edit >> Paste 10) There is no step 10 as GIMP has crashed and removed all windows. Basically, get something in the buffer Also works with: A) Open and Select part of an existing image (edit >> copy) B) Resize image to 1px by 1px C) Edit >> Paste. Thanks for istening.
I can confirm this.
Seems to be a bug in the preview code. It tries to allocate a gigantic preview:
+ Trace 46718
What's happening here is that in order to create a preview of the layer in the image context (for the Layers dialog), the layer is first scaled up to correct for the fact that the preview is larger than the image. Then an area from the scaled preview is taken as the preview. A typical setup is to create a preview of 32x32 pixels. That means the layer is scaled up 32 times. For a typical screenshot size of 1024x786 the layer is scaled to a size of 32768 x 24576. That would need about 3GB of memory.
A trivial fix (or workaround) is to change line 171 of gimpimage-preview.c from ratio = (gdouble) width / (gdouble) gimage->width; to ratio = MIN (1.0, (gdouble) width / (gdouble) gimage->width); This causes previews for very small images to be shown at the actual image size rather than scaled up. The number 1.0 could be replaced with something larger if one wanted to limit the amount of magnification without preventing it completely. If this kind of trickery is not acceptable, then it seems necessary to clip each layer to the image dimensions before scaling it to create the preview, and this would involve substantial complications.
I think the proposed fix sounds sane.
To me the proposed fix sounds like a regression. I haven't tried the patch but it seems to disable the feature that previews show a magnified view of very small images. I know that people working on icons and such like this behaviour.
*** Bug 147576 has been marked as a duplicate of this bug. ***
Bug #147576 shows that this problem is not only triggered by pasting but can also happen when loading an image.
Here's what sounds logical to me: isolate the section of the layer that's actually within the image boundaries, then scale that to the preview size. I don't understand why the entire layer is scaled before taking out that section.
Yep, that's how it should be done.
Moving all bugs remaining on the 2.0.3 milestone to 2.0.4.
Moving remaining bugs from milestone 2.0.4 to milestone 2.0.4
Comment #9: Phillipe: The whole layer is scaled because it's not exactly trivial to get just the part of the layer in the image bounds. Alternative, perhaps easier to do, method is to check the scaling factor, and if we're scaling up to do the preview, then to compose first, and scale the result. I agree though that the best thing to do is to clip the layers first. I just have to figure out how to do that. Source reference: app/core/gimpimage-preview, gimp_image_get_new_preview (lines 143 to 336) The loop which is messing things up starts at line 225, which calls gimp_viewable_get_preview(), which in turn resolves to the implementation gimp_drawable_get_preview in gimpdrawable-preview.c, and there (I think) is where the actual scaling is done. I will spend some time looking at this this evening. Cheers, Dave.
I have gone round in circles with this a bit... I believe the correct thing to do is - Request a TempBuf from a Viewable corresponding to offset x, y and size w, h - Create a PixelRegion from this buffer with offset max(x,0), max(y, 0) - Merge the PixelRegions The stuff that has been confusing me is the second bit - in gimp_image_get_new_preview, everything is scaled already, and frankly I don't understand how the scaling is done in gimp_drawable_get_preview_private. So all of the PixBufs that you end up with are from scaled Viewables. There is currently no API for the first bit. Should be easy, but currently it's not there. Is adding something like that necessary? Is it appropriate for a stable release? There doesn't appear to me to be a way to delegate the creation of the relevant TempBuf to the drawable without this or some similar API. In the meantime, I reccommend that we put in the trivial fix (which is a regression) if (ratio > 1) as reccommended in comment #4.
It's not like we're being flooded with complaints about this bug, so it seems more reasonable to wait for a proper fix to evolve than to do something that would be a regression.
Created attachment 31453 [details] [review] Patch to allow you to get a TempBuf of a sub-section fo a Drawable. Untested. Adding this unfinished bit of fluff here so that if I don't have time to do the rest, siomeone else might like to have a go. It probably doesn't do what I think it does, it's not tested at all, but it compiles.
Moving all remaining bugs from the 2.0.6 milestone to 2.2.
Fixed in CVS: 2004-12-11 Michael Natterer <mitch@gimp.org> * app/core/gimpdrawable-preview.[ch]: added new function gimp_drawable_get_sub_preview() which returns a scaled preview of a part of a drawable. (gimp_drawable_preview_scale): made it work with srcPR.x and srcPR.y being != 0. * app/core/gimpimage-preview.c (gimp_image_get_new_preview) * app/widgets/gimpviewrendererdrawable.c (gimp_view_renderer_drawable_render): if the area of the drawable preview is more than 4 times larger than the drawable itself (evil heuristic, but seems to work fine), use above function to get a sub-preview of the drawable instead of getting an insanely large preview of the whole drawable just to use a small part of it. Fixes bug #142074. * app/core/gimpimage-preview.c (gimp_image_get_new_preview): optimized by skipping layers which do not intersect with the canvas.