Commit graph

6653 commits

Author SHA1 Message Date
Jehan
f00bf531ae app: do not warn for stray images from command lines.
The INFO message "a stray image seems to have been left around by a
plug-in" was annoying when GIMP is run non-interactively, and when it
was about images open from command lines. Typically this message would
be visible on our CI when the various gimp-data scripts would fail. This
could only confuse script developers.

The fact is that while a plug-in (or batch script) should definitely
clean after itself by deleting images it created (unless it gave it a
display, in which case ownership is moved to the GUI), it is absolutely
expected that images opened through the command line would still exist
at exit.
2026-04-06 16:29:40 +02:00
Jehan
1107d0f7af app, pdb, plug-ins: improve error feedback for gimp_temp_file().
It is not a fix yet for #14681 but would provide nicer and earlier error
when a call to gimp_temp_file() fails, which may happen in some cases.
E.g. if the temp directory doesn't exist and we fail to create it.

As a test, if I delete /tmp/gimp/3.2/ and give root ownership to
/tmp/gimp/, now the error when opening our gimp-splash.xcf.xz is:

GIMP-Error: Opening '/path/to/gimp/gimp-data/images/gimp-splash.xcf.xz' failed: Error creating directory /tmp/gimp/3.2: Permission denied
2026-04-04 23:05:26 +02:00
v4vansh
620850715e Core: Fix stale thumbnails after mode conversion 2026-04-03 16:17:47 +00:00
Jehan
4f69cd039c app: get rid of some unused internal API.
I noticed this yesterday, especially through gimp_image_get_active_array()
and gimp_image_get_visible_array() which are looping through
MAX_CHANNELS, hence assuming the passed components arrays are of
sufficient size. I could have just added some comment to document that
we must be careful when calling this, but this is currently completely
unused code. So I prefer to just clean it out.

If we need something like this in the future, we can just do it better.
2026-04-02 11:45:25 +02:00
Jehan
2c8d91c3cc app: further remove a variable length array.
Fixes when compiling:

> error: variable length array ‘mask_row_buf’ is used

With this and previous commit, we can now compile with C++ flags
-Werror=vla and get no build failures.
2026-04-01 18:52:45 +02:00
Jehan
9257af7570 app: do not use variable length arrays.
Fixing in the gimp-macos-inhouse: [arm64] job:

> ../app/core/gimpbrush-transform.cc:869:17: warning: variable length arrays in C++ are a Clang extension [-Wvla-cxx-extension]

Also adding some asserts in some places where we rely on the
MAX_CHANNELS constant so that we will quickly detect if this variable
needs to be further bumped in the future (especially as we will add
CMYK+ support as backend format).
2026-04-01 18:52:45 +02:00
Bruno Lopes
3807b2f311 app, plug-ins: More sscanf_s on Windows 2026-03-31 21:44:51 -03:00
Bruno Lopes
8aeb5d6f53 app, libgimpwidgets: More strcpy_s on Windows 2026-03-31 21:44:51 -03:00
Alx Sa
127510cd81 core: Use MAX_CHANNELS for Histogram limit
gimphistogram.c used its own custom MAX_N_COMPONENTS
define for the max value of its "n-components" property.
Since this value is the same as MAX_CHANNELS, it would be
good to use the global constant so the histogram limit automatically
updates when we added a new format with a larger number of components
such as CMYKA.
2026-03-31 19:28:05 +00:00
Bruno Lopes
d254c5684c app, libgimp*, plug-ins: Use strtok_s on Windows to fix CRT_INSECURE_DEPRECATE 2026-03-31 16:27:25 -03:00
Bruno Lopes
ed3611efa6 app, libgimp*, plug-ins: Use strncpy_s on Windows to fix CRT_INSECURE_DEPRECATE 2026-03-31 13:31:33 -03:00
Bruno Lopes
8b9ee6d2a8 app, tools: Use cross-platform g_getenv, not getenv
It uses the safe URCT function under the hood.
2026-03-30 21:36:54 -03:00
Bruno Lopes
811c0c8546 app: Use posix_spawn on macOS
Fixes a Apple Clang warning.
vfork is considered deprecated and unsafe on such platform
2026-03-30 16:09:13 -03:00
Bruno Lopes
af1dac3c51 app, plug-ins: Comment unused stuff on macOS
This fixes Apple Clang warnings about:

- idx
- count_large
- count_nan
- n
- iteration
- original_id
- real_pos
2026-03-29 17:19:42 -03:00
Bruno Lopes
c8c420aa18 app, plug-ins: Comment pixel, total, flags and count unused variables 2026-03-28 19:51:25 -03:00
balooii
8bdb5cbfd7 app: Fix duplicating vector layers 2026-03-26 11:52:24 -03:00
Alx Sa
d1662f8f2c core: Stop double-resizing on Fit Canvas to Layers
Resolves #16018
This patch extends a2c5d70c to also apply to the
"Fit Canvas to Layers" action. It prevents the non-rasterized
vector layer from being shifted out of place when the
canvas is resized.
2026-03-26 05:44:27 +00:00
Alx Sa
a131100075 core: Prevent double-resizing on vector image crop
Resolves #16045
This patch extends a2c5d70c to also apply to the Crop Tool.
It prevents the non-rasterized vector layer from being shifted
out of place when cropped.
2026-03-26 05:02:52 +00:00
balooii balooii
a2c5d70c92 core, path: Fix image transforms with vector layers
(Modified by CmykStudent from balooii's original merge request)
When performing image-level operations (resize, crop, scale, flip,
rotate, arbitrary transform), paths referenced by non-rasterized vector
layers were being transformed twice:

1. Via the vector layer's overrides, which explicitly transforms
   the referenced path to keep it in sync
2. Via the image-level queue that processes all paths independently

This patch adds a check for whether the layer has been rasterized.
If so, we bypass the vector layer's transform so the path is not
transformed a second time.
2026-03-25 20:29:17 -04:00
Alx Sa
c3cbd5c21f core: Use selection when counting colors...
...in Histogram Editor.
The 2.10 Colorcube Analysis plug-in took into
account the selection when displaying the colors.
The Histogram Editor itself does as well, but our
unique color count did not.
This patch adds a check in gimp_histogram_unique_colors ()
to see if there's an active selection in the image.
If so, we get its area and use that as the bounds in
gegl_buffer_iterator_new () instead of setting it to NULL.
2026-03-25 12:43:00 +00:00
Jehan
7f67536f1a Issue #16010: do not mind buffers with non-0 offsets in the case of group layers.
In fact, the previous commit was unneeded and we could have done without
reverting the old commit. On the other hand, a buffer using another
buffer as "source" may be nicer in memory.

But the previous commit alone was not right as group boundaries were
wrong. In fact, right now, we can see that group boundaries are computed
using only the children layers (except for pass-through of course), not
including any effects they might have. And the buffer passed to
gimp_drawable_set_buffer_full() was the projection's buffer itself — it
was shared, which was also why copying at setting time was wrong —, in
the case of a group layer. That means that when we translated to (0, 0)
offset, either we would have moved the render to the wrong place, or
moved the boundaries to the wrong place.
The offset needs to stay what it is, even when it's not (0, 0), for
group layers.

Another alternative fix would be instead to fix layer groups' boundaries
to encompass the full projection's render. But I just went with this
special-casing of group layers instead.
2026-03-24 20:41:53 +01:00
Jehan
af44043108 Issue #16010: adding a layer with filter to a group makes it invisible.
Part of it reverts commit 3a53e4743e.
Another part is a fix to the CRITICAL mentioned in this commit.

This being said, it's clearly not entirely right yet. The boundaries of
the layer when the filter is merged are not correct, which is especially
visible when trying to draw on this layer afterwards.
Also the layer group boundaries (when reproducing the steps in #16010)
are clearly wrong too.
2026-03-24 20:37:00 +01:00
Bruno Lopes
b697dc8a48 app: Fix critical at user_install_detect_old on distro and Flatpak packages
Closes: #16067

This fixes a regression introduced by 62467359
2026-03-22 08:17:15 -03:00
Jehan
040fac494e app: do not leak string allocated by g_ascii_strdown(). 2026-03-18 23:36:56 +01:00
Jehan
f4f83b973c app: SwatchBooker support also uses libarchive and has similar bugs! 2026-03-18 23:11:20 +01:00
Jehan
b3eaf3a577 app: better handle error cases for invalid Swatches palette.
My use case was loading a 0-bytes swatches palette. This would crash
GIMP. And so would likely a zip archive suffixed .swatches with no .json
file in it, or a corrupted archive which would return ARCHIVE_FATAL when
attempting to read entries…

This patch fixes these edge cases. It also better handle the various
return values of libarchive. E.g. we should not abandon reading when we
get ARCHIVE_RETRY; and ARCHIVE_WARN is also a success case (despite
having some warning message).

Finally I break from the archive reading loop at the first JSON file, so
that we don't leak memory if there are several JSON file. It does raise
the question if this palette format allows such use case (several
palettes in a single .swatches archive).
2026-03-18 22:41:14 +01:00
Jehan
591518fdb1 app: fix failure to read a Procreate palette with no profiles.
The sample in the description of !2613 was failing to load with a bunch
of criticals. That was because when profiles == NULL, we would call
json_reader_end_member() while we never called the associated
json_reader_read_member(). Inverting the order of tests fix this.
2026-03-18 22:32:31 +01:00
Jehan
fdda75deb8 app: localize some more strings.
Also give a bit more accurate error message when possible, e.g. when we
may have an error message from libarchive.
2026-03-18 17:57:23 +01:00
Alx Sa
ff647fccb0 path, core: Create gimp_vector_layer_set ()
Currently to change vector layer properties,
you need to grab the VectorLayerOptions
and then grab its FillOptions or the
StrokeOptions to make changes.
To make this process more self-contained,
this patch creates a gimp_vector_layer_set ()
function that operates in the same manner
as gimp_text_layer_set (). 
This patch adds properties for Fill -
Stroke properties will be added in a
follow-up commit.
This also adds
automatic tracking for Undoing/Redoing
vector property settings.
A demonstration of its use in DnD colors
and patterns onto the layer dock is
included.
2026-03-17 19:32:51 +00:00
Jehan
0074bef0ea Revert "Issue #15824: better detect the first filter."
This reverts commit 75e665f0ed.

In fact, this commit was wrong too and was creating new issues with
pass-through group layers. See #15956.
2026-03-06 21:13:52 +01:00
Bruno Lopes
6246735966 app: migrate also from ~/snap/ if the 3.0 folder is not found in XDG config home. 2026-03-03 21:33:38 -03:00
Jehan
6283ec669d app: verify all playground features to forcibly show the playground tab.
Maybe I should find a more "automatic" logic…
2026-03-02 22:25:07 +01:00
Jehan
b87bab9e8c app, libgimp*: add GimpCurve sample API in libgimp and PDB. 2026-03-01 22:33:58 +01:00
Alx Sa
804991a215 libgimp, pdb: Allow access to GimpCurve in PDB
Adds a GimpCurve object and functions in libgimp.
Rather than creating a GimpCurve object in core and
passing it back and forth, we just pass the attributes
and reconstruct it across.
In the future, we may combine this with the app/core one
and put it in libgimpbase.
2026-03-01 13:41:35 +00:00
Jehan
3a53e4743e app: copy the buffer rather than using it as source.
I think the previous code should be OK, but I had some criticals when
painting with a paint tool in the area which got extended:

> (gimp:577203): GLib-GObject-CRITICAL **: 21:37:08.402: value "-31" of type 'gint' is invalid or out of range for property 'y' of type 'gint'

It looks like there lingering pieces from the negative offset in the
buffer, which is probably a bug in GEGL?
Anyway let's go the shorter route for now, which is to copy the buffer
with a different offset. I don't think it's less efficient either
anyway.
2026-02-28 21:52:10 +01:00
Jehan
4c15be6a56 app: fix merging filters with negative top-left point.
When merging filters whose rendering was expanding in negative
ccordinates, I realized that the drawable was not properly resized (it
was resized properly when the width/height increased, but not when the x
or y points became negative, even though this "cropped" part still
showed… until you saved and reloaded your XCF!).

The problem is that drawable buffers are always stored with (0, 0)
top-left and this was just confusing our existing code. So let's check
when trying to set a buffer with a non-(0, 0) origin, and update the
offset subsequently.

I hesitated with an alternative implementation which was to edit the
buffer applied to the drawable in gimp_drawable_merge_filters(). But I
figured this would be more future-proof for other similar cases, though
I hope I did not break any use case where this was actually considered a
normal case.
2026-02-28 21:04:05 +01:00
Bruno Lopes
b7d89728c4 app, libgimpthumb, plug-ins, tools: Fix POSIX namespace warnings on MSVC 2026-02-28 10:06:46 -03:00
balooii balooii
d80ad177af Issue #13401: Fix crash opening channels after apply/undo drawable filter 2026-02-26 15:06:14 +00:00
Jehan
ad936482a2 Revert "Issue #15824: waterpixels filter on a selection appears to hang GIMP."
This reverts commit d91a8b2abe.

As reported by Liam on #15824, this commit was clearly wrong and
reintroduced the old cropping bug with multiple filters. Reverting.

The next commit was likely good, though the real hanging bug is — as far
as my test go — in the GEGL op itself. This second commit 75e665f0ed was
improving things, but obviously, as the bug is still in the op, it can
still be triggered. We'll have to fix the source bug next.
2026-02-25 23:51:56 +01:00
Jehan
75e665f0ed Issue #15824: better detect the first filter.
Ah my previous commit was working fine with a selection in the "Use the
selection as input" case, but was still hanging when "Use the entire
layer as input" was chosen.

The detection of whether we were the first filter was not working fine
when adding a new filter. Now this should work in all cases.

I don't revert the previous commit, because I think it's fine anyway.
When we have a selection, unconditionally adding a cropping-before node
on the selection boundaries seems logical to me.
Hopefully it doesn't bring back any of the cropping issues we had on
filters, but so far I could not reproduce any.
2026-02-25 15:44:29 +01:00
Jehan
d91a8b2abe Issue #15824: waterpixels filter on a selection appears to hang GIMP. 2026-02-25 15:38:23 +01:00
Alx Sa
1282384417 core: Update filter area if changed
Previously, we only updated an NDE filter's
`filter_area` if the filter itself contained a
width or height property.
However, the filter_area is also used by
GimpDrawableFilter to indicate where we
should draw the filter, and needs to be
updated if we scale/rotate/shear the layer
and change its dimensions.

This patch moves the code so that the
filter_area width and height is always
updated if we pass a GeglRectangle in to
gimp_drawable_filter_refresh_crop ().
2026-02-24 11:32:08 +00:00
Jehan
87810ae6fe app: make explicit that "White Balance" auto effect works in linear space.
This commit doesn't actually changes anything, but it fixes the
gimp_histogram_new() call, since the argument is supposed to be a
GimpTRCType, not a boolean. Yet GIMP_TRC_LINEAR is the first value in
the enum type, so it's indeed the same as FALSE.
I also set the "trc" property to "gimp:levels" config object explicitly,
to the same TRC value as the histogram, so that this doesn't depend on
the default anymore (which is linear too, right now; so this part
doesn't change a thing here again), and therefore would survive to any
possible default change in the future.

Note that it was considered to set this all to non-linear, just as it
used to be in 2.10, as requested in #15738. After discussing it with
Øyvind on IRC, we concluded that working in linear space may be a nicer
default for this feature, as we'd be doing a "meaningful rebalancing of
photon count per component". Now there may be cases where doing a
white-balancing in non-linear may yield better result, of course. For
these case, you may still go to "Levels", set to non-linear, and hit
"Auto Input Levels". This is exactly the same code runing (but in
non-linear space). The "White Balance" action still needs to be the
simple non-GUI option and keeping work in linear seems like the more
appropriate default here.
2026-02-24 01:36:32 +01:00
Alx Sa
b9d4e315e8 core: Adjust logic for gimp_drawable_filter_refresh_crop ()
In 0157a958, we prevent the NDE crop refresh
code from running unless the filter's crop
enabled is TRUE. However, this prevents
the width and height settings built into
certain filters from running, separate from
the crop nodes in GimpDrawableFilter.
This patch moves the check to only cover
the calls to gimp_drawable_filter_set_crop ().
This should fix the width/height update issue
without causing a regression to #14442.
2026-02-22 18:10:15 +00:00
Alx Sa
581afd1516 core: Fix GEGL warning after bucket fill
In 6279d7b7, I did not free the GEGL buffer created
by gimp_pickable_get_buffer_with_effects ().
This resulted in an "EEEEeEeek! 1 GeglBuffers leaked"
warning on exit, which of course could cumulate.

This patch makes to sure to clear out the src_buffer
both times it's used.
2026-02-22 00:28:16 +00:00
Alx Sa
6949400a03 core: Fix Equalize TRC compared to 2.10
In GIMP 2.10, gimp_histogram_new () takes a boolean
parameter to indicate if it should be rendered in a linear
or non-linear TRC. In GIMP 3.0, this function instead takes
a GimpTRCType where 0 is equal to the linear enum and 1
is equal to the non-linear enum.

Since gimp_drawable_equalize () still passes FALSE as it
did in 2.10, this is treated as 0 and thus setting it as a linear
operation.

This patch changes the FALSE to be GIMP_TRC_NON_LINEAR,
both for clarify and to better match the 2.10 behavior.
2026-02-20 15:00:39 +00:00
Alx Sa
4bfa65d72d core: Refresh new vector layers when pasting it
When copying and pasting vector layers, if we needed
to add a new path then the layer was not redrawn.
This would require the user to move or edit the path
to see the correct view of it.

This patch adds a call to gimp_vector_layer_refresh ()
after pasting it if it is not rasterized, in order to correct
the initial view.
2026-02-19 23:18:39 +00:00
Jehan
2b45e54b0c app: set the rasterized status properly on opening XCF files. 2026-02-14 18:30:37 +01:00
Jehan
b8e094416f Issue #15119: flipping link layers should not rasterize them. 2026-02-14 18:30:37 +01:00
Alx Sa
31eb0d86cf core: Associate color profile with SBZ palette
Color profiles were not being correctly connected to
Swatchbooker imported palettes, because the path
was included with the profile name (so a direct comparison
did not match). This patch fixes this by comparing the suffix
instead. It also fixes some minor formatting issues.
2026-02-12 02:07:49 +00:00