Commit Graph

472 Commits

Author SHA1 Message Date
Ell 95393722cc Revert "Bug 796090 - (wrong) true-color preview of GEGL filter ops, ..."
We now perform the conversion of filter output to the drawable
format as part of the individual filter nodes (see the last few
commits), so there's no need for another conversion after the
filter stack.

This reverts commit d6e0ca5054.
2018-12-28 03:56:31 -05:00
Ell 85e454bae8 app: add GimpDrawable::format-changed signal
... which is emitted when the drawable's format is changed.
2018-12-28 03:55:33 -05:00
Ell ef9b1f6694 app: in GimpLineArt, use "invalidate-preview" signal of input viewable
In GimpLineArt, use the "invalidate-preview" signal of the input
viewable, instead of its "painted" or "rendered" signals, for
asynchronously computing the line art.  Subsequently, remove the
aforementioned signals from GimpDrawable and GimpProjection,
respectively.  This simplifies the code, and reduces the number of
signals.
2018-12-27 17:14:28 -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 bb9dd049fb app: align drawable undo rectangle to tile grid
When creating a drawable undo from the drawable's buffer, align the
copied rectangle to the buffer's tile grid, so that all the copied
tiles are COWed, saving memory and gaining speed.

Add applied_x and applied_y fields to GimpDrawableUndo, specifying
the position at which to apply the applied_buffer, so that we apply
it in the right place, even if the undo rect has changed due to
alignment.
2018-12-02 03:10:28 -05:00
Jehan 047265333c app: better handle drawable and image update for line art computation.
The "update" signal on drawable or projection can actually be emitted
many times for a single painting event. Just add new signals ("painted"
on GimpDrawable and "rendered" on GimpProjection) which are emitted once
for a single update (from user point of view), at the end, after actual
rendering is done (i.e. after the various "update" signals).

Also better support the sample merge vs current drawable paths for
bucket fill.
2018-11-19 14:18:18 +01:00
Ell 3b0040c043 app, libgimp*, modules: don't use g_type_class_add_private() ...
... and G_TYPE_INSTANCE_GET_PRIVATE()

g_type_class_add_private() and G_TYPE_INSTANCE_GET_PRIVATE() were
deprecated in GLib 2.58.  Instead, use
G_DEFINE_[ABSTRACT_]TYPE_WITH_PRIVATE(), and
G_ADD_PRIVATE[_DYNAMIC](), and the implictly-defined
foo_get_instance_private() functions, all of which are available in
the GLib versions we depend on.

This commit only covers types registered using one of the
G_DEFINE_FOO() macros (i.e., most types), but not types with a
custom registration function, of which we still have a few -- GLib
currently only provides a (non-deprecated) public API for adding a
private struct using the G_DEFINE_FOO() macros.

Note that this commit was 99% auto-generated (because I'm not
*that* crazy :), so if there are any style mismatches... we'll have
to live with them for now.
2018-09-18 14:39:56 -04:00
Michael Natterer 8226265b12 Issue #1954 - GIMP-2.99 color changes when converting between...
...linear and perceptual precision

Under certain circumstances (e.g. the image has no color profile),
GimpLayer's implementation of GimpDrawable::convert_type() didn't have
enough information to do the right color space conversion.

Intead of messing with stuff like "set profile in between doing a and b",
simply add a "src_profile" parameter to GimpDrawable::convert_type() so
the complete color space conversion information is available without
relying on obscure states that could change in the future.

Make sure all callers pass the right src_profile, particularly in
gimp_image_convert_precision(), which also needed fixing.
2018-08-05 22:28:56 +02:00
Ell 26a8d141f6 app: add "update" parameter to gimp_drawable_set_buffer_full()
... which specifies whether or not to update the drawable in
response to the buffer change.

Pass TRUE for "update" at all existing call sites, to keep the
current behavior.
2018-08-03 13:50:13 -04:00
Michael Natterer 248199e997 app: make replacing a drawable's format use almost no undo memory
Add gimp_drawable_set_format() as low-level part of
gimp_layer_fix_format_space(), and add a special undo type for it that
only remembers the format and not the entire drawable buffer, because
all pixels stay the same.
2018-07-24 12:56:36 +02: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
Michael Natterer 1b7d63cce9 Use g_set_object() in a lot of places, and splrinkle some g_clear_object() 2018-06-01 12:59:52 +02:00
Ell 08ff2ac8c8 app: use gimp_gegl_buffer_copy() all over the place
Replace all uses of gegl_buffer_copy() in app/ with
gimp_gegl_buffer_copy(), added in the previous commit.
2018-05-25 08:12:27 -04:00
Ell 25490b0251 app: implement GimpPickable::get_pixel_average() in various classes
Implement GimpPickable::get_pixel_average(), added in the previous
commit, in GimpDrawable, GimpImage, and GimpProjection, using
gimp_gegl_average_color(), added in the commit before last.  This
is significantly faster than the default implementation.
2018-05-18 15:07:32 -04:00
Michael Natterer d6e0ca5054 Bug 796090 - (wrong) true-color preview of GEGL filter ops, ...
...like gaussian blur in indexed mode

In GimpDrawable's source node, after the filter stack, insert a node
that converts the pixels back to the drawable's format if the drawable
is indexed.
2018-05-16 02:09:19 +02:00
Ell f5cb1fed85 Bug 795081 - Crash when using a brush combined with a dynamics
In GimpPaintTool, brush outline generation took place during
gimp_paint_tool_draw() even while painting.  This function is run
concurrently with the paint thread.  When using dynamics, this
introduced a race conidition between updating the brush mask in the
paint thread, and updating the brush boundary in the main thread.

Move brush outline generation during painting to
gimppainttool-paint.c, and perform it in the display-update
timeout, while the main thread and the paint thread are
synchronized.
2018-04-09 14:27:48 -04:00
Ell ce9ca03ed4 app: add gimp_drawable_{start,end,flush}_paint()
gimp_drawable_start/end_paint() are used to enter/exit paint mode
for a given drawable.  While the drawable is in paint mode,
gimp_drawable_get_buffer() returns a copy of the real drawable's
buffer, referred to as the paint buffer, so that modifications to
the returned buffer don't immediately affect the projection, and
calls to gimp_drawable_update() queue the updated region, instead
of emitting an "update" signal.

gimp_drawable_flush_paint() can be called while the drawable is in
paint mode, in order to copy the updated region of the paint buffer
back to the drawable's real buffer, and to emit "update" signals
for the queued region.

We use these functions in the next commit, to move painting to a
separate thread in the paint tools.
2018-04-08 09:42:47 -04:00
Ell 91a947bbe5 app: don't allow setting NULL buffer to drawables; modify steal_buffer()
Revert commit 24fcabc1ca, which
allowed passing a NULL buffer to gimp_drawable_set_buffer[_full](),
leaving the drawable without a buffer in a semi-functional state --
this is too risky.

Instead, have gimp_drawable_steal_buffer() assign an empty 1x1
buffer to the stolen-from drawable, rather than leaving it without
a buffer at all.
2018-02-14 10:39:37 -05:00
Ell b50be495cb app: add gimp_drawable_steal_buffer()
... which transfers a buffer from one drawable to another in a safe
manner, leaving the source drawable empty.

There are already two ad-hoc instances where we steal a drawable's
buffer through simple pointer assignment, however, this avoids
performing potentially necessary cleanup and setup.  In particular,
since commit d0ae244fe8 this causes
actual errors.  The next two commits replace those instances with
calls to gimp_drawable_steal_buffer().
2018-02-13 13:29:15 -05:00
Ell 24fcabc1ca app: allow passing a NULL buffer to gimp_drawable_set_buffer[_full]()
... which clears the drawable's buffer, performing any necessary
cleanup, without setting a new buffer.  While the drawable has no
buffer, it can only be used in a very limited way, in particular,
it may be destroyed, and it may be assigned a new buffer.

This is used by the next commit to implement
gimp_drawable_steal_buffer(), which transfers a buffer from one
drawable to another in a safe manner, leaving the source drawable
empty.
2018-02-13 13:29:15 -05:00
Ell d0ae244fe8 app: invalidate channel boundary upon buffer "changed" signal
Have GimpChannel connect to the drawable buffer's "changed" signal,
so that we can invalidate the channel's boundary whenever the
buffer contents change.  Currently, the calls to
gimp_drawable_invalidate_boundary() dispersed throughout the code
are not enough.

Moreover, invalidate both the boundary and the bounds in
gimp_channel_invalidate_boundary(), since both are necessary when
the buffer changes.
2018-02-10 05:36:40 -05:00
Ell e02cb6adfe app: exclude invisible filters from filter-stack graph
Currently, when a GimpFilter's visibility changes, we rely on its
various visibility-changed signal handlers to rewire the filter
node's graph to reflect the change.  This has two main
disadvantages:

  - There's no easy, generic way to toggle a filter's  effect,
    especially one that is not subclassed, since GimpFilter only
    takes care of the case where visibility becomes FALSE, and does
    nothing by itself when it becomes TRUE again.

  - While GimpDrawable does handle the visibility => TRUE case, it
    doesn't disconnect the filter's input from its mode and
    (potentially) source nodes when it becomes invisible.  As a
    result, while none of the drawable's graph is processed as part
    of the composition when not visible, the mode and source nodes
    do get invalidated when the filter's input is invalidated, such
    as while painting on a layer below the drawable.  This is
    particularly bad for pass-through groups, since their source
    node can be an arbitrarily complex graph, whose invlidation
    incurs a nontrivial overhead.

Instead, don't touch the filter's node at all when visibility
changes, and rather have GimpFilterStack remove it from the graph
entirely when the filter becomes invisible, and re-add it once it
becomes visible again.  This solves both of the above problems, as
well as simplifies the code.
2017-12-05 16:12:08 -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 dc1d61ff91 app: handle excludes_backdrop in GimpGroupLayer
When any of the children of a pass-through group excludes its
backdrop, the group itself should exclude the backdrop too.  Override
get_excludes_backdrop() to follow this logic, and call
update_excludes_backdrop() when this condition might change.

Note that we always composite pass-through groups using src-over mode,
so to actually hide the backdrop, we need to disconnect it from the
group's mode node's input pad (and reconnect it, when the backdrop is
no longer hidden).
2017-08-08 15:39:27 -04:00
Ell ac3190215b app: connect layer backdrop to source node's input
Make sure the input of the layer's filter node is connected to its
source node (when it has an input pad), so that, once we implement
pass-though mode, the group's source node can see the backdrop.
2017-08-08 15:39:27 -04:00
Ell 785a0834a2 app: add GimpDrawable::get_source_node() vfunc
For pass-through groups, we want to use the group's layer-stack
graph directly in its filter node, in place of the drawable's
buffer-source node.  Add a get_source_node() vfunc to GimpDrawable,
which defaults to returning the buffer-source node, and use it in
gimp_drawable_get_source_node() instead of using the buffer-source
node directly.  We'll later override this function for
GimpGroupLayer.
2017-08-08 15:39:26 -04:00
Michael Natterer 0cb3e75f79 app: use a lot of g_clear_object() and g_clear_pointer()
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);
2017-07-15 18:42:44 +02:00
Michael Natterer 8634b5cbc3 app: make layer blend color space and compositing color space configurable
...they say it's going to get worse before it gets better...
2017-02-12 23:49:26 +01:00
Michael Natterer 2a96d598c3 app: add internal and PDB API and UI to control a layer's composite mode
Largely based on a patch by Ell, with the enum type renamed and
various small changes. Adds another axis of configurability to the
existing layer mode madness, and is WIP too.
2017-02-02 00:38:25 +01:00
Michael Natterer 68cc8bb86f app: make using gimp_drawable_update() less verbose
Allow passing -1 for the drawable's width/height, instead of requiring
gimp_item_get_width,height() in many callers.
2017-01-13 02:14:40 +01:00
Michael Natterer 0891028232 app: forgot to s/gimp:normal-mode/gimp:normal/g 2017-01-11 00:28:57 +01:00
Michael Natterer 07600c6db6 libgimpbase: proper names for the GimpChannelType enum
Register the old value names as compat. Also add some forgotten
values and enums to gimpcompatenums.h
2017-01-09 19:40:30 +01:00
Michael Natterer 66060e3307 app, libgimp*, plug-ins: replace enum GimpLayerModeEffects by GimpLayerMode
with proper value names. Mark most values as _BROKEN because they use
weird alpha compositing that has to die. Move GimpLayerModeEffects to
libgimpbase, deprecate it, and set it as compat enum for GimpLayerMode.
Add the GimpLayerModeEffects values as compat constants to script-fu
and pygimp.
2017-01-08 23:00:19 +01:00
Øyvind Kolås 5627ad589f app: use gegl:dither instead of gegl:reduction 2016-12-24 19:40:12 +01:00
Michael Natterer 56ce447bc9 Bug 735895 - Precision Conversion "Dithering" dialog
gimp_drawable_convert_type(): never dither when converting to a higher
bit depth, or to anything more than 16 bits.
2016-11-09 12:45:52 +01:00
Michael Natterer 87d38194d7 app, pdb: use GeglDitherMethod instead of simply an integer 2016-11-07 20:41:39 +01:00
Michael Natterer 997ae1e28b Bug 764024 - Allow to choose fill color when resizing layers and images
Add a GimpFillType argument to GimpItem::resize() and fill type
widgets to the canvas and layer resize dialogs. Fill the new parts of
the drawable according to fill type in gimp_drawable_resize(). Make
sure places that need the old behavior get GIMP_FILL_TRANSPARENT
passed by hardcoding it in the GimpItem::resize() implemetations of
channel, mask, selection etc.
2016-10-10 00:02:16 +02:00
Michael Natterer ecf4af88b8 app: add "gboolean new_has_alpha" to gimp_drawable_convert_type()
making its external API "complete". Remove the redundant
"new_base_type" and "new_precision" from the internal (vfunc) API (the
Babl format has the same information).
2016-10-04 01:39:15 +02:00
Michael Natterer 4fefc3817c Bug 766988 - Colors applied to images are not color managed
Color manage colors applied when painting, and when filling, merging,
resizing and transforming drawables.
2016-05-29 17:51:06 +02:00
Michael Natterer 28e1a379e6 app: remove const qualifiers from all object parameters
They are unreliable because every type checking cast discards them,
they are useless anyway, visual clutter, added inconsistently, and
generally suck. Wanted to do this a long time ago, it was a bad idea
in the first place.
2016-05-19 23:54:14 +02:00
Michael Natterer 81fd3e9c3f app: move GimpDrawable's FS to gimpdrawable-floating-selection.[ch]
and refactor it a bit to have separate functions for adding, removing
and updating the FS' drawable filter. Should be a lot more
understandable now.
2016-05-19 17:40:33 +02:00
Michael Natterer 265dfec525 app: split GimpApplicator's opacity and mode API into two functions
Added gimp_applicator_set_opacity() and remove the opacity argument
from set_mode().
2016-05-18 01:51:09 +02:00
Michael Natterer 9fb70a44f2 app: rename GimpImageMap to GimpDrawableFilter
and gimpdrawable-filter.[ch] to gimpdrawable-filters.[ch] because of
the name clash.
2016-05-12 01:49:53 +02:00
Michael Natterer 8eb6cdf488 app: pass profiles around along with the buffers in the transform code
"transform" as in flip, rotate, affine. Same reasoning as in the
gimp_selection_float() commit below.
2016-05-08 18:35:40 +02:00
Michael Natterer 7ae81e70b9 app: move the "visible" property from GimpItem to GimpFilter
Same for the "visibility_changed" signal. GimpItem keeps its
visibility API because it adds undo over GimpItem's API.
2016-05-01 14:27:43 +02:00
Michael Natterer 8c107963e6 app: implement GimpColorManaged in GimpDrawable
so now all drawables have a profile. Default to the babl format's
bultin profile and override to use the image's format in GimpLayer.
2016-04-30 23:41:32 +02:00
Michael Natterer ef4ab94a12 app: change GimpDrawable::convert_type() to take a target profile
instead of just a boolean "convert_profile". This takes the logic to
figure the right target profile out of gimp_layer_convert_type(), it
can't possibly know everything about how to convert anyway, and having
the logic in the callers conveniently splits it up and distributes its
parts to the places they belong.

This commit should cause no behavor change and is just preparation for
fixing bug 765176.
2016-04-30 18:35:52 +02:00
Michael Natterer 66525e634e app: fix wrong parameter name in gimp_drawable_real_convert_type() 2016-04-20 04:19:44 +01:00
Michael Natterer 9e8499bb48 Bug 478528 - Layer and Image previews are not color managed
Change gimp_viewable_get_[new]_preview() to return buffers of the
image's and layers' colorspace, but in u8. This way layer and image
previews can transform them correctly to the display profile.

Note: this makes plug-ins receive thumbnail buffers in that
pixel format too.

Also change gimp_viewable_get_[new]_pixbuf() to always return sRGB
buffers that can reasonably be put to screen directly, or put into DND
buffers. This is at least more correct now.
2016-04-15 16:52:25 +01:00