Bug 630748 - display filters do not work

Create and use Cairo-compatible API for display filters. Also
includes logic changes to the display filters to deal with cairo's
ARGB32 pre-multiplied buffer format.
This commit is contained in:
Omari Stephens 2011-01-23 07:28:33 +00:00 committed by Michael Natterer
parent 47eaecdc9d
commit 5cae0bf65c
11 changed files with 434 additions and 259 deletions

View File

@ -160,29 +160,24 @@ gimp_display_shell_render (GimpDisplayShell *shell,
switch (type)
{
case GIMP_RGBA_IMAGE:
render_image_rgb_a (&info);
break;
case GIMP_GRAYA_IMAGE:
render_image_gray_a (&info);
break;
default:
g_warning ("%s: unsupported projection type (%d)", G_STRFUNC, type);
g_assert_not_reached ();
case GIMP_RGBA_IMAGE:
render_image_rgb_a (&info);
break;
case GIMP_GRAYA_IMAGE:
render_image_gray_a (&info);
break;
default:
g_warning ("%s: unsupported projection type (%d)", G_STRFUNC, type);
g_assert_not_reached ();
}
/* apply filters to the rendered projection */
#if 0
if (shell->filter_stack)
gimp_color_display_stack_convert (shell->filter_stack,
shell->render_buf,
w, h,
3,
3 * GIMP_DISPLAY_RENDER_BUF_WIDTH);
#endif
cairo_surface_mark_dirty (shell->render_surface);
/* apply filters to the rendered projection */
if (shell->filter_stack)
gimp_color_display_stack_convert_surface (shell->filter_stack,
shell->render_surface);
if (shell->mask)
{
if (! shell->mask_surface)

View File

@ -140,6 +140,7 @@ gimp_color_display_class_init (GimpColorDisplayClass *klass)
klass->stock_id = GIMP_STOCK_DISPLAY_FILTER;
klass->clone = NULL;
klass->convert_surface = NULL;
klass->convert = NULL;
klass->load_state = NULL;
klass->save_state = NULL;
@ -334,6 +335,46 @@ gimp_color_display_clone (GimpColorDisplay *display)
return GIMP_COLOR_DISPLAY (gimp_config_duplicate (GIMP_CONFIG (display)));
}
/**
* gimp_color_display_convert_surface:
* @display: a #GimpColorDisplay
* @surface: a #cairo_image_surface_t of type ARGB32
*
* Converts all pixels in @surface.
*
* Since: GIMP 2.8
**/
void
gimp_color_display_convert_surface (GimpColorDisplay *display,
cairo_surface_t *surface)
{
g_return_if_fail (GIMP_IS_COLOR_DISPLAY (display));
g_return_if_fail (surface != NULL);
g_return_if_fail (cairo_surface_get_type (surface) ==
CAIRO_SURFACE_TYPE_IMAGE);
if (display->enabled &&
GIMP_COLOR_DISPLAY_GET_CLASS (display)->convert_surface)
{
cairo_surface_flush (surface);
GIMP_COLOR_DISPLAY_GET_CLASS (display)->convert_surface (display, surface);
cairo_surface_mark_dirty (surface);
}
}
/**
* gimp_color_display_convert:
* @display: a #GimpColorDisplay
* @buf: the pixel buffer to convert
* @width: the width of the buffer
* @height: the height of the buffer
* @bpp: the number of bytes per pixel
* @bpl: the buffer's rowstride
*
* Converts all pixels in @buf.
*
* Deprecated: GIMP 2.8: Use gimp_color_display_convert_surface() instead.
**/
void
gimp_color_display_convert (GimpColorDisplay *display,
guchar *buf,
@ -344,6 +385,8 @@ gimp_color_display_convert (GimpColorDisplay *display,
{
g_return_if_fail (GIMP_IS_COLOR_DISPLAY (display));
/* implementing the convert method is deprecated
*/
if (display->enabled && GIMP_COLOR_DISPLAY_GET_CLASS (display)->convert)
GIMP_COLOR_DISPLAY_GET_CLASS (display)->convert (display, buf,
width, height,

View File

@ -56,6 +56,7 @@ struct _GimpColorDisplayClass
/* implementing the GimpColorDisplay::clone method is deprecated */
GimpColorDisplay * (* clone) (GimpColorDisplay *display);
/* implementing the GimpColorDisplay::convert method is deprecated */
void (* convert) (GimpColorDisplay *display,
guchar *buf,
gint width,
@ -80,8 +81,10 @@ struct _GimpColorDisplayClass
const gchar *stock_id;
void (* convert_surface) (GimpColorDisplay *display,
cairo_surface_t *surface);
/* Padding for future expansion */
void (* _gimp_reserved2) (void);
void (* _gimp_reserved3) (void);
void (* _gimp_reserved4) (void);
};
@ -95,12 +98,16 @@ GimpColorDisplay * gimp_color_display_new (GType display_typ
GimpColorDisplay * gimp_color_display_clone (GimpColorDisplay *display);
void gimp_color_display_convert_surface (GimpColorDisplay *display,
cairo_surface_t *surface);
#ifndef GIMP_DISABLE_DEPRECATED
void gimp_color_display_convert (GimpColorDisplay *display,
guchar *buf,
gint width,
gint height,
gint bpp,
gint bpl);
#endif
void gimp_color_display_load_state (GimpColorDisplay *display,
GimpParasite *state);
GimpParasite * gimp_color_display_save_state (GimpColorDisplay *display);

View File

@ -27,6 +27,7 @@
#include "gimpwidgetstypes.h"
#undef GIMP_DISABLE_DEPRECATED
#include "gimpcolordisplay.h"
#include "gimpcolordisplaystack.h"
#include "gimpwidgetsmarshal.h"
@ -283,6 +284,47 @@ gimp_color_display_stack_reorder_down (GimpColorDisplayStack *stack,
}
}
/**
* gimp_color_display_stack_convert_surface:
* @display: a #GimpColorDisplayStack
* @surface: a #cairo_image_surface_t of type ARGB32
*
* Runs all the stack's filters on all pixels in @surface.
*
* Since: GIMP 2.8
**/
void
gimp_color_display_stack_convert_surface (GimpColorDisplayStack *stack,
cairo_surface_t *surface)
{
GList *list;
g_return_if_fail (GIMP_IS_COLOR_DISPLAY_STACK (stack));
g_return_if_fail (surface != NULL);
g_return_if_fail (cairo_surface_get_type (surface) ==
CAIRO_SURFACE_TYPE_IMAGE);
for (list = stack->filters; list; list = g_list_next (list))
{
GimpColorDisplay *display = list->data;
gimp_color_display_convert_surface (display, surface);
}
}
/**
* gimp_color_display_stack_convert:
* @display: a #GimpColorDisplayStack
* @buf: the pixel buffer to convert
* @width: the width of the buffer
* @height: the height of the buffer
* @bpp: the number of bytes per pixel
* @bpl: the buffer's rowstride
*
* Converts all pixels in @buf.
*
* Deprecated: GIMP 2.8: Use gimp_color_display_stack_convert_surface() instead.
**/
void
gimp_color_display_stack_convert (GimpColorDisplayStack *stack,
guchar *buf,

View File

@ -71,24 +71,26 @@ GType gimp_color_display_stack_get_type (void) G_GNUC_CONST;
GimpColorDisplayStack * gimp_color_display_stack_new (void);
GimpColorDisplayStack * gimp_color_display_stack_clone (GimpColorDisplayStack *stack);
void gimp_color_display_stack_changed (GimpColorDisplayStack *stack);
void gimp_color_display_stack_add (GimpColorDisplayStack *stack,
GimpColorDisplay *display);
void gimp_color_display_stack_remove (GimpColorDisplayStack *stack,
GimpColorDisplay *display);
void gimp_color_display_stack_reorder_up (GimpColorDisplayStack *stack,
GimpColorDisplay *display);
void gimp_color_display_stack_reorder_down (GimpColorDisplayStack *stack,
GimpColorDisplay *display);
void gimp_color_display_stack_convert (GimpColorDisplayStack *stack,
guchar *buf,
gint width,
gint height,
gint bpp,
gint bpl);
void gimp_color_display_stack_changed (GimpColorDisplayStack *stack);
void gimp_color_display_stack_add (GimpColorDisplayStack *stack,
GimpColorDisplay *display);
void gimp_color_display_stack_remove (GimpColorDisplayStack *stack,
GimpColorDisplay *display);
void gimp_color_display_stack_reorder_up (GimpColorDisplayStack *stack,
GimpColorDisplay *display);
void gimp_color_display_stack_reorder_down (GimpColorDisplayStack *stack,
GimpColorDisplay *display);
void gimp_color_display_stack_convert_surface (GimpColorDisplayStack *stack,
cairo_surface_t *surface);
#ifndef GIMP_DISABLE_DEPRECATED
void gimp_color_display_stack_convert (GimpColorDisplayStack *stack,
guchar *buf,
gint width,
gint height,
gint bpp,
gint bpl);
#endif
G_END_DECLS

View File

@ -112,28 +112,24 @@ enum
};
GType cdisplay_colorblind_get_type (void);
GType cdisplay_colorblind_get_type (void);
static void cdisplay_colorblind_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void cdisplay_colorblind_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void cdisplay_colorblind_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void cdisplay_colorblind_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void cdisplay_colorblind_convert (GimpColorDisplay *display,
guchar *buf,
gint w,
gint h,
gint bpp,
gint bpl);
static GtkWidget * cdisplay_colorblind_configure (GimpColorDisplay *display);
static void cdisplay_colorblind_changed (GimpColorDisplay *display);
static void cdisplay_colorblind_convert_surface (GimpColorDisplay *display,
cairo_surface_t *surface);
static GtkWidget * cdisplay_colorblind_configure (GimpColorDisplay *display);
static void cdisplay_colorblind_changed (GimpColorDisplay *display);
static void cdisplay_colorblind_set_deficiency (CdisplayColorblind *colorblind,
ColorblindDeficiency value);
static void cdisplay_colorblind_set_deficiency (CdisplayColorblind *colorblind,
ColorblindDeficiency value);
/* The RGB<->LMS transforms above are computed from the human cone
@ -147,7 +143,7 @@ static void cdisplay_colorblind_set_deficiency (CdisplayColorblind *col
* following are the gamma estimates that we have used in the
* Vischeck code. Many colorblind users have viewed our simulations
* and told us that they "work" (simulated and original images are
* indistinguishabled).
* indistinguishable).
*/
static const gfloat gammaRGB = 2.1;
@ -248,8 +244,8 @@ cdisplay_colorblind_class_init (CdisplayColorblindClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpColorDisplayClass *display_class = GIMP_COLOR_DISPLAY_CLASS (klass);
object_class->get_property = cdisplay_colorblind_get_property;
object_class->set_property = cdisplay_colorblind_set_property;
object_class->get_property = cdisplay_colorblind_get_property;
object_class->set_property = cdisplay_colorblind_set_property;
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_DEFICIENCY,
"deficiency", NULL,
@ -257,13 +253,13 @@ cdisplay_colorblind_class_init (CdisplayColorblindClass *klass)
DEFAULT_DEFICIENCY,
0);
display_class->name = _("Color Deficient Vision");
display_class->help_id = "gimp-colordisplay-colorblind";
display_class->stock_id = GIMP_STOCK_DISPLAY_FILTER_COLORBLIND;
display_class->name = _("Color Deficient Vision");
display_class->help_id = "gimp-colordisplay-colorblind";
display_class->stock_id = GIMP_STOCK_DISPLAY_FILTER_COLORBLIND;
display_class->convert = cdisplay_colorblind_convert;
display_class->configure = cdisplay_colorblind_configure;
display_class->changed = cdisplay_colorblind_changed;
display_class->convert_surface = cdisplay_colorblind_convert_surface;
display_class->configure = cdisplay_colorblind_configure;
display_class->changed = cdisplay_colorblind_changed;
}
static void
@ -359,55 +355,61 @@ lut_lookup (gfloat value,
}
static void
cdisplay_colorblind_convert (GimpColorDisplay *display,
guchar *buf,
gint width,
gint height,
gint bpp,
gint bpl)
cdisplay_colorblind_convert_surface (GimpColorDisplay *display,
cairo_surface_t *surface)
{
CdisplayColorblind *colorblind = CDISPLAY_COLORBLIND (display);
const gfloat a1 = colorblind->a1;
const gfloat b1 = colorblind->b1;
const gfloat c1 = colorblind->c1;
const gfloat a2 = colorblind->a2;
const gfloat b2 = colorblind->b2;
const gfloat c2 = colorblind->c2;
gfloat tmp;
gfloat red, green, blue;
gfloat redOld, greenOld;
guchar *b;
gint x, y;
gint width = cairo_image_surface_get_width (surface);
gint height = cairo_image_surface_get_height (surface);
gint stride = cairo_image_surface_get_stride (surface);
guchar *buf = cairo_image_surface_get_data (surface);
cairo_format_t fmt = cairo_image_surface_get_format (surface);
const gfloat a1 = colorblind->a1;
const gfloat b1 = colorblind->b1;
const gfloat c1 = colorblind->c1;
const gfloat a2 = colorblind->a2;
const gfloat b2 = colorblind->b2;
const gfloat c2 = colorblind->c2;
gfloat tmp;
gfloat red, green, blue;
gfloat redOld, greenOld;
guchar r, g, b, a;
gint x, y, skip;
/* Require 3 bytes per pixel (assume RGB) */
if (bpp != 3)
/* Require ARGB32 pixel format */
if (fmt != CAIRO_FORMAT_ARGB32)
return;
for (y = 0; y < height; y++, buf += bpl)
for (x = 0, b = buf; x < width; x++, b += bpp)
skip = stride - 4 * width;
for (y = 0; y < height; y++, buf += skip)
for (x = 0; x < width; x++, buf += 4)
{
guint32 pixel;
guint index;
/* First check our cache */
pixel = b[0] << 16 | b[1] << 8 | b[2];
GIMP_CAIRO_ARGB32_GET_PIXEL (buf, r, g, b, a);
pixel = r << 16 | g << 8 | b;
index = pixel % COLOR_CACHE_SIZE;
if (colorblind->cache[2 * index] == pixel)
{
pixel = colorblind->cache[2 * index + 1];
b[2] = pixel & 0xFF; pixel >>= 8;
b[1] = pixel & 0xFF; pixel >>= 8;
b[0] = pixel & 0xFF;
b = pixel & 0xFF; pixel >>= 8;
g = pixel & 0xFF; pixel >>= 8;
r = pixel & 0xFF;
GIMP_CAIRO_ARGB32_SET_PIXEL (buf, r, g, b, a);
continue;
}
/* Remove gamma to linearize RGB intensities */
red = colorblind->gamma_lut[b[0]];
green = colorblind->gamma_lut[b[1]];
blue = colorblind->gamma_lut[b[2]];
red = colorblind->gamma_lut[r];
green = colorblind->gamma_lut[g];
blue = colorblind->gamma_lut[b];
/* Convert to LMS (dot product with transform matrix) */
redOld = red;
@ -459,13 +461,14 @@ cdisplay_colorblind_convert (GimpColorDisplay *display,
blue = redOld * lms2rgb[6] + greenOld * lms2rgb[7] + blue * lms2rgb[8];
/* Apply gamma to go back to non-linear intensities */
b[0] = lut_lookup (red, colorblind->gamma_lut);
b[1] = lut_lookup (green, colorblind->gamma_lut);
b[2] = lut_lookup (blue, colorblind->gamma_lut);
r = lut_lookup (red, colorblind->gamma_lut);
g = lut_lookup (green, colorblind->gamma_lut);
b = lut_lookup (blue, colorblind->gamma_lut);
GIMP_CAIRO_ARGB32_SET_PIXEL (buf, r, g, b, a);
/* Put the result into our cache */
colorblind->cache[2 * index] = pixel;
colorblind->cache[2 * index + 1] = b[0] << 16 | b[1] << 8 | b[2];
colorblind->cache[2 * index + 1] = r << 16 | g << 8 | b;
}
}

View File

@ -61,26 +61,22 @@ enum
};
GType cdisplay_gamma_get_type (void);
GType cdisplay_gamma_get_type (void);
static void cdisplay_gamma_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void cdisplay_gamma_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void cdisplay_gamma_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void cdisplay_gamma_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void cdisplay_gamma_convert (GimpColorDisplay *display,
guchar *buf,
gint w,
gint h,
gint bpp,
gint bpl);
static GtkWidget * cdisplay_gamma_configure (GimpColorDisplay *display);
static void cdisplay_gamma_set_gamma (CdisplayGamma *gamma,
gdouble value);
static void cdisplay_gamma_convert_surface (GimpColorDisplay *display,
cairo_surface_t *surface);
static GtkWidget * cdisplay_gamma_configure (GimpColorDisplay *display);
static void cdisplay_gamma_set_gamma (CdisplayGamma *gamma,
gdouble value);
static const GimpModuleInfo cdisplay_gamma_info =
@ -117,20 +113,20 @@ cdisplay_gamma_class_init (CdisplayGammaClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpColorDisplayClass *display_class = GIMP_COLOR_DISPLAY_CLASS (klass);
object_class->get_property = cdisplay_gamma_get_property;
object_class->set_property = cdisplay_gamma_set_property;
object_class->get_property = cdisplay_gamma_get_property;
object_class->set_property = cdisplay_gamma_set_property;
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_GAMMA,
"gamma", NULL,
0.01, 10.0, DEFAULT_GAMMA,
0);
display_class->name = _("Gamma");
display_class->help_id = "gimp-colordisplay-gamma";
display_class->stock_id = GIMP_STOCK_DISPLAY_FILTER_GAMMA;
display_class->name = _("Gamma");
display_class->help_id = "gimp-colordisplay-gamma";
display_class->stock_id = GIMP_STOCK_DISPLAY_FILTER_GAMMA;
display_class->convert = cdisplay_gamma_convert;
display_class->configure = cdisplay_gamma_configure;
display_class->convert_surface = cdisplay_gamma_convert_surface;
display_class->configure = cdisplay_gamma_configure;
}
static void
@ -182,15 +178,20 @@ cdisplay_gamma_set_property (GObject *object,
}
static void
cdisplay_gamma_convert (GimpColorDisplay *display,
guchar *buf,
gint width,
gint height,
gint bpp,
gint bpl)
cdisplay_gamma_convert_surface (GimpColorDisplay *display,
cairo_surface_t *surface)
{
CdisplayGamma *gamma = CDISPLAY_GAMMA (display);
gint i, j = height;
CdisplayGamma *gamma = CDISPLAY_GAMMA (display);
gint width = cairo_image_surface_get_width (surface);
gint height = cairo_image_surface_get_height (surface);
gint stride = cairo_image_surface_get_stride (surface);
guchar *buf = cairo_image_surface_get_data (surface);
cairo_format_t fmt = cairo_image_surface_get_format (surface);
gint i, j, skip;
gint r, g, b, a;
if (fmt != CAIRO_FORMAT_ARGB32)
return;
/* You will not be using the entire buffer most of the time.
* Hence, the simplistic code for this is as follows:
@ -203,18 +204,22 @@ cdisplay_gamma_convert (GimpColorDisplay *display,
* }
*/
width *= bpp;
bpl -= width;
j = height;
skip = stride - 4 * width;
while (j--)
{
i = width;
while (i--)
{
*buf = gamma->lookup[*buf];
buf++;
GIMP_CAIRO_ARGB32_GET_PIXEL (buf, r, g, b, a);
r = gamma->lookup[r];
g = gamma->lookup[g];
b = gamma->lookup[b];
GIMP_CAIRO_ARGB32_SET_PIXEL (buf, r, g, b, a);
buf += 4;
}
buf += bpl;
buf += skip;
}
}

View File

@ -61,26 +61,22 @@ enum
};
GType cdisplay_contrast_get_type (void);
GType cdisplay_contrast_get_type (void);
static void cdisplay_contrast_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void cdisplay_contrast_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void cdisplay_contrast_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void cdisplay_contrast_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void cdisplay_contrast_convert (GimpColorDisplay *display,
guchar *buf,
gint w,
gint h,
gint bpp,
gint bpl);
static GtkWidget * cdisplay_contrast_configure (GimpColorDisplay *display);
static void cdisplay_contrast_set_contrast (CdisplayContrast *contrast,
gdouble value);
static void cdisplay_contrast_convert_surface (GimpColorDisplay *display,
cairo_surface_t *surface);
static GtkWidget * cdisplay_contrast_configure (GimpColorDisplay *display);
static void cdisplay_contrast_set_contrast (CdisplayContrast *contrast,
gdouble value);
static const GimpModuleInfo cdisplay_contrast_info =
@ -117,20 +113,20 @@ cdisplay_contrast_class_init (CdisplayContrastClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpColorDisplayClass *display_class = GIMP_COLOR_DISPLAY_CLASS (klass);
object_class->get_property = cdisplay_contrast_get_property;
object_class->set_property = cdisplay_contrast_set_property;
object_class->get_property = cdisplay_contrast_get_property;
object_class->set_property = cdisplay_contrast_set_property;
GIMP_CONFIG_INSTALL_PROP_DOUBLE (object_class, PROP_CONTRAST,
"contrast", NULL,
0.01, 10.0, DEFAULT_CONTRAST,
0);
display_class->name = _("Contrast");
display_class->help_id = "gimp-colordisplay-contrast";
display_class->stock_id = GIMP_STOCK_DISPLAY_FILTER_CONTRAST;
display_class->name = _("Contrast");
display_class->help_id = "gimp-colordisplay-contrast";
display_class->stock_id = GIMP_STOCK_DISPLAY_FILTER_CONTRAST;
display_class->convert = cdisplay_contrast_convert;
display_class->configure = cdisplay_contrast_configure;
display_class->convert_surface = cdisplay_contrast_convert_surface;
display_class->configure = cdisplay_contrast_configure;
}
static void
@ -182,15 +178,20 @@ cdisplay_contrast_set_property (GObject *object,
}
static void
cdisplay_contrast_convert (GimpColorDisplay *display,
guchar *buf,
gint width,
gint height,
gint bpp,
gint bpl)
cdisplay_contrast_convert_surface (GimpColorDisplay *display,
cairo_surface_t *surface)
{
CdisplayContrast *contrast = CDISPLAY_CONTRAST (display);
gint i, j = height;
gint width = cairo_image_surface_get_width (surface);
gint height = cairo_image_surface_get_height (surface);
gint stride = cairo_image_surface_get_stride (surface);
guchar *buf = cairo_image_surface_get_data (surface);
cairo_format_t fmt = cairo_image_surface_get_format (surface);
gint i, j, skip;
gint r, g, b, a;
if (fmt != CAIRO_FORMAT_ARGB32)
return;
/* You will not be using the entire buffer most of the time.
* Hence, the simplistic code for this is as follows:
@ -203,18 +204,22 @@ cdisplay_contrast_convert (GimpColorDisplay *display,
* }
*/
width *= bpp;
bpl -= width;
j = height;
skip = stride - 4 * width;
while (j--)
{
i = width;
while (i--)
{
*buf = contrast->lookup[*buf];
buf++;
GIMP_CAIRO_ARGB32_GET_PIXEL (buf, r, g, b, a);
r = contrast->lookup[r];
g = contrast->lookup[g];
b = contrast->lookup[b];
GIMP_CAIRO_ARGB32_SET_PIXEL (buf, r, g, b, a);
buf += 4;
}
buf += bpl;
buf += skip;
}
}

View File

@ -51,7 +51,7 @@
#define CDISPLAY_IS_LCMS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CDISPLAY_TYPE_LCMS))
typedef struct _CdisplayLcms CdisplayLcms;
typedef struct _CdisplayLcms CdisplayLcms;
typedef struct _CdisplayLcmsClass CdisplayLcmsClass;
struct _CdisplayLcms
@ -67,32 +67,28 @@ struct _CdisplayLcmsClass
};
GType cdisplay_lcms_get_type (void);
GType cdisplay_lcms_get_type (void);
static void cdisplay_lcms_finalize (GObject *object);
static void cdisplay_lcms_finalize (GObject *object);
static GtkWidget * cdisplay_lcms_configure (GimpColorDisplay *display);
static void cdisplay_lcms_convert (GimpColorDisplay *display,
guchar *buf,
gint width,
gint height,
gint bpp,
gint bpl);
static void cdisplay_lcms_changed (GimpColorDisplay *display);
static GtkWidget * cdisplay_lcms_configure (GimpColorDisplay *display);
static void cdisplay_lcms_convert_surface (GimpColorDisplay *display,
cairo_surface_t *surface);
static void cdisplay_lcms_changed (GimpColorDisplay *display);
static cmsHPROFILE cdisplay_lcms_get_rgb_profile (CdisplayLcms *lcms);
static cmsHPROFILE cdisplay_lcms_get_display_profile (CdisplayLcms *lcms);
static cmsHPROFILE cdisplay_lcms_get_printer_profile (CdisplayLcms *lcms);
static cmsHPROFILE cdisplay_lcms_get_rgb_profile (CdisplayLcms *lcms);
static cmsHPROFILE cdisplay_lcms_get_display_profile (CdisplayLcms *lcms);
static cmsHPROFILE cdisplay_lcms_get_printer_profile (CdisplayLcms *lcms);
static void cdisplay_lcms_attach_labelled (GtkTable *table,
gint row,
const gchar *text,
GtkWidget *widget);
static void cdisplay_lcms_update_profile_label (CdisplayLcms *lcms,
const gchar *name);
static void cdisplay_lcms_notify_profile (GObject *config,
GParamSpec *pspec,
CdisplayLcms *lcms);
static void cdisplay_lcms_attach_labelled (GtkTable *table,
gint row,
const gchar *text,
GtkWidget *widget);
static void cdisplay_lcms_update_profile_label (CdisplayLcms *lcms,
const gchar *name);
static void cdisplay_lcms_notify_profile (GObject *config,
GParamSpec *pspec,
CdisplayLcms *lcms);
static const GimpModuleInfo cdisplay_lcms_info =
@ -128,15 +124,15 @@ cdisplay_lcms_class_init (CdisplayLcmsClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpColorDisplayClass *display_class = GIMP_COLOR_DISPLAY_CLASS (klass);
object_class->finalize = cdisplay_lcms_finalize;
object_class->finalize = cdisplay_lcms_finalize;
display_class->name = _("Color Management");
display_class->help_id = "gimp-colordisplay-lcms";
display_class->stock_id = GIMP_STOCK_DISPLAY_FILTER_LCMS;
display_class->name = _("Color Management");
display_class->help_id = "gimp-colordisplay-lcms";
display_class->stock_id = GIMP_STOCK_DISPLAY_FILTER_LCMS;
display_class->configure = cdisplay_lcms_configure;
display_class->convert = cdisplay_lcms_convert;
display_class->changed = cdisplay_lcms_changed;
display_class->configure = cdisplay_lcms_configure;
display_class->convert_surface = cdisplay_lcms_convert_surface;
display_class->changed = cdisplay_lcms_changed;
cmsErrorAction (LCMS_ERROR_IGNORE);
}
@ -257,24 +253,55 @@ cdisplay_lcms_configure (GimpColorDisplay *display)
}
static void
cdisplay_lcms_convert (GimpColorDisplay *display,
guchar *buf,
gint width,
gint height,
gint bpp,
gint bpl)
cdisplay_lcms_convert_surface (GimpColorDisplay *display,
cairo_surface_t *surface)
{
CdisplayLcms *lcms = CDISPLAY_LCMS (display);
gint y;
CdisplayLcms *lcms = CDISPLAY_LCMS (display);
gint width = cairo_image_surface_get_width (surface);
gint height = cairo_image_surface_get_height (surface);
gint stride = cairo_image_surface_get_stride (surface);
guchar *buf = cairo_image_surface_get_data (surface);
cairo_format_t fmt = cairo_image_surface_get_format (surface);
guchar *rowbuf;
gint x, y;
guchar r, g, b, a;
if (bpp != 3)
if (fmt != CAIRO_FORMAT_ARGB32)
return;
if (! lcms->transform)
return;
for (y = 0; y < height; y++, buf += bpl)
cmsDoTransform (lcms->transform, buf, buf, width);
rowbuf = g_malloc (stride);
for (y = 0; y < height; y++, buf += stride)
{
/* Switch buf from ARGB premul to ARGB non-premul, since lcms ignores the
* alpha channel. The macro takes care of byte order.
*/
for (x = 0; x < width; x++)
{
GIMP_CAIRO_ARGB32_GET_PIXEL (buf + 4*x, r, g, b, a);
rowbuf[4*x+0] = a;
rowbuf[4*x+1] = r;
rowbuf[4*x+2] = g;
rowbuf[4*x+3] = b;
}
cmsDoTransform (lcms->transform, rowbuf, rowbuf, width);
/* And back to ARGB premul */
for (x = 0; x < width; x++)
{
a = rowbuf[4*x+0];
r = rowbuf[4*x+1];
g = rowbuf[4*x+2];
b = rowbuf[4*x+3];
GIMP_CAIRO_ARGB32_SET_PIXEL (buf + 4*x, r, g, b, a);
}
}
g_free (rowbuf);
}
static void
@ -339,8 +366,8 @@ cdisplay_lcms_changed (GimpColorDisplay *display)
cmsSetAlarmCodes (r, g, b);
}
lcms->transform = cmsCreateProofingTransform (src_profile, TYPE_RGB_8,
dest_profile, TYPE_RGB_8,
lcms->transform = cmsCreateProofingTransform (src_profile, TYPE_ARGB_8,
dest_profile, TYPE_ARGB_8,
proof_profile,
config->simulation_intent,
config->display_intent,
@ -355,8 +382,8 @@ cdisplay_lcms_changed (GimpColorDisplay *display)
if (! dest_profile)
dest_profile = cmsCreate_sRGBProfile ();
lcms->transform = cmsCreateTransform (src_profile, TYPE_RGB_8,
dest_profile, TYPE_RGB_8,
lcms->transform = cmsCreateTransform (src_profile, TYPE_ARGB_8,
dest_profile, TYPE_ARGB_8,
config->display_intent,
flags);
}

View File

@ -38,7 +38,7 @@
#define CDISPLAY_IS_PROOF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CDISPLAY_TYPE_PROOF))
typedef struct _CdisplayProof CdisplayProof;
typedef struct _CdisplayProof CdisplayProof;
typedef struct _CdisplayProofClass CdisplayProofClass;
struct _CdisplayProof
@ -67,27 +67,23 @@ enum
};
GType cdisplay_proof_get_type (void);
GType cdisplay_proof_get_type (void);
static void cdisplay_proof_finalize (GObject *object);
static void cdisplay_proof_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void cdisplay_proof_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void cdisplay_proof_finalize (GObject *object);
static void cdisplay_proof_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec);
static void cdisplay_proof_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec);
static void cdisplay_proof_convert (GimpColorDisplay *display,
guchar *buf,
gint width,
gint height,
gint bpp,
gint bpl);
static GtkWidget * cdisplay_proof_configure (GimpColorDisplay *display);
static void cdisplay_proof_changed (GimpColorDisplay *display);
static void cdisplay_proof_convert_surface (GimpColorDisplay *display,
cairo_surface_t *surface);
static GtkWidget * cdisplay_proof_configure (GimpColorDisplay *display);
static void cdisplay_proof_changed (GimpColorDisplay *display);
static const GimpModuleInfo cdisplay_proof_info =
@ -123,9 +119,9 @@ cdisplay_proof_class_init (CdisplayProofClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GimpColorDisplayClass *display_class = GIMP_COLOR_DISPLAY_CLASS (klass);
object_class->finalize = cdisplay_proof_finalize;
object_class->get_property = cdisplay_proof_get_property;
object_class->set_property = cdisplay_proof_set_property;
object_class->finalize = cdisplay_proof_finalize;
object_class->get_property = cdisplay_proof_get_property;
object_class->set_property = cdisplay_proof_set_property;
GIMP_CONFIG_INSTALL_PROP_ENUM (object_class, PROP_INTENT,
"intent", NULL,
@ -141,13 +137,13 @@ cdisplay_proof_class_init (CdisplayProofClass *klass)
GIMP_CONFIG_PATH_FILE, NULL,
0);
display_class->name = _("Color Proof");
display_class->help_id = "gimp-colordisplay-proof";
display_class->stock_id = GIMP_STOCK_DISPLAY_FILTER_PROOF;
display_class->name = _("Color Proof");
display_class->help_id = "gimp-colordisplay-proof";
display_class->stock_id = GIMP_STOCK_DISPLAY_FILTER_PROOF;
display_class->convert = cdisplay_proof_convert;
display_class->configure = cdisplay_proof_configure;
display_class->changed = cdisplay_proof_changed;
display_class->convert_surface = cdisplay_proof_convert_surface;
display_class->configure = cdisplay_proof_configure;
display_class->changed = cdisplay_proof_changed;
cmsErrorAction (LCMS_ERROR_IGNORE);
}
@ -238,24 +234,55 @@ cdisplay_proof_set_property (GObject *object,
}
static void
cdisplay_proof_convert (GimpColorDisplay *display,
guchar *buf,
gint width,
gint height,
gint bpp,
gint bpl)
cdisplay_proof_convert_surface (GimpColorDisplay *display,
cairo_surface_t *surface)
{
CdisplayProof *proof = CDISPLAY_PROOF (display);
gint y;
CdisplayProof *proof = CDISPLAY_PROOF (display);
gint width = cairo_image_surface_get_width (surface);
gint height = cairo_image_surface_get_height (surface);
gint stride = cairo_image_surface_get_stride (surface);
guchar *buf = cairo_image_surface_get_data (surface);
cairo_format_t fmt = cairo_image_surface_get_format (surface);
guchar *rowbuf;
gint x, y;
guchar r, g, b, a;
if (bpp != 3)
if (fmt != CAIRO_FORMAT_ARGB32)
return;
if (! proof->transform)
return;
for (y = 0; y < height; y++, buf += bpl)
cmsDoTransform (proof->transform, buf, buf, width);
rowbuf = g_malloc (stride);
for (y = 0; y < height; y++, buf += stride)
{
/* Switch buf from ARGB premul to ARGB non-premul, since lcms ignores the
* alpha channel. The macro takes care of byte order.
*/
for (x = 0; x < width; x++)
{
GIMP_CAIRO_ARGB32_GET_PIXEL (buf + 4*x, r, g, b, a);
rowbuf[4*x+0] = a;
rowbuf[4*x+1] = r;
rowbuf[4*x+2] = g;
rowbuf[4*x+3] = b;
}
cmsDoTransform (proof->transform, rowbuf, rowbuf, width);
/* And back to ARGB premul */
for (x = 0; x < width; x++)
{
a = rowbuf[4*x+0];
r = rowbuf[4*x+1];
g = rowbuf[4*x+2];
b = rowbuf[4*x+3];
GIMP_CAIRO_ARGB32_SET_PIXEL (buf + 4*x, r, g, b, a);
}
}
g_free (rowbuf);
}
static void
@ -442,9 +469,8 @@ cdisplay_proof_changed (GimpColorDisplay *display)
if (proof->bpc)
flags |= cmsFLAGS_BLACKPOINTCOMPENSATION;
proof->transform = cmsCreateProofingTransform (rgbProfile,
TYPE_RGB_8,
rgbProfile, TYPE_RGB_8,
proof->transform = cmsCreateProofingTransform (rgbProfile, TYPE_ARGB_8,
rgbProfile, TYPE_ARGB_8,
proofProfile,
proof->intent,
proof->intent,

View File

@ -798,6 +798,15 @@
(return-type "GimpColorDisplay*")
)
(define-method convert_surface
(of-object "GimpColorDisplay")
(c-name "gimp_color_display_convert_surface")
(return-type "none")
(parameters
'("cairo_surface_t*" "surface")
)
)
(define-method convert
(of-object "GimpColorDisplay")
(c-name "gimp_color_display_convert")
@ -809,6 +818,7 @@
'("gint" "bpp")
'("gint" "bpl")
)
(deprecated "use convert_surface(cairo_surface_t*) instead")
)
(define-method load_state
@ -934,6 +944,15 @@
)
)
(define-method convert_surface
(of-object "GimpColorDisplayStack")
(c-name "gimp_color_display_stack_convert_surface")
(return-type "none")
(parameters
'("cairo_surface_t*" "surface")
)
)
(define-method convert
(of-object "GimpColorDisplayStack")
(c-name "gimp_color_display_stack_convert")
@ -945,6 +964,7 @@
'("gint" "bpp")
'("gint" "bpl")
)
(deprecated "use convert_surface(cairo_surface_t*) instead")
)