Ejemplo n.º 1
0
static GimpValueArray *
image_set_color_profile_invoker (GimpProcedure         *procedure,
                                 Gimp                  *gimp,
                                 GimpContext           *context,
                                 GimpProgress          *progress,
                                 const GimpValueArray  *args,
                                 GError               **error)
{
  gboolean success = TRUE;
  GimpImage *image;
  gint32 num_bytes;
  const guint8 *color_profile;

  image = gimp_value_get_image (gimp_value_array_index (args, 0), gimp);
  num_bytes = g_value_get_int (gimp_value_array_index (args, 1));
  color_profile = gimp_value_get_int8array (gimp_value_array_index (args, 2));

  if (success)
    {
      if (color_profile)
        {
          GimpColorProfile *profile;

          profile = gimp_color_profile_new_from_icc_profile (color_profile,
                                                             num_bytes,
                                                             error);

          if (profile)
            {
              success = gimp_image_set_color_profile (image, profile, error);
              g_object_unref (profile);
            }
          else
            success = FALSE;
        }
      else
        {
          success = gimp_image_set_color_profile (image, NULL, error);
        }
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}
Ejemplo n.º 2
0
static GimpValueArray *
image_set_color_profile_from_file_invoker (GimpProcedure         *procedure,
                                           Gimp                  *gimp,
                                           GimpContext           *context,
                                           GimpProgress          *progress,
                                           const GimpValueArray  *args,
                                           GError               **error)
{
  gboolean success = TRUE;
  GimpImage *image;
  const gchar *uri;

  image = gimp_value_get_image (gimp_value_array_index (args, 0), gimp);
  uri = g_value_get_string (gimp_value_array_index (args, 1));

  if (success)
    {
      if (uri)
        {
          GFile            *file = g_file_new_for_uri (uri);
          GimpColorProfile *profile;

          profile = gimp_color_profile_new_from_file (file, error);

          if (profile)
            {
              success = gimp_image_set_color_profile (image, profile, error);
              g_object_unref (profile);
            }
          else
            success = FALSE;

          g_object_unref (file);
        }
      else
        {
          success = gimp_image_set_color_profile (image, NULL, error);
        }
    }

  return gimp_procedure_get_return_values (procedure, success,
                                           error ? *error : NULL);
}
Ejemplo n.º 3
0
gboolean
gimp_image_convert_color_profile (GimpImage                *image,
                                  GimpColorProfile         *dest_profile,
                                  GimpColorRenderingIntent  intent,
                                  gboolean                  bpc,
                                  GimpProgress             *progress,
                                  GError                  **error)
{
  GimpColorProfile *src_profile;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
  g_return_val_if_fail (dest_profile != NULL, FALSE);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (! gimp_image_validate_color_profile (image, dest_profile, NULL, error))
    return FALSE;

  src_profile = gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (image));

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

  if (progress)
    gimp_progress_start (progress, FALSE,
                         _("Converting from '%s' to '%s'"),
                         gimp_color_profile_get_label (src_profile),
                         gimp_color_profile_get_label (dest_profile));

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_CONVERT,
                               _("Color profile conversion"));

  gimp_image_set_color_profile (image, dest_profile, NULL);
  /*  omg...  */
  gimp_image_parasite_detach (image, "icc-profile-name");

  switch (gimp_image_get_base_type (image))
    {
    case GIMP_RGB:
      gimp_image_convert_profile_rgb (image,
                                      src_profile, dest_profile,
                                      intent, bpc,
                                      progress);
      break;

    case GIMP_GRAY:
      break;

    case GIMP_INDEXED:
      gimp_image_convert_profile_indexed (image,
                                          src_profile, dest_profile,
                                          intent, bpc,
                                          progress);
      break;
    }

  gimp_image_undo_group_end (image);

  if (progress)
    gimp_progress_end (progress);

  return TRUE;
}
Ejemplo n.º 4
0
static void
color_profile_dialog_response (GtkWidget     *widget,
                               gint           response_id,
                               ProfileDialog *dialog)
{
  gboolean  success = TRUE;
  GError   *error   = NULL;

  if (response_id == GTK_RESPONSE_OK)
    {
      GimpColorProfile *dest_profile = NULL;
      GFile            *file;

      file = gimp_color_profile_combo_box_get_active_file (GIMP_COLOR_PROFILE_COMBO_BOX (dialog->combo));

      if (file)
        {
          dest_profile = gimp_color_profile_new_from_file (file, &error);

          if (! dest_profile)
            success = FALSE;

          g_object_unref (file);
        }
      else
        {
          dest_profile = g_object_ref (dialog->builtin_profile);
        }

      if (success)
        {
          switch (dialog->dialog_type)
            {
            case COLOR_PROFILE_DIALOG_ASSIGN_PROFILE:
              {
                gimp_image_undo_group_start (dialog->image,
                                             GIMP_UNDO_GROUP_PARASITE_ATTACH,
                                             _("Assign color profile"));

                success = gimp_image_set_color_profile (dialog->image,
                                                        dest_profile,
                                                        &error);

                if (success)
                  {
                    gimp_image_set_is_color_managed (dialog->image, TRUE, TRUE);

                    /*  omg...  */
                    gimp_image_parasite_detach (dialog->image,
                                                "icc-profile-name");
                  }

                gimp_image_undo_group_end (dialog->image);

                if (! success)
                  gimp_image_undo (dialog->image);
              }
              break;

            case COLOR_PROFILE_DIALOG_CONVERT_TO_PROFILE:
              {
                GimpProgress *progress;
                const gchar  *label;

                label = gimp_color_profile_get_label (dest_profile);

                progress = gimp_progress_start (dialog->progress, FALSE,
                                                _("Converting to '%s'"), label);

                success = gimp_image_convert_color_profile (dialog->image,
                                                            dest_profile,
                                                            dialog->intent,
                                                            dialog->bpc,
                                                            progress,
                                                            &error);

                if (progress)
                  gimp_progress_end (progress);

                if (success)
                  {
                    saved_intent = dialog->intent;
                    saved_bpc    = dialog->bpc;
                  }
              }
              break;

            case COLOR_PROFILE_DIALOG_CONVERT_TO_RGB:
              {
                GimpProgress *progress;
                const gchar  *label;

                label = gimp_color_profile_get_label (dest_profile);

                progress = gimp_progress_start (dialog->progress, FALSE,
                                                _("Converting to RGB (%s)"),
                                                label);

                success = gimp_image_convert_type (dialog->image,
                                                   GIMP_RGB,
                                                   dest_profile,
                                                   progress,
                                                   &error);

                if (progress)
                  gimp_progress_end (progress);
              }
              break;

            case COLOR_PROFILE_DIALOG_CONVERT_TO_GRAY:
              {
                GimpProgress *progress;
                const gchar  *label;

                label = gimp_color_profile_get_label (dest_profile);

                progress = gimp_progress_start (dialog->progress, FALSE,
                                                _("Converting to grayscale (%s)"),
                                                label);

                success = gimp_image_convert_type (dialog->image,
                                                   GIMP_GRAY,
                                                   dest_profile,
                                                   progress,
                                                   &error);

                if (progress)
                  gimp_progress_end (progress);
              }
              break;
            }

          if (success)
            gimp_image_flush (dialog->image);

          g_object_unref (dest_profile);
        }
    }

  if (success)
    {
      gtk_widget_destroy (dialog->dialog);
    }
  else
    {
      gimp_message (dialog->image->gimp, G_OBJECT (dialog->dialog),
                    GIMP_MESSAGE_ERROR,
                    "%s", error->message);
      g_clear_error (&error);
    }
}
Ejemplo n.º 5
0
gboolean load_image(const gchar *filename,
                    gint32      *image_ID,
                    GError     **error)
{
    gboolean              status      = FALSE;
    gchar                *indata      = NULL;
    gsize                 indatalen;
    gint                  width;
    gint                  height;
    WebPMux              *mux         = NULL;
    WebPData              wp_data;
    uint32_t              flags;
    uint8_t              *outdata     = NULL;

#ifdef GIMP_2_9
    /* Initialize GEGL */
    gegl_init(NULL, NULL);
#endif

    do {

        /* Attempt to read the file contents from disk */
        if (g_file_get_contents(filename,
                                &indata,
                                &indatalen,
                                error) == FALSE) {
            break;
        }

        /* Validate WebP data, grabbing the width and height */
        if (!WebPGetInfo(indata, indatalen, &width, &height)) {
            break;
        }

        /* Create a WebPMux from the contents of the file */
        wp_data.bytes = (uint8_t*)indata;
        wp_data.size = indatalen;

        mux = WebPMuxCreate(&wp_data, 1);
        if (mux == NULL) {
            break;
        }

        /* Retrieve the features present */
        if (WebPMuxGetFeatures(mux, &flags) != WEBP_MUX_OK) {
            break;
        }

        /* TODO: decode the image in "chunks" or "tiles" */
        /* TODO: check if an alpha channel is present */

        /* Create the new image and associated layer */
        *image_ID = gimp_image_new(width, height, GIMP_RGB);

#ifdef WEBP_0_5
        if (flags & ANIMATION_FLAG) {
            int frames, i;

            /* Retrieve the number of frames */
            WebPMuxNumChunks(mux, WEBP_CHUNK_ANMF, &frames);

            /* Loop over each of the frames */
            for (i = 0; i < frames; ++i) {
                WebPMuxFrameInfo frame = {0};

                /* Retrieve the data for the frame */
                if (WebPMuxGetFrame(mux, i, &frame) != WEBP_MUX_OK) {
                    goto error;
                }

                /* Decode the frame */
                outdata = WebPDecodeRGBA(frame.bitstream.bytes,
                                         frame.bitstream.size,
                                         &width, &height);

                /* Free the compressed data */
                WebPDataClear(&frame.bitstream);

                if (!outdata) {
                    goto error;
                }

                /* Create a layer for the frame */
                char name[255];
                snprintf(name, 255, "Frame %d", (i + 1));

                if (create_layer(*image_ID,
                                 outdata,
                                 0,
                                 (gchar*)name,
                                 width, height,
                                 frame.x_offset,
                                 frame.y_offset) == FALSE) {
                    goto error;
                }
            }

            /* If all is well, jump *over* the error label - otherwise
               leave the loop and begin cleaning things up */

            goto success;

        error:
            break;

        success: ;

        } else {
#endif

            /* Attempt to decode the data as a WebP image */
            outdata = WebPDecodeRGBA(indata, indatalen, &width, &height);
            if (!outdata) {
                break;
            }

            /* Create a single layer */
            status = create_layer(*image_ID,
                                  outdata,
                                  0,
                                  "Background",
                                  width, height,
                                  0, 0);

#ifdef WEBP_0_5
        }

#ifdef GIMP_2_9
        /* Load a color profile if one was provided */
        if (flags & ICCP_FLAG) {
            WebPData          icc_profile;
            GimpColorProfile *profile;

            /* Load the ICC profile from the file */
            WebPMuxGetChunk(mux, "ICCP", &icc_profile);

            /* Have Gimp load the color profile */
            profile = gimp_color_profile_new_from_icc_profile(
                        icc_profile.bytes, icc_profile.size, NULL);
            if (profile) {
                gimp_image_set_color_profile(image_ID, profile);
                g_object_unref(profile);
            }
        }
#endif
#endif
        /* Set the filename for the image */
        gimp_image_set_filename(*image_ID, filename);

    } while(0);

    /* Delete the mux object */
    if (mux) {
        WebPMuxDelete(mux);
    }

    /* Free the data read from disk */
    if (indata) {
        g_free(indata);
    }

    return status;
}
Ejemplo n.º 6
0
void
gimp_image_convert_precision (GimpImage     *image,
                              GimpPrecision  precision,
                              gint           layer_dither_type,
                              gint           text_layer_dither_type,
                              gint           mask_dither_type,
                              GimpProgress  *progress)
{
  GimpColorProfile *old_profile;
  GimpColorProfile *new_profile = NULL;
  const Babl       *old_format;
  const Babl       *new_format;
  GList            *all_drawables;
  GList            *list;
  const gchar      *undo_desc    = NULL;
  GimpProgress     *sub_progress = NULL;
  gint              nth_drawable, n_drawables;

  g_return_if_fail (GIMP_IS_IMAGE (image));
  g_return_if_fail (precision != gimp_image_get_precision (image));
  g_return_if_fail (precision == GIMP_PRECISION_U8_GAMMA ||
                    gimp_image_get_base_type (image) != GIMP_INDEXED);
  g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress));

  all_drawables = g_list_concat (gimp_image_get_layer_list (image),
                                 gimp_image_get_channel_list (image));

  n_drawables = g_list_length (all_drawables) + 1 /* + selection */;

  if (progress)
    sub_progress = gimp_sub_progress_new (progress);

  switch (precision)
    {
    case GIMP_PRECISION_U8_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 8 bit linear integer");
      break;
    case GIMP_PRECISION_U8_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 8 bit gamma integer");
      break;
    case GIMP_PRECISION_U16_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 16 bit linear integer");
      break;
    case GIMP_PRECISION_U16_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 16 bit gamma integer");
      break;
    case GIMP_PRECISION_U32_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 32 bit linear integer");
      break;
    case GIMP_PRECISION_U32_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 32 bit gamma integer");
      break;
    case GIMP_PRECISION_HALF_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 16 bit linear floating point");
      break;
    case GIMP_PRECISION_HALF_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 16 bit gamma floating point");
      break;
    case GIMP_PRECISION_FLOAT_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 32 bit linear floating point");
      break;
    case GIMP_PRECISION_FLOAT_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 32 bit gamma floating point");
      break;
    case GIMP_PRECISION_DOUBLE_LINEAR:
      undo_desc = C_("undo-type", "Convert Image to 64 bit linear floating point");
      break;
    case GIMP_PRECISION_DOUBLE_GAMMA:
      undo_desc = C_("undo-type", "Convert Image to 64 bit gamma floating point");
      break;
    }

  if (progress)
    gimp_progress_start (progress, FALSE, "%s", undo_desc);

  g_object_freeze_notify (G_OBJECT (image));

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_CONVERT,
                               undo_desc);

  /*  Push the image precision to the stack  */
  gimp_image_undo_push_image_precision (image, NULL);

  old_profile = gimp_image_get_color_profile (image);
  old_format  = gimp_image_get_layer_format (image, FALSE);

  /*  Set the new precision  */
  g_object_set (image, "precision", precision, NULL);

  new_format = gimp_image_get_layer_format (image, FALSE);

  if (old_profile &&
      gimp_babl_format_get_linear (old_format) !=
      gimp_babl_format_get_linear (new_format))
    {
      GimpColorProfile *new_profile;

      /* when converting between linear and gamma, we create a new
       * profile using the original profile's chromacities and
       * whitepoint, but a linear/sRGB-gamma TRC.
       */

      if (gimp_babl_format_get_linear (new_format))
        {
          new_profile =
            gimp_color_profile_new_linear_from_color_profile (old_profile);
        }
      else
        {
          new_profile =
            gimp_color_profile_new_srgb_trc_from_color_profile (old_profile);
        }

      /* if a new profile cannot be be generated, convert to the
       * builtin profile, which is better than leaving the user with
       * broken colors
       */
      if (! new_profile)
        {
          new_profile = gimp_image_get_builtin_color_profile (image);
          g_object_ref (new_profile);
        }
    }

  for (list = all_drawables, nth_drawable = 0;
       list;
       list = g_list_next (list), nth_drawable++)
    {
      GimpDrawable *drawable = list->data;
      gint          dither_type;

      if (gimp_item_is_text_layer (GIMP_ITEM (drawable)))
        dither_type = text_layer_dither_type;
      else
        dither_type = layer_dither_type;

      if (sub_progress)
        gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (sub_progress),
                                    nth_drawable, n_drawables);

      gimp_drawable_convert_type (drawable, image,
                                  gimp_drawable_get_base_type (drawable),
                                  precision,
                                  new_profile,
                                  dither_type,
                                  mask_dither_type,
                                  TRUE, sub_progress);
    }

  g_list_free (all_drawables);

  if (old_profile)
    {
      gimp_image_set_color_profile (image, new_profile, NULL);
      g_object_unref (new_profile);
    }

  /*  convert the selection mask  */
  {
    GimpChannel *mask = gimp_image_get_mask (image);
    GeglBuffer  *buffer;

    if (sub_progress)
      gimp_sub_progress_set_step (GIMP_SUB_PROGRESS (sub_progress),
                                  nth_drawable, n_drawables);

    gimp_image_undo_push_mask_precision (image, NULL, mask);

    buffer = gegl_buffer_new (GEGL_RECTANGLE (0, 0,
                                              gimp_image_get_width  (image),
                                              gimp_image_get_height (image)),
                              gimp_image_get_mask_format (image));

    gegl_buffer_copy (gimp_drawable_get_buffer (GIMP_DRAWABLE (mask)), NULL,
                      GEGL_ABYSS_NONE,
                      buffer, NULL);

    gimp_drawable_set_buffer (GIMP_DRAWABLE (mask), FALSE, NULL, buffer);
    g_object_unref (buffer);

    nth_drawable++;
  }

  if (sub_progress)
    gimp_progress_set_value (sub_progress, 1.0);

  gimp_image_undo_group_end (image);

  gimp_image_precision_changed (image);
  g_object_thaw_notify (G_OBJECT (image));

  if (sub_progress)
    g_object_unref (sub_progress);

  if (progress)
    gimp_progress_end (progress);
}
Ejemplo n.º 7
0
gboolean
gimp_image_convert_color_profile (GimpImage                *image,
                                  GimpColorProfile         *dest_profile,
                                  GimpColorRenderingIntent  intent,
                                  gboolean                  bpc,
                                  GimpProgress             *progress,
                                  GError                  **error)
{
  GimpColorProfile *src_profile;
  GimpColorProfile *builtin_profile;
  const Babl       *layer_format;

  g_return_val_if_fail (GIMP_IS_IMAGE (image), FALSE);
  g_return_val_if_fail (dest_profile != NULL, FALSE);
  g_return_val_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress), FALSE);
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);

  if (! gimp_image_validate_color_profile (image, dest_profile, error))
    return FALSE;

  src_profile = gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (image));

  if (gimp_color_profile_is_equal (src_profile, dest_profile))
    {
      g_object_unref (src_profile);
      return TRUE;
    }

  if (progress)
    gimp_progress_start (progress, FALSE,
                         _("Converting from '%s' to '%s'"),
                         gimp_color_profile_get_label (src_profile),
                         gimp_color_profile_get_label (dest_profile));

  gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_CONVERT,
                               _("Color profile conversion"));

  layer_format = gimp_image_get_layer_format (image, FALSE);

  if (gimp_babl_format_get_linear (layer_format))
    builtin_profile = gimp_color_profile_new_linear_rgb ();
  else
    builtin_profile = gimp_color_profile_new_srgb ();

  if (gimp_color_profile_is_equal (dest_profile, builtin_profile))
    {
      /*  don't tag the image with the built-in profile  */
      gimp_image_set_color_profile (image, NULL, NULL);
    }
  else
    {
      gimp_image_set_color_profile (image, dest_profile, NULL);
    }

  g_object_unref (builtin_profile);

  /*  omg...  */
  gimp_image_parasite_detach (image, "icc-profile-name");

  switch (gimp_image_get_base_type (image))
    {
    case GIMP_RGB:
      gimp_image_convert_profile_rgb (image,
                                      src_profile, dest_profile,
                                      intent, bpc,
                                      progress);
      break;

    case GIMP_GRAY:
      break;

    case GIMP_INDEXED:
      gimp_image_convert_profile_indexed (image,
                                          src_profile, dest_profile,
                                          intent, bpc,
                                          progress);
      break;
    }

  gimp_image_undo_group_end (image);

  if (progress)
    gimp_progress_end (progress);

  g_object_unref (src_profile);

  return TRUE;
}