With newer Little CMS, colour manage ARGB surfaces
This commit is contained in:
parent
6cc4ca1f44
commit
d6e79cf976
79
fiv-io.c
79
fiv-io.c
|
@ -429,30 +429,6 @@ fiv_io_profile_page(cairo_surface_t *page, FivIoProfile target,
|
||||||
fiv_io_profile_free(source);
|
fiv_io_profile_free(source);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define fiv_io_profile_xrgb32_page(page, target) \
|
|
||||||
fiv_io_profile_page((page), (target), fiv_io_profile_xrgb32)
|
|
||||||
|
|
||||||
// TODO(p): Offer better integration, upgrade the bit depth if appropriate.
|
|
||||||
static cairo_surface_t *
|
|
||||||
fiv_io_profile_finalize(cairo_surface_t *image, FivIoProfile target)
|
|
||||||
{
|
|
||||||
if (!image || !target)
|
|
||||||
return image;
|
|
||||||
|
|
||||||
for (cairo_surface_t *page = image; page != NULL;
|
|
||||||
page = cairo_surface_get_user_data(page, &fiv_io_key_page_next)) {
|
|
||||||
// TODO(p): 1. un/premultiply ARGB, 2. do colour management
|
|
||||||
// early enough, so that no avoidable increase of quantization error
|
|
||||||
// occurs beforehands, and also for correct alpha compositing.
|
|
||||||
// FIXME: This assumes that if the first frame is opaque, they all are.
|
|
||||||
if (cairo_image_surface_get_format(page) == CAIRO_FORMAT_RGB24)
|
|
||||||
fiv_io_profile_xrgb32_page(page, target);
|
|
||||||
}
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fiv_io_premultiply_argb32(cairo_surface_t *surface)
|
fiv_io_premultiply_argb32(cairo_surface_t *surface)
|
||||||
{
|
{
|
||||||
|
@ -480,13 +456,27 @@ fiv_io_premultiply_argb32(cairo_surface_t *surface)
|
||||||
#define FIV_IO_PROFILE_ARGB32_PREMUL \
|
#define FIV_IO_PROFILE_ARGB32_PREMUL \
|
||||||
(G_BYTE_ORDER == G_LITTLE_ENDIAN ? TYPE_BGRA_8_PREMUL : TYPE_ARGB_8_PREMUL)
|
(G_BYTE_ORDER == G_LITTLE_ENDIAN ? TYPE_BGRA_8_PREMUL : TYPE_ARGB_8_PREMUL)
|
||||||
|
|
||||||
|
static void
|
||||||
|
fiv_io_profile_argb32(cairo_surface_t *surface,
|
||||||
|
FivIoProfile source, FivIoProfile target)
|
||||||
|
{
|
||||||
|
g_return_if_fail(
|
||||||
|
cairo_image_surface_get_format(surface) == CAIRO_FORMAT_ARGB32);
|
||||||
|
|
||||||
|
unsigned char *data = cairo_image_surface_get_data(surface);
|
||||||
|
int w = cairo_image_surface_get_width(surface);
|
||||||
|
int h = cairo_image_surface_get_height(surface);
|
||||||
|
fiv_io_profile_rgb_direct(data, w, h, source, target,
|
||||||
|
FIV_IO_PROFILE_ARGB32_PREMUL, FIV_IO_PROFILE_ARGB32_PREMUL);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fiv_io_profile_argb32_premultiply(cairo_surface_t *surface,
|
fiv_io_profile_argb32_premultiply(cairo_surface_t *surface,
|
||||||
FivIoProfile source, FivIoProfile target)
|
FivIoProfile source, FivIoProfile target)
|
||||||
{
|
{
|
||||||
|
unsigned char *data = cairo_image_surface_get_data(surface);
|
||||||
int w = cairo_image_surface_get_width(surface);
|
int w = cairo_image_surface_get_width(surface);
|
||||||
int h = cairo_image_surface_get_height(surface);
|
int h = cairo_image_surface_get_height(surface);
|
||||||
unsigned char *data = cairo_image_surface_get_data(surface);
|
|
||||||
if (cairo_image_surface_get_format(surface) != CAIRO_FORMAT_ARGB32) {
|
if (cairo_image_surface_get_format(surface) != CAIRO_FORMAT_ARGB32) {
|
||||||
fiv_io_profile_xrgb32_direct(data, w, h, source, target);
|
fiv_io_profile_xrgb32_direct(data, w, h, source, target);
|
||||||
} else if (!fiv_io_profile_rgb_direct(data, w, h, source, target,
|
} else if (!fiv_io_profile_rgb_direct(data, w, h, source, target,
|
||||||
|
@ -501,11 +491,14 @@ fiv_io_profile_argb32_premultiply(cairo_surface_t *surface,
|
||||||
|
|
||||||
#else // ! HAVE_LCMS2 || LCMS_VERSION < 2130
|
#else // ! HAVE_LCMS2 || LCMS_VERSION < 2130
|
||||||
|
|
||||||
|
// TODO(p): Unpremultiply, transform, repremultiply. Or require lcms2>=2.13.
|
||||||
|
#define fiv_io_profile_argb32(surface, source, target)
|
||||||
|
|
||||||
static void
|
static void
|
||||||
fiv_io_profile_argb32_premultiply_page(
|
fiv_io_profile_argb32_premultiply_page(
|
||||||
cairo_surface_t *page, FivIoProfile target)
|
cairo_surface_t *page, FivIoProfile target)
|
||||||
{
|
{
|
||||||
fiv_io_profile_xrgb32_page(page, target);
|
fiv_io_profile_page(page, target, fiv_io_profile_xrgb32);
|
||||||
|
|
||||||
for (cairo_surface_t *frame = page; frame != NULL;
|
for (cairo_surface_t *frame = page; frame != NULL;
|
||||||
frame = cairo_surface_get_user_data(frame, &fiv_io_key_frame_next))
|
frame = cairo_surface_get_user_data(frame, &fiv_io_key_frame_next))
|
||||||
|
@ -514,6 +507,38 @@ fiv_io_profile_argb32_premultiply_page(
|
||||||
|
|
||||||
#endif // ! HAVE_LCMS2 || LCMS_VERSION < 2130
|
#endif // ! HAVE_LCMS2 || LCMS_VERSION < 2130
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
static void
|
||||||
|
fiv_io_profile_any(cairo_surface_t *surface,
|
||||||
|
FivIoProfile source, FivIoProfile target)
|
||||||
|
{
|
||||||
|
// TODO(p): Ensure we do colour management early enough, so that
|
||||||
|
// no avoidable increase of quantization error occurs beforehands,
|
||||||
|
// and also for correct alpha compositing.
|
||||||
|
switch (cairo_image_surface_get_format(surface)) {
|
||||||
|
break; case CAIRO_FORMAT_RGB24:
|
||||||
|
fiv_io_profile_xrgb32(surface, source, target);
|
||||||
|
break; case CAIRO_FORMAT_ARGB32:
|
||||||
|
fiv_io_profile_argb32(surface, source, target);
|
||||||
|
break; default:
|
||||||
|
g_debug("CM attempted on an unsupported surface format");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(p): Offer better integration, upgrade the bit depth if appropriate.
|
||||||
|
static cairo_surface_t *
|
||||||
|
fiv_io_profile_finalize(cairo_surface_t *image, FivIoProfile target)
|
||||||
|
{
|
||||||
|
if (!target)
|
||||||
|
return image;
|
||||||
|
|
||||||
|
for (cairo_surface_t *page = image; page != NULL;
|
||||||
|
page = cairo_surface_get_user_data(page, &fiv_io_key_page_next))
|
||||||
|
fiv_io_profile_page(page, target, fiv_io_profile_any);
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
// --- Wuffs -------------------------------------------------------------------
|
// --- Wuffs -------------------------------------------------------------------
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -1420,7 +1445,7 @@ load_jpeg_finalize(cairo_surface_t *surface, bool cmyk,
|
||||||
if (cmyk)
|
if (cmyk)
|
||||||
fiv_io_profile_cmyk(surface, source, ctx->screen_profile);
|
fiv_io_profile_cmyk(surface, source, ctx->screen_profile);
|
||||||
else
|
else
|
||||||
fiv_io_profile_xrgb32(surface, source, ctx->screen_profile);
|
fiv_io_profile_any(surface, source, ctx->screen_profile);
|
||||||
|
|
||||||
if (source)
|
if (source)
|
||||||
fiv_io_profile_free(source);
|
fiv_io_profile_free(source);
|
||||||
|
|
Loading…
Reference in New Issue