GIMP was saving the last changed/saved date to IPTC tag DateCreated,
which should only be used for the original creating date of the image
and thus should not be changed by GIMP.
After discussion in the cited issue, there is no tag in IPTC that we can
use, so we remove saving modified date from the IPTC metadata.
Instead we add two XMP tags, one for modified date and the other for the
date that metadata was changed. Since we do both when exporting, both are
saved with the same date/time in ISO 8601 format.
This also fixes another issue where we were not storing the timezone offset
for Xmp.tiff.DateTime. Since this has the same format as the other
XMP tags, we fix this together with this issue.
… in the gimp-release file.
This will be useful to disable the update check for the Windows Store
even though we use the same build as the installer. All it will take
will be to append the line `check-update=false` to the file
`share/gimp/2.10/gimp-release` and it will behave as though the update
check is disabled (even though it is actually built-in).
More safety checks for detecting broken xcf files, also based on examining
issue #8230.
After reading an offset where layer, channel, etc. data is stored, we
add a check to make sure that offset is not before where we read the
offset value. Because the data is always written after the offset that
points to it.
Improvements in loading broken xcf files, based on examining issue #8230.
Besides checking for a minimum width and height, GIMP also has a maximum
size we can and should check.
In the case of the image itself, we change invalid dimensions to a size of
1 in hope that the individual layers etc will have the correct size.
For layer, we will also try to go on, but for channel and layer mask, we
will give up.
gimp_channel_is_empty returns FALSE if channel is NULL. This causes
gimp_layer_invalidate_boundary to crash if the mask channel is NULL.
With a NULL channel gimp_channel_is_empty should return TRUE, just like
the similar gimp_image_is_empty does, because returning FALSE here
suggests we have a non empty channel.
I guess I missed this one as I was not building it locally.
Fixes:
> In file included from ../plug-ins/common/file-jp2-load.c:86:
> ../plug-ins/common/file-jp2-load.c: In function ‘jp2_class_init’:
> ../libgimp/stdplugins-intl.h:42:22: error: ‘set_i18n’ undeclared (first use in this function)
I hesitated a lot whether we should just drop the whole localization of
plug-ins' label and description (blurb) within the core. Actually the
commit messages I wrote a few days ago were moving towards this logic.
It really looks to me like plug-in localization can happen fully within
plug-in themselves. As far as I can see, the only advantage which the
current logic has theoretically is that if we needed, we have access to
both the original strings and their translations (e.g. it could be
useful for text search). Nevertheless I am not sure if we will ever make
use of this, and this is limited cases as all filters turned GEGL ops
don't have such ability anyway.
Nevertheless since previous contributors clearly put quite a lot of work
on this code of localizing the plug-in's label and description within
the main binary, I want to give myself a little more time to think and
study the whole thing because doing anything rash.
In the meantime, what changes is that by default now, a plug-in without
a local gettext catalog is simply not localized. In particular, the core
process doesn't try to localize it using the default catalog, a.k.a.
GETTEXT_PACKAGE"-std-plug-ins" ("gimp30-std-plug-ins"). It just doesn't
make sense and the worst which could happen would be to get unexpected
and wrong translations.
Now by default, plug-ins will try to find a catalog in their main
folder, named as this folder. If it fails to find it, a message is
printed to stderr and localization is disabled (rather than falling back
to a default catalog). It is up to plug-in developers to either install
a catalog, or implement set_i18n() to give the right catalog, folder, or
disable localization with gettext, as handled by libgimp.
gimp_procedure_set_static_help().
The indentation was wrong, probably because of changes to function
names. Fix the generation scripts and regenerate the PDB C files.
We changed the logic of _gimp_plug_in_domain_register() which is now
only called when a domain is explicitly registered (which is not the
case by default anymore). Let's update the function documentation and
also make it clear that third-party developers in particular should not
play with it if they want their plug-ins to be properly localized.
Since these are demos, for the sake of showing how the localization
works, let's localize the goat-exercises with a locally installed
catalog.
Note that actually use the gimp30-std-plug-ins catalog, simply I copy it
in the plug-in folder and rename it as org.gimp.extension.goat-exercises
domain.
As a consequence:
- The C plug-in does not need the INIT_I18N anymore, which was
specifically for the centrally installed catalog and cannot be used by
third-party plug-in developers (so it's not a good demo code).
- I now use GLib.dgettext() for Python instead of the gettext Python
module, because the later won't "catch" the catalog declared in
libgimp.
- The other Goat exercises are now localized correctly, unlike before.
- Just setting GETTEXT_PACKAGE is apparently enough for the Vala
plug-in.
- Lua is untested. Hopefully the code will work.
Hence avoiding the stderr messages. These are going to be localized with
centrally installed catalogs "gimp*-std-plugins", "gimp*-script-fu" and
"gimp*-python".
We now handle core plug-in localizations differently and in particular,
with kind of a reverse logic:
- We don't consider "gimp*-std-plugins" to be the default catalog
anymore. It made sense in the old world where we would consider the
core plug-ins to be the most important and numerous ones. But we want
to push a world where people are even more encouraged to develop their
own plug-ins. These won't use the standard catalog anymore (because
there are nearly no reasons that the strings are the same, it's only a
confusing logic). So let's explicitly set the standard catalogs with
DEFINE_STD_SET_I18N macro (which maps to a different catalog for
script-fu plug-ins).
- Doing something similar for Python plug-ins which have again their own
catalog.
- Getting rid of the INIT_I18N macro since now all the locale domain
binding is done automatically by libgimp when using the set_i18n()
method infrastructure.
Clearly the old logic for localizing plug-ins was "core plug-ins first":
* In particular, we were defaulting to the "gimp*-std-plugins" domain,
asking plug-ins to override it with libgimp function
gimp_plug_in_set_translation_domain(). Obviously any third-party
plug-in would have to call this function since their strings are most
likely not the same as GIMP core plug-ins.
* Moreover this was only for the localization of menu items, which means
we had to duplicate work anyway (simplified for core C plug-ins only
with the INIT_I18N macro).
* Also plug-ins had to manage the location of the Gettext catalogs,
which is simpler for core plug-ins with gimp_locale_directory(), but
more annoying for third-party plug-ins which can be installed
basically anywhere (assuming their message catalogs are in their
directory, not centrally installed on the system, especially for
non-UNIX-like packages, with relocatable GIMP, no central package
system and so on).
* Finally in this logic of centrally installed catalogs, we were
requesting that the domain name is unique, which makes sense in a
Linux world with well maintained packages to avoid name clashes, not
in a world with people making plug-ins without knowing too much what's
done by their neighbour.
So now the new logic is:
- By default, GIMP will search for a folder called locale/ on the same
level as the plug-in executable. The Gettext domain will be the name
of the executable folder (and it doesn't matter too much if it's not
unique in such configuration).
- This can be disabled by overriding set_i18n() to NULL or
reimplementing it. All our core plug-ins will do this since they will
continue to use the centrally installed "gimp*-std-plugins" domain (or
"gimp*-python" for Python plug-ins).
- When not disabled while the folder is not available, warning messages
will be outputted to stderr, so that plug-in developers can easily
detect what is missing and how to handle it (and how to easily support
internationalization of their plug-in).
- gimp_plug_in_set_translation_domain() is removed and a future commit
is going to get rid of _gimp_plug_in_domain_register() because we are
going to get rid of the core-side localization of menu items (with
logic explained in the upcoming commit).
- Set the "gimp30-python" Gettext domain and bind it to the proper
locale directory as installed by GIMP.
- Localize various strings with gettext.
- Remove calls to self.set_translation_domain() in
do_query_procedures(). This is technically wrong right now but I am
going to get rid of the menu item localization for plug-ins done by
the core.
We were using parameter iter in metadata_dialog_add_tag and
metadata_dialog_add_translated_tag.
However, iter is only ever set inside metadata_dialog_add_tag by calling
gtk_list_store_append. So, there is no need to pass this parameter around.
For this reason, let's remove parameter iter from the above two functions
and replace with a local variable.
In other cases we need to free value, but in this case it was used and
trying to free it caused a GIMP to crash.
Let's duplicate value, so we don't need to special case our g_free.
There was one case where horizontally and vertically were mixed up in a
call to gimp_display_shell_scale_image_stops_to_fit.
The more usual order of parameters is first horizontal and then vertical.
So, let's fix the actual functions that have the illogical order
of vertically, horizontally instead of fixing the one call.
This brings it in line with the order in other functions and makes it less
likely we mistakenly mess up the parameters.
Besides that gimp_display_shell_scale_image_stops_to_fit also was not
declared as a local function, so we add that too.
Also fixed quotient to only take two arguments. Applied minor
optimization in execution of quotient, remainder, and modulo.
From revision 122 of the TinyScheme repository in SourceForge.
Instead, make outer script-fu-server register callbacks with inner scheme-wrapper.
Why? the inner scheme-wrapper should not know about the outer script-fu-server.
The change will allow a future, smaller scriptfu shared library,
that does not contain networking code.
We want a scriptfu library shared by separate script-fu-server,
future gimp-scheme-interpreter (!647), and script-fu executables.
This change does not alter observable functioning of the script-fu-server.
Except that I also changing the logging by script-fu-server,
so that I could test the changes.
I put a test plan in the comments.
With large image sizes a 32-bit int is not enough for the intermediate
computations, which byte per pixel, width and height are.
So, just like the function below it does: gimp_gegl_pyramid_get_memsize,
we will cast these to gint64.
Thanks to Massimo Valentini for finding the cause.
I added this call originally, mimicking the C plug-ins. Yet in Python,
this function is deprecated since Python 3.8 and removed in 3.10.
Looking closer in the docs, it looks like Python's gettext module works
differently.
While all the *gettext() functions return strings in the locale's
encoding in C, unless overriden by bind_textdomain_codeset() (therefore
we need this call, in order to have locale-independent string encoding),
this is not the case in Python, whose gettext() call is already
locale-independent. The gettext.bind_textdomain_codeset() function only
applies to the specific l*gettext() functions which are deprecated too.
Fixes the warning:
> goat-exercise-py3.py:37: DeprecationWarning: bind_textdomain_codeset() is deprecated
Bugs introduced in commit 8eb7f6df9e9:
- The type test was wrong.
- The UTF-8 validation test was also wrong since it was still working on
a GimpArray even though the data was now a GStrv.
Also I stop at the first invalid UTF-8 string element, otherwise later
valid strings may hide previous invalid ones.
This bug was mostly invisible since we don't have any core PDB API with
GStrv parameter so far, only GStrv return value.
Even if the container is empty, then we return a GStrv of length 1 (i.e.
an array of length 1, terminating with NULL).
In particular, it improves gimp_container_get_filtered_name_array() as
well, and in turn various list-returning functions in libgimp. This
makes the API more consistent after changes from commit 8eb7f6df9e.
Note that a NULL return can be acceptable for error cases, but an empty
list because this is the expected result for the request should be an
empty GStrv, not NULL.
In particular, since commit 8eb7f6df9e, even if it returns an empty
array of procedure, it still means an array of size 1 (with the unique
value being NULL).
This also fixes the public API gimp_pdb_query_procedures() which returns
a GStrv using gimp_pdb_query() internally.
Finally don't keep track of the array size, just recompute it with
g_strv_length(), which will be much less bug-prone.
Since GStrv are NULL-terminated arrays, there is always one additional
pointer (NULL).
This is a detail, but still, wrong since commit 8eb7f6df9e which
replaced GimpStringArray by GStrv usage.