From f78dec232a643c4b44ac849f1889ba80a4db470e Mon Sep 17 00:00:00 2001 From: Elle Stone Date: Mon, 21 Sep 2015 14:40:04 -0400 Subject: [PATCH] Bug 755270 - Decompose/Compose LAB: scaling code produces odd L, a, and b values Decompose/compose to/from LCH: remove unconditional CLAMP (only clamp if the component really needs clamping), change LAB AB range. --- plug-ins/common/compose.c | 15 +++++++++++-- plug-ins/common/decompose.c | 45 ++++++++++++++++++++++++++++--------- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/plug-ins/common/compose.c b/plug-ins/common/compose.c index e8c0fb96f0..b1bfd52dbf 100644 --- a/plug-ins/common/compose.c +++ b/plug-ins/common/compose.c @@ -173,8 +173,12 @@ static void type_combo_callback (GimpIntComboBox *combo, #define CPN_CMY_Y {"yellow", N_("_Yellow:"), NULL, 0.0, 1.0, TRUE} #define CPN_LAB_L {"CIE L", N_("_L:"), NULL, 0.0, 100.0, TRUE} -#define CPN_LAB_A {"CIE a", N_("_A:"), NULL, -128.0, 127.0, TRUE} -#define CPN_LAB_B {"CIE b", N_("_B:"), NULL, -128.0, 127.0, TRUE} +#define CPN_LAB_A {"CIE a", N_("_A:"), NULL, -127.5, 127.5, TRUE} +#define CPN_LAB_B {"CIE b", N_("_B:"), NULL, -127.5, 127.5, TRUE} + +#define CPN_LCH_L {"CIE L", N_("_L"), NULL, 0.0, 100.0, TRUE} +#define CPN_LCH_C {"CIE C(ab)", N_("_C"), NULL, 0.0, 200.0, TRUE} +#define CPN_LCH_H {"CIE H(ab)", N_("_H"), NULL, 0.0, 360.0, TRUE} #define CPN_YCBCR_Y {"Y'", N_("_Luma y470:"), NULL, 0.0, 1.0, TRUE} #define CPN_YCBCR_CB {"Cb", N_("_Blueness cb470:"), NULL, -0.5, 0.5, TRUE} @@ -238,6 +242,13 @@ static COMPOSE_DSC compose_dsc[] = CPN_LAB_B }, "lab-compose" }, + { "CIE LCH(ab)", + N_("LCH"), 3, + { CPN_LCH_L, + CPN_LCH_C, + CPN_LCH_H }, + "lch-compose" }, + { "Y'CbCr", N_("YCbCr_ITU_R470"), 3, { CPN_YCBCR_Y, diff --git a/plug-ins/common/decompose.c b/plug-ins/common/decompose.c index 59c8524c95..7bcb2f0e2b 100644 --- a/plug-ins/common/decompose.c +++ b/plug-ins/common/decompose.c @@ -121,7 +121,8 @@ static void transfer_registration_color (GeglBuffer *src, gint count); static void cpn_affine_transform_clamp (GeglBuffer *buffer, gdouble min, - gdouble max); + gdouble max, + gboolean clamp); static void copy_n_components (GeglBuffer *src, GeglBuffer **dst, EXTRACT ext); @@ -159,8 +160,12 @@ static gchar * generate_filename (guint32 image_ID, #define CPN_CMY_Y {"yellow", N_("yellow"), 0.0, 1.0, TRUE} #define CPN_LAB_L {"CIE L", N_("L"), 0.0, 100.0, TRUE} -#define CPN_LAB_A {"CIE a", N_("A"), -128.0, 127.0, TRUE} -#define CPN_LAB_B {"CIE b", N_("B"), -128.0, 127.0, TRUE} +#define CPN_LAB_A {"CIE a", N_("A"), -127.5, 127.5, TRUE} +#define CPN_LAB_B {"CIE b", N_("B"), -127.5, 127.5, TRUE} + +#define CPN_LCH_L {"CIE L", N_("L"), 0.0, 100.0, TRUE} +#define CPN_LCH_C {"CIE C(ab)", N_("C"), 0.0, 200.0, TRUE} +#define CPN_LCH_H {"CIE H(ab)", N_("H"), 0.0, 360.0, TRUE} #define CPN_YCBCR_Y {"Y'", N_("luma-y470"), 0.0, 1.0, TRUE} #define CPN_YCBCR_CB {"Cb", N_("blueness-cb470"), -0.5, 0.5, TRUE} @@ -202,6 +207,8 @@ static const EXTRACT extract[] = { N_("LAB"), "CIE Lab", TRUE, 3, FALSE, {CPN_LAB_L, CPN_LAB_A, CPN_LAB_B} }, + { N_("LCH"), "CIE LCH(ab)", TRUE, 3, FALSE, {CPN_LCH_L, CPN_LCH_C, CPN_LCH_H} }, + { N_("YCbCr_ITU_R470"), "Y'CbCr", TRUE, 3, FALSE, { CPN_YCBCR_Y, CPN_YCBCR_CB, CPN_YCBCR_CR} }, { N_("YCbCr_ITU_R470_256"), "Y'CbCr", TRUE, 3, TRUE, { CPN_YCBCR_Y, CPN_YCBCR_CB, CPN_YCBCR_CR} }, @@ -672,12 +679,12 @@ transfer_registration_color (GeglBuffer *src, static void cpn_affine_transform_clamp (GeglBuffer *buffer, gdouble min, - gdouble max) + gdouble max, + gboolean clamp) { GeglBufferIterator *gi; - - gdouble scale = 1.0 / (max - min); - gdouble offset = - min; + gdouble scale = 1.0 / (max - min); + gdouble offset = - min; /* We want to scale values linearly, regardless of the format of the buffer */ gegl_buffer_set_format (buffer, babl_format ("Y double")); @@ -692,9 +699,19 @@ cpn_affine_transform_clamp (GeglBuffer *buffer, data = (double*) gi->data[0]; - for (k = 0; k < gi->length; k++) + if (clamp) { - data[k] = CLAMP ((data[k] + offset) * scale, 0.0, 1.0); + for (k = 0; k < gi->length; k++) + { + data[k] = CLAMP ((data[k] + offset) * scale, 0.0, 1.0); + } + } + else + { + for (k = 0; k < gi->length; k++) + { + data[k] = (data[k] + offset) * scale; + } } } } @@ -747,8 +764,14 @@ copy_one_component (GeglBuffer *src, gegl_buffer_set_format (temp, component_format); gegl_buffer_copy (src, NULL, GEGL_ABYSS_NONE, temp, NULL); - if (component.range_min != 0.0 || component.range_max != 1.0 || clamp) - cpn_affine_transform_clamp (temp, component.range_min, component.range_max); + if (component.range_min != 0.0 || + component.range_max != 1.0 || + clamp) + { + cpn_affine_transform_clamp (temp, + component.range_min, component.range_max, + clamp); + } /* This is our new "Y(') double" component buffer */ gegl_buffer_set_format (temp, NULL);