File I/O: Exporting image with Alpha layer creates two files

@jan.cosmigo, while working on a File I/O Export plugin I run into an odd behaviour, which might be a bug.

Description

Assume the plugin save images with the .abc extension.

Regardless of whether isWriteTrueColorSupported() returns true or false, whenever an image containing an Alpha layer is exported, the plugin is passed two output images to save: <filename>.abc and then <filename>.alpha.abc.

Basically, the plugin then creates two identical images — unless, of course, it first checks the current filename to see if it ends in .alpha.abc and skips writing anything in beginWrite() and writeNextImage() if it does.

Thoughts and Questions

I guess that this double invocation is tied to how PM NG handles exporting to image formats that don’t support Alpha layers, as mention in the Documentation in the Alpha Primer section:

File I/O

Usually palette based images can not be stored with alpha. To get around this problem the application will save additional files containing the alpha plane data as soon as you use a file type that can not carry alpha data. If you for example store your image as foo.pcx then a second file foo.alpha.pcx will be stored containing the alpha data. When loading such files then such an alpha file is recognized and loaded it into the alpha plane. Same works for animations.

Now, I’m wondering if PM is expecting the plugin to handle exporting the alpha plane data (in which case it’s an undocumented feature) or whether it’s a bug and PM should be handling the extra .alpha.<ext> file on its own — the latter seems to make more sense, since PM is likely to require this data to be in a fixed format.

I’ve used the Fake Plugin to monitor all DLL calls and info exchange, and I noticed that there are many spurious calls to the plugins — e.g. whenever a file is selected in the file open dialog, or when an image is opened, setFilename() is called on all plugins. Such calls seem odd, for they would only make sense in a context in which file operations are narrowing down to some specific plugins, and not just any file read operations.

So, I wonder if it’s due to these spurious calls that the plugin is getting invoked to export also the .alpha.<ext> additional image. So far, I noticed that PM is not writing this additional image (i.e. in my tests I simply ignore processing files that end in .alpha.abc, so it’s not a case of PM creating the alpha file and then the plugin overwriting).

In either case, the interface seems buggy — if it was PM duty to create the additional alpha file, then it shouldn’t be calling the plugin for it, and it’s not creating it either. If instead it’s the duty of the plugin to create this extra alpha file, then we need to document this and provide the exact specs of the expected file’s format.

Clarification

Just to make sure I’m getting this correctly, when writeNextImage() is called, the *rgba parameter always points to an RGBA representation of the image?

If I’ve understood correctly, the *rgba image could also be a true color image (in case flattening layers exceeded 256 colors, in which case *colorFrame points a colour-reduced indexed bitmap) or it might just be an identical representation of the bitmap image contained in *colorFrame plus *alphaFrame (in this case, whether the plugin should use *rgba or the bitmaps is a matter of choice or depend on the kind of output format being worked on).

And, I guess, for images that don’t have an Alpha layer the *rgba image will have all A channels to 255, except if indexed-colour transparency is used, in which case some entries will have A set to 0.

I’m asking just to check that I’m getting the right picture here, amidst the undocumented features and the odd interface behaviours.

Sorry for the silence on this topic. Will address this with 7.2.5. (pending update)

Edit: I initially thought that writing the alpha file is a bug, but it only happens if the function isAlphaEnabled of the plugin interface returns “false”.
In that case the application takes care of storing alpha data in a separate file. That means, the plugin is called with a separate file name and alpha data as “normal” image data.

But there is still a bug, because even if the plugin says that it’s able to write true color data the corresponding function is never called with RGBA-data :frowning:
At the moment you will always get “writeNextImage” being called indexed color data and (if the plugin says that it supports alpha) with corresponding alpha data.

Need to have a look at all this separately, so there won’t be a change on this with 7.2.5.

Thanks for the explanation. So, right now, it’s only safe to create plugins that don’t handle alpha layers, which also means that when they get a writeNextImage() call they should check if the file ends with .alpha.<ext> and skip processing the call entirely.

Possibly, this approach should be safe enough to guarantee that the plugin will still work when the issue is fixed (even if the fixes require bumping up the Interface version, because if the plugin informs PMNG that it’s using Interface v1 then PMNG should treat it backward compatibly).

When the plugin does not handle alpha (because the file format just can’t or it’s not wanted) then there is no need to skip the .alpha.xxx file calls. Just store the file data as the host application does request it.
But if the plugin handles alpha based on storing it non-indexed but true color, it must take the alpha data from the indexed planes given with writeNextImage() instead of using RGBA given there.

Hope this makes sense.