mirror of https://github.com/GNOME/gimp.git
plug-ins: follow the assigned profile TRC.
GIMP should not convert assigned profile to sRGB just because we stored
as linear on the XCF. In other words, we should not look at the image
precision to decide whether to export as linear (previously only 8-bit
linear images), but at the profile TRC. There are basically 3 cases:
(1) We don't save a profile, then convert to sRGB whatever the source
precision (because readers would assume sRGB for a no-profile jpeg).
(2) We save the default profiles: convert to sRGB because it's usually
a better choice for 8-bit formats and even working at 32-bit float
*linear* doesn't mean you want to export as 8-bit int *linear*. As the
image creator made no explicit export choice, we make an acceptable
default one.
(3) We save an explicitly assigned profile: keep the profile TRC, don't
convert!
Note that this apparently won't work perfectly right now, as GIMP
replaces the original TRC with the linear default TRC when converting to
linear. So the expected TRC is lost in such case when you have not
explicitly reset the correct profile. Yet this is on GIMP side and this
part of the issue should be fixed with the space invasion merge. For
now, this is how the plug-in should work.
This is based on my late discussion with Ell. Please everyone, and Ell
especially, review! :-)
(cherry picked from commit c5f7bac2ba
)
This commit is contained in:
parent
a6f50a6bc4
commit
417f2c873f
|
@ -270,13 +270,15 @@ save_image (const gchar *filename,
|
|||
static struct jpeg_compress_struct cinfo;
|
||||
static struct my_error_mgr jerr;
|
||||
|
||||
GimpImageType drawable_type;
|
||||
GeglBuffer *buffer;
|
||||
const Babl *format;
|
||||
JpegSubsampling subsampling;
|
||||
FILE * volatile outfile;
|
||||
guchar *data;
|
||||
guchar *src;
|
||||
GimpImageType drawable_type;
|
||||
GeglBuffer *buffer;
|
||||
const Babl *format;
|
||||
JpegSubsampling subsampling;
|
||||
FILE * volatile outfile;
|
||||
guchar *data;
|
||||
guchar *src;
|
||||
GimpColorProfile *profile;
|
||||
|
||||
gboolean has_alpha;
|
||||
gboolean out_linear = FALSE;
|
||||
gint rowstride, yend;
|
||||
|
@ -333,21 +335,16 @@ save_image (const gchar *filename,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
profile = gimp_image_get_color_profile (orig_image_ID);
|
||||
if (jsvals.save_profile)
|
||||
{
|
||||
/* In most cases we want to save 8-bit image formats as
|
||||
* non-linear, even though the work image may have been linear
|
||||
* itself (yet with higher bit depth). The reasons are shadow
|
||||
* posterization on low bit depth, and the fact that JPEG
|
||||
* compression was designed for perceptually uniform RGB and
|
||||
* introduces shadow artifacts with linear RGB (or so I have been
|
||||
* told; see #1070).
|
||||
* The only exception is when the creator was working explicitly
|
||||
* on 8-bit linear AND if we export the profile.
|
||||
* In such a case, let's consider the creator knows what one is
|
||||
* doing and keep the exported image linear.
|
||||
/* When we don't save profiles, we convert data to sRGB because
|
||||
* that's what most/all readers expect on a no-profile JPEG.
|
||||
* If we save an assigned profile, let's just follow its TRC.
|
||||
* If we save the default linear profile (i.e. no assigned
|
||||
* profile), we convert it to sRGB.
|
||||
*/
|
||||
if (gimp_image_get_precision (orig_image_ID) == GIMP_PRECISION_U8_LINEAR)
|
||||
if (profile && gimp_color_profile_is_linear (profile))
|
||||
out_linear = TRUE;
|
||||
}
|
||||
|
||||
|
@ -575,60 +572,34 @@ save_image (const gchar *filename,
|
|||
(guchar *) image_comment, strlen (image_comment));
|
||||
}
|
||||
|
||||
/* Step 4.2: store the color profile if there is one */
|
||||
/* Step 4.2: store the color profile */
|
||||
if (jsvals.save_profile)
|
||||
{
|
||||
GimpColorProfile *profile;
|
||||
const guint8 *icc_data;
|
||||
gsize icc_length;
|
||||
|
||||
profile = gimp_image_get_effective_color_profile (orig_image_ID);
|
||||
if (! profile)
|
||||
/* There is always an effective profile. */
|
||||
profile = gimp_image_get_effective_color_profile (orig_image_ID);
|
||||
|
||||
if (profile)
|
||||
if (gimp_color_profile_is_linear (profile) && ! out_linear)
|
||||
{
|
||||
const guint8 *icc_data;
|
||||
gsize icc_length;
|
||||
/* Convert profile from linear to sRGB. This would normally
|
||||
* only happen when there was no assigned profile (i.e. the
|
||||
* default linear profile is in use). */
|
||||
|
||||
switch (gimp_image_get_precision (orig_image_ID))
|
||||
{
|
||||
case GIMP_PRECISION_U16_LINEAR:
|
||||
case GIMP_PRECISION_U32_LINEAR:
|
||||
case GIMP_PRECISION_HALF_LINEAR:
|
||||
case GIMP_PRECISION_FLOAT_LINEAR:
|
||||
case GIMP_PRECISION_DOUBLE_LINEAR:
|
||||
/* Convert profile from linear to sRGB. */
|
||||
{
|
||||
GimpColorProfile *saved_profile;
|
||||
|
||||
saved_profile = gimp_color_profile_new_srgb_trc_from_color_profile (profile);
|
||||
g_object_unref (profile);
|
||||
profile = saved_profile;
|
||||
}
|
||||
break;
|
||||
|
||||
case GIMP_PRECISION_U8_LINEAR:
|
||||
/* Only exception where we don't convert from linear to
|
||||
* sRGB TRC is when the work format was 8-bit linear. */
|
||||
case GIMP_PRECISION_U8_NON_LINEAR:
|
||||
case GIMP_PRECISION_U16_NON_LINEAR:
|
||||
case GIMP_PRECISION_U32_NON_LINEAR:
|
||||
case GIMP_PRECISION_HALF_NON_LINEAR:
|
||||
case GIMP_PRECISION_FLOAT_NON_LINEAR:
|
||||
case GIMP_PRECISION_DOUBLE_NON_LINEAR:
|
||||
|
||||
case GIMP_PRECISION_U8_PERCEPTUAL:
|
||||
case GIMP_PRECISION_U16_PERCEPTUAL:
|
||||
case GIMP_PRECISION_U32_PERCEPTUAL:
|
||||
case GIMP_PRECISION_HALF_PERCEPTUAL:
|
||||
case GIMP_PRECISION_FLOAT_PERCEPTUAL:
|
||||
case GIMP_PRECISION_DOUBLE_PERCEPTUAL:
|
||||
break;
|
||||
}
|
||||
|
||||
icc_data = gimp_color_profile_get_icc_profile (profile, &icc_length);
|
||||
jpeg_icc_write_profile (&cinfo, icc_data, icc_length);
|
||||
GimpColorProfile *saved_profile;
|
||||
|
||||
saved_profile = gimp_color_profile_new_srgb_trc_from_color_profile (profile);
|
||||
g_object_unref (profile);
|
||||
profile = saved_profile;
|
||||
}
|
||||
|
||||
icc_data = gimp_color_profile_get_icc_profile (profile, &icc_length);
|
||||
jpeg_icc_write_profile (&cinfo, icc_data, icc_length);
|
||||
}
|
||||
if (profile)
|
||||
g_object_unref (profile);
|
||||
|
||||
/* Step 5: while (scan lines remain to be written) */
|
||||
/* jpeg_write_scanlines(...); */
|
||||
|
|
Loading…
Reference in New Issue