[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