From c6d89361a5e2a46818d67ce4a21856ddecc129a4 Mon Sep 17 00:00:00 2001 From: Přemysl Eric Janouch Date: Sat, 27 Jan 2024 22:22:08 +0100 Subject: WIP: Thread-safe colour management --- fiv-io.c | 71 +++++++++++++++++++++++++++++++--------------------------------- 1 file changed, 34 insertions(+), 37 deletions(-) (limited to 'fiv-io.c') diff --git a/fiv-io.c b/fiv-io.c index f16a245..be15a18 100644 --- a/fiv-io.c +++ b/fiv-io.c @@ -379,6 +379,7 @@ struct load_wuffs_frame_context { GBytes *meta_iccp; ///< Reference-counted ICC profile GBytes *meta_xmp; ///< Reference-counted XMP + FivIoCmm *cmm; ///< CMM context, if any FivIoProfile *target; ///< Target device profile, if any FivIoProfile *source; ///< Source colour profile, if any @@ -447,12 +448,12 @@ load_wuffs_frame(struct load_wuffs_frame_context *ctx, GError **error) if (ctx->target) { if (ctx->expand_16_float || ctx->pack_16_10) { - fiv_io_cmm_4x16le_direct(fiv_io_cmm_get_default(), + fiv_io_cmm_4x16le_direct(ctx->cmm, targetbuf, ctx->width, ctx->height, ctx->source, ctx->target); // The first one premultiplies below, the second doesn't need to. } else { - fiv_io_cmm_argb32_premultiply(fiv_io_cmm_get_default(), - image, ctx->source, ctx->target); + fiv_io_cmm_argb32_premultiply( + ctx->cmm, image, ctx->source, ctx->target); } } @@ -590,7 +591,8 @@ open_wuffs(wuffs_base__image_decoder *dec, wuffs_base__io_buffer src, const FivIoOpenContext *ioctx, GError **error) { struct load_wuffs_frame_context ctx = { - .dec = dec, .src = &src, .target = ioctx->screen_profile}; + .dec = dec, .src = &src, + .cmm = ioctx->cmm, .target = ioctx->screen_profile}; // TODO(p): PNG text chunks, like we do with PNG thumbnails. // TODO(p): See if something could and should be done about @@ -674,9 +676,11 @@ open_wuffs(wuffs_base__image_decoder *dec, wuffs_base__io_buffer src, // 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); + ctx.source = fiv_io_cmm_get_profile_from_bytes( + ctx.cmm, ctx.meta_iccp); else if (isfinite(gamma) && gamma > 0) - ctx.source = fiv_io_profile_new_sRGB_gamma(gamma); + ctx.source = fiv_io_cmm_get_profile_sRGB_gamma( + ctx.cmm, gamma); } // Wuffs maps tRNS to BGRA in `decoder.decode_trns?`, we should be fine. @@ -1060,7 +1064,7 @@ parse_exif_profile_subifd( } static FivIoProfile * -parse_exif_profile(const void *data, size_t len) +parse_exif_profile(FivIoCmm *cmm, const void *data, size_t len) { struct tiffer T = {}; if (!tiffer_init(&T, (const uint8_t *) data, len) || !tiffer_next_ifd(&T)) @@ -1092,7 +1096,7 @@ parse_exif_profile(const void *data, size_t len) // If sRGB is claimed, assume all parameters are standard. if (params.colorspace == Exif_ColorSpace_sRGB) - return fiv_io_profile_new_sRGB(); + return fiv_io_cmm_get_profile_sRGB(cmm); // AdobeRGB Nikon JPEGs provide all of these. if (params.colorspace != Exif_ColorSpace_Uncalibrated || @@ -1101,7 +1105,7 @@ parse_exif_profile(const void *data, size_t len) !params.have_primaries) return NULL; - return fiv_io_profile_new_parametric( + return fiv_io_cmm_get_profile_parametric(cmm, params.gamma, params.whitepoint, params.primaries); } @@ -1256,19 +1260,17 @@ load_jpeg_finalize(FivIoImage *image, bool cmyk, g_byte_array_free(meta.icc, TRUE); FivIoProfile *source = NULL; - if (icc_profile) - source = fiv_io_profile_new( + if (icc_profile && ctx->cmm) + source = fiv_io_cmm_get_profile(ctx->cmm, g_bytes_get_data(icc_profile, NULL), g_bytes_get_size(icc_profile)); - else if (image->exif) - source = parse_exif_profile( + else if (image->exif && ctx->cmm) + source = parse_exif_profile(ctx->cmm, g_bytes_get_data(image->exif, NULL), g_bytes_get_size(image->exif)); if (cmyk) - fiv_io_cmm_cmyk(fiv_io_cmm_get_default(), - image, source, ctx->screen_profile); + fiv_io_cmm_cmyk(ctx->cmm, image, source, ctx->screen_profile); else - fiv_io_cmm_any(fiv_io_cmm_get_default(), - image, source, ctx->screen_profile); + fiv_io_cmm_any(ctx->cmm, image, source, ctx->screen_profile); if (source) fiv_io_profile_free(source); @@ -1669,8 +1671,8 @@ open_libwebp( WebPDemuxDelete(demux); if (ctx->screen_profile) - fiv_io_cmm_argb32_premultiply_page(fiv_io_cmm_get_default(), - result, ctx->screen_profile); + fiv_io_cmm_argb32_premultiply_page( + ctx->cmm, result, ctx->screen_profile); fail: WebPFreeDecBuffer(&config.output); @@ -2053,8 +2055,7 @@ open_libraw( out: libraw_close(iprc); - return fiv_io_cmm_finalize(fiv_io_cmm_get_default(), - result, ctx->screen_profile); + return fiv_io_cmm_finalize(ctx->cmm, result, ctx->screen_profile); } #endif // HAVE_LIBRAW --------------------------------------------------------- @@ -2204,7 +2205,7 @@ load_librsvg_destroy(FivIoRenderClosure *closure) static FivIoImage * load_librsvg_render_internal(FivIoRenderClosureLibrsvg *self, double scale, - FivIoProfile *target, GError **error) + FivIoCmm *cmm, FivIoProfile *target, GError **error) { RsvgRectangle viewport = {.x = 0, .y = 0, .width = self->width * scale, .height = self->height * scale}; @@ -2231,16 +2232,15 @@ load_librsvg_render_internal(FivIoRenderClosureLibrsvg *self, double scale, fiv_io_image_unref(image); return NULL; } - return fiv_io_cmm_finalize(fiv_io_cmm_get_default(), - image, target); + return fiv_io_cmm_finalize(cmm, image, target); } static FivIoImage * -load_librsvg_render( - FivIoRenderClosure *closure, FivIoProfile *target, double scale) +load_librsvg_render(FivIoRenderClosure *closure, + FivIoCmm *cmm, FivIoProfile *target, double scale) { FivIoRenderClosureLibrsvg *self = (FivIoRenderClosureLibrsvg *) closure; - return load_librsvg_render_internal(self, scale, target, NULL); + return load_librsvg_render_internal(self, scale, cmm, target, NULL); } static FivIoImage * @@ -2289,8 +2289,8 @@ open_librsvg( // librsvg rasterizes filters, so rendering to a recording Cairo surface // has been abandoned. - FivIoImage *image = - load_librsvg_render_internal(closure, 1., ctx->screen_profile, error); + FivIoImage *image = load_librsvg_render_internal( + closure, 1., ctx->cmm, ctx->screen_profile, error); if (!image) { load_librsvg_destroy(&closure->parent); return NULL; @@ -2606,8 +2606,7 @@ open_libheif( g_free(ids); fail_read: heif_context_free(ctx); - return fiv_io_cmm_finalize(fiv_io_cmm_get_default(), - result, ioctx->screen_profile); + return fiv_io_cmm_finalize(ioctx->cmm, result, ioctx->screen_profile); } #endif // HAVE_LIBHEIF -------------------------------------------------------- @@ -2838,8 +2837,7 @@ fail: TIFFSetWarningHandlerExt(whe); TIFFSetErrorHandler(eh); TIFFSetWarningHandler(wh); - return fiv_io_cmm_finalize(fiv_io_cmm_get_default(), - result, ctx->screen_profile); + return fiv_io_cmm_finalize(ctx->cmm, result, ctx->screen_profile); } #endif // HAVE_LIBTIFF -------------------------------------------------------- @@ -2934,11 +2932,10 @@ open_gdkpixbuf( g_object_unref(pixbuf); if (custom_argb32) - fiv_io_cmm_argb32_premultiply_page(fiv_io_cmm_get_default(), - image, ctx->screen_profile); + fiv_io_cmm_argb32_premultiply_page( + ctx->cmm, image, ctx->screen_profile); else - image = fiv_io_cmm_finalize(fiv_io_cmm_get_default(), - image, ctx->screen_profile); + image = fiv_io_cmm_finalize(ctx->cmm, image, ctx->screen_profile); return image; } -- cgit v1.2.3-70-g09d2