aboutsummaryrefslogtreecommitdiff
path: root/fiv-io.c
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2021-12-26 03:10:50 +0100
committerPřemysl Eric Janouch <p@janouch.name>2021-12-26 03:25:38 +0100
commit2f993502fc6584a5877b300a1353cabf58c4e0e9 (patch)
tree8cc1400537e0ff544cdede782d7a523e2b06c293 /fiv-io.c
parente5b1a1861cb0e69411b4ebbfaadb235b9bd8a001 (diff)
downloadfiv-2f993502fc6584a5877b300a1353cabf58c4e0e9.tar.gz
fiv-2f993502fc6584a5877b300a1353cabf58c4e0e9.tar.xz
fiv-2f993502fc6584a5877b300a1353cabf58c4e0e9.zip
Make use of gAMA and sRGB PNG chunks
Neither EoG nor gThumb handle this correctly.
Diffstat (limited to 'fiv-io.c')
-rw-r--r--fiv-io.c49
1 files changed, 45 insertions, 4 deletions
diff --git a/fiv-io.c b/fiv-io.c
index 2ab97f1..468f223 100644
--- a/fiv-io.c
+++ b/fiv-io.c
@@ -198,6 +198,30 @@ fiv_io_profile_new_sRGB(void)
#endif
}
+FivIoProfile
+fiv_io_profile_new_sRGB_gamma(double gamma)
+{
+#ifdef HAVE_LCMS2
+ // TODO(p): Make sure to use the library in a thread-safe manner.
+ cmsContext context = NULL;
+
+ static const cmsCIExyY D65 = {0.3127, 0.3290, 1.0};
+ static const cmsCIExyYTRIPLE primaries = {
+ {0.6400, 0.3300, 1.0}, {0.3000, 0.6000, 1.0}, {0.1500, 0.0600, 1.0}};
+ cmsToneCurve *curve = cmsBuildGamma(context, gamma);
+ if (!curve)
+ return NULL;
+
+ cmsHPROFILE profile = cmsCreateRGBProfileTHR(
+ context, &D65, &primaries, (cmsToneCurve *[3]){curve, curve, curve});
+ cmsFreeToneCurve(curve);
+ return profile;
+#else
+ (void) gamma;
+ return NULL;
+#endif
+}
+
static FivIoProfile
fiv_io_profile_new_from_bytes(GBytes *bytes)
{
@@ -740,13 +764,17 @@ open_wuffs(wuffs_base__image_decoder *dec, wuffs_base__io_buffer src,
struct load_wuffs_frame_context ctx = {
.dec = dec, .src = &src, .target = profile};
- // TODO(p): PNG also has sRGB and gAMA, as well as text chunks (Wuffs #58).
- // The former two use WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED.
+ // TODO(p): PNG text chunks (Wuffs #58).
wuffs_base__image_decoder__set_report_metadata(
ctx.dec, WUFFS_BASE__FOURCC__EXIF, true);
wuffs_base__image_decoder__set_report_metadata(
ctx.dec, WUFFS_BASE__FOURCC__ICCP, true);
+ wuffs_base__image_decoder__set_report_metadata(
+ ctx.dec, WUFFS_BASE__FOURCC__SRGB, true);
+ wuffs_base__image_decoder__set_report_metadata(
+ ctx.dec, WUFFS_BASE__FOURCC__GAMA, true);
+ double gamma = 0;
while (true) {
wuffs_base__status status =
wuffs_base__image_decoder__decode_image_config(
@@ -786,6 +814,14 @@ open_wuffs(wuffs_base__image_decoder *dec, wuffs_base__io_buffer src,
}
ctx.meta_xmp = bytes;
continue;
+
+ case WUFFS_BASE__FOURCC__SRGB:
+ gamma = 2.2;
+ break;
+ case WUFFS_BASE__FOURCC__GAMA:
+ gamma = 1e5 /
+ wuffs_base__more_information__metadata_parsed__gama(&minfo);
+ break;
}
g_bytes_unref(bytes);
@@ -805,8 +841,13 @@ open_wuffs(wuffs_base__image_decoder *dec, wuffs_base__io_buffer src,
goto fail;
}
- if (ctx.target && ctx.meta_iccp)
- ctx.source = fiv_io_profile_new_from_bytes(ctx.meta_iccp);
+ // TODO(p): Improve our simplistic PNG handling of: gAMA, cHRM, sRGB.
+ if (ctx.target) {
+ if (ctx.meta_iccp)
+ ctx.source = fiv_io_profile_new_from_bytes(ctx.meta_iccp);
+ else if (isfinite(gamma) && gamma > 0)
+ ctx.source = fiv_io_profile_new_sRGB_gamma(gamma);
+ }
// Wuffs maps tRNS to BGRA in `decoder.decode_trns?`, we should be fine.
// wuffs_base__pixel_format__transparency() doesn't reflect the image file.