GLib has a specific type for byte arrays: `GBytes` (and it's underlying
GType `G_TYPE_BYTES`).
By using this type, we can avoid having a `GimpUint8Array` which is a
bit cumbersome to use for both the C API, as well as bindings. By using
`GBytes`, we allow other languages to pass on byte arrays as they are
used to, while the bindings will make sure to do the right thing.
In the end, it makes the API a little bit simpler for everyone, and
reduces confusion for people who are used to working with byte arrays
in other C/GLib based code (and not having 2 different types to denote
the same thing).
Related: https://gitlab.gnome.org/GNOME/gimp/-/issues/5919
This is not made to set the imported or exported file, but only the XCF file.
See previous commit to see what happens when this API is used to set non-XCF
file extensions (saving fails unless one edits the filename).
Missing functions were:
* gimp_image_get_selected_channels()
* gimp_image_get_selected_vectors()
* gimp_image_list_selected_channels()
* gimp_image_list_selected_vectors()
* gimp_image_set_selected_channels()
* gimp_image_set_selected_vectors()
* gimp_image_take_selected_channels()
* gimp_image_take_selected_vectors()
There are discussions of renaming GimpVectors to GimpPath, which would
also be consistent with the GUI and make the always-plural less akward
in API. We'll see. For now keeping named like this.
The get() API are sometimes nicer in C code because it's just simpler to
loop through C arrays, but they end up with similar API to the list()
variants for binding, or with a useless size return value (since most
higher level languages have length-aware array types, which is what
GList are transformed into).
So let's use the list() variants as the main ones and skip the get()
variants. I hesitated to rename the list() variants to get() with
`(rename-to)` annotations but since I am unsure if the get() bindings
are absolutely useless, I don't think it's the best idea. Maybe on some
other language usable as GI binding, the get() variant might be
different again and nicer to use. So if we shadowed these by renaming
list() ones, the day we change our mind, we'd have to rename get() ones
too (which would be very confusing), or else break bindings' API. To
avoid this, I just skip the get() ones altogether in bindings but leave
their name available in the bindings.
GLib has a specific type of NULL-terminated string arrays:
`G_TYPE_STRV`, which is the `GType` of `char**` aka `GStrv`.
By using this type, we can avoid having a `GimpStringArray` which is a
bit cumbersome to use for both the C API, as well as bindings. By using
`GStrv`, we allow other languages to pass on string lists as they are
used to, while the bindings will make sure to do the right thing.
In the end, it makes the API a little bit simpler for everyone, and
reduces confusion for people who are used to working with string arrays
in other C/GLib based code (and not having 2 different types to denote
the same thing).
Related: https://gitlab.gnome.org/GNOME/gimp/-/issues/5919
Since it appeared with GLib 2.68.0, we could not change this until we
bumped the dependency which has only become possible a few days ago
(since Debian testing is our baseline for dependency bumps). Cf.
previous commit.
As this is a drop-in replacement (just a guint parameter changed to
gsize to avoid integer overflow), search-and-replace with:
> sed -i 's/g_memdup\>/g_memdup2/g' `grep -rIl 'g_memdup\>' *`
… followed by a few manual alignment tweaks when necessary.
This gets rid of the many deprecation warnings which we had lately when
building with a recent GLib version.
s/gimp_image_base_type/gimp_image_get_base_type/
s/gimp_image_width/gimp_image_get_width/
s/gimp_image_height/gimp_image_get_height/
Sorry plug-in developers, more porting work! But really this seems like
the right thing to do in order not to get stuck with inconsistent naming
for many more years to come.
I always found the docs misleading because when it says "Returns the
list of layers contained in the specified image", I really read "all the
layers, at any level", except it doesn't. It only returns the root
layers and it is up to the plug-in developer to loop through these if
one needs to go deeper.
So let's make the function docs clearer.
It is more accurate to say it returns a list of parasite names rather
than a list of parasites (as we could take it as meaning a list of
GimpParasite). Of course, we would soon see the actual element contents
(if not for the introspection metadata (element-type gchar*)), but
better being accurate in textual docs too.
Our Preferences exposes a concept of "Preferred color profile" (for RGB,
grayscale and CMYK), which is used in some places to be proposed as
default alternative to built-in profiles. But it was not used in the
import color profile dialog (only 2 choices were: keep the image profile
or convert to built-in RGB).
This commit now adds this third choice, which is even made default when
hitting the "Convert" button directly, without tweaking with the dialog.
Because we can assume that if someone made the explicit choice to label
such a profile as "Preferred", this is more likely the one to convert to
(if one even wants to convert from an embedded profile anyway).
As for the `Preferences > Image Import & Export > Color profile policy`,
they now propose 4 choices: Ask, Keep embedded profile, Convert to
built-in or preferred profiles.
… gimp_image_policy_color_profile().
These functions allow a plug-in to explicitly execute the Rotation and
Profile conversion policies on an image (which may be any of
Rotating/Discarding/Ask or Converting/Keeping/Ask respectively). These
policies are automatically executed when loading an image from GIMP
interfaces, but they won't be when loading an image from the PDB. Then
it is up to the calling code to decide what to do (which can be either
some arbitrary code or following the user policy).
When several layers are selected, each layer will merge down with the
layer below it. This is similar to running Merge Down several times, one
for each selected layer.
The PDB creates the array of drawables as a `const GimpItem *` and the
compiler does not like when we drop the const qualifier. So force this
const dropping with explicit type casting.
Color picking on a single layer still works as it used to. On multiple
layer, it will now pick on the composited color, similarly to sample
merged if only selected layers were made visible.
The PDB/libgimp function gimp_image_pick_color() is also updated to work
on multiple drawables too, giving the same ability to plug-ins (the only
call to this function in core plug-ins have been updated).
Multi selection actually only really matter when "Merge within active
groups only" option is checked, in which case we are able to merge
layers within several layer groups simultaneously, and end up with
multi-selected merged layers.
Also not sure why both layers-merge-layers and image-merge-layers exist,
as they are exactly the same (exact same callback called when
activated).
After much thought, tests and discussions with Aryeom, we decided adding
back an active item concept additionally to the selected items ones is a
bad idea as it makes only usage unecessarily complex.
We will just have selected layers. Some kind of operations will work
when more than one item (layers, channels, vectors) are selected while
others will require exacty one item.
In particular, let's replace instances of gimp_image_(s|g)et_active_*()
by corresponding gimp_image_(s|g)et_selected_*(). Also replace single
item in various undo classes by GList of items.
Also "active-*-changed" GimpImage signals are no more, fully replaced by
"selected-*s-changed".
This is still work-in-progress.
and in an attack of madness, changes almost all file plug-in
code to use GFile instead of filenames, which means passing
the GFile down to the bottom and get its filename at the very
end where it's actually needed.
Add a show_all parameter to gimp_image_pick_color(), which, when
TRUE, allows picking colors outside the canvas bounds in sample-
merged mode. Forward the display's "show all" mode through this
parameter where applicable (in particular, in the color-picker tool
and the pointer dockable).
Turn all ID param specs into object param specs (e.g. GimpParamImageID
becomes GimpParamImage) and convert between IDs and objects in
gimpgpparams.c directly above the the wire protocol, so all of app/,
libgimp/ and plug-ins/ can deal directly with objects down to the
lowest level and not care about IDs.
Use the actual object param specs for procedure arguments and return
values again instead of a plain g_param_spec_object() and bring back
the none_ok parameter.
This implies changing the PDB type checking functions to work on pure
integers instead of IDs (one can't check whether object creation is
possible if performing that check requires the object to already
exist).
For example gimp_foo_is_valid() becomes gimp_foo_id_is_valid() and is
not involved in automatic object creation magic at the protocol
level. Added wrappers which still say gimp_foo_is_valid() and take the
respective objects.
Adapted all code, and it all becomes nicer and less convoluted, even
the generated PDB wrappers in app/ and libgimp/.
I.e.: gimp_image_get_(layers|channels|vectors)(), gimp_image_list() and
gimp_item_get_children().
Instead of returning an array of IDs, these will now return a GList with
the right objects ready to use.
This means that all functions which were returning or taking as
parameter an image id (as gint32) are now taking a GimpImage object
instead.
The PDB is still passing around an id only over the wire. But we create
an object for plug-ins to work on.
This is quite a huge API break, but is probably the best bet for the
future quality. It will make nicer API instrospection (and nicer API in
binding), will fix the issues with pspec on GimpImageID in Python
bindings (which makes the current Python API unusable as soon as we need
to work on images, which is most of our plug-ins!), etc.
Also it will allow to use signals on images, which will be a great asset
when we will finally have bi-directionnal communications (i.e. plug-ins
would be able to connect to image changes, destructions, and whatnot).
Also generate comments like "Must be freed with g_free()" for all
return values instead of manually and inconsistently having them on
some return values only.
Add "gboolean push_undo" parameters to gimp_image_parasite_attach()
and _detach() and use the API also from undo, instead of implementing
attaching/removing manually and forgetting about the signals.
Fixes updating of the image properties color profile page.
In gimp_image_merge_layers() -- the internal function used by the
various layer-merging/flattenning functions -- process the merged-
layer graph in chunks, using gimp_gegl_apply_operation(), instead
of in one go, using gegl_node_blit_buffer(). Processing in chunks
better utilizes the cache, since it reduces the size of
intermediate buffers, reducing the chances of hitting the swap when
merging large images (see, for example, issue #3012.)
Additionally, this allows us to show progress indication. Have the
relevant gimpimage-merge functions take a GimpProgress, and pass it
down to gimp_image_merge_layers(). Adapt all callers.
If you click on a zone filled in several visible layers, you don't
necessarily want the top layer. You may want one below. With this
change, as long as you hold alt, you will loop through all candidate
layers from top to bottom (then looping back top when reaching the
bottom).
In a first alt-click, you will always end up to the top candidate.
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.
so plug-ins cannot thaw what they haven't frozen, and the code
can clean up frozen stuff left behind by crashed or broken plug-ins.
Also redo the cleanup code so it only keeps track of the undo group
counts and freeze counts of what *this* GimpPlugInProcFrame did
itself. That should make it even stricter against broken code that
could mess up internals.
These procedures freeze/thaw the corresponding containers of the
image, allowing plug-ins that perform many changes affecting any of
these containers to suppress updates to the corresponding dialogs,
significantly improving performance.