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.
Rename XCF property PROP_SAMPLE_POINT to PROP_OLD_SAMPLE_POINT and add
new PROP_SAMPLE_POINT.
The new property saves the sample point's pick mode plus some padding
for whatever else we might want to add. Always save the old property
too so nothing changes for older GIMP versions, and avoid loading the
old property if the new one was loaded before.
... (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().
In xcf_write_int8(), avoid calling g_output_stream_write_all() with
data == NULL and count == 0, in which case it raises a CRITICAL and
doesn't set bytes_written, which we proceed to use uninitialized.
This can happen, e.g., when writing an empty parasite.
... (Invalid read reported by valgrind)
In xcf_read_int8(), avoid calling g_input_stream_read_all() with
data == NULL and count == 0, in which case it raises a CRITICAL and
doesn't set bytes_read, which we proceed to use uninitialized.
This can happen, e.g., when reading an empty parasite.
...won't work with older GIMP?
Make gimp_image_get_xcf_version() return a "reason" string which lists
all reasons why the image can't be saved with compatibility for older
GIMP versions. Display the reason as tooltip on the compat hint label
in the save dialog.
g_alloca() is not very advisable, especially when it might be used to
allocate a big chunk of memory at once. It is better to allocate dynamic
memory with malloc(), or in particular with g_try_malloc() which won't
abort the program on failure.
This might be slightly slower (one of the advantages of memory on the
stack, though not even an absolute truth) but probably not by much, if
at all, and it's better to be safe anyway.
Remove the impromptu boundary invalidation when converting a
channel to a selection mask in xcf_load_channel_props(), as this
happens implicitly when stealing the channel's buffer, since
commit 38d4aa8121.
Since commit d0ae244fe8, which
connects GimpChannel instances to their buffer's "changed" signal,
the XCF loading code that steals a channel's buffer when converting
it to a selection mask (which happens when loading an XCF with a
saved selection mask) is unsafe, since fails to perform the
necessary cleanup and setup of the buffer in the old and new
channel objects, respectively.
Perform the buffer transfer using the new
gimp_drawable_steal_buffer(), which does the same thing in a safe
manner.
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.
When loading tile data, avoid copying the data into the GEGL
buffer when the tile is empty (i.e., all its bytes are 0), so that
GEGL doesn't allocate memory for it unnecessarily.
It was always supposed to be like that, but simply forgotten.
Fortunately, big-endian machines are almost extinct...
The new code is triggered with XCF version >= 12, but we will start
using that only after code review.
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.
When loading tiles from an XCF, reject tiles whose on-disk size is
greater than 1.5 times the size of an uncompressed tile -- a limit
that is already present for the last tile in the buffer. This
should allow for the possibility of negative compression, while
restricting placing a realistic limit.
Currently, no limit is placed on the on-disk tile data size. When
loading RLE- and zlib-compressed tiles, a buffer large enough to
hold the entire on-disk tile data, up to 2GB, is allocated on the
stack, and the data is read into it. If the file is smaller than
the reported tile data size, the area of the buffer past the end
of the file is not touched. This allows a malicious XCF to write
up to 2GB of arbitrary data, at an arbitrary offset, up to 2GB,
below the stack.
Note that a similar issue had existed for earlier versions of GIMP
(see commit d7a9e6079d), however,
since prior to 2.9 the tile data buffer was allocated on the heap,
the potential risk is far smaller.
The layer blend space, composite space, and composite mode
properties have a special AUTO value, which may map to different
concrete values based on the layer mode. Make sure we can change
this mapping in the future, without affecting existing XCFs (saved
after this commit), by encoding these properties as follows:
When saving an XCF, if the property has a concrete (non-AUTO)
value, which is always positive, encode it as is. If the property
is AUTO, which is always 0, encode it as the negative of the value
it actually maps to at the time of saving (note that in some cases
AUTO may map to AUTO, in which case it's encoded as 0).
When loading an XCF, if the encoded property (stored in the file)
is nonnegative, use it as is. Otherwise, compare the negative of
the encoded property to the value AUTO maps to at the time of
loading. If the values are equal, set the property to AUTO;
otherwise, use the concrete value (i.e., the negative of the value
stored in the XCF).
Note that XCFs saved prior to this commit still load fine, it's
simply that if we change the AUTO mapping in the future, all their
AUTO properties will keep being loaded as AUTO, even if the
resulting concrete values will have changed.
We were still saving channel colors in 8 bit, this additionally
saves/loads the color as float values. Still save the old PROP_COLOR
for compatibility.
Both in the GimpImage API and in the GUI. The toggle in the save
dialog now controls ZLIB compression directly. Changed the various
info labels accordingly. Ditch the XCF parasite that saved the XCF
compat mode.
Enable 64 bit file offsets in XCF files, starting with newly added XCF
version 11.
We use at least version 11 if:
- we would use the previous version 10 (essentially skipping 10)
- the in-memory size of the image is larger than 4 Gig
Change the xcf_read_foo() functions to take the XcfInfo* instead of
a GInputStream*, and make them advance the info->cp offset by
themselves. Makes xcf-load.c a lot more readable.
Step one, without changing anything in the saved XCFs yet:
Abstract reading and writing of file offsets away into their own
xcf_read_offset() and xcf_write_offset() functions, which take
"goffset" instead of "guint32". Also change xcf_seek_pos() to take a
goffset argument.
Change all file offset variables in xcf-load.c, xcf-write.c and struct
XcfInfo to goffset, and add new member "bytes_per_offset" to XcfInfo,
which is currently always 4.
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.
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.