And always pass URIs to all file procedures, the ones what didn't
register as "handles remove" will only ever get local file:// URIs.
Change all file plug-ins (also legacy ones) to expect URIs instead
of filenames, and convert to local paths in the plug-in.
The wire protocol should now be almost 100% clean of non-UTF-8 strings.
This new capacity was created just 3 commits ago (9933f46f85).
The point was that the real fix is to remove the implication
HANDLE_LAYERS => HANDLE_ALPHA, but this breaks public API behavior,
which is why I didn't go with it.
Still it just felt wrong to add a NEEP_OPAQUE capability when it should
be the same thing as not setting HANDLE_ALPHA. After discussion on IRC,
we decided that this implication was basically a bug, and since in all
core plug-ins, when HANDLE_LAYERS was set, we were also setting
HANDLE_ALPHA, no core plug-in code even has to be changed. As for
third-party plug-ins, let's assume that none has been relying on this
wrong assumption.
G3/G4 compression does not support transparency, yet in multi-layer
export, gimp_export_image() capability GIMP_EXPORT_CAN_HANDLE_LAYERS
implied GIMP_EXPORT_CAN_HANDLE_ALPHA. I guess multi-layer TIFF is more
for multi-page (at least with G3/G4 which is apparently a fax format, so
it makes sense) than actual multi-layer.
So I use the new GIMP_EXPORT_NEEDS_OPAQUE_LAYERS capability from
previous commit for this particular use case of export layers + G3/G4
compression.
Also it is better to run gimp_export_image() *after* the option dialog,
as we do for other formats, with variable capabilities depending on
which options was chosen, instead of running it before then after
merging layers when user chose not to export layers. This is duplicating
the purpose of gimp_export_image().
...always AdobeRGB!
Change all file plug-ins to never call gimp_image_metadata_load_finish()
with the GIMP_METADATA_LOAD_COLORSPACE when they loaded a color profile.
This keeps gimp_image_metadata_load_finish() from assigning a profile
from DCT even if the loaded profile was GIMP's built-in sRGB.
Complete commit ac8ad13f0a.
Channels are Y' on 8-bit non-linear images. So to avoid data conversion,
this is the only case where we want to consider TIFF channels to be Y'
as well.
In GIMP, our channels (the ones from Channels dock) are always linear,
and don't follow the image/profile TRC. When a TIFF image has extra
channels (no semantic attached), we probably want to load the channel
as-is, without converting the values. So let's assume that TIFF extra
samples with "Unspecified data" in it are linear data. This way, their
values goes copied straight into a channel.
Instead of treating any unspecified TIFF channel as non-premultiplied
alpha, let's now ask the user (in non-interactive case, we continue
defaulting to non-premultiplied channel and outputing a message). The 3
choices are: premultiplied, non-premultiplied (which is the default so
you can just hit Enter and get same result as previously) and channel.
It's still not perfect as it still assumes that an alpha channel will
necessarily be the first extra channel (though the spec does not mandate
such assumption). Let's say for now that it is enough. Using extra
channels for the alpha channel only is most likely the most common usage
(actually the spec only has specific types for such usage).
Note that I am using twice TIFFErrorHandler type. This is because
TIFFWarningHandler does not exist, despite what the docs says and
upstream code actually uses twice the same handler type.
...and pngs
Fix yesterday's fix and pippin's fix to not move lines around that
should be together (never move around code between testing and
pushing)...
Initialize channel[0].buffer before using it, as a response to the following
critical warning reported in issue #3264 about it being NULL:
(file-tiff:1074): GEGL-CRITICAL **: 17:10:57.175: gegl_buffer_get_format: assertion 'buffer' failed
...and pngs
Create formats with the drawable's space so no conversions happen when
reading/writing the drawable's buffer. Original patches from Massimo.
Our TIFF loading code was not taking into account the case when extra
channels were stored in the TIFF file while ExtraSamples field is not
set. Yet as a side effect of a later channel count, we were setting
`alpha` to TRUE while `save_transp_pixels` was left uninitialized (hence
undefined behavior).
For now let's make sure we have no undefined behavior. When the
ExtraSamples field is missing and at least one extra channel is stored,
we will consider the first extra channel as non-premultiplied alpha
(this is also what we were doing when ExtraSamples was set to
"Unspecified data" and apparently according to Massimo, it would be a
common behavior in other software).
Note that it is an improvement from previous code (no undefined
behaviour anymore, instead we handle explicitly the TIFF error). Yet
this is not perfect yet. Ideally we should pop-up a dialog asking what
to do with this extra channel: either open as a channel (no alpha), or
as premultiplied or non-premultiplied alpha.
Same as we did for PNG and JPEG, we want to always export data with the
TRC of a profile manually assigned, and in particular NOT the curve of
the storage in GIMP (i.e. you may work on 32-bit linear, yet if you
assigned a sRGB TRC profile, this is what you should export). The
storage format will only dictate the exported data TRC when writing out
the default profile (i.e. no explicit profile assignement).
As a last case, when no profile is saved, we always export as sRGB.
As for the export precision, we always follow the storage one's, except
sometimes for 8-bit images. We promote 8-bit images to 16-bit if and
only if the storage does not match the export data linearity, to avoid
too much quality loss during format conversion.
In file-tiff, when not saving layers, avoid duplicating the image
to create the merged version if it's already been duplicated, and
make sure to delete the duplicated image otherwise.
The export code was checking the existence of a profile variable which
was never set. In other words, it seems we were always converting TIFF
pixels to non-linear, even when we were also exporting a linear profile.
Note that is not useful anymore to check profile existence as we now use
the effective profile (which always exists). So we just have to check if
the "save profile" option is on.
This argument should actually say "Do not store premultiplied channel
values", which is what the TIFF spec calls "Unassociated alpha" (vs.
"associated alpha" when values are stored premultiplied by alpha).
Now I can see where the current description is coming from, which is
that any color with alpha 0 (totally masked) ends up as RGBA value (0,
0, 0, 0), in other words, the color information is completely lost. Yet
this label is not very helpful to understand what the checkbox really
does. I decided to not just change it altogether as people would have
gotten used to this for years, but at least adding completary
information in API and tooltip in GUI.
(copied from 18a2f576bb instead of
cherry-picking since differences in the ui file was making
cherry-picking over-complicated for just one line)
Not sure what this @image_types parameter of gimp_install_procedure() is
used for. Exporting was working find with INDEXEDA image even when not
advertized by this function. Let's update this anyway.
(cherry picked from commit a0a7ead13f)
Add flag GIMP_METADATA_SAVE_COLOR_PROFILE to GimpMetadataSaveFlags and
initialize it from gimp_export_color_profile() in
gimp_image_metadata_save_prepare().
Adapt all plug-ins to use the bit from the suggested export flags and
pass the actually used value back to
gimp_image_metadata_save_finish().
This changes no behavior at all but creates hooks on the libgimp side
that are called with the context of an image before and after the
actual export, which might become useful later. Also, consistency
is good even though the color profile is not strictly "metadata".
...export dialogs
Remove the "Advanced" expander and have all options in plain sight.
Issue #701: Add a "Save color profile" toggle and always honor it.
All babl formats now have a space equivalent to a color profile,
determining the format's primaries and TRCs. This commit makes GIMP
aware of this.
libgimp:
- enum GimpPrecision: rename GAMMA values to NON_LINEAR and keep GAMMA
as deprecated aliases, add PERCEPTUAL values so we now have LINEAR,
NON_LINEAR and PERCPTUAL for each encoding, matching the babl
encoding variants RGB, R'G'B' and R~G~B~.
- gimp_color_transform_can_gegl_copy() now returns TRUE if both
profiles can return a babl space, increasing the amount of fast babl
color conversions significantly.
- TODO: no solution yet for getting libgimp drawable proxy buffers in
the right format with space.
plug-ins:
- follow the GimpPrecision change.
- TODO: everything else unchanged and partly broken or sub-optimal,
like setting a new image's color profile too late.
app:
- add enum GimpTRCType { LINEAR, NON_LINEAR, PERCEPTUAL } as
replacement for all "linear" booleans.
- change gimp-babl functions to take babl spaces and GimpTRCType
parameters and support all sorts of new perceptual ~ formats.
- a lot of places changed in the early days of goat invasion didn't
take advantage of gimp-babl utility functions and constructed
formats manually. They all needed revisiting and many now use much
simpler code calling gimp-babl API.
- change gimp_babl_format_get_color_profile() to really extract a
newly allocated color profile from the format, and add
gimp_babl_get_builtin_color_profile() which does the same as
gimp_babl_format_get_color_profile() did before. Visited all callers
to decide whether they are looking for the format's actual profile,
or for one of the builtin profiles, simplifying code that only needs
builtin profiles.
- drawables have a new get_space_api(), get_linear() is now get_trc().
- images now have a "layer space" and an API to get it,
gimp_image_get_layer_format() returns formats in that space.
- an image's layer space is created from the image's color profile,
change gimpimage-color-profile to deal with that correctly
- change many babl_format() calls to babl_format_with_space() and take
the space from passed formats or drawables
- add function gimp_layer_fix_format_space() which replaces the
layer's buffer with one that has the image's layer format, but
doesn't change pixel values
- use gimp_layer_fix_format_space() to make sure layers loaded from
XCF and created by plug-ins have the right space when added to the
image, because it's impossible to always assign the right space upon
layer creation
- "assign color profile" and "discard color profile" now require use
of gimp_layer_fix_format_space() too because the profile is now
embedded in all formats via the space. Add
gimp_image_assign_color_profile() which does all that and call it
instead of a simple gimp_image_set_color_profile(), also from the
PDB set-color-profile functions, which are essentially "assign" and
"discard" calls.
- generally, make sure a new image's color profile is set before
adding layers to it, gimp_image_set_color_profile() is more than
before considered know-what-you-are-doing API.
- take special precaution in all places that call
gimp_drawable_convert_type(), we now must pass a new_profile from
all callers that convert layers within the same image (such as
image_convert_type, image_convert_precision), because the layer's
new space can't be determined from the image's layer format during
the call.
- change all "linear" properties to "trc", in all config objects like
for levels and curves, in the histogram, in the widgets. This results
in some GUI that now has three choices instead of two.
TODO: we might want to reduce that back to two later.
- keep "linear" boolean properties around as compat if needed for file
pasring, but always convert the parsed parsed boolean to
GimpTRCType.
- TODO: the image's "enable color management" switch is currently
broken, will fix that in another commit.
I am going to forbid plug-ins from being installed directly in the root
of the plug-ins/ directory. They will have to be installed in a
subdirectory named the same as the entry point binary.
This may seem useless for our core plug-ins which are nearly all
self-contained in single binaries, but this is actually a necessary
restriction to eliminate totally the DLL hell issue on Windows. Moving
core plug-ins in subfolders is only a necessary consequence for it.
Various plug-ins exporting metadata should now follow preferences, which
would override any default. Of course these preferences can still be
overriden by saved settings (global parasite), previous run settings,
and finally through the GUI when interactive.
This is a privacy concern. Whereas importing metadata is usually a good
idea, exporting it should be a conscious action. A lot of private data
can be leaked through metadata and many people don't realize it (which
also usually means they don't need it). On the other hand, the people
who realize it are the ones who would explicitly edit the metadata and
check what they want to be exported or not.
This is only a first step. Some people may want to always export the
metadata and for these people, there should be abilities to change the
default.
...in both the core and libgimp.
Images now know what the default mode for new layers is:
- NORMAL for empty images
- NORMAL for images with any non-legacy layer
- NORMAL_LEGAVY for images with only legacy layers
This changes behavior when layers are created from the UI, but *also*
when created by plug-ins (yes there is a compat issue here):
- Most (all?) single-layer file importers now create NORMAL layers
- Screenshot, Webpage etc also create NORMAL layers
Scripts that create images from scratch (logos etc) should not be
affected because they usually have NORMAL_LEGACY hardcoded.
3rd party plug-ins and scripts will also behave old-style unless they
get ported to gimp_image_get_default_new_layer_mode().
with proper value names. Mark most values as _BROKEN because they use
weird alpha compositing that has to die. Move GimpLayerModeEffects to
libgimpbase, deprecate it, and set it as compat enum for GimpLayerMode.
Add the GimpLayerModeEffects values as compat constants to script-fu
and pygimp.
Completing fix from commit 3cb70e6.
Checking further into libtiff logs, I can see another version of the
warning message for private tags which was used before libtiff 3.7.
For sake of completeness, let's check against this version of the
warning as well.
This is a regression from bug 131975. Any unknown tag over 32768 is not
an error. This is a reserved zone where it is allowed to create custom
tags.
The warning indeed changed since libtiff 4.0.0alpha where it has become:
"Unknown field with tag %d (0x%x) encountered"
This explains why it was not recognized anymore.