Commit Graph

214 Commits

Author SHA1 Message Date
Niels De Graef def862bae4 meson: Always enable CPU extensions
Don't enable conditionally based on the buildtype.

Further, don't use `add_project_arguments()` to enable the instructions:
this will lead to crashes within g-ir-scanner, which can't properly
parse these instructions.

https://gitlab.gnome.org/GNOME/gimp/-/issues/5053
2021-06-15 21:15:32 +00:00
Jehan 75e6f1062e app: fix "Luma Lighten/Darken only" layer modes.
This is a continuation of #5888 as I realized that most layer modes were
fixed with my commit b3fc24268a (and follow-up f40dc40cbc) but at least
2 were still crashing GIMP: "Luma Lighten/Darken only" modes.

There were 2 bugs here:

* The first bug was that when gimp_operation_layer_mode_real_process()
  ran, gimp_operation_layer_mode_prepare() had not been run yet.
  prepare() is called before the process() of GeglOperation, but it
  would seem the process() of GimpOperationLayerMode on the other end
  happens before GeglOperation's prepare() is run. I am absolutely
  unsure if this is expected or not and have a hard time figuring out
  all the details of the C/C++ cohabitation.
  As a solution, I am moving out the fish caching (the needed part
  inside gimp_operation_layer_mode_real_process()) in its own function
  so that I can easily call it separately before inspecting the fishes.

* The second issue was that some blend functions needed more than a
  GeglOperation alone. E.g. blend_function() for luma lighten
  gimp_operation_layer_mode_blend_luma_lighten_only() would call
  gegl_operation_get_source_space() which requires the node to exist.
  Similarly for the Luma darken only mode. So I keep both the node and
  operation around, and when finalizing, I free the node (which in turn
  frees the operation).

Ell > if you are reading our commits, I would really appreciate your
review (or fixes) of my code here! :)
2020-11-10 17:25:34 +01:00
Jehan f40dc40cbc app: fix autotools build.
My previous commit broke the autotools build. Apparently when using
g_object_unref(), some C++ symbol leaked into libapppaint.a archive
library, hence the main binaries (e.g. gimp-2.99) could not be linked
without adding -lstdc++ flag:

> /usr/bin/ld: paint/libapppaint.a(gimppaintcore-loops.o): undefined reference to symbol '__gxx_personality_v0@@CXXABI_1.3'
> /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libstdc++.so.6: error adding symbols: DSO missing from command line

Not exactly sure why using this GLib function in particular caused this,
but let's just try another approach in order not to link the main binary
with C++ standard lib.
Instead let's manage all GeglOperation allocation in gimp-layer-modes.c
by adding a gimp_layer_modes_exit() function and some static array for
storing operation object of each layer mode.
2020-11-10 12:52:01 +01:00
Jehan b3fc24268a Issue #5888: GIMP 2.99.2 crash when using brush in multiply mode.
The GimpOperationLayerMode variable member in DoLayerBlend was not
properly constructed. C++ class constructor can be called by creating
object variables, but with GObject, we have to do it with pointers.
Otherwise here we were only allocating the memory for the struct, but
not actually calling any initialization functions.

Also it would seem that the struct was not initialized at zero, as the
space_fish variable was not NULL when it should (i.e. even with same
composite and blend space), hence composite_to_blend_fish was not NULL
and since the operation was not a valid GeglOperation when entering
gimp_operation_layer_mode_real_process(), we crashed.
Not sure how it went unseen for so long!

So instead let's make the layer_mode class member into a pointer. As
such, I have to properly allocate and free it. This is also why I am
adding a copy constructor which will ref the pointer (otherwise we unref
more than we ref as the default copy constructor would just copy the
pointer).
2020-11-10 01:11:01 +01:00
Ell 59f3b07c5f app: remove ANTI_ERASE from filter mode set
It used to be included in "Edit -> Fade", but it's too low-level.
2020-05-08 14:42:22 +03:00
Ell 38059dc5fd app: rename "Fade" section of GimpFilterTool to "Blending Options"
... and GIMP_LAYER_MODE_CONTEXT_FADE to
GIMP_LAYER_MODE_CONTEXT_FILTER.
2020-04-08 15:59:33 +03:00
Ell 8384d37e66 app: add "Fade" options to filter tools
As per commit ed7ea51fb7, reintroduce
the "Fade" functionality for filters, by incorporating it directly
into GimpFilterTool.

Add "mode" and "opacity" options to GimpOperationSettings, and add
a corresponding "Fade" expander to the GimpFilterTool dialog
allowing to control them.

Reintroduce the FADE layer-mode context, and use it to mark the
layer modes avaialable for fading.
2020-04-07 19:40:05 +03:00
Ell 646c804c04 app: fix compositing of layers with masks, outside the mask bounds
In GimpOperationLayerMode, when the op has a mask connected, and
we're processing an area outside the mask bounds, set the op's
opacity to 0, so that the backdrop shows through.  The actual
process() function gets a NULL mask pointer in this case, and so
would composite the layer as if it had no mask, exposing areas that
should be masked out.

Add a GimpOperationLayerMode::parent_process() function, which
subclasses can override instead of GeglOperation::process(), and
make sure to update the GimpOperationLayerMode::opacity field
before calling this function (and, subsequently, before calling
GimpOperationLayerMode::process()).

Clean up the rest of the fields, and adjust the rest of the code.
2020-02-21 22:54:16 +02:00
Ell 2eaaa950a5 app: in gimp:replace, add fast path when compositing a layer over itself
In gimp:replace, when compositing the same content over itself,
i.e., when the input and aux buffers share the same storage and
same tile alignment, pass the input buffer directly as output,
instead of doing actual processing.

In particular, this happens when processing a pass-through group
outside of its actual bounds.
2020-02-20 13:03:10 +02:00
Félix Piédallu 65eff6f150 Meson port. 2019-09-11 16:42:04 +02:00
Ell 998f89e3cb app: in gimp:replace, implement GeglOperation::get_bounding_box()
... similarly to gimp:layer-mode, however, assume the destnation
(backdrop) is not included when the layer's opacity is 1, and
there's no mask.
2019-08-02 00:40:01 +03:00
Ell 89c97bcf26 app: in gimp:layer-mode, implement GeglOperation::get_bounding_box()
... to take the layer's composite mode and opacity into account.
2019-08-02 00:40:01 +03:00
Ell 1dd3d7e91e app: clean up Luminance blend function
... in particular, don't use a static fish.
2019-06-10 10:53:00 -04:00
Elle Stone 65f85e7078 Make luma_lighten/darken_only blend modes work in AnyRGB 2019-06-10 11:44:55 +02:00
Elle Stone 19e74f0e28 app: make luminance blend mode depend on space
Fixes issue #3451 Space invasion/AnyRGB: Luminance blend mode doesn't work

It might be faster to fetch the RGB luminance and do the computation
ourselves than looking up the same fish for each processing request, at
least now we're faster. (commit message and code slightly revised by pippin)
2019-06-09 20:35:35 +02:00
Øyvind Kolås 8e90468308 app: add GeglOperation *operation argument to GimpLayerModeBlendFunc
Some blend funcs depend on constants from the specifc color space we are
operating in and needs the space or operation propagated to the worker function
of the operation as discovered in issue #3451.

This commit propagates the operation, leaving the specific blend functions
needing it to call gegl_operation_get_source_space or similar without needing
that overhead for the rest.
2019-06-09 12:35:45 +02:00
Ell 3766af9ac9 Revert "app: avoid NULL output in layer-mode ops"
On a second thought... nope :)  We'll fix it another way.

This reverts commit 60947b7a34826657395ca485d334ccb302106e07.
2019-05-31 13:11:13 -04:00
Ell 8fcac3298c app: avoid NULL output in layer-mode ops
In GimpOperationLayerMode and GimpOperationReplace, make sure we
don't return a NULL output buffer, or forward a NULL input buffer,
but rather create an appropriate empty buffer in this case.  This
avoids wrong results when the layer-mode op's output is connected
to the aux input of a subsequent op, as a result of the op behaving
differently with a NULL aux buffer (in particular, this can happen
when a drawable filter's output bounding box is smaller than the
drawable.)
2019-05-31 12:25:32 -04:00
Ell c2021d3c5b app: disregard composite space in source-only trivial layer modes
Extend last commit to also disregard the composite space when the
layer mode is trivial and only the source region is included in
compositing, since, in this case, the source color is unmodified.
2019-05-24 02:42:56 -04:00
Ell a5962e4049 app: disregard composite space in non-union alpha-only layer modes
In gimp_layer_mode_get_format(), disregard the requested composite
space when selecting the format, if the input layer mode is alpha-
only, and the requested composite mode is not UNION, since, in this
case, the layer mode doesn't combine the layer/backdrop colors, and
rather only modifies the alpha of one of them.  This allows us to
use the preferred format, avoiding gamma conversion.

This particularly improves the performance of the Eraser tool in
perceptual images.
2019-05-24 01:43:20 -04:00
Ell 0cf77b0a3b app: #include <string.h> in gimpoperationreplace.c
... for memset().
2019-02-14 11:09:17 -05:00
Ell 27e8f452b3 app: change behavior of REPLACE mode for fully-transparent pixels
When the result of compositing has an alpha value of 0, the
corresponding color value is not mathematically defined.
Currently, all out layer modes opt to preserve the destination's
color value in this case.  However, REPLACE mode is different
enough to warrant a different behavior:

Unlike the other layer modes, when the compositing opacity
approaches 0 or 1, the output color value approaches the
destination or source color values, respectively, regardless of the
output alpha value.  When the opacity doesn't approach 0 or 1, the
output color value generally doesn't approach a limit as the output
alpha value approaches 0, however, when both the destination and
source alpha values are equal, the output color value is always a
simple linear interpolation between the destination and source
color values, according to the opacity.  In other words, this means
that it's reasonable to simply use the above linear interpolation
for the output color value, whenever the output alpha value is 0.

Since filters are commonly combined with the input using REPALCE
mode with full opacity, this has the effect that filters may now
modify the color values of fully-transparent pixels.  This is
generally desirable, IMO, especially for point filters.  Indeed,
painting with REPLACE mode (i.e., with tools that use
gimp_paint_core_replace()) behaved excatly as described above, and
had this property, before we switched gimp_paint_core_replace() to
use the common compositing code; this created a discrepancy between
painting and applying filters, which is now gone.

A side effect of this change is that we can now turn gimp:replace
into a NOP when the opacity is 100% and there's no mask, which
avoids the compositing step when applying filters.  We could
previously only apply this optimization to PASS_THROUGH mode, which
is a subclass of REPLACE mode.

Note that the discussion above concerns the UNION composite mode,
which is the only mode we currently use REPLACE in.  We modify the
rest of the composite modes to match the new behavior:
CLIP_TO_BACKDROP always preserves the color values of the
destionation, CLIP_TO_LAYER always preserves the color values of
the source, and INTERSECTION always produces fully-zeroed pixels.
2019-02-14 11:04:53 -05:00
Ell 889e2e26ee app: remove gimp-scratch; replace with gegl-scratch
The scratch allocator has been moved to GEGL (commit
gegl@b99032d799dda3436ffa8c1cc28f8b0d34fb965d).  Remove gimp-
scratch, and replace all its uses with gegl-scratch.
2019-01-06 07:37:19 -05:00
Ell ed7ea51fb7 app: remove "Edit -> Fade..."
This commit completely removes the "Edit -> Fade..." feature,
because...

- The main reason is that "fade" requires us to keep two buffers,
  instead of one, for each fadeable undo step, doubling (or worse,
  since the extra buffer might have higher precision than the
  drawable) the space consumed by these steps.  This has notable
  impact when editing large images.  This overhead is incurred even
  when not actually using "fade", and since it seems to be very
  rarely used, this is too wasteful.

- "Fade" is broken in 2.10: when comitting a filter, we copy the
  cached parts of the result into the apply buffer.  However, the
  result cache sits after the mode node, while the apply buffer
  should contain the result of the filter *before* the mode node,
  which can lead to wrong results in the general case.

- The same behavior can be trivially achieved "manually", by
  duplicating the layer, editing the duplicate, and changing its
  opacity/mode.

- If we really want this feature, now that most filters are GEGL
  ops, it makes more sense to just add opacity/mode options to the
  filter tool, instead of having this be a separate step.
2018-12-27 11:44:25 -05:00
Ell f508ec8b89 app: mark REPLACE and PASS_THROUGH modes as trivial 2018-12-03 09:54:09 -05:00
Ell 8adec5fb3a app: add gimp_layer_mode_is_trivial()
Add a TRIVIAL layer-mode flag, and corresponding
gimp_layer_mode_is_trivial() function, which indicates if the blend
function of a given layer mode is trivial, i.e., either never
modifies the source pixels (for non-subtractive modes), or always
clears the destination pixels (for subtractive modes).
2018-12-02 03:10:30 -05:00
Ell dbab0b557d app: in Luminance mode, cache RGBA -> Y fish 2018-12-01 05:55:17 -05:00
Ell 70b7316ebc app: in Luminance mode, replace VLAs with gimp-scratch
In the Luminance layer-mode, use the scratch allocator for
allocating temporary buffers, instead of using VLAs.
GimpOperationLayerMode already allocates data on the stack,
calculated as not to overflow the stack on any platform, so having
any of its descendants also allocate big buffers on the stack is
risky.
2018-12-01 05:55:16 -05:00
Øyvind Kolås 4dd3e2197a app: cache fishes per operation instance in layer-modes
There was a global 3x3 array of babl fishes used for converting between
blending and compositing pixel representations, these were all hard-coded to
operate within the sRGB babl-space family. This commit updates a per-instance
array during operation prepare instead, that comes preconfigured with fishes
derived from the correct space. Since the same operation instance might get
different space input during its life time we store and compare the cached
fishes with the current format (which is unique depending on space).

This should address the problem seen in issue #2592
2018-11-30 01:23:25 +01:00
Øyvind Kolås 34376c7abf app: propagate space in gimp_layer_mode_get_format
We were not propagating the space properly causing compositing and blending to
always happen in default/linear sRGB space.
2018-11-01 01:51:47 +01:00
Michael Natterer e09e563a70 Initial space invasion commit in GIMP
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.
2018-07-21 16:42:57 +02:00
Michael Natterer 5f700549e7 Change the license URL from http://www.gnu.org/licenses/ to https:// 2018-07-11 23:29:46 +02:00
Ell 367399e5c0 Issue #1490 - Crash when flattening an XCF file
The default stack size for new threads on MacOS is 512 KiB, making
our 512 KiB limit for stack-allocated buffers in
gimp_operation_layer_mode_real_process() too high.  Lower it to
256 KiB.
2018-05-25 20:34:46 -04:00
Ell 2c58598172 app: add gimp_layer_mode_is_alpha_only()
... which determines if a layer mode's blend function only affects
the alpha, maintaining the backdrop's color.  This is currently
true only for ERASE, SPLIT, and ANTI_ERASE modes.
2018-05-07 16:53:29 -04:00
Ell f6a56fac51 app: move exclusion and linear-burn modes to a more logical position
... in the layer-mode menu (this only affects UI.)
2018-04-26 16:08:55 -04:00
Ell f49e4b4263 Bug 794634 - CRITICAL when adding layers with Dissolve mode
Fix a CRITICAL when calling gimp_layer_mode_get_format() with an
AUTO composite space and a NULL preferred format, which is valid:
it means the layer mode is composite-space agnostic (as DISSOLVE
is), and that there's no preferred format.

A NULL preferred format can occur during
gimp_operation_layer_mode_prepare() if the layer's mode node is not
yet attached anything through its "input" or "aux" pads, which is
the case during the call to gimp_layer_update_mode_node() while
constructing the layer's node in gimp_layer_get_node().
2018-03-23 14:57:10 -04:00
Ell a7f3a2dd9f app, pdb, libgimp, plug-ins, menus: rename layer composite modes
Our composite modes don't correspond directly to the Porter-Duff
operators after which they're named, and these names aren't too
descriptive anyway.

Rename the composite modes as follows:

  Source Over       =>  Union
  Source Atop       =>  Clip to Backdrop
  Destination Atop  =>  Clip to Layer
  Source In         =>  Intersection

Update relevant code, including UI text, enumerator names, function
names, and action names.
2018-03-14 16:19:09 -04:00
Ell 8d3b287273 app: improve gimp_layer_mode_get_format()
When the layer mode is composite-space agnostic, return a fast
format based on the preferred format's model, not the exact format.
2018-02-12 13:49:03 -05:00
Michael Natterer 539927ebfa app: replace all g_assert() by the newly added gimp_assert()
which is just a #define to g_assert for now, but can now easily be
turned into something that does some nicer debugging using our new
stack trace infrastructure. This commit also reverts all constructed()
functions to use assert again.
2018-02-11 22:23:10 +01:00
Ell d34800c5fc app: reintroduce clamping to vivid-light mode
... removed by commit 0f9da165e0, and
improved by this commit.

Our foo-light modes aren't really prepared to handle out-of-range
input.  Make sure that in-range input doesn't result in out-of-
range output.
2018-01-06 12:56:44 -05:00
Ell 3b52b044f9 app: small cleanup in gimpoperationlayermode-blend.c
Indentation, float literals, etc...
2018-01-06 12:31:51 -05:00
Ell 0f9da165e0 Bug 790566 - Modify the divide blend mode to not max out at 5.0
Add a safe_div() function to gimpoperationlayermode-blend.c, and
use it in the relevant blend funcs, instead of plain division.
This function clamps the quotient to some reasonable range, to
avoid infinities, and maps epsilon/... to 0, to avoid NaN.  The
latter part results in similar qualitative results to the
corresponding legacy modes, when calculating 0/0.
2018-01-06 12:31:51 -05:00
Ell 4e4c1cd57e Bug 790810 - Nested layer groups lead to a deadlock with multithreading
Use gimp:buffer-source-validate, introduced in the previous commit,
for the source node of GimpDrawables.  This avoids threading issues
with layer groups, or any other drawables that may use a validating
buffer, by making sure the buffer is validated before any
succeeding operations, and hence the associated graph is processed
on the same thread as the parent composition.

Restore multithreaded processing in GimpOperationLayerMode.
2017-12-04 16:03:15 -05:00
Ell 2ff52af5a9 Bug 790810 - Nested layer groups lead to a deadlock with multithreading
Temporarily disable multithreading for GimpOperationLayerMode, to
avoid the deadlock.  The environment variable
GIMP_MULTITHREADED_COMPOSITING can be set to reenable it, for the
sake of debugging.
2017-11-26 10:54:41 -05:00
Ell 6f7d95c21c app: remove legacy color-erase mode from the layer mode combo
It was accidentally made applicable to layers by commit
7d345071c7.  Only the non-legacy
color-erase mode shoule be applicable to layers (since 2.8 didn't
allow it as a layer mode), while the legacy mode is only available
for painting, and in the fade dialog.
2017-10-23 09:53:07 -04:00
Ell 2bf166d2ce app: use fuzzy comparison in various layer-mode blendfuncs
Use fuzzy comparison, instead of exact comparison, in various layer-mode
blendfuncs which may be sensitive to small error.
2017-10-17 08:47:23 -04:00
Ell 5effdd03b4 app: add dedicated op for pass through mode, with shortcuts
Pass through mode uses the same compositing logic as REPLACE mode,
however, it's a special case of REPLACE, where the layer is already
composited against the backdrop.  This allows us to take a few
shortcuts that aren't generally applicable to REPLACE mode.

Add a dedicated op class for pass through mode, derived from the
REPLACE mode op, implementing these shortcuts.
2017-08-31 11:39:38 -04:00
Ell f13c177ea7 app: fix babl format names in luminance mode
More refactoring fallout :P
2017-08-20 17:15:32 -04:00
Ell 77f51dd737 app: specify blend function for GIMP_LAYER_MODE_COLOR_ERASE_LEGACY
This is what happens when you edit code with sed :P
2017-08-19 15:37:49 -04:00
Michael Natterer 0cfe550639 app, pdb: change a lot of GIMP_LAYER_MODE_NORMAL_LEGACY to just NORMAL
this commit changes just those which make no difference to
functionality: property and object member defaults that get overridden
anyway, return values of g_return_val_if_fail(), some other stuff.
2017-08-19 20:33:47 +02:00