In gimp_pickable_contiguous_region_by_color(), add a small epsilon
to the threshold value, to allow for small errors due to the input
color and pickable pixel-colors being converted to the common
format through different paths.
While we *could* special-case threshold == 0 when the input color
comes from the same pickable, as is the case for the select-by-
color tool, and perform an exact comparison in the original format,
in the more general case the input color can come from an arbitrary
source, such as a plug-in.
(cherry picked from commit a6c79770c3)
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.
(cherry picked from commit e83d8ac4f2)
In gimp_temp_buf_{ref,unref}(), and
gimp_temp_buf_create_{buffer,pixmap}(), accept a const GimpTempBuf
argument.
(cherry picked from commit 0a1e62768a)
Just the GimpData::save() and ::copy() part that is needed to
duplicate and rename them, the image-to-pipe logic from the export
plug-in remains to be ported.
(cherry picked from commit aee097fa97)
- don't clear the names of the individual brushes, we need them for
a load -> save roundtrip
- for the same reason, and for convenience, store the parameter string
in the object
- clean up gimp_brush_pipe_finalize()
(cherry picked from commit 4b456e6079)
In gimp_drawable_filter_sync_affect(), don't mask-out the filter's
alpha component when the drawable doesn't have an alpha channel,
since this is no longer necessary -- we now explicitly convert the
output to the drawable format as part of the graph -- and it
prevents the gimp:mask-components node from becoming a NOP.
(cherry picked from commit af2c7d1b33)
In gimp_drawable_get_active_mask(), when the drawable doesn't have
an alpha channel, set or clear the mask's alpha bit, according to
the state of the other bits, so that it never gets in the way of a
fully set/clear mask. The value of the alpha bit doesn't matter
when there's no alpha channel, however, having a uniform mask
allows us to skip component masking altogether.
Additionally, provide a default implementation for
GimpDrawable::get_active_mask() which returns a full mask, and
remove the equivalent implementation for GimpChannel.
(cherry picked from commit 1b900bfa16)
Remove gimp_drawable_replace_buffer(), which is no longer used
anywhere since commits ddb69b77a7 and
3451ffb62c. This eliminates
redundancy, since all compositing is now done through the layer-
mode code.
Furthermore, gimp_drawable_replace_buffer() used the drawable's
active-component array, whose layout depends on the image mode, as
an argument to gimp_gegl_replace(), which always expects an RGBA
component array, resulting in broken component masking in non-RGB
images.
(cherry picked from commit 2074accb60)
The algorithm to compute a zone area by following its border only works
well for fully closed zones. It may return negative values otherwise.
Let's just assume the created zone is big in this case (which may or may
not be the case, but this is the safe case as it does not prevent
closure creation).
(cherry picked from commit 0636c302a3)
Add some comments and string docs as it is not that obvious to
understand the whole logics, invert the return value (returning TRUE
when the closure line is accepted, instead of the opposite) and rename
it to more appropriate gimp_line_art_allow_closure().
(cherry picked from commit c4beca8c90)
Add GimpData::save() implementation to GimpPattern, and change some
glue code to make patterns editable.
Also implement GimpData::duplicate() in GimpPatternClipboard, which
makes it possible to simply copy an area and duplicate the clipboard
pattern to create a new persistent pattern.
(cherry picked from commit e93fd73fac)
We currently have brush and pattern I/O code in both the core and
plug-ins. This commit starts removing plug-in code in favor of having
one copy of the code in the core, much like XCF loading and saving is
implemented.
Add app/file-data/ module with file procedure registering code, for
now just with an implementation of file-gbr-load.
Remove the file-gbr-load code from the file-gbr plug-in.
(cherry picked from commit a4e77e57f6)
gimp_brush_load_brush(): support legacy gpb brushes, and port a check
for gsize overflow what was added to the plug-in.
(cherry picked from commit 619f999280)
The line art imaginary segments/splines are not added when they create
too small zones, unless when these are just too small ("unsignificant").
Why the original algorithm keeps such micro-zones is because there may
be such zones created when several splines or segments are leaving from
a same key point (and we don't necessarily won't to forbid this). Also
we had cases when using very spiky brushes (for the line art) would
create many zones, and such micro-zones would appear just too often
(whereas with very smooth lines, they are much rarer, if not totally
absent most of the time).
Also it is to be noted that the original paper would call these
"unsignificant" indeed, but these are definitely significant for the
artists. Therefore having to "fix" the filling afterwards (with a brush
for instance) kind of defeat the whole purpose of this tool.
I already had code which would special-case (fill) 1-pixel zones in the
end, but bigger micro zones could appear (up to 4 pixels in the current
code, but this could change). Also I don't want to use the "Remove
Holes" (gimp:flood) operation as I want to make sure I remove only
micro-holes created by the line art closure code (not micro-holes from
original line arts in particular).
This code takes care of this issue by filling the micro-holes with
imaginary line art pixels, which may later be potentially bucket filled
when water-filling the line art.
(cherry picked from commit 72092fbdbc)
Avoid unnecessary calls to gimp_temp_buf_data_clear() in various
places, where either the entire buffer is being written to, or most
of it is, only requiring clearing the edges.
(cherry picked from commit 9d19e804ed)
Promote the precision of generated brushes to 32-bit float, and
modify brush preview generation, and gimpbrushcore-loops, to handle
float brushes. This avoids posterization in large brushes.
Note that non-generated brushes are still uint8.
(cherry picked from commit 8ef1113dee)
In GimpTempBuf, add gimp_temp_buf_lock() and gimp_temp_buf_unlock()
functions, which lock/unlock the buffer for data access. Unlike
gimp_temp_buf_get_data(), which returns a direct pointer to the
buffer's data, the new functions take a format parameter and may
return a temporary buffer, allowing the buffer to be accessed using
an arbitrary format.
(cherry picked from commit 12dde445c4)
In gimp_transform_matrix_generic(), apply the resulting matrix even
if the transformation is invalid, since GimpGenericTransformTool
relies on the matrix to properly update the transform-grid widget.
(cherry picked from commit 59ef222c7f)
When clearing a channel, do nothing if the channel is already
empty; otherwise, align the cleared rectangle to the channel
buffer's tile grid, so that all affected tiles are dropped, rather
than zeroed. Furthermore, only update the affected region of the
channel.
(cherry picked from commit ac5e4f4c33)
After discussion with Sébastien Fourey and David Tschumperlé, it was
decided that a better fix for the edge case raised in #2785 was to add a
keypoint anyway, even if the point and none of its neigbours have a
positive smoothed curvature, yet they have a positive raw curvature. In
such case, we use the local maximum raw curvature instead of the local
maximum smoothed curvature.
(cherry picked from commit aa04258620)
Additionally to sample merge and active layer, now we can only use the
layer above or below the active layer as line art source.
The line art fill is meant to work on drawing lines. Though sample merge
still is ok in many cases, the more you fill with colors, the more the
line art computation becomes unecessarily complex. Also when you use a
lot of layers with some of them already filled with colors, it makes it
impossible to colorize some line art zones with the tool. Moreover you
just don't want to have to hide every layers out there to colorize one
layer (especially background layers and such as you may want to see the
result with your background).
Thus we want to be able to set the source as a unique layer, while it
not being necessarily the active one (because you want lines and colors
on different layers). In this case, I am assuming that the color and the
line layers are next to each other (most common organization).
(cherry picked from commit c71b4916af)
In gimp_projection_finish_draw(), clear the chunk iterator's
priority rect before finishing rendering, since it's not needed at
this point, and this is slightly more efficient.
(cherry picked from commit 9833da3431)
This is sometimes asked, and myself also need to find it from time to
time. I may as well put the link inside the code comments, where it is
just easy to find!
(cherry picked from commit 005bc1406b)
In gimp_projection_chunk_render_start(), when the current
projection rendering is complete, but not finalized yet, and no new
rendering is started (since the current update region is empty),
make sure to invalidate the projectable's preview, since it
normally happens when rendering is finalized, which doesn't happen
in this case.
(cherry picked from commit 42845c9462)
In gimp_projection_chunk_render_start(), don't leak the current
update region when it's empty, but not NULL, and properly shut down
the idle source.
(cherry picked from commit 0e5de95760)
Factor out the region-chunking logic of GimpProjection into a new
GimpChunkIterator type, providing a generic mechanism for iterating
over a cairo region in discrete chunks. The iterator doesn't
perform any processing itself, but rather dispenses rectangular
chunks, which the user then processes.
Iteration is broken into intervals, the duration of which is
configurable. Each iteration begins with a call to
gimp_chunk_iterator_next(), after which
gimp_chunk_iterator_get_rect() should be called in succession to
fetch a rectangle to process, until it returns FALSE, which marks
the end of the iteration. Updates to the UI should take place in
the interval between iterations, but not during an iteration. The
iterator dynamically adjusts the chunk size according to processing
speed, in order to match the target iteration interval.
The iterator can be given a priority rectangle, which is processed
before the rest of the region. It can also be given a
representative tile rectangle, defining a regular tile grid;
dispensed chunks are aligned to the tile grid as much as possible.
(cherry picked from commit ba9ce34e10)
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.
(cherry picked from commit 90e9eb3fca)
In the bucket-fill tool, don't pre-calculate the line art when not
using a line-art fill area. Also, misc. cleanup.
(cherry picked from commit 823d4a0d24)
The scratch allocator has been moved to GEGL (commit
gegl@b99032d799dda3436ffa8c1cc28f8b0d34fb965d). Remove gimp-
scratch, and replace all its uses with gegl-scratch.
(cherry picked from commit 889e2e26ee)
In gimp_histogram_calculate_async(), align the copied region of the
drawable and mask buffers to the tile grid, so that all copied
tiles are COWed.
(cherry picked from commit d56d663eaa)
...palette views despite selected color being in the currently
selected pallette
As suggested by Massimo, changing the color comparison EPSILON in
gimppalette.c from 1e-10 to 1e-6 fixes this, and is really small
enough.
Also, generally clean up color comparison epsilons:
- use a #define, not hardcoded values for all uses of
gimp_rgb[a]_distance()
- call the #defines RGB_EPSILON and RGBA_EPSILON
- make them all 1e-6 or larger
(cherry picked from commit abd7cbfc8d)
...text layer, not an image of the text
In gimp_edit_paste_get_layer(), when pasting as floating selection,
collapse the pasted layer into an ordinary layer only if it's a group
layer. There is nothing that speaks against having a floating text
layer, it works just fine.
(cherry picked from commit 8a4aacb52f)
In gimp_drawable_edit_fill(), if the fill only affects the alpha
channel, and if the drawable has no alpha channel, or the alpha
channel is masked out, do nothing, instead of unnecessarily
performing the fill, which has no effect.
(cherry picked from commit 6384ff01b6)
In GimpDrawableFilter, when updating the entire filter area, only
update the crop/preview area (as set by
gimp_drawable_filter_set_{crop,preview}()), instead of the entire
drawable.
(cherry picked from commit b846ffed19)
Add gimp_drawable_filter_set_crop(), which allows setting an output
crop rectangle for the filter; anything outside the rectangle
doesn't get filtered. The crop area is combined with the preview
area to determine the filtered area during preview, however, unlike
the preview area, the crop area remains in effect while committing
the filter.
Consequently, when merging a drawable filter, if the filter has a
crop, only process the cropped area.
(cherry picked from commit 5c27d14fdf)