GNOME Bugzilla – Bug 51114
Incorrect data saved in image file (mask/channel/offset/opacity)
Last modified: 2009-08-15 18:40:50 UTC
Quick summary: when you select File->Save, what gets saved in the image file may be different from what the user intended. There are actually two bugs in one report, but they are closely related: 1) In some cases, the saved data is correct but is not what the user expects (saving a mask or a channel instead of saving the whole image). 2) In some other cases, the saved data is not identical to what the user sees (the image file ignores the layer offset or the opacity). The first bug is a user interface problem and can be solved by adding a warning/question to the user. The second one is a real bug that can only be solved by modifying the File->Save option (most file plug-ins) so that it really saves what the user sees, maybe by triggering the Export feature even when a single layer is saved (see below). This bug affects all versions of the Gimp (from 0.99.x to 1.3.0, including the stable versions 1.0.4 and 1.2.1). The effects of this bug were originally reported in bug #23610 for 1.0.4, although the description was not very clear. Further effects were described in bug #25266 and in bug #25272 (the .xvpics thumbnails do not always match the image, which is a direct consequence of the bugs described here). This new bug report tries to summarize the problems that are affecting the File->Save plug-ins. Here is a more detailled description of the two problems: 1) The saved data is correct but is not what the user expects (this is described in the "How to repeat" part of bug #25272). If you have a layer mask or channel mask active when you save the image using a format other than XCF, then only that mask will be saved as a grayscale image, without any warning. This may be dangerous if you use the option "Select->Save to Channel" just before saving the image, because it will select the new channel mask automatically. Solution: always display a warning message when the user tries to save a layer mask or channel mask, and ask if the user really wants to save only that mask as a grayscale image or if he/she wants to save the whole image. 2) The saved data is not identical to what the user sees. This affects single-layer images in the following cases (as described in bug #23610): - the size of the layer is different from the size of the canvas - the offsets of the layer are not zero - the opacity of the layer is less than 100% Most file plug-ins (except XCF) will save the layer and ignore its relative position, size and opacity. The original reporter of #23610 mentioned that resizing an image did not work; actually it does work but the changes in the canvas size are ignored when the single-layer image is saved: only the size of the layer is taken into account when saving the file (as PNG, TIFF, JPEG, ...), so you get the original image back. As described in the following discussion in #23610, the PNG plug-in behaves strangely because it does take the offsets into account but it ignores the canvas size. As a result, you can get the correct offset but the wrong size for the image (see the comment that I posted on the 21st of September 2000). Solution: trigger the Export feature even on a single-layer image, when one of the cases listed above is encountered (size mismatch, non-zero offsets, or less than 100% opacity). How to repeat ------------- 1a) - Create or open an image and draw something in it. - Add an alpha channel if not done already - Add a layer mask (draw something in it if you want) - Save the image as JPEG, GIF, TIFF, PNG, TGA or any other format that saves only the current drawable. * Result: without warning, only the layer mask is saved 1b) - Create or open an image and draw something in it. - Select some area of the image - Use Select->Save To Channel. - Save the image as JPEG, GIF, TIFF, PNG, TGA, ... * Result: without warning, only the channel mask is saved 2a) - Create a new image (default size 256x256 is OK) - Use the Gradient tool to create a gradient that starts with black in the top left corner and ends with white in the bottom right corner. - Use Image->Canvas Size to resize the image to something smaller, for example 40x40. You will only see the black corner. - Use the Move tool to move the layer until you see some light gray or white area. - Save the image as PNG. * If you load the PNG image, you will see that the whole layer was saved (with the correct offset) but the canvas size is still 256x256. 2b) - Same steps as in 2a, but save as JPEG or TIFF or TGA instead. * If you load the JPEG image, you will see that a 40x40 image was saved, but it has ignored the layer offset so you see a black area where it should have been white. 2c) - Create or load a single-layer image (with or without transparency). - In the Layers,C&P dialog, move the Opacity slider to 50%. - Save the image as PNG or other formats. * If you load the PNG image, you will see that the opacity has been ignored.
*** Bug 23610 has been marked as a duplicate of this bug. ***
*** Bug 51009 has been marked as a duplicate of this bug. ***
In the "how to repeat" section, I forgot to include the following simpler example, which can happen if you want to add some transparent space around an existing image (for example, to add some padding in a GIF image that you inlcude in a web page): 2d) - Create or load a single-layer image (with or without transparency). - Use Image->Canvas Size to increase the width or height of the image (or both) so that some transparent space is visible around it. - Save the image as GIF, PNG, TGA, ... * If you load the image, you will see that it was not resized. This is probably what happened in bug #23610. And the test case (1b) describes what happened in bug #51009.
Re-assigning all Gimp bugs to default component owner (Gimp bugs list)
*** Bug 56792 has been marked as a duplicate of this bug. ***
Is there a trivial way to issue a warning for such cases?
If we want to issue a warning in some cases, we might as well try to apply the correct solution. As described above, a simple warning is probably sufficient for the problems described in (1a) and (1b). The second series of problems (2a) to (2d) can be solved triggering the Export feature even on single-layer images in the cases described above. This should not be too hard to fix. The main problem is to detect these special cases, which means that the core should know that some plug-ins would not save the correct data in the image file. Also, the new warning messages will require new translations. This bug seems to hit many people, according to the duplicate bug reports and the messages posted on comp.graphics.apps.gimp describing some of the problems listed above. I will have a look at the code on Sunday and see if I can find an easy way to fix it.
still present in 1.2.2
I have started writing a patch for libgimp/gimpexport.c and .h. I haven't covered all cases yet, but it will be ready soon. As I mentioned above, it introduces new dialogs with new strings that will have to be translated.
While working on this patch, I have detected a minor consistency problem that could occur when saving a single-layer PNG image that has non-zero offsets for its layer: PNG does not support multi-layer images but it does support offsets (the "oFFs" chunk). With the current version of the Gimp and the corresponding PNG plug-in, you can save an image in which the layer is not at (0,0) and this will work (both for saving and loading). This is also accepted by other programs because this is part of libpng. In order to solve bug #51114 (examples 2a, 2b, 2c, 2d), I trigger the Export feature when the image size does not match the canvas size, or the layer opacity is not 100%, or when the layer offsets are non-zero and the image format does not support this feature. In these cases, a new Export option can merge the existing layer with a transparent layer that has the same size as the image, using CLIP_TO_IMAGE. This ensures that all image formats that do not support layers will save an image that looks like what the user sees on the screen. But now there is a problem if you consider the following scenario: 1 - Create a new image (256x256, for example) and put something in it, such as a plasma cloud or a gradient. 2 - Use the Move Tool to move the layer so that only one quarter of the layer is visible (for example, move it by -100,-200). 3 - Save the image as PNG and make sure that the "Save layer offset" box is checked. 4 - Load this new file and everything will be as expected. 5 - Now change the canvas size to 128x128. 6 - Save the image as a new PNG file. 7 - Load this file and you will see the problem described in (2a): the layer offset is saved, but the image size is still 256x256 so the user does not get what he expected. Now, using the modified Export feature, there is no change in steps 3 and 4 (because PNG supports offsets) but step 6 triggers the Export dialog. If the user chooses to clip the layer to the size of the image, then he will only get the visible part of the layer saved in the file (and the offsets of this new layer will be (0,0)). This may seem strange to some users to have a different behaviour in these two cases: in both cases the image would be shown correctly, but in the first one the full layer data is still there and in the second one the non-visible part is clipped. I am wondering if it wouldn't be more consistent to trigger the Export dialog also in step 3, even if the PNG file format supports offsets (although this is optional). But then if any users of 1.2.2 are familiar the current behavior, they may be wondering why 1.2.3 would ask them if the want to export the image. So I don't know what it the best solution in this case. For the other file formats, the solution is obvious because they do not support offsets so the Export dialog must be triggered every time.
Created attachment 5899 [details] [review] patch that should solve both issues mentioned in this report
This patch should fix the bugs. This is a stripped down version of the patch that I was working on last week: this one is simpler and does not require a new PDB function. Also, I did not add a new symbol GIMP_EXPORT_CAN_HANDLE_LAYER_OFFSETS that I originally planned for PNG so this means that the Export dialog will be used when saving a PNG image with a single layer that is not attached at (0,0). This makes the patch simpler, and maybe some people will think that it is more consistent like that. Maybe not. See my previous comment for a discussion about this. This patch modifies libgimp/gimpexport.c and adds the following tests: 1) The user is asked for confirmation before saving a layer mask or channel. You can test this by trying to save a file immediately after adding a layer mask or using Select->Save to Channel. 2) If the user tries to save a single-layer image (or more precisely, an image in which only one layer is visible) and the size of the layer does not match the size of the canvas, or the opacity of that layer is not 100%, or the offsets of the layer are not 0, then the Export dialog is triggered. If the user chooses to export the image, a new transparent layer is added and merged with the current one. This ensures that what is saved in the file matches what the user sees on the screen. While writing this patch, I discovered that an image with no visible layers could be saved incorrectly, especially if the (invisible) active layer did not have the same size as the image. This is also fixed by this patch. However, some users might rely on the current behavior, which (for some file formats) allows them to save the selected layer even if it is not visible. If you think that it would be better to allow this, then simply add a test gimp_drawable_visible(*drawable_ID) in the line that checks the layer size, opacity and offsets in gimp_export_image(). Issues that still have to be solved: * this patch adds new strings that will have to be translated * the "Confirm Save" dialog needs a help file dialog/confirm_save.html that is not included in this patch
I have applied the patch to the stable and the development branch (although I hope we will find a better solution for gimp-1.4). Syngin promised to add the missing help file and I'll inform the translators that new strings are waiting. I think we can close this beast now :-)
Fix is part of gimp-1.2.3, which has just been released. Bug is now CLOSED.
*** Bug 57766 has been marked as a duplicate of this bug. ***