When converting Brightness-Contrast to Levels, and Levels to
Curves, make sure to copy the common settings as well as the
operation-specific settings.
(cherry picked from commit 987447f18f)
In gimp_operation_config_sync_node(), when the operation has a
property of the config object's type, don't skip the other
properties. This makes sure to set the "linear" property of
GimpOperation{Curves,Levels} according to the config object. We'd
previously done it manually in GimpFilterTool, but the setting was
not applied when repeating the filter.
(cherry picked from commit 0096e563f6)
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.
Add a new GimpOperationSettings class, to be used as a base class
for all operation-config types. The class provides options common
to all operations (namely, the clipping mode, input region, and
color options), which were previously stored in GimpFilterOptions,
and were therefore bound to the filter tool, instead of being
stored as part of the operation settings; as a result, these
options would have no effect when reapplying a filter, or when
restoring a preset.
The GimpOperationSettings options do not affect the operation
node, but rather the associated GimpDrawableFilter object. The
class provides a gimp_operation_settings_sync_drawable_filter()
function, which applies the options to the filter.
Modify all custom and auto-generated operation-config types to
derive from GimpOperationSettings, and modify the GimpConfig
functions of the former to account for the GimpOperationSettings
properties, using a set of protected functions provided by the
class.
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.
(cherry picked from commit 646c804c04)
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.
(cherry picked from commit 2eaaa950a5)
In gimp:buffer-source-validate, invalidate the node in response to
GimpTileHandlerValidate::invalidated, added in the previous commit,
in addition to GeglBuffer::changed.
(cherry picked from commit bb8ee0e686)
In GimpHistogram, get rid of the "n-channels" property and
corresponding gimp_histogram_n_channels() function. The former
returned the actual number of channels, but this wasn't too useful,
as channel values may not be sequential; the latter returned the
number of components. Instead, add an "n-components" property and
a corresponding gimp_histogram_n_components() function, both of
which return the number of components. Furthermore, add a
gimp_histogram_has_channel() function, which determines if the
histogram has a given channel; this allows for simple testing for
channel availability, which was done wrong in various places.
Adjust the GimpHistogram code for the changes, and clean it up,
fixing a few bugs.
Adjust users of GimpHisotgram for the changes. In particular,
in GimpHisotgramView, fix the channel-availability test when
setting the view's histogram (which happens whenever the active
drawable's preview is frozen), to avoid erroneously swithcing the
view's channel back to "Value" when a non-RGB channel is selected.
(cherry picked from commit fc17f0ed0c)
... 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.
(cherry picked from commit 998f89e3cb)
The latter is broken and doesn't guarantee a decimal point with the
current bug. Also, g_ascii_dtostr() doesn't need the format parameter
and produces nicer output.
(cherry picked from commit c0fb66254e)
In gimp:gradient, fix dithering to correspond to how we actually
round float values to 8-bit. In particular, this avoids
introducing noise when a component is fixed at 0 or 1 along a
segment.
(cherry picked from commit e22fcc8942)
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.
(cherry picked from commit 8e90468308)
Blacklist the "tools-offset" action in the GUI, and only keep
"filters-offset", to avoid duplication. Update gimp:offset's
description, so that "filters-offset" gets a proper tool-tip.
(cherry picked from commit 42d4255262)
Add a new gimp:offset operation, which implements equivalent
functionality to gimp_drawable_offset(), in preparation for adding
an interactive offset tool.
To simplify things, add a GIMP_OFFSET_WRAP_AROUND value to the
GimpOffsetType enum, to avoid the need for a separate wrap-around
flag. This makes the gimp-drawable-offset procedure parameters a
little superfluous, but whatever.
(cherry picked from commit 40fefb6076)
In gimp:mask-components, add an "alpha" property, which controls
the masked-in alpha value in case there's no aux buffer. Set it to
0 by default, so that gimp:mask-components behaves normally in the
absence of an aux buffer (as if the aux buffer was empty). Set it
to 1 in the image's visible-mask node, to maintain the current
alpha-component visibility behavior.
This fixes incorrect results when the output bounding box of a
drawable filter is smaller than the drawable, which can lead to a
NULL aux buffer being fed to the filter's gimp:mask-components
node.
(cherry picked from commit 6425bf820a)
On a second thought... nope :) We'll fix it another way.
This reverts commit 60947b7a34826657395ca485d334ccb302106e07.
(cherry picked from commit 3766af9ac9)
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.)
(cherry picked from commit 8fcac3298c)
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.
(cherry picked from commit c2021d3c5b)
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.
(cherry picked from commit a5962e4049)
In GimpCurve, replace the use of a fixed-length control-point array
with a dynamically-sized array. Adapt GimpCurve's interface, and
the rest of the code.
In addition to simplifying the code, this fixes a bug where the
curve object could be broken by moving the mouse too fast (yep...),
and allows more accurate point placement, both in the GUI editor,
and through canvas interaction in the Curves tool (see issue #814).
(cherry picked from commit b6d829a1b2)
In gimp:fill-source, align the result rect to the drawable buffer's
tile grid, so that all tiles are COWed for solid-color fills.
(cherry picked from commit fa31854a66)
Add a new gimp:fill-source operation, which can act as a source
node for fill operations, instead of a fill buffer. The op takes
a GimpFillOptions object, a drawable, and a pattern offset, and
uses gimp_fill_options_create_buffer() to produce its output.
This allows performing the entire fill operation in chunks as a
graph, instead of allocating a full-size fill buffer, which can
can occupy a lot of space for pattern fills.
(cherry picked from commit 6b0337e384)
Fix gimp:mask-components to use full-oapcity value for the alpha
component when it's masked-in and there's no "aux" input, so that
the image is rendered with full opacity when the alpha channel's
visiblity is toggled off, as per bug #143315.
(cherry picked from commit 6419ed3246)
Replace the use of the deprecated GeglNode::dont-cache property,
and GeglOperationClass::no_cache field, with GeglNode::cache-policy
and GeglOperationClass::cache_policy, respectively.
See commit gegl@7f24430cda0d8c3eff311868823d445edc2a4e12.
(cherry picked from commit 7489f0aece)
Add specialized versions of gimp:mask-components for 8-, 16-, and
32-bpc formats, to improve efficiency, and to preserve the contents
of masked-out components exactly.
Provide public functions for format-selection and processing, which
we'll use in the painting code, instead of reimplementing component
masking.
(cherry picked from commit ee156b8fd6)
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.
(cherry picked from commit 27e8f452b3)