gimpcolortransform.c 20.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/* LIBGIMP - The GIMP Library
 * Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
 *
 * gimpcolortransform.c
 * Copyright (C) 2014  Michael Natterer <mitch@gimp.org>
 *                     Elle Stone <ellestone@ninedegreesbelow.com>
 *                     Øyvind Kolås <pippin@gimp.org>
 *
 * This library is free software: you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library.  If not, see
21
 * <https://www.gnu.org/licenses/>.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
 */

#include "config.h"

#include <string.h>

#include <lcms2.h>

#include <gio/gio.h>
#include <gegl.h>

#include "libgimpbase/gimpbase.h"
#include "libgimpconfig/gimpconfig.h"

#include "gimpcolortypes.h"

#include "gimpcolorprofile.h"
#include "gimpcolortransform.h"

#include "libgimp/libgimp-intl.h"


/**
 * SECTION: gimpcolortransform
 * @title: GimpColorTransform
 * @short_description: Definitions and Functions relating to LCMS.
 *
 * Definitions and Functions relating to LCMS.
 **/

/**
 * GimpColorTransform:
 *
 * Simply a typedef to #gpointer, but actually is a cmsHTRANSFORM. It's
 * used in public GIMP APIs in order to avoid having to include LCMS
 * headers.
 **/


enum
{
  PROGRESS,
  LAST_SIGNAL
};


struct _GimpColorTransformPrivate
{
  GimpColorProfile *src_profile;
  const Babl       *src_format;

  GimpColorProfile *dest_profile;
  const Babl       *dest_format;

  cmsHTRANSFORM     transform;
77
  const Babl       *fish;
78 79 80 81 82 83
};


static void   gimp_color_transform_finalize (GObject *object);


84 85
G_DEFINE_TYPE_WITH_PRIVATE (GimpColorTransform, gimp_color_transform,
                            G_TYPE_OBJECT)
86 87 88 89 90

#define parent_class gimp_color_transform_parent_class

static guint gimp_color_transform_signals[LAST_SIGNAL] = { 0 };

91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
static gchar *lcms_last_error = NULL;


static void
lcms_error_clear (void)
{
  if (lcms_last_error)
    {
      g_free (lcms_last_error);
      lcms_last_error = NULL;
    }
}

static void
lcms_error_handler (cmsContext       ContextID,
                    cmsUInt32Number  ErrorCode,
                    const gchar     *text)
{
  lcms_error_clear ();

  lcms_last_error = g_strdup_printf ("lcms2 error %d: %s", ErrorCode, text);
}
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131

static void
gimp_color_transform_class_init (GimpColorTransformClass *klass)
{
  GObjectClass *object_class = G_OBJECT_CLASS (klass);

  object_class->finalize = gimp_color_transform_finalize;

  gimp_color_transform_signals[PROGRESS] =
    g_signal_new ("progress",
                  G_OBJECT_CLASS_TYPE (object_class),
                  G_SIGNAL_RUN_FIRST,
                  G_STRUCT_OFFSET (GimpColorTransformClass,
                                   progress),
                  NULL, NULL,
                  g_cclosure_marshal_VOID__DOUBLE,
                  G_TYPE_NONE, 1,
                  G_TYPE_DOUBLE);

132
  cmsSetLogErrorHandler (lcms_error_handler);
133 134 135 136 137
}

static void
gimp_color_transform_init (GimpColorTransform *transform)
{
138
  transform->priv = gimp_color_transform_get_instance_private (transform);
139 140 141 142 143 144 145
}

static void
gimp_color_transform_finalize (GObject *object)
{
  GimpColorTransform *transform = GIMP_COLOR_TRANSFORM (object);

146 147
  g_clear_object (&transform->priv->src_profile);
  g_clear_object (&transform->priv->dest_profile);
148

149
  g_clear_pointer (&transform->priv->transform, cmsDeleteTransform);
150 151 152 153 154 155 156

  G_OBJECT_CLASS (parent_class)->finalize (object);
}


/**
 * gimp_color_transform_new:
157 158 159 160 161 162
 * @src_profile:      the source #GimpColorProfile
 * @src_format:       the source #Babl format
 * @dest_profile:     the destination #GimpColorProfile
 * @dest_format:      the destination #Babl format
 * @rendering_intent: the rendering intent
 * @flags:            transform flags
163 164 165
 *
 * This function creates an color transform.
 *
166 167 168 169 170 171 172 173 174 175 176 177 178 179
 * The color transform is determined exclusively by @src_profile and
 * @dest_profile. The color spaces of @src_format and @dest_format are
 * ignored, the formats are only used to decide between what pixel
 * encodings to transform.
 *
 * Note: this function used to return %NULL if
 * gimp_color_transform_can_gegl_copy() returned %TRUE for
 * @src_profile and @dest_profile. This is no longer the case because
 * special care has to be taken not to perform multiple implicit color
 * transforms caused by babl formats with color spaces. Now, it always
 * returns a non-%NULL transform and the code takes care of doing only
 * exactly the requested color transform.
 *
 * Return value: the #GimpColorTransform, or %NULL if there was an error.
180 181 182 183 184 185 186 187 188
 *
 * Since: 2.10
 **/
GimpColorTransform *
gimp_color_transform_new (GimpColorProfile         *src_profile,
                          const Babl               *src_format,
                          GimpColorProfile         *dest_profile,
                          const Babl               *dest_format,
                          GimpColorRenderingIntent  rendering_intent,
189
                          GimpColorTransformFlags   flags)
190 191 192 193 194 195 196
{
  GimpColorTransform        *transform;
  GimpColorTransformPrivate *priv;
  cmsHPROFILE                src_lcms;
  cmsHPROFILE                dest_lcms;
  cmsUInt32Number            lcms_src_format;
  cmsUInt32Number            lcms_dest_format;
197
  GError                    *error = NULL;
198 199 200 201 202 203 204 205 206 207

  g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (src_profile), NULL);
  g_return_val_if_fail (src_format != NULL, NULL);
  g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (dest_profile), NULL);
  g_return_val_if_fail (dest_format != NULL, NULL);

  transform = g_object_new (GIMP_TYPE_COLOR_TRANSFORM, NULL);

  priv = transform->priv;

208 209 210 211 212 213 214 215 216 217 218
  /* only src_profile and dest_profile must determine the transform's
   * color spaces, create formats with src_format's and dest_format's
   * encoding, and the profiles' color spaces; see process_pixels()
   * and process_buffer().
   */

  priv->src_format = gimp_color_profile_get_format (src_profile,
                                                    src_format,
                                                    BABL_ICC_INTENT_RELATIVE_COLORIMETRIC,
                                                    &error);
  if (! priv->src_format)
219 220 221 222 223 224
    {
      g_printerr ("%s: error making format: %s\n",
                  G_STRFUNC, error->message);
      g_clear_error (&error);
    }

225 226 227 228 229
  priv->dest_format = gimp_color_profile_get_format (dest_profile,
                                                     dest_format,
                                                     rendering_intent,
                                                     &error);
  if (! priv->dest_format)
230 231 232 233 234 235 236
    {
      g_printerr ("%s: error making format: %s\n",
                  G_STRFUNC, error->message);
      g_clear_error (&error);
    }

  if (! g_getenv ("GIMP_COLOR_TRANSFORM_DISABLE_BABL") &&
237
      priv->src_format && priv->dest_format)
238
    {
239 240
      priv->fish = babl_fish (priv->src_format,
                              priv->dest_format);
241 242 243 244 245

      g_printerr ("%s: using babl for '%s' -> '%s'\n",
                  G_STRFUNC,
                  gimp_color_profile_get_label (src_profile),
                  gimp_color_profile_get_label (dest_profile));
246

247 248 249
      return transform;
    }

250 251 252 253
  /* see above: when using lcms, don't mess with formats with color
   * spaces, gimp_color_profile_get_lcms_format() might return the
   * same format and it must be without space
   */
254 255
  src_format  = babl_format_with_space ((const gchar *) src_format,  NULL);
  dest_format = babl_format_with_space ((const gchar *) dest_format, NULL);
256

257 258 259 260
  priv->src_format  = gimp_color_profile_get_lcms_format (src_format,
                                                          &lcms_src_format);
  priv->dest_format = gimp_color_profile_get_lcms_format (dest_format,
                                                          &lcms_dest_format);
261

262 263 264
  src_lcms  = gimp_color_profile_get_lcms_profile (src_profile);
  dest_lcms = gimp_color_profile_get_lcms_profile (dest_profile);

265 266
  lcms_error_clear ();

267 268 269
  priv->transform = cmsCreateTransform (src_lcms,  lcms_src_format,
                                        dest_lcms, lcms_dest_format,
                                        rendering_intent,
270 271
                                        flags |
                                        cmsFLAGS_COPY_ALPHA);
272

273 274 275 276 277 278 279 280
  if (lcms_last_error)
    {
      if (priv->transform)
        {
          cmsDeleteTransform (priv->transform);
          priv->transform = NULL;
        }

281
      g_printerr ("%s: %s\n", G_STRFUNC, lcms_last_error);
282 283
    }

284 285 286 287 288 289
  if (! priv->transform)
    {
      g_object_unref (transform);
      transform = NULL;
    }

290 291 292 293 294
  return transform;
}

/**
 * gimp_color_transform_new_proofing:
295 296 297 298 299 300 301 302
 * @src_profile:    the source #GimpColorProfile
 * @src_format:     the source #Babl format
 * @dest_profile:   the destination #GimpColorProfile
 * @dest_format:    the destination #Babl format
 * @proof_profile:  the proof #GimpColorProfile
 * @proof_intent:   the proof intent
 * @display_intent: the display intent
 * @flags:          transform flags
303 304 305
 *
 * This function creates a simulation / proofing color transform.
 *
306 307 308 309
 * See gimp_color_transform_new() about the color spaces to transform
 * between.
 *
 * Return value: the #GimpColorTransform, or %NULL if there was an error.
310 311 312 313 314 315 316 317 318 319 320
 *
 * Since: 2.10
 **/
GimpColorTransform *
gimp_color_transform_new_proofing (GimpColorProfile         *src_profile,
                                   const Babl               *src_format,
                                   GimpColorProfile         *dest_profile,
                                   const Babl               *dest_format,
                                   GimpColorProfile         *proof_profile,
                                   GimpColorRenderingIntent  proof_intent,
                                   GimpColorRenderingIntent  display_intent,
321
                                   GimpColorTransformFlags   flags)
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344
{
  GimpColorTransform        *transform;
  GimpColorTransformPrivate *priv;
  cmsHPROFILE                src_lcms;
  cmsHPROFILE                dest_lcms;
  cmsHPROFILE                proof_lcms;
  cmsUInt32Number            lcms_src_format;
  cmsUInt32Number            lcms_dest_format;

  g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (src_profile), NULL);
  g_return_val_if_fail (src_format != NULL, NULL);
  g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (dest_profile), NULL);
  g_return_val_if_fail (dest_format != NULL, NULL);
  g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (proof_profile), NULL);

  transform = g_object_new (GIMP_TYPE_COLOR_TRANSFORM, NULL);

  priv = transform->priv;

  src_lcms   = gimp_color_profile_get_lcms_profile (src_profile);
  dest_lcms  = gimp_color_profile_get_lcms_profile (dest_profile);
  proof_lcms = gimp_color_profile_get_lcms_profile (proof_profile);

345 346 347
  /* see gimp_color_transform_new(), we can't have color spaces
   * on the formats
   */
348 349
  src_format  = babl_format_with_space ((const gchar *) src_format,  NULL);
  dest_format = babl_format_with_space ((const gchar *) dest_format, NULL);
350

351 352 353 354
  priv->src_format  = gimp_color_profile_get_lcms_format (src_format,
                                                          &lcms_src_format);
  priv->dest_format = gimp_color_profile_get_lcms_format (dest_format,
                                                          &lcms_dest_format);
355

356 357
  lcms_error_clear ();

358 359 360 361 362
  priv->transform = cmsCreateProofingTransform (src_lcms,  lcms_src_format,
                                                dest_lcms, lcms_dest_format,
                                                proof_lcms,
                                                proof_intent,
                                                display_intent,
363 364 365
                                                flags                 |
                                                cmsFLAGS_SOFTPROOFING |
                                                cmsFLAGS_COPY_ALPHA);
366

367 368 369 370 371 372 373 374
  if (lcms_last_error)
    {
      if (priv->transform)
        {
          cmsDeleteTransform (priv->transform);
          priv->transform = NULL;
        }

375
      g_printerr ("%s: %s\n", G_STRFUNC, lcms_last_error);
376 377
    }

378 379 380 381 382 383
  if (! priv->transform)
    {
      g_object_unref (transform);
      transform = NULL;
    }

384 385 386 387 388
  return transform;
}

/**
 * gimp_color_transform_process_pixels:
389 390 391 392 393 394
 * @transform:   a #GimpColorTransform
 * @src_format:  #Babl format of @src_pixels
 * @src_pixels:  pointer to the source pixels
 * @dest_format: #Babl format of @dest_pixels
 * @dest_pixels: pointer to the destination pixels
 * @length:      number of pixels to process
395 396 397
 *
 * This function transforms a contiguous line of pixels.
 *
398 399 400 401 402
 * See gimp_color_transform_new(): only the pixel encoding of
 * @src_format and @dest_format is honored, their color spaces are
 * ignored. The transform always takes place between the color spaces
 * determined by @transform's color profiles.
 *
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424
 * Since: 2.10
 **/
void
gimp_color_transform_process_pixels (GimpColorTransform *transform,
                                     const Babl         *src_format,
                                     gconstpointer       src_pixels,
                                     const Babl         *dest_format,
                                     gpointer            dest_pixels,
                                     gsize               length)
{
  GimpColorTransformPrivate *priv;
  gpointer                  *src;
  gpointer                  *dest;

  g_return_if_fail (GIMP_IS_COLOR_TRANSFORM (transform));
  g_return_if_fail (src_format != NULL);
  g_return_if_fail (src_pixels != NULL);
  g_return_if_fail (dest_format != NULL);
  g_return_if_fail (dest_pixels != NULL);

  priv = transform->priv;

425 426 427 428 429 430
  /* we must not do any babl color transforms when reading from
   * src_pixels or writing to dest_pixels, so construct formats with
   * src_format's and dest_format's encoding, and the transform's
   * input and output color spaces.
   */
  src_format =
431
    babl_format_with_space ((const gchar *) src_format,
432 433
                            babl_format_get_space (priv->src_format));
  dest_format =
434
    babl_format_with_space ((const gchar *) dest_format,
435 436
                            babl_format_get_space (priv->dest_format));

437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
  if (src_format != priv->src_format)
    {
      src = g_malloc (length * babl_format_get_bytes_per_pixel (priv->src_format));

      babl_process (babl_fish (src_format,
                               priv->src_format),
                    src_pixels, src, length);
    }
  else
    {
      src = (gpointer) src_pixels;
    }

  if (dest_format != priv->dest_format)
    {
      dest = g_malloc (length * babl_format_get_bytes_per_pixel (priv->dest_format));
    }
  else
    {
      dest = dest_pixels;
    }

459 460 461 462 463 464
  if (priv->transform)
    {
      cmsDoTransform (priv->transform, src, dest, length);
    }
  else
    {
465
      babl_process (priv->fish, src, dest, length);
466
    }
467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484

  if (src_format != priv->src_format)
    {
      g_free (src);
    }

  if (dest_format != priv->dest_format)
    {
      babl_process (babl_fish (priv->dest_format,
                               dest_format),
                    dest, dest_pixels, length);

      g_free (dest);
    }
}

/**
 * gimp_color_transform_process_buffer:
485 486 487 488 489
 * @transform:   a #GimpColorTransform
 * @src_buffer:  source #GeglBuffer
 * @src_rect:    rectangle in @src_buffer
 * @dest_buffer: destination #GeglBuffer
 * @dest_rect:   rectangle in @dest_buffer
490
 *
491
 * This function transforms buffer into another buffer.
492
 *
493 494 495 496 497
 * See gimp_color_transform_new(): only the pixel encoding of
 * @src_buffer's and @dest_buffer's formats honored, their color
 * spaces are ignored. The transform always takes place between the
 * color spaces determined by @transform's color profiles.
 *
498 499 500 501 502 503 504 505 506 507
 * Since: 2.10
 **/
void
gimp_color_transform_process_buffer (GimpColorTransform  *transform,
                                     GeglBuffer          *src_buffer,
                                     const GeglRectangle *src_rect,
                                     GeglBuffer          *dest_buffer,
                                     const GeglRectangle *dest_rect)
{
  GimpColorTransformPrivate *priv;
508 509
  const Babl                *src_format;
  const Babl                *dest_format;
510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
  GeglBufferIterator        *iter;
  gint                       total_pixels;
  gint                       done_pixels = 0;

  g_return_if_fail (GIMP_IS_COLOR_TRANSFORM (transform));
  g_return_if_fail (GEGL_IS_BUFFER (src_buffer));
  g_return_if_fail (GEGL_IS_BUFFER (dest_buffer));

  priv = transform->priv;

  if (src_rect)
    {
      total_pixels = src_rect->width * src_rect->height;
    }
  else
    {
      total_pixels = (gegl_buffer_get_width  (src_buffer) *
                      gegl_buffer_get_height (src_buffer));
    }

530 531
  /* we must not do any babl color transforms when reading from
   * src_buffer or writing to dest_buffer, so construct formats with
532 533
   * the transform's expected input and output encoding and
   * src_buffer's and dest_buffers's color spaces.
534 535 536 537 538
   */
  src_format  = gegl_buffer_get_format (src_buffer);
  dest_format = gegl_buffer_get_format (dest_buffer);

  src_format =
539
    babl_format_with_space ((const gchar *) priv->src_format,
540
                            babl_format_get_space (src_format));
541
  dest_format =
542
    babl_format_with_space ((const gchar *) priv->dest_format,
543
                            babl_format_get_space (dest_format));
544

545 546 547
  if (src_buffer != dest_buffer)
    {
      iter = gegl_buffer_iterator_new (src_buffer, src_rect, 0,
548
                                       src_format,
549
                                       GEGL_ACCESS_READ,
550
                                       GEGL_ABYSS_NONE, 2);
551

552
      gegl_buffer_iterator_add (iter, dest_buffer, dest_rect, 0,
553
                                dest_format,
554 555
                                GEGL_ACCESS_WRITE,
                                GEGL_ABYSS_NONE);
556

557 558
      while (gegl_buffer_iterator_next (iter))
        {
559 560 561
          if (priv->transform)
            {
              cmsDoTransform (priv->transform,
562
                              iter->items[0].data, iter->items[1].data, iter->length);
563 564 565
            }
          else
            {
566
              babl_process (priv->fish,
567
                            iter->items[0].data, iter->items[1].data, iter->length);
568
            }
569

570
          done_pixels += iter->items[0].roi.width * iter->items[0].roi.height;
571

572 573 574 575 576 577 578 579
          g_signal_emit (transform, gimp_color_transform_signals[PROGRESS], 0,
                         (gdouble) done_pixels /
                         (gdouble) total_pixels);
        }
    }
  else
    {
      iter = gegl_buffer_iterator_new (src_buffer, src_rect, 0,
580
                                       src_format,
581
                                       GEGL_ACCESS_READWRITE,
582
                                       GEGL_ABYSS_NONE, 1);
583 584 585

      while (gegl_buffer_iterator_next (iter))
        {
586 587 588
          if (priv->transform)
            {
              cmsDoTransform (priv->transform,
589
                              iter->items[0].data, iter->items[0].data, iter->length);
590 591 592
            }
          else
            {
593
              babl_process (priv->fish,
594
                            iter->items[0].data, iter->items[0].data, iter->length);
595
            }
596

597
          done_pixels += iter->items[0].roi.width * iter->items[0].roi.height;
598 599 600 601 602

          g_signal_emit (transform, gimp_color_transform_signals[PROGRESS], 0,
                         (gdouble) done_pixels /
                         (gdouble) total_pixels);
        }
603 604 605 606 607
    }

  g_signal_emit (transform, gimp_color_transform_signals[PROGRESS], 0,
                 1.0);
}
608 609 610

/**
 * gimp_color_transform_can_gegl_copy:
611 612
 * @src_profile:  source #GimpColorProfile
 * @dest_profile: destination #GimpColorProfile
613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631
 *
 * This function checks if a GimpColorTransform is needed at all.
 *
 * Return value: %TRUE if pixels can be correctly converted between
 *               @src_profile and @dest_profile by simply using
 *               gegl_buffer_copy(), babl_process() or similar.
 *
 * Since: 2.10
 **/
gboolean
gimp_color_transform_can_gegl_copy (GimpColorProfile *src_profile,
                                    GimpColorProfile *dest_profile)
{
  g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (src_profile), FALSE);
  g_return_val_if_fail (GIMP_IS_COLOR_PROFILE (dest_profile), FALSE);

  if (gimp_color_profile_is_equal (src_profile, dest_profile))
    return TRUE;

632 633 634 635 636 637
  if (gimp_color_profile_get_space (src_profile,
                                    GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC,
                                    NULL) &&
      gimp_color_profile_get_space (dest_profile,
                                    GIMP_COLOR_RENDERING_INTENT_RELATIVE_COLORIMETRIC,
                                    NULL))
638 639 640 641 642 643
    {
      return TRUE;
    }

  return FALSE;
}