... (valgrind reports Invalid read)
Add gimp_babl_is_valid(), which takes a GimpImageBaseType and a
GimpPrecision, and determines whether the image-type/precision
combination is valid. Use this function to validate that loaded
XCFs use a valid type/precision combination, before trying to
create the image. Otherwise, we get a CRITICAL, and eventually a
segfault, when the combination is invalid.
Use the same function to validate the arguments of
gimp_image_new().
- remove gimp_widget_flush_expose()
- remove the "now" argument to gimp_display_shell_flush() and make it
only update widget states
- rename gimp_display_flush_whenever() to gimp_display_flush_update_region()
and call gimp_display_shell_flush() separately in the only case we
passed FALSE to flush_whenever()
- remove th flush_now interval logic from GimpDisplay, as soon as we
have exposed the canvas, we are in the loop for the next frame clock
tick anyway, so delaying a useless and removed process_updates serves
no purpose
- in gimptool-progress.c, create the invisible grab widget also for
non-cencelable cases, so we can always safely run the main loop
manually to make the progress updates visible
- in gimp-gegl-apply-operation.c, always run the main loop manually
to make the progress updates visible
- in gimpstatusbar.c, leave some FIXME comments as reminder that
we might need the same logic as in gimptool-progress.c
... and gimppaintcore-loops
When a rectangle argument is NULL, use the extents of the
corresponding buffer, instead of raising a CRITICAL, to match the
old behavior.
... which is a drop-in replacement for gegl_buffer_copy(),
parallelizing the copy operation when the source and destination
formats are different, requiring a conversion.
When the operation doesn't have an input pad, composite it over the
input using gimp:normal, instead of gegl:over, for consistency with
the rest of our compositing code (although the result should be the
same).
Blend them on top of the source buffer using gegl:over like
GimpDrawableFilter does interactively. Fixes "Repeat Last" and
probably some other stuff for source OPs.
One additional fix for the gimp-channel-combine-masks procedure,
it needs both the combined *and* combined-to buffer in
gimp_gegl_mask_combine_buffer() to be treated specially.
Storing selections and layer masks as linear grayscale, but channels
as whatever-the-layers-are caused severe problems in images with
gamma-corrected layers: when combining channels with the selection,
they would go thorugh a gamma conversion before being combined, giving
unexpected results.
This commit changes all channels to always be linear, except in 8-bit
images, where they continue to be "Y' u8", for compatibility with old
XCF files, and because linear 8-bit can't really be used in
compositing (channels can be visible too).
To fix channel -> selection combinations also for these images, add a
small hack to gimp_gegl_mask_combine_buffer() which makes sure the
to-be-combined channel's pixels are always read as-is, without any
gamma conversion. After changing channels to linear, this makes no
difference except in the 8-bit images where we need this hack.
In gimp_gegl_convert_color_profile(), when src/dest_rect is NULL,
use the extents of src/dest_buffer, instead of passing a NULL area
to gimp_parallel_distribute_area(), which results in a CRITICAL.
Additionally, only report progress on the main thread.
Commit cb239e60f6 introduced
artifacts when using the smudge tool with multithreads. Fix this
(caused by a wrong offset passed to an iterator) plus indentation
fixes.
Add gimp-parallel.[cc,h], which provides a set of parallel
algorithms.
These currently include:
- gimp_parallel_distribute(): Calls a callback function in
parallel on multiple threads, passing it the current thread
index, and the total number of threads. Allows specifying the
maximal number of threads used.
- gimp_parallel_distribute_range(): Splits a range of integers
between multiple threads, passing the sub-range to a callback
function. Allows specifying the minimal sub-range size.
- gimp_parallel_distribute_area(): Splits a rectangular area
between multiple threads, passing the sub-area to a callback
function. Allows specifying the minimal sub-area.
The callback function is passed using an appropriately-typed
function pointer, and a user-data pointer. Additionally, when used
in a C++ file, each of the above functions has an overloaded
template version, taking the callback through a generic parameter,
without a user-data pointer, which allows using function objects.
Use the recently-added gegl_tile_handler_damage_rect() function
during GimpTileHandlerValidate invalidation, instead of manually
voiding the tile pyramid. This function avoids voiding mipmapped
tiles entirely when only a subarea of the tile needs to be redrawn.
See GEGL commit 3210f4ffc3c569a2acd9483811cb141070112bc6.
In gimp_gegl_apply_scale(), use a CLAMP abyss policy for the scale
op, to avoid leaking transparency into the image when scaling
drawables.
Note that this (intentionally) only affects whole-image/layer
scaling, and not scaling done using any of the transform tools.
In gimp_gegl_apply_{border,grow,shrink,flood}(), which are used
by the corresponding channel functions, pass crop_input = TRUE to
gimp_gegl_apply_operation(), to clip the input to the output rect.
These operations process the entire input in one go, regardless of
the requested output region; however, the channel functions
calculate the output region according to the known channel bounds,
hence clipping the input to these bounds doesn't affect discard any
information, while avoiding unnecessary work. In particular, this
makes the corresponding operations on small selections in big images
much faster.
Add a crop_input parameter to gimp_gegl_apply_[cached_]operation().
When TRUE, the functions crop the op's input to the destination
rect. This is particularly useful for functions that process the
entire input in one go (by means of get_cached_region()). See the
next commit.
Pass crop_input = FALSE at all call sites for now, to keep the
current behavior.
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.
... so that the transformed boundary is properly clipped.
Adjust the boundary-size algorithms to operate on arbitrary
polygons.
Avoid using gimp_matrix3_will_explode() in
gimp_drawable_transform_buffer_affine() and falling back to
cropping the result, and avoid setting the "clip-to-input" property
of gegl:transform. Neither of those in needed anymore.
This effectively reverts the app/ part of commit
768d06614f. The next commit revets
the libgimpmath/ part.
When merging a drawable filter, we call
gimp_gegl_apply_cached_operation() on a node that's part of the
drawable's filter stack graph. The function rewires the node's
input, and doesn't restore its original input connection before
returning, leaving the graph in an inconsistent state. Currently,
this doesn't matter, since we remove the filter right after that,
but the next commit expects the filter stack graph to remain
consistent.
Remember the original source node of "operation" in
gimp_gegl_apply_cached_operation(), and restore it upon exit, to
fix that.
gimp:buffer-source-validate is a drop-in replacement for
gegl:buffer-source, however, if the attached buffer has a
validating tile-handler, it makes sure the required region is
validated during process(). This avoids a situation in which
validation happens in different worker threads at the same time
during the processing of a succeeding operation; since validation
is protected by the buffer's tile-storage mutex, this can result in
either a deadlock (currently), or an effective fallback to single-
threaded processing.
Update the dprod production of generated enum files to include
abbreviated value descriptions, as per the previous commits.
Add a comment for translators above the abbreviated descriptions,
specifying the full description they abbreviate.
This reverts commit 4bd118ec8a.
The mutex introduced by the above commit should no longer be
necessary, after GEGL commit
8b034c437b0162b26f85eb80867914977ac3cf57.
When creating a flatten node, which is used when removing alpha
channels and when flattening an image, use a gimp:normal node to
combine the layer with the background color, instead of a gegl:over
node. gegl:over can apparently result in completely black output
with OpenCL enabled, under certain (not fully pinned-down)
conditions.
As long as the OpenCL version of gegl:over is borked, there is not
much reason to use it over gimp:normal, which is more consistent
(in intension, if not in extension) with the rest of the
compositing pipeline.
Add a composite_space parameter to gimp_gegl_create_flatten_node()
and gimp_gegl_apply_flatten(), which controld the color space --
linear or perceptual RGB -- used for the operation (instead of
hardcoding it to linear).
When removing a layer's alpha channel, use the layer's composite
space for the flattening. When flattening an image, use the bottom
layer's composite space. Keep using linear space when creating a
channel or a mask from a drawable with alpha.
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.
Split libappgegl into libappgegl-generic and libappgegl-sse2, and
move the SSE2 code (part of the newly added smudge code) to the
latter, so that the rest of the code can be compiled without SSE2
compiler flags. This allows building GIMP with SSE acceleration
enabled, while running the resulting binary on a target with no
SSE accelration.
... causing compilation to fail on 32 bit targets
Use SSE2 compiler flags when building libappgegl, since it's used by
the new smudge tool code.
Avoid using SSE for the smudge tool if SSE acceleration is disabled
at runtime, or if the buffers are not properly aligned.
More than 2000 lines of code less in app/, instead of
if (instance->member)
{
g_object_unref/g_free/g_whatever (instance->member);
instance->member = NULL;
}
we now simply use
g_clear_object/pointer (&instance->member);
- enable the setting code in gimp-gegl.c again
- but set the default to one thread in GimpGeglConfig, with a CPP warning
- rename "processors" to "threads" in the GUI
- add a warning box about unexpected results when increasing #threads
Commit 1e6acbd4e1 modified the
generated enum recipes to run gimp-mkenums from the source
directory, instead of the build directory, so that only the
basenames of the corresponding header files would appear in
the comment at the top of the generated files. This was a
mistake -- $(GIMP_MKENUMS) is expecting to be invoked from the
build directory.
Switch back to running gimp-mkenums from the build directory. To
avoid including the relative path from the build directory to the
source directory in the generated file, add a @basename@ production
variable to gimp-mkenums, which exapnds to the basename of the
input file, and use it instead of @filename@ in the recipes for the
generated enum files.
When regenerating an enum file, don't copy it back to the source
directory if it hasn't actually changed. This allows using a read-
only source directory where the enum header is newer than the
generated file, as long as they're not really out of sync.
OTOH, *do* touch the generated source-dir file even when unchanged,
in order to avoid re-running its recipe on the next build, however,
allow this to silently fail (which is harmless).
We check them into git, so this makes it easier to keep them in
sync when using a separate build directory.
Case in point -- this commit also syncs a few enum files that went
out-of-sync with their headers.
The halftones transfer mode of dodge/burn uses pow(), which produces
NaN for negative input values. This tool doesn't really have OOG
values in mind, but using an odd power function fixes this issue,
and is in line with the behavior of the other modes w.r.t. OOG
values.