[PATCH] Add initial color management framework code
Pekka Paalanen
ppaalanen at gmail.com
Fri May 3 03:53:54 PDT 2013
On Thu, 2 May 2013 15:16:09 +0100
Richard Hughes <hughsient at gmail.com> wrote:
> ICC profiles can now be specified in weston.ini for each output, or a CMS
> implementation can optionally loaded from a pluggable module.
> ---
> configure.ac | 7 ++
> src/Makefile.am | 13 +++-
> src/cms-static.c | 211 +++++++++++++++++++++++++++++++++++++++++++++++++++
> src/cms.c | 143 ++++++++++++++++++++++++++++++++++
> src/cms.h | 65 ++++++++++++++++
> src/compositor-drm.c | 2 +
> src/compositor.c | 2 +
> src/compositor.h | 11 +++
> weston.ini | 3 +-
> 9 files changed, 454 insertions(+), 3 deletions(-)
> create mode 100644 src/cms-static.c
> create mode 100644 src/cms.c
> create mode 100644 src/cms.h
>
> diff --git a/src/cms.c b/src/cms.c
> new file mode 100644
> index 0000000..588fb7e
> --- /dev/null
> +++ b/src/cms.c
> @@ -0,0 +1,143 @@
> +/*
> + * Copyright © 2013 Richard Hughes
> + *
> + * Permission to use, copy, modify, distribute, and sell this software and
> + * its documentation for any purpose is hereby granted without fee, provided
> + * that the above copyright notice appear in all copies and that both that
> + * copyright notice and this permission notice appear in supporting
> + * documentation, and that the name of the copyright holders not be used in
> + * advertising or publicity pertaining to distribution of the software
> + * without specific, written prior permission. The copyright holders make
> + * no representations about the suitability of this software for any
> + * purpose. It is provided "as is" without express or implied warranty.
> + *
> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
> + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
> + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
> + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
> + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
> + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
> + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
> + */
> +
> +#ifdef HAVE_CONFIG_H
> +#include <config.h>
> +#endif
> +
> +#include <stdlib.h>
> +#include <string.h>
> +#include <stdio.h>
> +
> +#ifdef HAVE_LCMS
> +#include <lcms2.h>
> +#endif
> +
> +#include "compositor.h"
> +#include "cms.h"
> +
> +static void
> +weston_cms_gamma_clear(struct weston_output *o)
> +{
> + int i;
> + uint16_t *red;
> +
> + if (!o->set_gamma)
> + return;
> +
> + red = calloc(sizeof(uint16_t), o->gamma_size);
> + for (i = 0; i < o->gamma_size; i++)
> + red[i] = (uint32_t) 0xffff * (uint32_t) i / (uint32_t) (o->gamma_size - 1);
> + o->set_gamma(o, o->gamma_size, red, red, red);
> + free(red);
> +}
> +
> +static void
> +weston_cms_gamma_update(struct weston_output *o)
> +{
> +#ifdef HAVE_LCMS
> + cmsFloat32Number in;
> + const cmsToneCurve **vcgt;
> + int i;
> + int size;
> + uint16_t *red = NULL;
> + uint16_t *green = NULL;
> + uint16_t *blue = NULL;
> +
> + if (!o->set_gamma)
> + return;
> + if (!o->color_profile) {
> + weston_cms_gamma_clear(o);
> + return;
> + }
> +
> + weston_log("Using ICC profile %s\n", o->color_profile->filename);
> + vcgt = cmsReadTag (o->color_profile->lcms_handle, cmsSigVcgtTag);
> + if (vcgt == NULL || vcgt[0] == NULL) {
> + weston_cms_gamma_clear(o);
> + return;
> + }
> +
> + size = o->gamma_size;
> + red = calloc(sizeof(uint16_t), size);
> + green = calloc(sizeof(uint16_t), size);
> + blue = calloc(sizeof(uint16_t), size);
> + for (i = 0; i < size; i++) {
> + in = (cmsFloat32Number) i / (cmsFloat32Number) (size - 1);
> + red[i] = cmsEvalToneCurveFloat(vcgt[0], in) * (double) 0xffff;
> + green[i] = cmsEvalToneCurveFloat(vcgt[1], in) * (double) 0xffff;
> + blue[i] = cmsEvalToneCurveFloat(vcgt[2], in) * (double) 0xffff;
> + }
> + o->set_gamma(o, size, red, red, red);
Three times red? :-)
> + free(red);
> + free(green);
> + free(blue);
> +#endif
> +}
> +
> +WL_EXPORT void
> +weston_cms_set_color_profile(struct weston_output *o,
> + struct weston_color_profile *p)
> +{
> + if (o->color_profile == p)
> + return;
> + if (o->color_profile)
> + weston_cms_destroy_profile(o->color_profile);
> + o->color_profile = p;
> + weston_cms_gamma_update(o);
> +}
> +
> +WL_EXPORT void
> +weston_cms_destroy_profile(struct weston_color_profile *p)
> +{
> + if (!p)
> + return;
> +#ifdef HAVE_LCMS
> + cmsCloseProfile(p->lcms_handle);
> +#endif
> + free(p->filename);
> + free(p);
> +}
> +
> +WL_EXPORT struct weston_color_profile *
> +weston_cms_create_profile(const char *filename,
> + void *lcms_profile)
> +{
> + struct weston_color_profile *p;
> + p = calloc(sizeof(struct weston_color_profile), 1);
Calloc arguments are swapped.
> + p->filename = strdup(filename);
> + p->lcms_handle = lcms_profile;
> + return p;
> +}
> +
> +WL_EXPORT struct weston_color_profile *
> +weston_cms_load_profile(const char *filename)
> +{
> + struct weston_color_profile *p = NULL;
> +#ifdef HAVE_LCMS
> + cmsHPROFILE lcms_profile;
> + lcms_profile = cmsOpenProfileFromFile(filename, "r");
> + if (lcms_profile)
> + p = weston_cms_create_profile(filename, lcms_profile);
> +#endif
> + return p;
> +}
> diff --git a/src/compositor.c b/src/compositor.c
> index a6610e6..4c0bd4b 100644
> --- a/src/compositor.c
> +++ b/src/compositor.c
> @@ -56,6 +56,7 @@
>
> #include <wayland-server.h>
> #include "compositor.h"
> +#include "cms.h"
> #include "../shared/os-compatibility.h"
> #include "git-version.h"
> #include "version.h"
> @@ -2912,6 +2913,7 @@ weston_output_destroy(struct weston_output *output)
> pixman_region32_fini(&output->region);
> pixman_region32_fini(&output->previous_damage);
> output->compositor->output_id_pool &= ~(1 << output->id);
> + weston_cms_destroy_profile(output->color_profile);
Was this call supposed to be replaced by an output destroy signal
listener? IIRC there were some such comments before.
>
> wl_display_remove_global(c->wl_display, output->global);
> }
Thanks,
pq
More information about the wayland-devel
mailing list