コード例 #1
0
ファイル: gap_image.c プロジェクト: kleopatra999/gimp-gap
/* ============================================================================
 * gap_image_merge_visible_layers
 *    merge visible layer an return layer_id of the resulting merged layer.
 *    (with workaround, for empty images return transparent layer)
 * ============================================================================
 */
gint32
gap_image_merge_visible_layers(gint32 image_id, GimpMergeType mergemode)
{
  GimpImageBaseType l_type;
  guint   l_width, l_height;
  gint32  l_layer_id;

  /* get info about the image */
  l_width  = gimp_image_width(image_id);
  l_height = gimp_image_height(image_id);
  l_type   = gimp_image_base_type(image_id);

  l_type   = (l_type * 2); /* convert from GimpImageBaseType to GimpImageType */

  /* add 2 full transparent dummy layers at top
   * (because gimp_image_merge_visible_layers complains
   * if there are less than 2 visible layers)
   */
  l_layer_id = gimp_layer_new(image_id, "dummy",
                                 l_width, l_height,  l_type,
                                 0.0,       /* Opacity full transparent */
                                 0);        /* NORMAL */
  gimp_image_insert_layer(image_id, l_layer_id, 0, 0);

  l_layer_id = gimp_layer_new(image_id, "dummy",
                                 10, 10,  l_type,
                                 0.0,       /* Opacity full transparent */
                                 0);        /* NORMAL */
  gimp_image_insert_layer(image_id, l_layer_id, 0, 0);

  return gimp_image_merge_visible_layers (image_id, mergemode);
}       /* end gap_image_merge_visible_layers */
コード例 #2
0
ファイル: decompose.c プロジェクト: ChristianBusch/gimp
static gint32
create_new_layer (gint32              image_ID,
                  gint                position,
                  const gchar        *layername,
                  guint               width,
                  guint               height,
                  GimpImageBaseType   type)
{
  gint32        layer_ID;
  GimpImageType gdtype = GIMP_RGB_IMAGE;

  switch (type)
    {
    case GIMP_RGB:
      gdtype = GIMP_RGB_IMAGE;
      break;
    case GIMP_GRAY:
      gdtype = GIMP_GRAY_IMAGE;
      break;
    case GIMP_INDEXED:
      gdtype = GIMP_INDEXED_IMAGE;
      break;
    }

  if (!layername)
    layername = _("Background");

  layer_ID = gimp_layer_new (image_ID, layername, width, height,
                             gdtype, 100, GIMP_NORMAL_MODE);
  gimp_image_insert_layer (image_ID, layer_ID, -1, position);

  return layer_ID;
}
コード例 #3
0
ファイル: gap_image.c プロジェクト: kleopatra999/gimp-gap
/* ----------------------------------------------------
 * gap_image_create_unicolor_image
 * ----------------------------------------------------
 * - create a new image with one black filled layer
 *   (both have the requested size)
 *
 * return the new created image_id
 *   and the layer_id of the black_layer
 */
gint32
gap_image_create_unicolor_image(gint32 *layer_id, gint32 width , gint32 height
                       , gdouble r_f, gdouble g_f, gdouble b_f, gdouble a_f)
{
  gint32 l_empty_layer_id;
  gint32 l_image_id;

  *layer_id = -1;
  l_image_id = gimp_image_new(width, height, GIMP_RGB);
  if(l_image_id >= 0)
  {
    l_empty_layer_id = gimp_layer_new(l_image_id, "black_background",
                          width, height,
                          GIMP_RGBA_IMAGE,
                          100.0,     /* Opacity full opaque */
                          GIMP_NORMAL_MODE);
    gimp_image_insert_layer(l_image_id, l_empty_layer_id, 0, 0);

    /* clear layer to unique color */
    gap_layer_clear_to_color(l_empty_layer_id, r_f, g_f, b_f, a_f);

    *layer_id = l_empty_layer_id;
  }
  return(l_image_id);
}       /* end gap_image_create_unicolor_image */
コード例 #4
0
ファイル: gap_image.c プロジェクト: kleopatra999/gimp-gap
/* ============================================================================
 * gap_image_new_with_layer_of_samesize
 * ============================================================================
 * create empty image
 *  if layer_id is NOT NULL then create one full transparent layer at full image size
 *  and return the layer_id
 */
gint32
gap_image_new_with_layer_of_samesize(gint32 old_image_id, gint32 *layer_id)
{
  GimpImageBaseType  l_type;
  guint       l_width;
  guint       l_height;
  gint32      new_image_id;
  gdouble     l_xresoulution, l_yresoulution;
  gint32     l_unit;


  /* create empty image  */
  l_width  = gimp_image_width(old_image_id);
  l_height = gimp_image_height(old_image_id);
  l_type   = gimp_image_base_type(old_image_id);
  l_unit   = gimp_image_get_unit(old_image_id);
  gimp_image_get_resolution(old_image_id, &l_xresoulution, &l_yresoulution);

  new_image_id = gimp_image_new(l_width, l_height,l_type);
  gimp_image_set_resolution(new_image_id, l_xresoulution, l_yresoulution);
  gimp_image_set_unit(new_image_id, l_unit);

  if(layer_id)
  {
    l_type   = (l_type * 2); /* convert from GimpImageBaseType to GimpImageType */
    *layer_id = gimp_layer_new(new_image_id, "dummy",
                                 l_width, l_height,  l_type,
                                 0.0,       /* Opacity full transparent */
                                 0);        /* NORMAL */
    gimp_image_insert_layer(new_image_id, *layer_id, 0, 0);
  }

  return (new_image_id);

}  /* end gap_image_new_with_layer_of_samesize */
コード例 #5
0
ファイル: gap_image.c プロジェクト: kleopatra999/gimp-gap
void gap_image_prevent_empty_image(gint32 image_id)
{
  GimpImageBaseType l_type;
  guint   l_width, l_height;
  gint32  l_layer_id;
  gint    l_nlayers;
  gint32 *l_layers_list;

  l_layers_list = gimp_image_get_layers(image_id, &l_nlayers);
  if(l_layers_list != NULL)
  {
     g_free (l_layers_list);
  }
  else l_nlayers = 0;

  if(l_nlayers == 0)
  {
     /* the resulting image has no layer, add a transparent dummy layer */

     /* get info about the image */
     l_width  = gimp_image_width(image_id);
     l_height = gimp_image_height(image_id);
     l_type   = gimp_image_base_type(image_id);

     l_type   = (l_type * 2); /* convert from GimpImageBaseType to GimpImageType */

     /* add a transparent dummy layer */
     l_layer_id = gimp_layer_new(image_id, "dummy",
                                    l_width, l_height,  l_type,
                                    0.0,       /* Opacity full transparent */
                                    0);        /* NORMAL */
     gimp_image_insert_layer(image_id, l_layer_id, 0, 0);
  }

}       /* end gap_image_prevent_empty_image */
コード例 #6
0
ファイル: winsnap.c プロジェクト: AjayRamanathan/gimp
/*
 * sendBMPToGIMP
 *
 * Take the captured data and send it across
 * to GIMP.
 */
static void
sendBMPToGimp(HBITMAP hBMP, HDC hDC, RECT rect)
{
  int		width, height;
  int		imageType, layerType;
  gint32	image_id;
  gint32	layer_id;
  GimpPixelRgn	pixel_rgn;
  GimpDrawable    *drawable;

  /* Our width and height */
  width = (rect.right - rect.left);
  height = (rect.bottom - rect.top);

  /* Check that we got the memory */
  if (!capBytes) {
    g_message (_("No data captured"));
    return;
  }

  /* Flip the red and blue bytes */
  flipRedAndBlueBytes(width, height);

  /* Set up the image and layer types */
  imageType = GIMP_RGB;
  layerType = GIMP_RGB_IMAGE;

  /* Create the GIMP image and layers */
  image_id = gimp_image_new(width, height, imageType);
  layer_id = gimp_layer_new(image_id, _("Background"),
			    ROUND4(width), height,
			    layerType, 100, GIMP_NORMAL_MODE);
  gimp_image_insert_layer(image_id, layer_id, -1, 0);

  /* Get our drawable */
  drawable = gimp_drawable_get(layer_id);

  gimp_tile_cache_size(ROUND4(width) * gimp_tile_height() * 3);

  /* Initialize a pixel region for writing to the image */
  gimp_pixel_rgn_init(&pixel_rgn, drawable, 0, 0,
		      ROUND4(width), height, TRUE, FALSE);

  gimp_pixel_rgn_set_rect(&pixel_rgn, (guchar *) capBytes,
			  0, 0, ROUND4(width), height);

  /* HB: update data BEFORE size change */
  gimp_drawable_flush(drawable);
  /* Now resize the layer down to the correct size if necessary. */
  if (width != ROUND4(width)) {
    gimp_layer_resize (layer_id, width, height, 0, 0);
    gimp_image_resize (image_id, width, height, 0, 0);
  }
  /* Finish up */
  gimp_drawable_detach(drawable);
  gimp_display_new (image_id);

  return;
}
コード例 #7
0
ファイル: edge-dog.c プロジェクト: Amerekanets/gimp-1
static void
preview_update_preview (GimpPreview  *preview,
                        GimpDrawable *drawable)
{
  gint          x1, y1;
  gint          width, height;
  gint          bpp;
  guchar       *buffer;
  GimpPixelRgn  src_rgn;
  GimpPixelRgn  preview_rgn;
  gint32        image_id, src_image_id;
  gint32        preview_id;
  GimpDrawable *preview_drawable;

  bpp = gimp_drawable_bpp (drawable->drawable_id);

  gimp_preview_get_position (preview, &x1, &y1);
  gimp_preview_get_size (preview, &width, &height);

  buffer = g_new (guchar, width * height * bpp);

  gimp_pixel_rgn_init (&src_rgn, drawable,
                       x1, y1, width, height, FALSE, FALSE);
  gimp_pixel_rgn_get_rect (&src_rgn, buffer,
                           x1, y1, width, height);

  /* set up gimp drawable for rendering preview into */
  src_image_id = gimp_item_get_image (drawable->drawable_id);
  image_id = gimp_image_new (width, height,
                             gimp_image_base_type (src_image_id));
  preview_id = gimp_layer_new (image_id, "preview", width, height,
                               gimp_drawable_type (drawable->drawable_id),
                               100,
                               GIMP_NORMAL_MODE);
  preview_drawable = gimp_drawable_get (preview_id);
  gimp_image_insert_layer (image_id, preview_id, -1, 0);
  gimp_layer_set_offsets (preview_id, 0, 0);
  gimp_pixel_rgn_init (&preview_rgn, preview_drawable,
                       0, 0, width, height, TRUE, TRUE);
  gimp_pixel_rgn_set_rect (&preview_rgn, buffer,
                           0, 0, width, height);
  gimp_drawable_flush (preview_drawable);
  gimp_drawable_merge_shadow (preview_id, TRUE);
  gimp_drawable_update (preview_id, 0, 0, width, height);

  dog (image_id, preview_drawable, dogvals.inner, dogvals.outer, FALSE);

  gimp_pixel_rgn_get_rect (&preview_rgn, buffer,
                           0, 0, width, height);

  gimp_preview_draw_buffer (preview, buffer, width * bpp);

  gimp_image_delete (image_id);
  g_free (buffer);
}
コード例 #8
0
ファイル: gap_image.c プロジェクト: kleopatra999/gimp-gap
/* -----------------------------
 * gap_image_reorder_layer
 * -----------------------------
 * move the specified layer to another position within the same image.
 * (done by removing and then re-inserting the layer)
 * new_groupname
 *   Name of a group or group/subgroup where the specified layer_id shall be moved to.
 *   Note that the string new_groupname uses the delimiter string
 *   to split nested group/sugrup names.
 *   use new_groupname = NULL to move the specified layer_id to image toplevel.
 * enableGroupCreation
 *   TRUE:
 *     in case the group layer with new_groupname does not exist
 *     it will be created automatically.
 *  FALSE:
 *     in case the group layer with new_groupname does not exist
 *     -1 is returned and the reorder operation is not performed.
 * new_position
 *     the desired new stackposition within the specified new_groupname
 *     or toplevel image (when new_groupname is NULL or empty)
 * returns   -1 on error
 */
gint32
gap_image_reorder_layer(gint32 image_id, gint32 layer_id,
              gint32 new_position,
              char *new_groupname,
              char *delimiter,
              gboolean enableGroupCreation,
              char *new_layername)
{
  gint32 l_parent_id;
  gint32 l_dup_layer_id;
  gchar *l_name;

  l_parent_id = gap_image_find_or_create_group_layer(image_id
                          , new_groupname
                          , delimiter
                          , 0      /* stackposition for the group in case it is created at toplevel */
                          , enableGroupCreation
                          );
  if (l_parent_id < 0)
  {
    return (-1);
  }

  l_dup_layer_id = gimp_layer_copy(layer_id);

  l_name = NULL;
  if (new_layername != NULL)
  {
    if (*new_layername != '\0')
    {
      l_name = g_strdup(new_layername);
    }
  }

  if (l_name == NULL)
  {
   l_name = gimp_item_get_name(layer_id);
  }
  gimp_image_remove_layer(image_id, layer_id);

  gimp_image_insert_layer(image_id, l_dup_layer_id, l_parent_id, new_position);
  gimp_item_set_name(l_dup_layer_id, l_name);
  g_free(l_name);

  return (0); /* OK */

}  /* end gap_image_reorder_layer */
コード例 #9
0
static gint32
layer_from_pixbuf (gint32        image,
                   const gchar  *layer_name,
                   gint          position,
                   GdkPixbuf    *pixbuf,
                   gdouble       progress_start,
                   gdouble       progress_scale)
{
    gint32 layer = gimp_layer_new_from_pixbuf (image, layer_name, pixbuf,
                   100.0, GIMP_NORMAL_MODE,
                   progress_start,
                   progress_start + progress_scale);

    gimp_image_insert_layer (image, layer, -1, position);

    return layer;
}
コード例 #10
0
ファイル: file-svg.c プロジェクト: Amerekanets/gimp-1
static gint32
load_image (const gchar  *filename,
            GError      **load_error)
{
  gint32        image;
  gint32        layer;
  GdkPixbuf    *pixbuf;
  gint          width;
  gint          height;
  GError       *error = NULL;

  pixbuf = load_rsvg_pixbuf (filename, &load_vals, &error);

  if (! pixbuf)
    {
      /*  Do not rely on librsvg setting GError on failure!  */
      g_set_error (load_error,
                   error ? error->domain : 0, error ? error->code : 0,
                   _("Could not open '%s' for reading: %s"),
                   gimp_filename_to_utf8 (filename),
                   error ? error->message : _("Unknown reason"));
      g_clear_error (&error);

      return -1;
    }

  gimp_progress_init (_("Rendering SVG"));

  width  = gdk_pixbuf_get_width (pixbuf);
  height = gdk_pixbuf_get_height (pixbuf);

  image = gimp_image_new (width, height, GIMP_RGB);
  gimp_image_undo_disable (image);

  gimp_image_set_filename (image, filename);
  gimp_image_set_resolution (image,
                             load_vals.resolution, load_vals.resolution);

  layer = gimp_layer_new_from_pixbuf (image, _("Rendered SVG"), pixbuf,
                                      100, GIMP_NORMAL_MODE, 0.0, 1.0);
  gimp_image_insert_layer (image, layer, -1, 0);

  gimp_image_undo_enable (image);

  return image;
}
コード例 #11
0
ファイル: gap_image.c プロジェクト: kleopatra999/gimp-gap
/* -----------------------------------------------
 * gap_image_greate_group_layer_path
 * -----------------------------------------------
 * create group layer specified by nameArray starting with
 * the element at start_idx end at 1st NULL pointer element.
 * in case the rest in this nameArray contains more than one name
 * a hierarchy of group layers is created, where each name
 * has the previous name as parent.
 */
gint32
gap_image_greate_group_layer_path(gint32 image_id
                             , gint32 parent_id      /* or 0 for top imagelevel */
                             , gint32 stackposition  /* where 0 is on top position */
                             , gchar  **nameArray
                             , gint   start_idx
                             )
{
  gint32 parent_layer_id;
  gint32 group_layer_id;
  gint32 position;
  gchar *namePtr;
  gint   l_ii;

  position = stackposition;
  parent_layer_id = 0;
  if (nameArray != NULL)
  {
    for(l_ii = 0; nameArray[l_ii] != NULL; l_ii++)
    {
      if(l_ii >= start_idx)
      {
        namePtr = nameArray[l_ii];
        group_layer_id = gimp_layer_group_new(image_id);
        gimp_item_set_name(group_layer_id, namePtr);
        gimp_image_insert_layer(image_id, group_layer_id, parent_layer_id, position);
        if(gap_debug)
        {
          printf("gap_image_greate_group_layer_path: name[%d]:%s group_layer_id:%d\n"
                 , (int)l_ii
                 , namePtr
                 , (int)group_layer_id
                 );
        }

        parent_layer_id =  group_layer_id;
      }
      position = 0;
    }
  }

  return (group_layer_id);

}  /* end gap_image_greate_group_layer_path */
コード例 #12
0
/* ----------------------------------------
 * p_createEmptyEdgeDrawable
 * ----------------------------------------
 * create the (empty) edge drawable as layer of a new image
 *
 */
static void
p_createEmptyEdgeDrawable(GapEdgeContext *ectx)
{
  ectx->edgeImageId = gimp_image_new(ectx->refDrawable->width
                                   , ectx->refDrawable->height
                                   , GIMP_GRAY
                                   );
  ectx->edgeDrawableId = gimp_layer_new(ectx->edgeImageId
                , "edge"
                , ectx->refDrawable->width
                , ectx->refDrawable->height
                , GIMP_GRAY_IMAGE
                , 100.0   /* full opacity */
                , 0       /* normal mode */
                );

  gimp_image_insert_layer (ectx->edgeImageId, ectx->edgeDrawableId, 0, 0 /* stackposition */ );

  ectx->edgeDrawable = gimp_drawable_get(ectx->edgeDrawableId);
  
}  /* end p_createEmptyEdgeDrawable */
コード例 #13
0
ファイル: gimp-plugin-vtf.cpp プロジェクト: lxndr/vtf
static gboolean
file_vtf_load_layer (Vtf::HiresImageResource *vres, gint32 image, gint16 frame)
{
    uint8_t *rgba = vres->getImageRGBA(0, frame, 0, 0);
    g_return_val_if_fail (rgba != NULL, FALSE);

    gchar *name = g_strdup_printf ("Frame %d", frame);
    gint32 layer = gimp_layer_new (image, name, vres->width (), vres->height(),
                                   GIMP_RGBA_IMAGE, 100, GIMP_NORMAL_MODE);
    gimp_image_insert_layer (image, layer, -1, frame);
    g_free (name);

    GimpPixelRgn pixel_rgn;
    GimpDrawable *drawable = gimp_drawable_get (layer);
    gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, drawable->width,
                         drawable->height, TRUE, FALSE);
    gimp_pixel_rgn_set_rect (&pixel_rgn, rgba, 0, 0, drawable->width,
                             drawable->height);
    gimp_drawable_detach (drawable);

    return TRUE;
}
コード例 #14
0
ファイル: decompose.c プロジェクト: WilfR/Gimp-Matting
static gint32
create_new_layer (gint32              image_ID,
                  gint                position,
                  const gchar        *layername,
                  guint               width,
                  guint               height,
                  GimpImageBaseType   type,
                  GimpDrawable      **drawable,
                  GimpPixelRgn       *pixel_rgn)
{
  gint32        layer_ID;
  GimpImageType gdtype = GIMP_RGB_IMAGE;

  switch (type)
    {
    case GIMP_RGB:
      gdtype = GIMP_RGB_IMAGE;
      break;
    case GIMP_GRAY:
      gdtype = GIMP_GRAY_IMAGE;
      break;
    case GIMP_INDEXED:
      gdtype = GIMP_INDEXED_IMAGE;
      break;
    }

  if (!layername)
    layername = _("Background");

  layer_ID = gimp_layer_new (image_ID, layername, width, height,
                             gdtype, 100, GIMP_NORMAL_MODE);
  gimp_image_insert_layer (image_ID, layer_ID, -1, position);

  *drawable = gimp_drawable_get (layer_ID);
  gimp_pixel_rgn_init (pixel_rgn, *drawable, 0, 0, (*drawable)->width,
                       (*drawable)->height, TRUE, FALSE);

  return layer_ID;
}
コード例 #15
0
ファイル: film.c プロジェクト: LebedevRI/gimp
/* Create an image. Sets layer_ID, drawable and rgn. Returns image_ID */
static gint32
create_new_image (const gchar    *filename,
                  guint           width,
                  guint           height,
                  GimpImageType   gdtype,
                  gint32         *layer_ID,
                  GimpDrawable  **drawable,
                  GimpPixelRgn   *pixel_rgn)
{
  gint32            image_ID;
  GimpImageBaseType gitype;

  if ((gdtype == GIMP_GRAY_IMAGE) || (gdtype == GIMP_GRAYA_IMAGE))
    gitype = GIMP_GRAY;
  else if ((gdtype == GIMP_INDEXED_IMAGE) || (gdtype == GIMP_INDEXEDA_IMAGE))
    gitype = GIMP_INDEXED;
  else
    gitype = GIMP_RGB;

  image_ID = gimp_image_new (width, height, gitype);
  gimp_image_set_filename (image_ID, filename);

  gimp_image_undo_disable (image_ID);
  *layer_ID = gimp_layer_new (image_ID, _("Background"), width, height,
                              gdtype, 100, GIMP_NORMAL_MODE);
  gimp_image_insert_layer (image_ID, *layer_ID, -1, 0);

  if (drawable)
    {
      *drawable = gimp_drawable_get (*layer_ID);
      if (pixel_rgn != NULL)
        gimp_pixel_rgn_init (pixel_rgn, *drawable, 0, 0, (*drawable)->width,
                             (*drawable)->height, TRUE, FALSE);
    }

  return image_ID;
}
コード例 #16
0
ファイル: web-page.c プロジェクト: jiapei100/gimp
static void
snapshot_ready (GObject      *source_object,
                GAsyncResult *result,
                gpointer      user_data)
{
  WebKitWebView   *view = WEBKIT_WEB_VIEW (source_object);
  cairo_surface_t *surface;

  surface = webkit_web_view_get_snapshot_finish (view, result,
                                                 &webpagevals.error);

  if (surface)
    {
      gint   width;
      gint   height;
      gint32 layer;

      width  = cairo_image_surface_get_width (surface);
      height = cairo_image_surface_get_height (surface);

      webpagevals.image = gimp_image_new (width, height, GIMP_RGB);

      gimp_image_undo_disable (webpagevals.image);
      layer = gimp_layer_new_from_surface (webpagevals.image, _("Webpage"),
                                           surface,
                                           0.25, 1.0);
      gimp_image_insert_layer (webpagevals.image, layer, -1, 0);
      gimp_image_undo_enable (webpagevals.image);

      cairo_surface_destroy (surface);
    }

  gimp_progress_update (1.0);

  gtk_main_quit ();
}
コード例 #17
0
ファイル: file-wmf.c プロジェクト: MichaelMure/Gimp-Cage-Tool
/*
 * 'load_image()' - Load a WMF image into a new image window.
 */
static gint32
load_image (const gchar  *filename,
            GError      **error)
{
  gint32        image;
  gint32        layer;
  GimpDrawable *drawable;
  guchar       *pixels;
  GimpPixelRgn  pixel_rgn;
  guint         width, height;
  guint         rowstride;
  guint         count = 0;
  guint         done  = 0;
  gpointer      pr;

  pixels = wmf_load_file (filename, &width, &height, error);

  if (! pixels)
    return -1;

  rowstride = width * 4;

  gimp_progress_init_printf (_("Opening '%s'"),
                             gimp_filename_to_utf8 (filename));

  image = gimp_image_new (width, height, GIMP_RGB);
  gimp_image_set_filename (image, filename);
  gimp_image_set_resolution (image,
                             load_vals.resolution, load_vals.resolution);

  layer = gimp_layer_new (image,
                          _("Rendered WMF"),
                          width, height,
                          GIMP_RGBA_IMAGE, 100, GIMP_NORMAL_MODE);

  drawable = gimp_drawable_get (layer);

  gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, width, height, TRUE, FALSE);

  for (pr = gimp_pixel_rgns_register (1, &pixel_rgn);
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr))
    {
      const guchar *src  = pixels + pixel_rgn.y * rowstride + pixel_rgn.x * 4;
      guchar       *dest = pixel_rgn.data;
      gint          y;

      for (y = 0; y < pixel_rgn.h; y++)
        {
          memcpy (dest, src, pixel_rgn.w * pixel_rgn.bpp);

          src  += rowstride;
          dest += pixel_rgn.rowstride;
        }

      done += pixel_rgn.h * pixel_rgn.w;

      if (count++ % 16 == 0)
        gimp_progress_update ((gdouble) done / (width * height));
    }

  g_free (pixels);

  gimp_drawable_detach (drawable);

  gimp_progress_update (1.0);

  /* Tell GIMP to display the image.
   */
  gimp_image_insert_layer (image, layer, -1, 0);
  gimp_drawable_flush (drawable);

  return image;
}
コード例 #18
0
static gboolean apply_watermark(watermark_settings settings, image_output out) 
{
    gboolean success = TRUE;
    gint32 layerId;
    gdouble posX, posY;
    gint wmwidth, wmheight, wmasc, wmdesc;
    
    if (settings->mode) {
        if (strlen(settings->text) == 0) {
            return TRUE;
        }
        
        GimpRGB old_foreground, new_foreground;
        
        gimp_context_get_foreground(&old_foreground);
        gimp_rgb_parse_hex (&new_foreground, gdk_color_to_string(&(settings->color)), strlen(gdk_color_to_string(&(settings->color))));
        gimp_context_set_foreground(&new_foreground);
        
        gimp_text_get_extents_fontname(
            settings->text,
            pango_font_description_get_size(settings->font) / PANGO_SCALE,
            GIMP_PIXELS,
            pango_font_description_get_family(settings->font),
            &wmwidth,
            &wmheight,
            &wmasc,
            &wmdesc
        );

        if (settings->position == WM_POS_TL) {
            posX = 10;
            posY = 5;
        }
        else if (settings->position == WM_POS_TC) {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = 5;
        }
        else if (settings->position == WM_POS_TR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = 5;
        }
        else if (settings->position == WM_POS_BL) {
            posX = 10;
            posY = gimp_image_height(out->image_id) - wmheight - 5;
        }
        else if (settings->position == WM_POS_BC) {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = gimp_image_height(out->image_id) - wmheight - 5;
        }
        else if (settings->position == WM_POS_BR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = gimp_image_height(out->image_id) - wmheight - 5;
        }
        else if (settings->position == WM_POS_CL) {
            posX = 10;
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        else if (settings->position == WM_POS_CR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        else {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        
        layerId = gimp_text_fontname(
            out->image_id,
            -1,
            posX,
            posY,
            settings->text,
            -1,
            TRUE,
            pango_font_description_get_size(settings->font) / PANGO_SCALE,
            GIMP_PIXELS,
            pango_font_description_get_family(settings->font)
        );
        gimp_context_set_foreground(&old_foreground);
        gimp_layer_set_opacity(layerId, settings->opacity);
    }
    else {
        if (!g_file_test(settings->image_file, G_FILE_TEST_IS_REGULAR)) {//((access(settings->image_file, R_OK) == -1)) {
            // error, can't access image file
            return TRUE;
        }
        
        layerId = gimp_file_load_layer(
            GIMP_RUN_NONINTERACTIVE,
            out->image_id,
            settings->image_file
        );
        
        gimp_layer_set_opacity(layerId, settings->opacity);
        wmwidth = gimp_drawable_width(layerId);
        wmheight = gimp_drawable_height(layerId);
        
        #if USE_API26
        
            gimp_image_add_layer(
                out->image_id,
                layerId,
                0
            );
        
        #else
        
            // starting from 2.8, gimp_image_add_layer is deprecated. 
            // use gimp_image_insert_layer instead
            gimp_image_insert_layer(
                out->image_id,
                layerId,
                0,
                0
            );
            
        #endif
        
        if (settings->position == WM_POS_TL) {
            posX = 10;
            posY = 10;
        }
        else if (settings->position == WM_POS_TC) {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = 10;
        }
        else if (settings->position == WM_POS_TR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = 10;
        }
        else if (settings->position == WM_POS_BL) {
            posX = 10;
            posY = gimp_image_height(out->image_id) - wmheight - 10;
        }
        else if (settings->position == WM_POS_BC) {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = gimp_image_height(out->image_id) - wmheight - 10;
        }
        else if (settings->position == WM_POS_BR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = gimp_image_height(out->image_id) - wmheight - 10;
        }
        else if (settings->position == WM_POS_CL) {
            posX = 10;
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        else if (settings->position == WM_POS_CR) {
            posX = gimp_image_width(out->image_id) - wmwidth - 10;
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        else {
            posX = (gimp_image_width(out->image_id) / 2) - (wmwidth / 2);
            posY = (gimp_image_height(out->image_id) / 2) - (wmheight / 2);
        }
        
        gimp_layer_set_offsets(
            layerId,
            posX,
            posY
        );   
    }
    
    // refresh all drawables
    g_free(out->drawable_ids);
    out->drawable_ids = gimp_image_get_layers(out->image_id, &out->drawable_count);
    
    return success;
}
コード例 #19
0
static gboolean apply_resize(resize_settings settings, image_output out) 
{
    gboolean success = FALSE;
    gint orig_w, orig_h, final_w, final_h, view_w, view_h;
    gdouble orig_res_x, orig_res_y;
    
    if (settings->change_res) {
        success = gimp_image_get_resolution(
            out->image_id,
            &orig_res_x,
            &orig_res_y
        );
        
        if ((settings->new_res_x != orig_res_x) || (settings->new_res_y != orig_res_y)) {
            // change resolution 
            success = gimp_image_set_resolution(
                out->image_id,
                settings->new_res_x,
                settings->new_res_y
            );
        }
    }

    orig_w = gimp_image_width(out->image_id);
    orig_h = gimp_image_height(out->image_id);
    
    if (settings->resize_mode == RESIZE_PERCENT) {
        
        if (settings->stretch_mode == STRETCH_ASPECT) {
            gdouble newpct = min(settings->new_w_pc, settings->new_h_pc);
            
            final_w = view_w = round((orig_w * newpct) / 100.0);
            final_h = view_h = round((orig_h * newpct) / 100.0);
        }
        else if (settings->stretch_mode == STRETCH_PADDED) {
            gdouble newpct = min(settings->new_w_pc, settings->new_h_pc);
            
            final_w = round((orig_w * newpct) / 100.0);
            final_h = round((orig_h * newpct) / 100.0);
            view_w = round((orig_w * settings->new_w_pc) / 100.0);
            view_h = round((orig_h * settings->new_h_pc) / 100.0);
        }
        else {
            final_w = view_w = round((orig_w * settings->new_w_pc) / 100.0);
            final_h = view_h = round((orig_h * settings->new_h_pc) / 100.0);
        }
    }
    else {
        // user typed exact pixel size 
        if (settings->resize_mode == RESIZE_PIXEL_WIDTH) {
            view_w = settings->new_w_px; // width is fixed 
            
            if (settings->stretch_mode == STRETCH_ASPECT) {
                final_w = view_w;
                final_h = view_h = round(((float)final_w * orig_h) / orig_w);
            }
            else if (settings->stretch_mode == STRETCH_PADDED) {
                final_w = min(view_w, orig_w);
                final_h = round(((float)final_w * orig_h) / orig_w);
                view_h = max(orig_h, final_h);
            }
            else {
                final_w = view_w;
                final_h = view_h = orig_h;
            }
        }
        else if (settings->resize_mode == RESIZE_PIXEL_HEIGHT) {
            view_h = settings->new_h_px; // height is fixed
            
            if (settings->stretch_mode == STRETCH_ASPECT) {
                final_h = view_h;
                final_w = view_w = round(((float)final_h * orig_w) / orig_h);
            }
            else if (settings->stretch_mode == STRETCH_PADDED) {
                final_h = min(view_h, orig_h);
                final_w = round(((float)final_h * orig_w) / orig_h);
                view_w = max(orig_w, final_w);
            }
            else {
                final_h = view_h;
                final_w = view_w = orig_w;
            }
        }
        else {
            // both dimensions are defined 
            if (settings->stretch_mode == STRETCH_ASPECT) {
                // Find which new dimension is the smallest percentage of the existing image dimension
                gdouble newwpct = (float)settings->new_w_px / (float)orig_w;
                gdouble newhpct = (float)settings->new_h_px / (float)orig_h;
                gdouble newpct = min(newwpct, newhpct);

                final_w = view_w = round(orig_w * newpct);
                final_h = view_h = round(orig_h * newpct);
            }
            else if (settings->stretch_mode == STRETCH_PADDED) {
                // Find which new dimension is the smallest percentage of the existing image dimension
                gdouble newwpct = (float)settings->new_w_px / (float)orig_w;
                gdouble newhpct = (float)settings->new_h_px / (float)orig_h;
                gdouble newpct = min(newwpct, newhpct);
                
                final_w = round(orig_w * newpct);
                final_h = round(orig_h * newpct);
                view_w = round(orig_w * newwpct);
                view_h = round(orig_h * newhpct);
            }
            else {
                final_w = view_w = settings->new_w_px;
                final_h = view_h = settings->new_h_px;
            }
        }
    }
    
    // do resize 
    #if USE_API26
    
        success = gimp_image_scale_full (
            out->image_id, 
            final_w, 
            final_h, 
            settings->interpolation
        );
        
    #else
    
        // starting from 2.8, gimp_image_scale_full is deprecated. 
        // use gimp_image_scale instead
        GimpInterpolationType old_interpolation;
        old_interpolation = gimp_context_get_interpolation();
        
        success = gimp_context_set_interpolation (settings->interpolation);
        
        success = gimp_image_scale (
            out->image_id, 
            final_w, 
            final_h
        );
        
        success = gimp_context_set_interpolation (old_interpolation);
    
    #endif
    
    // add a padding if requested
    if (settings->stretch_mode == STRETCH_PADDED) {
        
        // the padding will be drawn using a coloured layer at the bottom of the image
        gint32 layerId = gimp_layer_new(
            out->image_id,
            "padding_layer",
            view_w, view_h,
            GIMP_RGBA_IMAGE,
            (settings->padding_color_alpha / (float)G_MAXUINT16) * 100,
            GIMP_NORMAL_MODE
        );
        
        #if USE_API26
        
            gimp_image_add_layer (
                out->image_id,
                layerId,
                0
            );
            
            gimp_image_lower_layer_to_bottom(out->image_id, layerId);
        
        #else
            
            gimp_image_insert_layer(
                out->image_id,
                layerId,
                0,
                0
            );
            
            gimp_image_lower_item_to_bottom(out->image_id, layerId);
            
        #endif
        
        // fill it with the selected color
        GimpRGB old_background, new_background;
            
        gimp_context_get_background(&old_background);
        gimp_rgb_parse_hex (&new_background, gdk_color_to_string(&(settings->padding_color)), strlen(gdk_color_to_string(&(settings->padding_color))));
        gimp_context_set_background(&new_background);
        gimp_drawable_fill(layerId, GIMP_BACKGROUND_FILL);
        gimp_context_set_background(&old_background);
        
        // move it to the center
        gimp_layer_translate(layerId, -abs(view_w - final_w) / 2, -abs(view_h - final_h) / 2);
        
        // finish changing the canvas size accordingly
        success = gimp_image_resize_to_layers(out->image_id);
    }
    
    return success;
}
コード例 #20
0
ファイル: ptGimp.cpp プロジェクト: divyang4481/photivo
void ptRun(const gchar*     Name,
           gint       NrParameters,
           const GimpParam* Parameter,
           gint *nreturn_vals,
           GimpParam **return_vals) {
  printf("(%s,%d) '%s'\n",__FILE__,__LINE__,__PRETTY_FUNCTION__);
  printf("Name         : '%s'\n",Name);
  printf("NrParameters : %d\n",NrParameters);
  if (!strcmp(Name,"photivoSendToGimp")) {
    printf("RunMode      : %d\n",Parameter[0].data.d_int32);
    printf("FileName1    : '%s'\n",Parameter[1].data.d_string);
    printf("FileName2    : '%s'\n",Parameter[2].data.d_string);

    QFile GimpFile(Parameter[1].data.d_string);
    bool result = GimpFile.open(QIODevice::ReadOnly | QIODevice::Text);
    assert(result);

    QTextStream In(&GimpFile);

    QString ImageFileName = In.readLine();
    QString ExifFileName  = In.readLine();
    QString ICCFileName   = In.readLine();

    // Read image
    FILE *InputFile = fopen(ImageFileName.toLocal8Bit().data(),"rb");
    if (!InputFile) {
      ptLogError(1,ImageFileName.toLocal8Bit().data());
      return; // ptError_FileOpen;
    }

    short    Colors;
    unsigned short Width;
    unsigned short Height;
    unsigned short BitsPerColor;
    char     Buffer[128];

    // Extremely naive. Probably just enough for testcases.
    char *s = fgets(Buffer,127,InputFile);
    assert ( s );
    int n = sscanf(Buffer,"P%hd",&Colors);
    assert ( 1 == n );
    assert(Colors == 6 );
    do {
      s = fgets(Buffer,127,InputFile);
      assert ( s );
    } while (Buffer[0] == '#');
    sscanf(Buffer,"%hd %hd",&Width,&Height);
    s = fgets(Buffer,127,InputFile);
    assert ( s );
    sscanf(Buffer,"%hd",&BitsPerColor);
    assert(BitsPerColor == 0xffff);

    Colors = 3;

    unsigned short (* ImageForGimp)[3] =
      (unsigned short (*)[3]) CALLOC2(Width*Height,sizeof(*ImageForGimp));
    ptMemoryError(ImageForGimp,__FILE__,__LINE__);

    unsigned short*  PpmRow = (unsigned short *) CALLOC2(Width*Height,sizeof(*PpmRow));
    ptMemoryError(PpmRow,__FILE__,__LINE__);

    for (unsigned short Row=0; Row<Height; Row++) {
      size_t RV = fread(PpmRow,Colors*2,Width,InputFile);
      if (RV != (size_t) Width) {
        printf("ReadPpm error. Expected %d bytes. Got %d\n",Width,(int)RV);
        exit(EXIT_FAILURE);
      }
      if (htons(0x55aa) != 0x55aa) {
        swab((char *)PpmRow,(char *)PpmRow,Width*Colors*2);
      }
      for (unsigned short Col=0; Col<Width; Col++) {
        for (short c=0;c<3;c++) {
          ImageForGimp[Row*Width+Col][c] = PpmRow[Col*Colors+c];
        }
      }
    }

    FREE2(PpmRow);
    FCLOSE(InputFile);

    QFile ExifFile(ExifFileName);
    result = ExifFile.open(QIODevice::ReadOnly);
    assert(result);
    qint64 FileSize = ExifFile.size();
    QDataStream ExifIn(&ExifFile);
    char* ExifBuffer = (char *) MALLOC2(FileSize);
    ptMemoryError(ExifBuffer,__FILE__,__LINE__);
    unsigned ExifBufferLength = ExifIn.readRawData(ExifBuffer,FileSize);
    ExifFile.close();

    QFile ICCFile(ICCFileName);
    result = ICCFile.open(QIODevice::ReadOnly);
    assert(result);
    qint64 FileSize2 = ICCFile.size();
    QDataStream ICCIn(&ICCFile);
    char* ICCBuffer = (char *) MALLOC2(FileSize2);
    ptMemoryError(ICCBuffer,__FILE__,__LINE__);
    unsigned ICCBufferLength = ICCIn.readRawData(ICCBuffer,FileSize2);
    ICCFile.close();

    // And now copy to gimp.
    gint32 GimpImage = gimp_image_new(Width,
                                      Height,
                                      GIMP_RGB);
    assert (GimpImage != -1);
    gint32 GimpLayer = gimp_layer_new(GimpImage,
                                      "BG",
                                      Width,
                                      Height,
                                      GIMP_RGB_IMAGE,
                                      100.0,
                                      GIMP_NORMAL_MODE);
#if GIMP_MINOR_VERSION<=6
    gimp_image_add_layer(GimpImage,GimpLayer,0);
#else
    gimp_image_insert_layer(GimpImage,GimpLayer,0,0);
#endif
    GimpDrawable* Drawable = gimp_drawable_get(GimpLayer);
    GimpPixelRgn PixelRegion;
    gimp_pixel_rgn_init(&PixelRegion,
                        Drawable,
                        0,
                        0,
                        Drawable->width,
                        Drawable->height,
                        true,
                        false);
    unsigned short TileHeight = gimp_tile_height();
    for (unsigned short Row=0; Row<Height; Row+=TileHeight) {
      unsigned short NrRows = MIN(Height-Row, (int)TileHeight);
      guint8* Buffer = g_new(guint8,TileHeight*Width*3);
      for (unsigned short i=0; i<NrRows; i++) {
        for (unsigned short j=0; j<Width; j++) {
          for (short c=0;c<3;c++) {
            Buffer[3*(i*Width+j)+c] =
              ImageForGimp[(Row+i)*Width+j][c]>>8;
          }
        }
      }
      gimp_pixel_rgn_set_rect(&PixelRegion,
                              Buffer,
                              0,
                              Row,
                              Width,
                              NrRows);
      g_free(Buffer);
    }
    gimp_drawable_flush(Drawable);
    gimp_drawable_detach(Drawable);
    FREE2(ImageForGimp);
    GimpParasite* GimpExifData = gimp_parasite_new("exif-data",
                                                   GIMP_PARASITE_PERSISTENT,
                                                   ExifBufferLength,
                                                   ExifBuffer);
    gimp_image_parasite_attach(GimpImage,GimpExifData);
    gimp_parasite_free(GimpExifData);
    FREE2(ExifBuffer);

    GimpParasite* GimpICCData = gimp_parasite_new("icc-profile",
                                                   GIMP_PARASITE_PERSISTENT,
                                                   ICCBufferLength,
                                                   ICCBuffer);
    gimp_image_parasite_attach(GimpImage,GimpICCData);
    gimp_parasite_free(GimpICCData);
    FREE2(ICCBuffer);

    static GimpParam Values[2];
    *nreturn_vals = 2;
    *return_vals = Values;
    Values[0].type = GIMP_PDB_STATUS;
    Values[0].data.d_status = GIMP_PDB_SUCCESS;
    Values[1].type = GIMP_PDB_IMAGE;
    Values[1].data.d_image = GimpImage;

    QFile::remove(ImageFileName);
    QFile::remove(ExifFileName);
    QFile::remove(ICCFileName);
    QFile::remove(Parameter[1].data.d_string);

  }
コード例 #21
0
ファイル: hot.c プロジェクト: MichaelMure/Gimp-Cage-Tool
static gboolean
pluginCore (piArgs *argp)
{
  GimpDrawable *drw, *ndrw = NULL;
  GimpPixelRgn  srcPr, dstPr;
  gboolean      success = TRUE;
  gint          nl      = 0;
  gint          y, i;
  gint          Y, I, Q;
  guint         width, height, bpp;
  gint          sel_x1, sel_x2, sel_y1, sel_y2;
  gint          prog_interval;
  guchar       *src, *s, *dst, *d;
  guchar        r, prev_r=0, new_r=0;
  guchar        g, prev_g=0, new_g=0;
  guchar        b, prev_b=0, new_b=0;
  gdouble       fy, fc, t, scale;
  gdouble       pr, pg, pb;
  gdouble       py;

  drw = gimp_drawable_get (argp->drawable);

  width  = drw->width;
  height = drw->height;
  bpp    = drw->bpp;

  if (argp->new_layerp)
    {
      gchar        name[40];
      const gchar *mode_names[] =
      {
        "ntsc",
        "pal",
      };
      const gchar *action_names[] =
      {
        "lum redux",
        "sat redux",
        "flag",
      };

      g_snprintf (name, sizeof (name), "hot mask (%s, %s)",
                  mode_names[argp->mode],
                  action_names[argp->action]);

      nl = gimp_layer_new (argp->image, name, width, height,
                           GIMP_RGBA_IMAGE, (gdouble)100, GIMP_NORMAL_MODE);
      ndrw = gimp_drawable_get (nl);
      gimp_drawable_fill (nl, GIMP_TRANSPARENT_FILL);
      gimp_image_insert_layer (argp->image, nl, -1, 0);
    }

  gimp_drawable_mask_bounds (drw->drawable_id,
                             &sel_x1, &sel_y1, &sel_x2, &sel_y2);

  width  = sel_x2 - sel_x1;
  height = sel_y2 - sel_y1;

  src = g_new (guchar, width * height * bpp);
  dst = g_new (guchar, width * height * 4);
  gimp_pixel_rgn_init (&srcPr, drw, sel_x1, sel_y1, width, height,
                       FALSE, FALSE);

  if (argp->new_layerp)
    {
      gimp_pixel_rgn_init (&dstPr, ndrw, sel_x1, sel_y1, width, height,
                           FALSE, FALSE);
    }
  else
    {
      gimp_pixel_rgn_init (&dstPr, drw, sel_x1, sel_y1, width, height,
                           TRUE, TRUE);
    }

  gimp_pixel_rgn_get_rect (&srcPr, src, sel_x1, sel_y1, width, height);

  s = src;
  d = dst;

  build_tab (argp->mode);

  gimp_progress_init (_("Hot"));
  prog_interval = height / 10;

  for (y = sel_y1; y < sel_y2; y++)
    {
      gint x;

      if (y % prog_interval == 0)
        gimp_progress_update ((double) y / (double) (sel_y2 - sel_y1));

      for (x = sel_x1; x < sel_x2; x++)
        {
          if (hotp (r = *(s + 0), g = *(s + 1), b = *(s + 2)))
            {
              if (argp->action == ACT_FLAG)
                {
                  for (i = 0; i < 3; i++)
                    *d++ = 0;
                  s += 3;
                  if (bpp == 4)
                    *d++ = *s++;
                  else if (argp->new_layerp)
                    *d++ = 255;
                }
              else
                {
                  /*
                   * Optimization: cache the last-computed hot pixel.
                   */
                  if (r == prev_r && g == prev_g && b == prev_b)
                    {
                      *d++ = new_r;
                      *d++ = new_g;
                      *d++ = new_b;
                      s += 3;
                      if (bpp == 4)
                        *d++ = *s++;
                      else if (argp->new_layerp)
                        *d++ = 255;
                    }
                  else
                    {
                      Y = tab[0][0][r] + tab[0][1][g] + tab[0][2][b];
                      I = tab[1][0][r] + tab[1][1][g] + tab[1][2][b];
                      Q = tab[2][0][r] + tab[2][1][g] + tab[2][2][b];

                      prev_r = r;
                      prev_g = g;
                      prev_b = b;
                      /*
                       * Get Y and chroma amplitudes in floating point.
                       *
                       * If your C library doesn't have hypot(), just use
                       * hypot(a,b) = sqrt(a*a, b*b);
                       *
                       * Then extract linear (un-gamma-corrected)
                       * floating-point pixel RGB values.
                       */
                      fy = (double)Y / (double)SCALE;
                      fc = hypot ((double) I / (double) SCALE,
                                  (double) Q / (double) SCALE);

                      pr = (double) pix_decode (r);
                      pg = (double) pix_decode (g);
                      pb = (double) pix_decode (b);

                      /*
                       * Reducing overall pixel intensity by scaling R,
                       * G, and B reduces Y, I, and Q by the same factor.
                       * This changes luminance but not saturation, since
                       * saturation is determined by the chroma/luminance
                       * ratio.
                       *
                       * On the other hand, by linearly interpolating
                       * between the original pixel value and a grey
                       * pixel with the same luminance (R=G=B=Y), we
                       * change saturation without affecting luminance.
                       */
                      if (argp->action == ACT_LREDUX)
                        {
                          /*
                           * Calculate a scale factor that will bring the pixel
                           * within both chroma and composite limits, if we scale
                           * luminance and chroma simultaneously.
                           *
                           * The calculated chrominance reduction applies
                           * to the gamma-corrected RGB values that are
                           * the input to the RGB-to-YIQ operation.
                           * Multiplying the original un-gamma-corrected
                           * pixel values by the scaling factor raised to
                           * the "gamma" power is equivalent, and avoids
                           * calling gc() and inv_gc() three times each.  */
                          scale = chroma_lim / fc;
                          t = compos_lim / (fy + fc);
                          if (t < scale)
                            scale = t;
                          scale = pow (scale, mode[argp->mode].gamma);

                          r = (guint8) pix_encode (scale * pr);
                          g = (guint8) pix_encode (scale * pg);
                          b = (guint8) pix_encode (scale * pb);
                        }
                      else
                        { /* ACT_SREDUX hopefully */
                          /*
                           * Calculate a scale factor that will bring the
                           * pixel within both chroma and composite
                           * limits, if we scale chroma while leaving
                           * luminance unchanged.
                           *
                           * We have to interpolate gamma-corrected RGB
                           * values, so we must convert from linear to
                           * gamma-corrected before interpolation and then
                           * back to linear afterwards.
                           */
                          scale = chroma_lim / fc;
                          t = (compos_lim - fy) / fc;
                          if (t < scale)
                            scale = t;

                          pr = gc (pr, argp->mode);
                          pg = gc (pg, argp->mode);
                          pb = gc (pb, argp->mode);

                          py = pr * mode[argp->mode].code[0][0] +
                               pg * mode[argp->mode].code[0][1] +
                               pb * mode[argp->mode].code[0][2];

                          r = pix_encode (inv_gc (py + scale * (pr - py),
                                                  argp->mode));
                          g = pix_encode (inv_gc (py + scale * (pg - py),
                                                  argp->mode));
                          b = pix_encode (inv_gc (py + scale * (pb - py),
                                                  argp->mode));
                        }

                      *d++ = new_r = r;
                      *d++ = new_g = g;
                      *d++ = new_b = b;

                      s += 3;

                      if (bpp == 4)
                        *d++ = *s++;
                      else if (argp->new_layerp)
                        *d++ = 255;
                    }
                }
            }
          else
            {
              if (!argp->new_layerp)
                {
                  for (i = 0; i < bpp; i++)
                    *d++ = *s++;
                }
              else
                {
                  s += bpp;
                  d += 4;
                }
            }
        }
    }

  gimp_pixel_rgn_set_rect (&dstPr, dst, sel_x1, sel_y1, width, height);

  g_free (src);
  g_free (dst);

  if (argp->new_layerp)
    {
      gimp_drawable_flush (ndrw);
      gimp_drawable_update (nl, sel_x1, sel_y1, width, height);
    }
  else
    {
      gimp_drawable_flush (drw);
      gimp_drawable_merge_shadow (drw->drawable_id, TRUE);
      gimp_drawable_update (drw->drawable_id, sel_x1, sel_y1, width, height);
    }

  gimp_displays_flush ();

  return success;
}
コード例 #22
0
ファイル: file-exr.c プロジェクト: AjayRamanathan/gimp
static gint32
load_image (const gchar  *filename,
            gboolean      interactive,
            GError      **error)
{
  gint32 status = -1;
  EXRLoader *loader;
  int width;
  int height;
  gboolean has_alpha;
  GimpImageBaseType image_type;
  GimpPrecision image_precision;
  gint32 image = -1;
  GimpImageType layer_type;
  int layer;
  const Babl *format;
  GeglBuffer *buffer = NULL;
  int bpp;
  int tile_height;
  gchar *pixels = NULL;
  int begin;
  int end;
  int num;

  loader = exr_loader_new (filename);
  if (!loader)
    {
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   _("Error opening file '%s' for reading"),
                   gimp_filename_to_utf8 (filename));
      goto out;
    }

  width = exr_loader_get_width (loader);
  height = exr_loader_get_height (loader);
  if ((width < 1) || (height < 1))
    {
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   _("Error querying image dimensions from '%s'"),
                   gimp_filename_to_utf8 (filename));
      goto out;
    }

  has_alpha = exr_loader_has_alpha (loader) ? TRUE : FALSE;

  switch (exr_loader_get_precision (loader))
    {
    case PREC_UINT:
      image_precision = GIMP_PRECISION_U32;
      break;
    case PREC_HALF:
      image_precision = GIMP_PRECISION_HALF;
      break;
    case PREC_FLOAT:
      image_precision = GIMP_PRECISION_FLOAT;
      break;
    default:
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   _("Error querying image precision from '%s'"),
                   gimp_filename_to_utf8 (filename));
      goto out;
    }

  switch (exr_loader_get_image_type (loader))
    {
    case IMAGE_TYPE_RGB:
      image_type = GIMP_RGB;
      layer_type = has_alpha ? GIMP_RGBA_IMAGE : GIMP_RGB_IMAGE;
      break;
    case IMAGE_TYPE_GRAY:
      image_type = GIMP_GRAY;
      layer_type = has_alpha ? GIMP_GRAYA_IMAGE : GIMP_GRAY_IMAGE;
      break;
    default:
      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                   _("Error querying image type from '%s'"),
                   gimp_filename_to_utf8 (filename));
      goto out;
    }

  gimp_progress_init_printf (_("Opening '%s'"),
                             gimp_filename_to_utf8 (filename));

  image = gimp_image_new_with_precision (width, height,
                                         image_type, image_precision);
  if (image == -1)
    {
      g_set_error (error, 0, 0,
                   _("Could not create new image for '%s': %s"),
                   gimp_filename_to_utf8 (filename), gimp_get_pdb_error ());
      goto out;
    }

  gimp_image_set_filename (image, filename);

  layer = gimp_layer_new (image, _("Background"), width, height,
                          layer_type, 100, GIMP_NORMAL_MODE);
  gimp_image_insert_layer (image, layer, -1, 0);

  buffer = gimp_drawable_get_buffer (layer);
  format = gimp_drawable_get_format (layer);
  bpp = babl_format_get_bytes_per_pixel (format);

  tile_height = gimp_tile_height ();
  pixels = g_new0 (gchar, tile_height * width * bpp);

  for (begin = 0; begin < height; begin += tile_height)
    {
      int retval;
      int i;
      end = MIN (begin + tile_height, height);
      num = end - begin;

      for (i = 0; i < num; i++)
        {
          retval = exr_loader_read_pixel_row (loader,
                                              pixels + (i * width * bpp),
                                              bpp, begin + i);
          if (retval < 0)
            {
              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
                           _("Error reading pixel data from '%s'"),
                           gimp_filename_to_utf8 (filename));
              goto out;
            }
        }

      gegl_buffer_set (buffer, GEGL_RECTANGLE (0, begin, width, num),
                       0, NULL, pixels, GEGL_AUTO_ROWSTRIDE);

      gimp_progress_update ((gdouble) begin / (gdouble) height);
    }

  gimp_progress_update (1.0);

  status = image;

 out:
  if (buffer)
    g_object_unref (buffer);

  if ((status != image) && (image != -1))
    {
      /* This should clean up any associated layers too. */
      gimp_image_delete (image);
    }

  if (pixels)
    g_free (pixels);

  if (loader)
    exr_loader_unref (loader);

  return status;
}
コード例 #23
0
ファイル: ico-save.c プロジェクト: Distrotech/gimp
static void
ico_image_get_reduced_buf (guint32   layer,
                           gint      bpp,
                           gint     *num_colors,
                           guchar  **cmap_out,
                           guchar  **buf_out)
{
  gint32      tmp_image;
  gint32      tmp_layer;
  gint        w, h;
  guchar     *buf;
  guchar     *cmap   = NULL;
  GeglBuffer *buffer = gimp_drawable_get_buffer (layer);
  const Babl *format;

  w = gegl_buffer_get_width  (buffer);
  h = gegl_buffer_get_height (buffer);

  switch (gimp_drawable_type (layer))
    {
    case GIMP_RGB_IMAGE:
      format = babl_format ("R'G'B' u8");
      break;

    case GIMP_RGBA_IMAGE:
      format = babl_format ("R'G'B'A u8");
      break;

    case GIMP_GRAY_IMAGE:
      format = babl_format ("Y' u8");
      break;

    case GIMP_GRAYA_IMAGE:
      format = babl_format ("Y'A u8");
      break;

    case GIMP_INDEXED_IMAGE:
    case GIMP_INDEXEDA_IMAGE:
      format = gegl_buffer_get_format (buffer);

    default:
      g_return_if_reached ();
    }

  *num_colors = 0;

  buf = g_new (guchar, w * h * 4);

  if (bpp <= 8 || bpp == 24 || babl_format_get_bytes_per_pixel (format) != 4)
    {
      gint32      image = gimp_item_get_image (layer);
      GeglBuffer *tmp;

      tmp_image = gimp_image_new (w, h, gimp_image_base_type (image));
      gimp_image_undo_disable (tmp_image);

      if (gimp_drawable_is_indexed (layer))
        {
          guchar *cmap;
          gint    num_colors;

          cmap = gimp_image_get_colormap (image, &num_colors);
          gimp_image_set_colormap (tmp_image, cmap, num_colors);
          g_free (cmap);
        }

      tmp_layer = gimp_layer_new (tmp_image, "tmp", w, h,
                                  gimp_drawable_type (layer),
                                  100, GIMP_NORMAL_MODE);
      gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0);

      tmp = gimp_drawable_get_buffer (tmp_layer);

      gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, w, h), 1.0,
                       format, buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

      gegl_buffer_copy (buffer, NULL, GEGL_ABYSS_NONE, tmp, NULL);

      g_object_unref (tmp);

      if (! gimp_drawable_is_rgb (tmp_layer))
        gimp_image_convert_rgb (tmp_image);

      if (bpp <= 8)
        {
          gimp_image_convert_indexed (tmp_image,
                                      GIMP_FS_DITHER, GIMP_MAKE_PALETTE,
                                      1 << bpp, TRUE, FALSE, "dummy");

          cmap = gimp_image_get_colormap (tmp_image, num_colors);

          if (*num_colors == (1 << bpp) &&
              ! ico_cmap_contains_black (cmap, *num_colors))
            {
              /* Windows icons with color maps need the color black.
               * We need to eliminate one more color to make room for black.
               */

              if (gimp_drawable_is_indexed (layer))
                {
                  g_free (cmap);
                  cmap = gimp_image_get_colormap (image, num_colors);
                  gimp_image_set_colormap (tmp_image, cmap, *num_colors);
                }
              else if (gimp_drawable_is_gray (layer))
                {
                  gimp_image_convert_grayscale (tmp_image);
                }
              else
                {
                  gimp_image_convert_rgb (tmp_image);
                }

              tmp = gimp_drawable_get_buffer (tmp_layer);

              gegl_buffer_set (tmp, GEGL_RECTANGLE (0, 0, w, h), 0,
                               format, buf, GEGL_AUTO_ROWSTRIDE);

              g_object_unref (tmp);

              if (! gimp_drawable_is_rgb (layer))
                gimp_image_convert_rgb (tmp_image);

              gimp_image_convert_indexed (tmp_image,
                                          GIMP_FS_DITHER, GIMP_MAKE_PALETTE,
                                          (1<<bpp) - 1, TRUE, FALSE, "dummy");
              g_free (cmap);
              cmap = gimp_image_get_colormap (tmp_image, num_colors);
            }

          gimp_image_convert_rgb (tmp_image);
        }
      else if (bpp == 24)
        {
          GimpParam    *return_vals;
          gint          n_return_vals;

          return_vals =
            gimp_run_procedure ("plug-in-threshold-alpha", &n_return_vals,
                                GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE,
                                GIMP_PDB_IMAGE, tmp_image,
                                GIMP_PDB_DRAWABLE, tmp_layer,
                                GIMP_PDB_INT32, ICO_ALPHA_THRESHOLD,
                                GIMP_PDB_END);
          gimp_destroy_params (return_vals, n_return_vals);
        }

      gimp_layer_add_alpha (tmp_layer);

      tmp = gimp_drawable_get_buffer (tmp_layer);

      gegl_buffer_get (tmp, GEGL_RECTANGLE (0, 0, w, h), 1.0,
                       NULL, buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);

      g_object_unref (tmp);

      gimp_image_delete (tmp_image);
    }
  else
    {
      gegl_buffer_get (buffer, GEGL_RECTANGLE (0, 0, w, h), 1.0,
                       format, buf,
                       GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE);
    }

  g_object_unref (buffer);

  *cmap_out = cmap;
  *buf_out = buf;
}
コード例 #24
0
ファイル: pagecurl.c プロジェクト: SHIVAPRASAD96/gimp
static gint32
do_curl_effect (gint32 drawable_id)
{
  gint          x = 0;
  gint          y = 0;
  gboolean      color_image;
  gint          x1, y1, k;
  guint         alpha_pos, progress, max_progress;
  gdouble       intensity, alpha;
  GimpVector2   v, dl, dr;
  gdouble       dl_mag, dr_mag, angle, factor;
  guchar       *pp, *dest, fore_grayval, back_grayval;
  guchar       *gradsamp;
  GimpPixelRgn  dest_rgn;
  gpointer      pr;
  gint32        curl_layer_id;
  guchar       *grad_samples  = NULL;

  color_image = gimp_drawable_is_rgb (drawable_id);

  curl_layer =
    gimp_drawable_get (gimp_layer_new (image_id,
				       _("Curl Layer"),
				       true_sel_width,
				       true_sel_height,
				       color_image ?
                                       GIMP_RGBA_IMAGE : GIMP_GRAYA_IMAGE,
				       100, GIMP_NORMAL_MODE));

  curl_layer_id = curl_layer->drawable_id;

  gimp_image_insert_layer (image_id, curl_layer->drawable_id,
                           gimp_item_get_parent (drawable_id),
                           drawable_position);
  gimp_drawable_fill (curl_layer->drawable_id, GIMP_FILL_TRANSPARENT);

  gimp_drawable_offsets (drawable_id, &x1, &y1);
  gimp_layer_set_offsets (curl_layer->drawable_id, sel_x + x1, sel_y + y1);
  gimp_tile_cache_ntiles (2 * (curl_layer->width / gimp_tile_width () + 1));

  gimp_pixel_rgn_init (&dest_rgn, curl_layer,
		       0, 0, true_sel_width, true_sel_height, TRUE, TRUE);

  /* Init shade_under */
  gimp_vector2_set (&dl, -sel_width, -sel_height);
  dl_mag = gimp_vector2_length (&dl);
  gimp_vector2_set (&dr,
		    -(sel_width - right_tangent.x),
		    -(sel_height - right_tangent.y));
  dr_mag = gimp_vector2_length (&dr);
  alpha = acos (gimp_vector2_inner_product (&dl, &dr) / (dl_mag * dr_mag));

  /* Init shade_curl */

  fore_grayval = GIMP_RGB_LUMINANCE (fore_color[0],
                                     fore_color[1],
                                     fore_color[2]) + 0.5;
  back_grayval = GIMP_RGB_LUMINANCE (back_color[0],
                                     back_color[1],
                                     back_color[2]) + 0.5;

  /* Gradient Samples */
  switch (curl.colors)
    {
    case CURL_COLORS_FG_BG:
      break;
    case CURL_COLORS_GRADIENT:
      grad_samples = get_gradient_samples (curl_layer->drawable_id, FALSE);
      break;
    case CURL_COLORS_GRADIENT_REVERSE:
      grad_samples = get_gradient_samples (curl_layer->drawable_id, TRUE);
      break;
    }

  max_progress = 2 * sel_width * sel_height;
  progress = 0;

  alpha_pos = dest_rgn.bpp - 1;

  /* Main loop */
  for (pr = gimp_pixel_rgns_register (1, &dest_rgn);
       pr != NULL;
       pr = gimp_pixel_rgns_process (pr))
    {
      dest = dest_rgn.data;

      for (y1 = dest_rgn.y; y1 < dest_rgn.y + dest_rgn.h; y1++)
	{
	  pp = dest;
	  for (x1 = dest_rgn.x; x1 < dest_rgn.x + dest_rgn.w; x1++)
	    {
	      /* Map coordinates to get the curl correct... */
              switch (curl.orientation)
                {
                case CURL_ORIENTATION_VERTICAL:
		  x = CURL_EDGE_RIGHT (curl.edge) ? x1 : sel_width  - 1 - x1;
		  y = CURL_EDGE_UPPER (curl.edge) ? y1 : sel_height - 1 - y1;
                  break;

                case CURL_ORIENTATION_HORIZONTAL:
                  x = CURL_EDGE_LOWER (curl.edge) ? y1 : sel_width  - 1 - y1;
		  y = CURL_EDGE_LEFT  (curl.edge) ? x1 : sel_height - 1 - x1;
                  break;
		}

	      if (left_of_diagl (x, y))
		{ /* uncurled region */
		  for (k = 0; k <= alpha_pos; k++)
		    pp[k] = 0;
		}
	      else if (right_of_diagr (x, y) ||
		       (right_of_diagm (x, y) &&
			below_diagb (x, y) &&
			!inside_circle (x, y)))
		{
		  /* curled region */
		  for (k = 0; k <= alpha_pos; k++)
		    pp[k] = 0;
		}
	      else
		{
		  v.x = -(sel_width - x);
		  v.y = -(sel_height - y);
		  angle = acos (gimp_vector2_inner_product (&v, &dl) /
				(gimp_vector2_length (&v) * dl_mag));

		  if (inside_circle (x, y) || below_diagb (x, y))
		    {
		      /* Below the curl. */
		      factor = angle / alpha;
		      for (k = 0; k < alpha_pos; k++)
			pp[k] = 0;

		      pp[alpha_pos] = (curl.shade ?
                                       (guchar) ((float) 255 * (float) factor) :
                                       0);
		    }
		  else
		    {
		      /* On the curl */
                      switch (curl.colors)
                        {
                        case CURL_COLORS_FG_BG:
			  intensity = pow (sin (G_PI * angle / alpha), 1.5);
			  if (color_image)
			    {
			      pp[0] = (intensity * back_color[0] +
                                       (1.0 - intensity) * fore_color[0]);
			      pp[1] = (intensity * back_color[1] +
                                       (1.0 - intensity) * fore_color[1]);
			      pp[2] = (intensity * back_color[2] +
                                       (1.0 - intensity) * fore_color[2]);
			    }
			  else
			    pp[0] = (intensity * back_grayval +
                                     (1 - intensity) * fore_grayval);

			  pp[alpha_pos] = (guchar) ((double) 255.99 *
                                                    (1.0 - intensity *
                                                     (1.0 - curl.opacity)));
                          break;

                        case CURL_COLORS_GRADIENT:
                        case CURL_COLORS_GRADIENT_REVERSE:
			  /* Calculate position in Gradient */
                          intensity =
                            (angle/alpha) + sin (G_PI*2 * angle/alpha) * 0.075;

			  /* Check boundaries */
			  intensity = CLAMP (intensity, 0.0, 1.0);
			  gradsamp  = (grad_samples +
                                       ((guint) (intensity * NGRADSAMPLES)) *
                                       dest_rgn.bpp);

			  if (color_image)
			    {
			      pp[0] = gradsamp[0];
			      pp[1] = gradsamp[1];
			      pp[2] = gradsamp[2];
			    }
			  else
			    pp[0] = gradsamp[0];

			  pp[alpha_pos] =
                            (guchar) ((double) gradsamp[alpha_pos] *
                                      (1.0 - intensity * (1.0 - curl.opacity)));
                          break;
                        }
		    }
		}
	      pp += dest_rgn.bpp;
	    }
	  dest += dest_rgn.rowstride;
	}
      progress += dest_rgn.w * dest_rgn.h;
      gimp_progress_update ((double) progress / (double) max_progress);
    }

  gimp_progress_update (1.0);
  gimp_drawable_flush (curl_layer);
  gimp_drawable_merge_shadow (curl_layer->drawable_id, FALSE);
  gimp_drawable_update (curl_layer->drawable_id,
			0, 0, curl_layer->width, curl_layer->height);
  gimp_drawable_detach (curl_layer);

  g_free (grad_samples);

  return curl_layer_id;
}
コード例 #25
0
ファイル: webp-load.c プロジェクト: nathan-osman/gimp-webp
/* Create a layer with the provided image data and add it to the image */
gboolean create_layer(gint32   image_ID,
                      uint8_t *layer_data,
                      gint32   position,
                      gchar   *name,
                      gint     width,
                      gint     height,
                      gint32   offsetx,
                      gint32   offsety)
{
    gint32        layer_ID;
#ifdef GIMP_2_9
    GeglBuffer   *geglbuffer;
    GeglRectangle extent;
#else
    GimpDrawable *drawable;
    GimpPixelRgn  region;
#endif

    layer_ID = gimp_layer_new(image_ID,
                              name,
                              width, height,
	                          GIMP_RGBA_IMAGE,
	                          100,
                              GIMP_NORMAL_MODE);

#ifdef GIMP_2_9
	/* Retrieve the buffer for the layer */
	geglbuffer = gimp_drawable_get_buffer(layer_ID);

	/* Copy the image data to the region */
    gegl_rectangle_set(&extent, 0, 0, width, height);
    gegl_buffer_set(geglbuffer, &extent, 0, NULL, layer_data, GEGL_AUTO_ROWSTRIDE);

	/* Flush the drawable and detach */
    gegl_buffer_flush(geglbuffer);

	g_object_unref(geglbuffer);
#else
    /* Retrieve the drawable for the layer */
    drawable = gimp_drawable_get(layer_ID);

    /* Get a pixel region from the layer */
    gimp_pixel_rgn_init(&region,
                        drawable,
                        0, 0,
                        width, height,
                        FALSE, FALSE);

    /* Copy the image data to the region */
    gimp_pixel_rgn_set_rect(&region,
                            layer_data,
                            0, 0,
                            width, height);

    /* Flush the drawable and detach */
    gimp_drawable_flush(drawable);
    gimp_drawable_detach(drawable);
#endif

    /* Add the new layer to the image */
    gimp_image_insert_layer(image_ID, layer_ID, -1, position);

    /* If layer offsets were provided, use them to position the image */
    if (offsetx || offsety) {
        gimp_layer_set_offsets(layer_ID, offsetx, offsety);
    }

    /* TODO: fix this */
    return TRUE;
}
コード例 #26
0
static gint32
ReadImage (FILE        *fd,
           const gchar *filename,
           gint         len,
           gint         height,
           CMap         cmap,
           gint         ncols,
           gint         format,
           gint         interlace,
           gint         number,
           guint        leftpos,
           guint        toppos,
           guint        screenwidth,
           guint        screenheight)
{
  static gint32 image_ID   = -1;
  static gint   frame_number = 1;

  gint32        layer_ID;
  GimpPixelRgn  pixel_rgn;
  GimpDrawable *drawable;
  guchar       *dest, *temp;
  guchar        c;
  gint          xpos = 0, ypos = 0, pass = 0;
  gint          cur_progress, max_progress;
  gint          v;
  gint          i, j;
  gchar        *framename;
  gchar        *framename_ptr;
  gboolean      alpha_frame = FALSE;
  static gint   previous_disposal;

  /* Guard against bogus frame size */
  if (len < 1 || height < 1)
    {
      g_message ("Bogus frame dimensions");
      return -1;
    }

  /*
   **  Initialize the Compression routines
   */
  if (! ReadOK (fd, &c, 1))
    {
      g_message ("EOF / read error on image data");
      return -1;
    }

  if (LZWReadByte (fd, TRUE, c) < 0)
    {
      g_message ("Error while reading");
      return -1;
    }

  if (frame_number == 1)
    {
      /* Guard against bogus logical screen size values */
      if (screenwidth == 0)
        screenwidth = len;

      if (screenheight == 0)
        screenheight = height;

      image_ID = gimp_image_new (screenwidth, screenheight, GIMP_INDEXED);
      gimp_image_set_filename (image_ID, filename);

      for (i = 0, j = 0; i < ncols; i++)
        {
          used_cmap[0][i] = gimp_cmap[j++] = cmap[0][i];
          used_cmap[1][i] = gimp_cmap[j++] = cmap[1][i];
          used_cmap[2][i] = gimp_cmap[j++] = cmap[2][i];
        }

      gimp_image_set_colormap (image_ID, gimp_cmap, ncols);

      if (Gif89.delayTime < 0)
        framename = g_strdup (_("Background"));
      else
        framename = g_strdup_printf (_("Background (%d%s)"),
                                     10 * Gif89.delayTime, "ms");

      previous_disposal = Gif89.disposal;

      if (Gif89.transparent == -1)
        {
          layer_ID = gimp_layer_new (image_ID, framename,
                                     len, height,
                                     GIMP_INDEXED_IMAGE, 100, GIMP_NORMAL_MODE);
        }
      else
        {
          layer_ID = gimp_layer_new (image_ID, framename,
                                     len, height,
                                     GIMP_INDEXEDA_IMAGE, 100, GIMP_NORMAL_MODE);
          alpha_frame=TRUE;
        }

      g_free (framename);
    }
  else /* NOT FIRST FRAME */
    {
      gimp_progress_set_text_printf (_("Opening '%s' (frame %d)"),
                                     gimp_filename_to_utf8 (filename),
                                     frame_number);
      gimp_progress_pulse ();

       /* If the colourmap is now different, we have to promote to RGB! */
      if (! promote_to_rgb)
        {
          for (i = 0; i < ncols; i++)
            {
              if ((used_cmap[0][i] != cmap[0][i]) ||
                  (used_cmap[1][i] != cmap[1][i]) ||
                  (used_cmap[2][i] != cmap[2][i]))
                {
                  /* Everything is RGB(A) from now on... sigh. */
                  promote_to_rgb = TRUE;

                  /* Promote everything we have so far into RGB(A) */
#ifdef GIFDEBUG
                  g_print ("GIF: Promoting image to RGB...\n");
#endif
                  gimp_image_convert_rgb (image_ID);

                  break;
                }
            }
        }

      if (Gif89.delayTime < 0)
        framename = g_strdup_printf (_("Frame %d"), frame_number);
      else
        framename = g_strdup_printf (_("Frame %d (%d%s)"),
                                     frame_number, 10 * Gif89.delayTime, "ms");

      switch (previous_disposal)
        {
        case 0x00:
          break; /* 'don't care' */
        case 0x01:
          framename_ptr = framename;
          framename = g_strconcat (framename, " (combine)", NULL);
          g_free (framename_ptr);
          break;
        case 0x02:
          framename_ptr = framename;
          framename = g_strconcat (framename, " (replace)", NULL);
          g_free (framename_ptr);
          break;
        case 0x03:  /* Rarely-used, and unhandled by many
                       loaders/players (including GIMP: we treat as
                       'combine' mode). */
          framename_ptr = framename;
          framename = g_strconcat (framename, " (combine) (!)", NULL);
          g_free (framename_ptr);
          break;
        case 0x04: /* I've seen a composite of this type. stvo_online_banner2.gif */
        case 0x05:
        case 0x06: /* I've seen a composite of this type. bn31.Gif */
        case 0x07:
          framename_ptr = framename;
          framename = g_strconcat (framename, " (unknown disposal)", NULL);
          g_free (framename_ptr);
          g_message (_("GIF: Undocumented GIF composite type %d is "
                       "not handled.  Animation might not play or "
                       "re-save perfectly."),
                     previous_disposal);
          break;
        default:
          g_message ("Disposal word got corrupted.  Bug.");
          break;
        }
      previous_disposal = Gif89.disposal;

      layer_ID = gimp_layer_new (image_ID, framename,
                                 len, height,
                                 promote_to_rgb ?
                                 GIMP_RGBA_IMAGE : GIMP_INDEXEDA_IMAGE,
                                 100, GIMP_NORMAL_MODE);
      alpha_frame = TRUE;
      g_free (framename);
    }

  frame_number++;

  gimp_image_insert_layer (image_ID, layer_ID, -1, 0);
  gimp_layer_translate (layer_ID, (gint) leftpos, (gint) toppos);

  drawable = gimp_drawable_get (layer_ID);

  cur_progress = 0;
  max_progress = height;

  if (alpha_frame)
    dest = (guchar *) g_malloc (len * height * (promote_to_rgb ? 4 : 2));
  else
    dest = (guchar *) g_malloc (len * height);

#ifdef GIFDEBUG
    g_print ("GIF: reading %d by %d%s GIF image, ncols=%d\n",
             len, height, interlace ? " interlaced" : "", ncols);
#endif

  if (! alpha_frame && promote_to_rgb)
    {
      /* I don't see how one would easily construct a GIF in which
         this could happen, but it's a mad mad world. */
      g_message ("Ouch!  Can't handle non-alpha RGB frames.\n"
                 "Please file a bug report in GIMP's bugzilla.");
      gimp_quit ();
    }

  while ((v = LZWReadByte (fd, FALSE, c)) >= 0)
    {
      if (alpha_frame)
        {
          if (((guchar) v > highest_used_index) && !(v == Gif89.transparent))
            highest_used_index = (guchar) v;

          if (promote_to_rgb)
            {
              temp = dest + ( (ypos * len) + xpos ) * 4;
              *(temp  ) = (guchar) cmap[0][v];
              *(temp+1) = (guchar) cmap[1][v];
              *(temp+2) = (guchar) cmap[2][v];
              *(temp+3) = (guchar) ((v == Gif89.transparent) ? 0 : 255);
            }
          else
            {
              temp = dest + ( (ypos * len) + xpos ) * 2;
              *temp = (guchar) v;
              *(temp+1) = (guchar) ((v == Gif89.transparent) ? 0 : 255);
            }
        }
      else
        {
          if ((guchar) v > highest_used_index)
            highest_used_index = (guchar) v;

          temp = dest + (ypos * len) + xpos;
          *temp = (guchar) v;
        }

      xpos++;
      if (xpos == len)
        {
          xpos = 0;
          if (interlace)
            {
              switch (pass)
                {
                case 0:
                case 1:
                  ypos += 8;
                  break;
                case 2:
                  ypos += 4;
                  break;
                case 3:
                  ypos += 2;
                  break;
                }

              if (ypos >= height)
                {
                  pass++;
                  switch (pass)
                    {
                    case 1:
                      ypos = 4;
                      break;
                    case 2:
                      ypos = 2;
                      break;
                    case 3:
                      ypos = 1;
                      break;
                    default:
                      goto fini;
                    }
                }
            }
          else
            {
              ypos++;
            }

          if (frame_number == 1)
            {
              cur_progress++;
              if ((cur_progress % 16) == 0)
                gimp_progress_update ((gdouble) cur_progress /
                                      (gdouble) max_progress);
            }
        }

      if (ypos >= height)
        break;
    }

 fini:
  if (LZWReadByte (fd, FALSE, c) >= 0)
    g_print ("GIF: too much input data, ignoring extra...\n");

  gimp_pixel_rgn_init (&pixel_rgn, drawable,
                       0, 0, drawable->width, drawable->height, TRUE, FALSE);
  gimp_pixel_rgn_set_rect (&pixel_rgn, dest,
                           0, 0, drawable->width, drawable->height);

  g_free (dest);

  gimp_drawable_flush (drawable);
  gimp_drawable_detach (drawable);

  return image_ID;
}
コード例 #27
0
ファイル: film.c プロジェクト: LebedevRI/gimp
/* Compose a roll film image from several images */
static gint32
film (void)
{
  gint          width, height;
  guchar       *hole;
  gint          film_height, film_width;
  gint          picture_width, picture_height;
  gint          picture_space, picture_x0, picture_y0;
  gint          hole_offset, hole_width, hole_height, hole_space, hole_x;
  gint          number_height, num_images, num_pictures;
  gint          j, k, picture_count;
  gdouble       f;
  gint          num_layers;
  gint32       *image_ID_src, image_ID_dst, layer_ID_src, layer_ID_dst;
  gint          image_ID_tmp;
  gint32       *layers;
  GimpDrawable *drawable_dst;
  GimpPixelRgn  pixel_rgn_dst;
  gint          new_layer;
  gint          floating_sel;

  /* initialize */

  layers = NULL;

  num_images = filmvals.num_images;
  image_ID_src = filmvals.image;

  if (num_images <= 0)
    return (-1);

  gimp_context_push ();
  gimp_context_set_foreground (&filmvals.number_color);
  gimp_context_set_background (&filmvals.film_color);

  if (filmvals.keep_height) /* Search maximum picture height */
    {
      picture_height = 0;
      for (j = 0; j < num_images; j++)
        {
          height = gimp_image_height (image_ID_src[j]);
          if (height > picture_height) picture_height = height;
        }
      film_height = (int)(picture_height / filmvals.picture_height + 0.5);
      filmvals.film_height = film_height;
    }
  else
    {
      film_height = filmvals.film_height;
      picture_height = (int)(film_height * filmvals.picture_height + 0.5);
    }

  picture_space = (int)(film_height * filmvals.picture_space + 0.5);
  picture_y0 = (film_height - picture_height)/2;

  number_height = film_height * filmvals.number_height;

  /* Calculate total film width */
  film_width = 0;
  num_pictures = 0;
  for (j = 0; j < num_images; j++)
    {
      layers = gimp_image_get_layers (image_ID_src[j], &num_layers);
      /* Get scaled image size */
      width = gimp_image_width (image_ID_src[j]);
      height = gimp_image_height (image_ID_src[j]);
      f = ((double)picture_height) / (double)height;
      picture_width = width * f;

      for (k = 0; k < num_layers; k++)
        {
          if (gimp_layer_is_floating_sel (layers[k]))
            continue;

          film_width += (picture_space/2);  /* Leading space */
          film_width += picture_width;      /* Scaled image width */
          film_width += (picture_space/2);  /* Trailing space */
          num_pictures++;
        }

      g_free (layers);
    }

#ifdef FILM_DEBUG
  g_printerr ("film_height = %d, film_width = %d\n", film_height, film_width);
  g_printerr ("picture_height = %d, picture_space = %d, picture_y0 = %d\n",
              picture_height, picture_space, picture_y0);
  g_printerr ("Number of pictures = %d\n", num_pictures);
#endif

  image_ID_dst = create_new_image (_("Untitled"),
                                   (guint) film_width, (guint) film_height,
                                   GIMP_RGB_IMAGE, &layer_ID_dst,
                                   &drawable_dst, &pixel_rgn_dst);

  /* Fill film background */
  gimp_drawable_fill (layer_ID_dst, GIMP_FILL_BACKGROUND);

  /* Draw all the holes */
  hole_offset = film_height * filmvals.hole_offset;
  hole_width = film_height * filmvals.hole_width;
  hole_height = film_height * filmvals.hole_height;
  hole_space = film_height * filmvals.hole_space;
  hole_x = hole_space / 2;

#ifdef FILM_DEBUG
  g_printerr ("hole_x %d hole_offset %d hole_width %d hole_height %d hole_space %d\n",
              hole_x, hole_offset, hole_width, hole_height, hole_space );
#endif

  hole = create_hole_rgb (hole_width, hole_height);
  if (hole)
    {
      while (hole_x < film_width)
        {
          draw_hole_rgb (drawable_dst, hole_x,
                         hole_offset,
                         hole_width, hole_height, hole);
          draw_hole_rgb (drawable_dst, hole_x,
                         film_height-hole_offset-hole_height,
                         hole_width, hole_height, hole);

          hole_x += hole_width + hole_space;
        }
      g_free (hole);
    }
  gimp_drawable_detach (drawable_dst);


  /* Compose all images and layers */
  picture_x0 = 0;
  picture_count = 0;
  for (j = 0; j < num_images; j++)
    {
      image_ID_tmp = gimp_image_duplicate (image_ID_src[j]);
      width = gimp_image_width (image_ID_tmp);
      height = gimp_image_height (image_ID_tmp);
      f = ((gdouble) picture_height) / (gdouble) height;
      picture_width = width * f;
      if (gimp_image_base_type (image_ID_tmp) != GIMP_RGB)
        gimp_image_convert_rgb (image_ID_tmp);
      gimp_image_scale (image_ID_tmp, picture_width, picture_height);

      layers = gimp_image_get_layers (image_ID_tmp, &num_layers);
      for (k = 0; k < num_layers; k++)
        {
          if (gimp_layer_is_floating_sel (layers[k]))
            continue;

          picture_x0 += picture_space / 2;

          layer_ID_src = layers[k];
          gimp_layer_resize_to_image_size (layer_ID_src);
          new_layer = gimp_layer_new_from_drawable (layer_ID_src,
                                                    image_ID_dst);
          gimp_image_insert_layer (image_ID_dst, new_layer, -1, -1);
          gimp_layer_set_offsets (new_layer, picture_x0, picture_y0);

          /* Draw picture numbers */
          if ((number_height > 0) &&
              (filmvals.number_pos[0] || filmvals.number_pos[1]))
            {
              if (filmvals.number_pos[0])
                draw_number (layer_ID_dst,
                             filmvals.number_start + picture_count,
                             picture_x0 + picture_width/2,
                             (hole_offset-number_height)/2, number_height);
              if (filmvals.number_pos[1])
                draw_number (layer_ID_dst,
                             filmvals.number_start + picture_count,
                             picture_x0 + picture_width/2,
                             film_height - (hole_offset + number_height)/2,
                             number_height);
            }

          picture_x0 += picture_width + (picture_space/2);

          gimp_progress_update (((gdouble) (picture_count + 1)) /
                                (gdouble) num_pictures);

          picture_count++;
        }

      g_free (layers);
      gimp_image_delete (image_ID_tmp);
    }
  gimp_progress_update (1.0);

  gimp_image_flatten (image_ID_dst);

  /* Drawing text/numbers leaves us with a floating selection. Stop it */
  floating_sel = gimp_image_get_floating_sel (image_ID_dst);
  if (floating_sel != -1)
    gimp_floating_sel_anchor (floating_sel);

  gimp_context_pop ();

  return image_ID_dst;
}
コード例 #28
0
ファイル: tile.c プロジェクト: MichaelMure/Gimp-Cage-Tool
static gint32
tile (gint32  image_id,
      gint32  drawable_id,
      gint32 *layer_id)
{
  GimpPixelRgn       src_rgn;
  GimpPixelRgn       dest_rgn;
  GimpDrawable      *drawable;
  GimpDrawable      *new_layer;
  GimpImageBaseType  image_type   = GIMP_RGB;
  gint32             new_image_id = 0;
  gint               old_width;
  gint               old_height;
  gint               i, j;
  gint               progress;
  gint               max_progress;
  gpointer           pr;

  /* sanity check parameters */
  if (tvals.new_width < 1 || tvals.new_height < 1)
    {
      *layer_id = -1;
      return -1;
    }

  /* initialize */
  old_width  = gimp_drawable_width  (drawable_id);
  old_height = gimp_drawable_height (drawable_id);

  if (tvals.new_image)
    {
      /*  create  a new image  */
      switch (gimp_drawable_type (drawable_id))
        {
        case GIMP_RGB_IMAGE:
        case GIMP_RGBA_IMAGE:
          image_type = GIMP_RGB;
          break;

        case GIMP_GRAY_IMAGE:
        case GIMP_GRAYA_IMAGE:
          image_type = GIMP_GRAY;
          break;

        case GIMP_INDEXED_IMAGE:
        case GIMP_INDEXEDA_IMAGE:
          image_type = GIMP_INDEXED;
          break;
        }

      new_image_id = gimp_image_new (tvals.new_width, tvals.new_height,
                                     image_type);
      gimp_image_undo_disable (new_image_id);

      *layer_id = gimp_layer_new (new_image_id, _("Background"),
                                  tvals.new_width, tvals.new_height,
                                  gimp_drawable_type (drawable_id),
                                  100, GIMP_NORMAL_MODE);

      if (*layer_id == -1)
        return -1;

      gimp_image_insert_layer (new_image_id, *layer_id, -1, 0);
      new_layer = gimp_drawable_get (*layer_id);

      /*  Get the source drawable  */
      drawable = gimp_drawable_get (drawable_id);
    }
  else
    {
      gimp_image_undo_group_start (image_id);

      gimp_image_resize (image_id,
                         tvals.new_width, tvals.new_height,
                         0, 0);

      if (gimp_item_is_layer (drawable_id))
        gimp_layer_resize (drawable_id,
                           tvals.new_width, tvals.new_height,
                           0, 0);

      /*  Get the source drawable  */
      drawable = gimp_drawable_get (drawable_id);
      new_layer = drawable;
    }

  /*  progress  */
  progress = 0;
  max_progress = tvals.new_width * tvals.new_height;

  /*  tile...  */
  for (i = 0; i < tvals.new_height; i += old_height)
    {
      gint height = old_height;

      if (height + i > tvals.new_height)
        height = tvals.new_height - i;

      for (j = 0; j < tvals.new_width; j += old_width)
        {
          gint width = old_width;
          gint c;

          if (width + j > tvals.new_width)
            width = tvals.new_width - j;

          gimp_pixel_rgn_init (&src_rgn, drawable,
                               0, 0, width, height, FALSE, FALSE);
          gimp_pixel_rgn_init (&dest_rgn, new_layer,
                               j, i, width, height, TRUE, FALSE);

          for (pr = gimp_pixel_rgns_register (2, &src_rgn, &dest_rgn), c = 0;
               pr != NULL;
               pr = gimp_pixel_rgns_process (pr), c++)
            {
              gint k;

              for (k = 0; k < src_rgn.h; k++)
                memcpy (dest_rgn.data + k * dest_rgn.rowstride,
                        src_rgn.data + k * src_rgn.rowstride,
                        src_rgn.w * src_rgn.bpp);

              progress += src_rgn.w * src_rgn.h;

              if (c % 16 == 0)
                gimp_progress_update ((gdouble) progress /
                                      (gdouble) max_progress);
            }
        }
    }

  gimp_drawable_update (new_layer->drawable_id,
                        0, 0, new_layer->width, new_layer->height);

  gimp_drawable_detach (drawable);

  if (tvals.new_image)
    {
      gimp_drawable_detach (new_layer);

      /*  copy the colormap, if necessary  */
      if (image_type == GIMP_INDEXED)
        {
          guchar *cmap;
          gint    ncols;

          cmap = gimp_image_get_colormap (image_id, &ncols);
          gimp_image_set_colormap (new_image_id, cmap, ncols);
          g_free (cmap);
        }

      gimp_image_undo_enable (new_image_id);
    }
  else
    {
      gimp_image_undo_group_end (image_id);
    }

  return new_image_id;
}
コード例 #29
0
ファイル: ico-dialog.c プロジェクト: Amerekanets/gimp-1
static void
ico_dialog_update_icon_preview (GtkWidget *dialog,
                                gint32     layer,
                                gint       bpp)
{
  GtkWidget *preview = ico_dialog_get_layer_preview (dialog, layer);
  GdkPixbuf *pixbuf;
  gint       w       = gimp_drawable_width (layer);
  gint       h       = gimp_drawable_height (layer);

  if (! preview)
    return;

  if (bpp <= 8)
    {
      GimpDrawable *drawable;
      GimpDrawable *tmp;
      GimpPixelRgn  src_pixel_rgn, dst_pixel_rgn;
      gint32        image;
      gint32        tmp_image;
      gint32        tmp_layer;
      guchar       *buffer;
      guchar       *cmap;
      gint          num_colors;

      image = gimp_item_get_image (layer);

      tmp_image = gimp_image_new (w, h, gimp_image_base_type (image));
      gimp_image_undo_disable (tmp_image);

      if (gimp_drawable_is_indexed (layer))
        {
          cmap = gimp_image_get_colormap (image, &num_colors);
          gimp_image_set_colormap (tmp_image, cmap, num_colors);
          g_free (cmap);
        }

      tmp_layer = gimp_layer_new (tmp_image, "temporary", w, h,
                                  gimp_drawable_type (layer),
                                  100, GIMP_NORMAL_MODE);
      gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0);

      drawable = gimp_drawable_get (layer);
      tmp      = gimp_drawable_get (tmp_layer);

      gimp_pixel_rgn_init (&src_pixel_rgn, drawable, 0, 0, w, h, FALSE, FALSE);
      gimp_pixel_rgn_init (&dst_pixel_rgn, tmp,      0, 0, w, h, TRUE, FALSE);

      buffer = g_malloc (w * h * 4);
      gimp_pixel_rgn_get_rect (&src_pixel_rgn, buffer, 0, 0, w, h);
      gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);

      gimp_drawable_detach (tmp);
      gimp_drawable_detach (drawable);

      if (gimp_drawable_is_indexed (layer))
        gimp_image_convert_rgb (tmp_image);

      gimp_image_convert_indexed (tmp_image,
                                  GIMP_FS_DITHER, GIMP_MAKE_PALETTE,
                                  1 <<bpp, TRUE, FALSE, "dummy");

      cmap = gimp_image_get_colormap (tmp_image, &num_colors);
      if ( num_colors == (1 << bpp) &&
           !ico_cmap_contains_black (cmap, num_colors))
        {
          /* Windows icons with color maps need the color black.
           * We need to eliminate one more color to make room for black.
           */
          if (gimp_drawable_is_indexed (layer))
            {
              g_free (cmap);
              cmap = gimp_image_get_colormap (image, &num_colors);
              gimp_image_set_colormap (tmp_image, cmap, num_colors);
            }
          else if (gimp_drawable_is_gray (layer))
            {
              gimp_image_convert_grayscale (tmp_image);
            }
          else
            {
              gimp_image_convert_rgb (tmp_image);
            }

          tmp = gimp_drawable_get (tmp_layer);
          gimp_pixel_rgn_init (&dst_pixel_rgn,
                               tmp, 0, 0, w, h, TRUE, FALSE);
          gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);
          gimp_drawable_detach (tmp);

          if (!gimp_drawable_is_rgb (layer))
            gimp_image_convert_rgb (tmp_image);

          gimp_image_convert_indexed (tmp_image,
                                      GIMP_FS_DITHER, GIMP_MAKE_PALETTE,
                                      (1<<bpp) - 1, TRUE, FALSE, "dummy");
        }
      g_free (cmap);
      g_free (buffer);

      pixbuf = gimp_drawable_get_thumbnail (tmp_layer,
                                            MIN (w, 128), MIN (h, 128),
                                            GIMP_PIXBUF_SMALL_CHECKS);

      gimp_image_delete (tmp_image);
    }
  else if (bpp == 24)
    {
      GimpDrawable *drawable;
      GimpDrawable *tmp;
      GimpPixelRgn  src_pixel_rgn, dst_pixel_rgn;
      gint32        image;
      gint32        tmp_image;
      gint32        tmp_layer;
      guchar       *buffer;
      GimpParam    *return_vals;
      gint          n_return_vals;

      image = gimp_item_get_image (layer);

      tmp_image = gimp_image_new (w, h, gimp_image_base_type (image));
      gimp_image_undo_disable (tmp_image);

      if (gimp_drawable_is_indexed (layer))
        {
          guchar *cmap;
          gint    num_colors;

          cmap = gimp_image_get_colormap (image, &num_colors);
          gimp_image_set_colormap (tmp_image, cmap, num_colors);
          g_free (cmap);
        }

      tmp_layer = gimp_layer_new (tmp_image, "temporary", w, h,
                                  gimp_drawable_type (layer),
                                  100, GIMP_NORMAL_MODE);
      gimp_image_insert_layer (tmp_image, tmp_layer, -1, 0);

      drawable = gimp_drawable_get (layer);
      tmp      = gimp_drawable_get (tmp_layer);

      gimp_pixel_rgn_init (&src_pixel_rgn, drawable, 0, 0, w, h, FALSE, FALSE);
      gimp_pixel_rgn_init (&dst_pixel_rgn, tmp,      0, 0, w, h, TRUE, FALSE);

      buffer = g_malloc (w * h * 4);
      gimp_pixel_rgn_get_rect (&src_pixel_rgn, buffer, 0, 0, w, h);
      gimp_pixel_rgn_set_rect (&dst_pixel_rgn, buffer, 0, 0, w, h);
      g_free (buffer);

      gimp_drawable_detach (tmp);
      gimp_drawable_detach (drawable);

      if (gimp_drawable_is_indexed (layer))
        gimp_image_convert_rgb (tmp_image);

      return_vals =
        gimp_run_procedure ("plug-in-threshold-alpha", &n_return_vals,
                            GIMP_PDB_INT32, GIMP_RUN_NONINTERACTIVE,
                            GIMP_PDB_IMAGE, tmp_image,
                            GIMP_PDB_DRAWABLE, tmp_layer,
                            GIMP_PDB_INT32, ICO_ALPHA_THRESHOLD,
                            GIMP_PDB_END);
      gimp_destroy_params (return_vals, n_return_vals);

      pixbuf = gimp_drawable_get_thumbnail (tmp_layer,
                                            MIN (w, 128), MIN (h, 128),
                                            GIMP_PIXBUF_SMALL_CHECKS);

      gimp_image_delete (tmp_image);
    }
  else
    {
      pixbuf = gimp_drawable_get_thumbnail (layer,
                                            MIN (w, 128), MIN (h, 128),
                                            GIMP_PIXBUF_SMALL_CHECKS);
    }

  gtk_image_set_from_pixbuf (GTK_IMAGE (preview), pixbuf);
  g_object_unref (pixbuf);
}
コード例 #30
0
gint32
load_image (const gchar  *filename,
            GimpRunMode   runmode,
            gboolean      preview,
            gboolean     *resolution_loaded,
            GError      **error)
{
  gint32 volatile  image_ID;
  gint32           layer_ID;
  struct jpeg_decompress_struct cinfo;
  struct my_error_mgr           jerr;
  jpeg_saved_marker_ptr         marker;
  FILE            *infile;
  guchar          *buf;
  guchar         **rowbuf;
  GimpImageBaseType image_type;
  GimpImageType    layer_type;
  GeglBuffer      *buffer = NULL;
  const Babl      *format;
  gint             tile_height;
  gint             scanlines;
  gint             i, start, end;
  cmsHTRANSFORM    cmyk_transform = NULL;

  /* We set up the normal JPEG error routines. */
  cinfo.err = jpeg_std_error (&jerr.pub);
  jerr.pub.error_exit = my_error_exit;

  if (!preview)
    {
      jerr.pub.output_message = my_output_message;

      gimp_progress_init_printf (_("Opening '%s'"),
                                 gimp_filename_to_utf8 (filename));
    }

  if ((infile = g_fopen (filename, "rb")) == NULL)
    {
      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
                   _("Could not open '%s' for reading: %s"),
                   gimp_filename_to_utf8 (filename), g_strerror (errno));
      return -1;
    }

  image_ID = -1;

  /* Establish the setjmp return context for my_error_exit to use. */
  if (setjmp (jerr.setjmp_buffer))
    {
      /* If we get here, the JPEG code has signaled an error.
       * We need to clean up the JPEG object, close the input file, and return.
       */
      jpeg_destroy_decompress (&cinfo);
      if (infile)
        fclose (infile);

      if (image_ID != -1 && !preview)
        gimp_image_delete (image_ID);

      if (preview)
        destroy_preview ();

      if (buffer)
        g_object_unref (buffer);

      return -1;
    }

  /* Now we can initialize the JPEG decompression object. */
  jpeg_create_decompress (&cinfo);

  /* Step 2: specify data source (eg, a file) */

  jpeg_stdio_src (&cinfo, infile);

  if (! preview)
    {
      /* - step 2.1: tell the lib to save the comments */
      jpeg_save_markers (&cinfo, JPEG_COM, 0xffff);

      /* - step 2.2: tell the lib to save APP1 data (Exif or XMP) */
      jpeg_save_markers (&cinfo, JPEG_APP0 + 1, 0xffff);

      /* - step 2.3: tell the lib to save APP2 data (ICC profiles) */
      jpeg_save_markers (&cinfo, JPEG_APP0 + 2, 0xffff);
    }

  /* Step 3: read file parameters with jpeg_read_header() */

  jpeg_read_header (&cinfo, TRUE);

  /* We can ignore the return value from jpeg_read_header since
   *   (a) suspension is not possible with the stdio data source, and
   *   (b) we passed TRUE to reject a tables-only JPEG file as an error.
   * See libjpeg.doc for more info.
   */

  /* Step 4: set parameters for decompression */

  /* In this example, we don't need to change any of the defaults set by
   * jpeg_read_header(), so we do nothing here.
   */

  /* Step 5: Start decompressor */

  jpeg_start_decompress (&cinfo);

  /* We may need to do some setup of our own at this point before reading
   * the data.  After jpeg_start_decompress() we have the correct scaled
   * output image dimensions available, as well as the output colormap
   * if we asked for color quantization.
   */

  /* temporary buffer */
  tile_height = gimp_tile_height ();
  buf = g_new (guchar,
               tile_height * cinfo.output_width * cinfo.output_components);

  rowbuf = g_new (guchar *, tile_height);

  for (i = 0; i < tile_height; i++)
    rowbuf[i] = buf + cinfo.output_width * cinfo.output_components * i;

  switch (cinfo.output_components)
    {
    case 1:
      image_type = GIMP_GRAY;
      layer_type = GIMP_GRAY_IMAGE;
      break;

    case 3:
      image_type = GIMP_RGB;
      layer_type = GIMP_RGB_IMAGE;
      break;

    case 4:
      if (cinfo.out_color_space == JCS_CMYK)
        {
          image_type = GIMP_RGB;
          layer_type = GIMP_RGB_IMAGE;
          break;
        }
      /*fallthrough*/

    default:
      g_message ("Don't know how to load JPEG images "
                 "with %d color channels, using colorspace %d (%d).",
                 cinfo.output_components, cinfo.out_color_space,
                 cinfo.jpeg_color_space);
      return -1;
      break;
    }

  if (preview)
    {
      image_ID = preview_image_ID;
    }
  else
    {
      image_ID = gimp_image_new_with_precision (cinfo.output_width,
                                                cinfo.output_height,
                                                image_type,
                                                GIMP_PRECISION_U8_GAMMA);

      gimp_image_undo_disable (image_ID);
      gimp_image_set_filename (image_ID, filename);
    }

  if (preview)
    {
      preview_layer_ID = gimp_layer_new (preview_image_ID, _("JPEG preview"),
                                         cinfo.output_width,
                                         cinfo.output_height,
                                         layer_type, 100, GIMP_NORMAL_MODE);
      layer_ID = preview_layer_ID;
    }
  else
    {
      layer_ID = gimp_layer_new (image_ID, _("Background"),
                                 cinfo.output_width,
                                 cinfo.output_height,
                                 layer_type, 100, GIMP_NORMAL_MODE);
    }

  if (! preview)
    {
      GString  *comment_buffer = NULL;
      guint8   *profile        = NULL;
      guint     profile_size   = 0;

      /* Step 5.0: save the original JPEG settings in a parasite */
      jpeg_detect_original_settings (&cinfo, image_ID);

      /* Step 5.1: check for comments, or Exif metadata in APP1 markers */
      for (marker = cinfo.marker_list; marker; marker = marker->next)
        {
          const gchar *data = (const gchar *) marker->data;
          gsize        len  = marker->data_length;

          if (marker->marker == JPEG_COM)
            {
#ifdef GIMP_UNSTABLE
              g_print ("jpeg-load: found image comment (%d bytes)\n",
                       marker->data_length);
#endif

              if (! comment_buffer)
                {
                  comment_buffer = g_string_new_len (data, len);
                }
              else
                {
                  /* concatenate multiple comments, separate them with LF */
                  g_string_append_c (comment_buffer, '\n');
                  g_string_append_len (comment_buffer, data, len);
                }
            }
          else if ((marker->marker == JPEG_APP0 + 1)
                   && (len > sizeof (JPEG_APP_HEADER_EXIF) + 8)
                   && ! strcmp (JPEG_APP_HEADER_EXIF, data))
            {
#ifdef GIMP_UNSTABLE
              g_print ("jpeg-load: found Exif block (%d bytes)\n",
                       (gint) (len - sizeof (JPEG_APP_HEADER_EXIF)));
#endif
            }
        }

      if (jpeg_load_resolution (image_ID, &cinfo))
        {
          if (resolution_loaded)
            *resolution_loaded = TRUE;
        }

      /* if we found any comments, then make a parasite for them */
      if (comment_buffer && comment_buffer->len)
        {
          GimpParasite *parasite;

          jpeg_load_sanitize_comment (comment_buffer->str);
          parasite = gimp_parasite_new ("gimp-comment",
                                        GIMP_PARASITE_PERSISTENT,
                                        strlen (comment_buffer->str) + 1,
                                        comment_buffer->str);
          gimp_image_attach_parasite (image_ID, parasite);
          gimp_parasite_free (parasite);

          g_string_free (comment_buffer, TRUE);
        }

      /* Step 5.3: check for an embedded ICC profile in APP2 markers */
      jpeg_icc_read_profile (&cinfo, &profile, &profile_size);

      if (cinfo.out_color_space == JCS_CMYK)
        {
          cmyk_transform = jpeg_load_cmyk_transform (profile, profile_size);
        }
      else if (profile) /* don't attach the profile if we are transforming */
        {
          GimpParasite *parasite;

          parasite = gimp_parasite_new ("icc-profile",
                                        GIMP_PARASITE_PERSISTENT |
                                        GIMP_PARASITE_UNDOABLE,
                                        profile_size, profile);
          gimp_image_attach_parasite (image_ID, parasite);
          gimp_parasite_free (parasite);
        }

      g_free (profile);

      /* Do not attach the "jpeg-save-options" parasite to the image
       * because this conflicts with the global defaults (bug #75398).
       */
    }

  /* Step 6: while (scan lines remain to be read) */
  /*           jpeg_read_scanlines(...); */

  /* Here we use the library's state variable cinfo.output_scanline as the
   * loop counter, so that we don't have to keep track ourselves.
   */

  buffer = gimp_drawable_get_buffer (layer_ID);
  format = babl_format (image_type == GIMP_RGB ? "R'G'B' u8" : "Y' u8");

  while (cinfo.output_scanline < cinfo.output_height)
    {
      start = cinfo.output_scanline;
      end   = cinfo.output_scanline + tile_height;
      end   = MIN (end, cinfo.output_height);

      scanlines = end - start;

      for (i = 0; i < scanlines; i++)
        jpeg_read_scanlines (&cinfo, (JSAMPARRAY) &rowbuf[i], 1);

      if (cinfo.out_color_space == JCS_CMYK)
        jpeg_load_cmyk_to_rgb (buf, cinfo.output_width * scanlines,
                               cmyk_transform);

      gegl_buffer_set (buffer,
                       GEGL_RECTANGLE (0, start, cinfo.output_width, scanlines),
                       0,
                       format,
                       buf,
                       GEGL_AUTO_ROWSTRIDE);

      if (! preview && (cinfo.output_scanline % 32) == 0)
        gimp_progress_update ((gdouble) cinfo.output_scanline /
                              (gdouble) cinfo.output_height);
    }

  /* Step 7: Finish decompression */

  jpeg_finish_decompress (&cinfo);
  /* We can ignore the return value since suspension is not possible
   * with the stdio data source.
   */

  if (cmyk_transform)
    cmsDeleteTransform (cmyk_transform);

  /* Step 8: Release JPEG decompression object */

  /* This is an important step since it will release a good deal of memory. */
  jpeg_destroy_decompress (&cinfo);

  g_object_unref (buffer);

  /* free up the temporary buffers */
  g_free (rowbuf);
  g_free (buf);

  /* After finish_decompress, we can close the input file.
   * Here we postpone it until after no more JPEG errors are possible,
   * so as to simplify the setjmp error logic above.  (Actually, I don't
   * think that jpeg_destroy can do an error exit, but why assume anything...)
   */
  fclose (infile);

  /* At this point you may want to check to see whether any corrupt-data
   * warnings occurred (test whether jerr.num_warnings is nonzero).
   */

  /* Detach from the drawable and add it to the image.
   */
  if (! preview)
    {
      gimp_progress_update (1.0);
    }

  gimp_image_insert_layer (image_ID, layer_ID, -1, 0);

  return image_ID;
}