GimpImage * gimp_create_image (Gimp *gimp, gint width, gint height, GimpImageBaseType type, GimpPrecision precision, gboolean attach_comment) { GimpImage *image; g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL); image = gimp_image_new (gimp, width, height, type, precision); if (attach_comment) { const gchar *comment; comment = gimp_template_get_comment (gimp->config->default_image); if (comment) { GimpParasite *parasite = gimp_parasite_new ("gimp-comment", GIMP_PARASITE_PERSISTENT, strlen (comment) + 1, comment); gimp_image_parasite_attach (image, parasite); gimp_parasite_free (parasite); } } return image; }
/* ============================================================================ * 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 */
/* Create an image. Sets layer_ID, drawable and rgn. Returns image_ID */ static gint32 create_new_image (const gchar *filename, const gchar *layername, guint width, guint height, GimpImageBaseType type, gdouble xres, gdouble yres, gint32 *layer_ID, GimpDrawable **drawable, GimpPixelRgn *pixel_rgn) { gint32 image_ID; image_ID = gimp_image_new (width, height, type); gimp_image_undo_disable (image_ID); gimp_image_set_filename (image_ID, filename); gimp_image_set_resolution (image_ID, xres, yres); *layer_ID = create_new_layer (image_ID, 0, layername, width, height, type, drawable, pixel_rgn); return image_ID; }
/* ---------------------------------------------------- * 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 */
static gint32 create_image (GdkPixbuf *pixbuf, GdkRegion *shape, const gchar *name) { gint32 image; gint32 layer; gdouble xres, yres; gchar *comment; gint width, height; gboolean status; status = gimp_progress_init (_("Importing screenshot")); 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_get_monitor_resolution (&xres, &yres); gimp_image_set_resolution (image, xres, yres); comment = gimp_get_default_comment (); if (comment) { GimpParasite *parasite; parasite = gimp_parasite_new ("gimp-comment", GIMP_PARASITE_PERSISTENT, strlen (comment) + 1, comment); gimp_image_parasite_attach (image, parasite); gimp_parasite_free (parasite); g_free (comment); } layer = gimp_layer_new_from_pixbuf (image, name ? name : _("Screenshot"), pixbuf, 100, GIMP_NORMAL_MODE, 0.0, 1.0); gimp_image_add_layer (image, layer, 0); if (shape && ! gdk_region_empty (shape)) { image_select_shape (image, shape); if (! gimp_selection_is_empty (image)) { gimp_layer_add_alpha (layer); gimp_edit_clear (layer); gimp_selection_none (image); } } gimp_image_undo_enable (image); return image; }
/* * 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; }
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_drawable_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_add_layer (image_id, preview_id, 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); }
static gint32 create_gimp_image (PSDimage *img_a, const gchar *filename) { gint32 image_id = -1; img_a->base_type = GIMP_RGB; /* Create gimp image */ IFDBG(2) g_debug ("Create image"); image_id = gimp_image_new (img_a->columns, img_a->rows, img_a->base_type); gimp_image_set_filename (image_id, filename); gimp_image_undo_disable (image_id); return image_id; }
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; }
/* ---------------------------------------- * 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_add_layer (ectx->edgeImageId, ectx->edgeDrawableId, 0 /* stackposition */ ); ectx->edgeDrawable = gimp_drawable_get(ectx->edgeDrawableId); } /* end p_createEmptyEdgeDrawable */
/* 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; }
gint32 file_vtf_load_image (const gchar *fname, GError **error) { gimp_progress_init_printf ("Opening '%s'", gimp_filename_to_utf8 (fname)); gint32 image = -1; std::auto_ptr<Vtf::File> vtf (new Vtf::File); try { vtf->load(fname); Vtf::HiresImageResource* vres = (Vtf::HiresImageResource*) vtf->findResource (Vtf::Resource::TypeHires); if (!vres) throw Vtf::Exception ("Cound not find high-resolution image"); image = gimp_image_new (vres->width (), vres->height (), GIMP_RGB); gimp_image_set_filename (image, fname); guint16 i, frame_count = vres->frameCount (); for (i = 0; i < frame_count; i++) { if (!file_vtf_load_layer (vres, image, i)) { g_set_error (error, 0, 0, "Unsupported format %s", Vtf::formatToString (vres->format())); gimp_image_delete (image); image = -1; break; } } gimp_progress_update (1.0); } catch (std::exception& e) { g_set_error (error, 0, 0, e.what ()); } return image; }
gint32 file_vtf_load_thumbnail_image (const gchar *fname, gint *width, gint *height, GError **error) { gint32 image = -1; gimp_progress_init_printf ("Opening thumbnail for '%s'", gimp_filename_to_utf8 (fname)); Vtf::File *vtf = new Vtf::File; try { vtf->load(fname); Vtf::HiresImageResource* vres = (Vtf::HiresImageResource*) vtf->findResource(Vtf::Resource::TypeHires); if (!vres) throw Vtf::Exception ("Cound not find high-resolution image"); *width = static_cast<gint> (vres->width ()); *height = static_cast<gint> (vres->height ()); image = gimp_image_new (*width, *height, GIMP_RGB); if (!file_vtf_load_layer (vres, image, 0)) { g_set_error (error, 0, 0, "Unsupported format %s", Vtf::formatToString(vres->format())); gimp_image_delete (image); image = -1; } gimp_progress_update (1.0); } catch (std::exception& e) { g_set_error (error, 0, 0, e.what()); } delete vtf; return image; }
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 (); }
static void ico_dialog_update_icon_preview (GtkWidget *dialog, gint32 layer, gint bpp) { GtkWidget *preview = ico_dialog_get_layer_preview (dialog, layer); GdkPixbuf *pixbuf; const Babl *format; gint w = gimp_drawable_width (layer); gint h = gimp_drawable_height (layer); if (! preview) return; 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 = gimp_drawable_get_format (layer); default: g_return_if_reached (); } if (bpp <= 8) { GeglBuffer *buffer; GeglBuffer *tmp; gint32 image; gint32 tmp_image; gint32 tmp_layer; guchar *buf; 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); buffer = gimp_drawable_get_buffer (layer); tmp = gimp_drawable_get_buffer (tmp_layer); buf = g_malloc (w * h * 4); 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, tmp, NULL); g_object_unref (tmp); g_object_unref (buffer); 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_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); g_free (buf); 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) { GeglBuffer *buffer; GeglBuffer *tmp; gint32 image; gint32 tmp_image; gint32 tmp_layer; 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); buffer = gimp_drawable_get_buffer (layer); tmp = gimp_drawable_get_buffer (tmp_layer); gegl_buffer_copy (buffer, NULL, tmp, NULL); g_object_unref (tmp); g_object_unref (buffer); 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); }
static GimpPDBStatusType plt_load(gchar *filename, gint32 *image_id) { FILE *stream = 0; unsigned int i; // Using uint for guaranteed sizes across all systems // guint may or may not work (?) uint8_t plt_version[8]; uint32_t plt_width = 0; uint32_t plt_height = 0; uint8_t *buffer; uint8_t px_value = 0; uint8_t px_layer = 0; uint32_t num_px = 0; gint32 newImgID = -1; gint32 newLayerID = -1; gint32 plt_layer_ids[PLT_NUM_LAYERS]; guint8 pixel[2] = {0, 255}; // GRAYA image = 2 Channels: Value + Alpha stream = fopen(filename, "rb"); if(stream == 0) { g_message("Error opening file.\n"); return (GIMP_PDB_EXECUTION_ERROR); } gimp_progress_init_printf("Opening %s", filename); gimp_progress_update(0.0); // Read header: Version, should be 8x1 bytes = "PLT V1 " if (fread(plt_version, 1, 8, stream) < 8) { g_message("Invalid plt file: Unable to read version information.\n"); fclose(stream); return (GIMP_PDB_EXECUTION_ERROR); } if (g_ascii_strncasecmp(plt_version, PLT_HEADER_VERSION, 8) != 0) { g_message("Invalid plt file: Version mismatch.\n"); fclose(stream); return (GIMP_PDB_EXECUTION_ERROR); } // Read header: Next 8 bytes don't matter fseek(stream, 8, SEEK_CUR); // Read header: Width if (fread(&plt_width, 4, 1, stream) < 1) { g_message("Invalid plt file: Unable to read width.\n"); fclose(stream); return (GIMP_PDB_EXECUTION_ERROR); } // Read header: Height if (fread(&plt_height, 4, 1, stream) < 1) { g_message("Invalid plt file: Unable to read height.\n"); fclose(stream); return (GIMP_PDB_EXECUTION_ERROR); } // Create a new image newImgID = gimp_image_new(plt_width, plt_height, GIMP_GRAY); if(newImgID == -1) { g_message("Unable to allocate new image.\n"); fclose(stream); return (GIMP_PDB_EXECUTION_ERROR); } gimp_image_set_filename(newImgID, filename); // Create the 10 plt layers, add them to the new image and save their ID's for (i = 0; i < PLT_NUM_LAYERS; i++) { newLayerID = gimp_layer_new(newImgID, plt_layernames[i], plt_width, plt_height, GIMP_GRAYA_IMAGE, 100.0, GIMP_NORMAL_MODE); gimp_image_insert_layer(newImgID, newLayerID, 0, 0); plt_layer_ids[i] = newLayerID; } // Read image data // Expecting width*height (value, layer) tuples = 2*width*height bytes num_px = plt_width * plt_height; buffer = (uint8_t*) g_malloc(sizeof(uint8_t)*2*num_px); if (fread(buffer, 1, 2*num_px, stream) < (2*num_px)) { g_message("Image size mismatch.\n"); fclose(stream); g_free(buffer); gimp_image_delete(newImgID); return (GIMP_PDB_EXECUTION_ERROR); } for (i = 0; i < num_px; i++) { pixel[0] = buffer[2*i]; px_layer = buffer[2*i+1]; gimp_drawable_set_pixel(plt_layer_ids[px_layer], i % plt_width, plt_height - (int)(floor(i / plt_width)) - 1, 2, pixel); gimp_progress_update((float) i/ (float) num_px); } gimp_progress_update(1.0); gimp_image_set_active_layer(newImgID, plt_layer_ids[0]); fclose(stream); g_free(buffer); *image_id = newImgID; return (GIMP_PDB_SUCCESS); }
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; }
static gint32 load_image (char *filename) { FILE *fp; gint32 image_ID = -1; gint32 layer_ID; GPixelRgn pixel_rgn; GDrawable *drawable; guchar *data; GDrawableType dtype; GImageType itype; struct stat st; int width, height, bpp=0; int i, j, k; int pelbytes, tileheight, wbytes, bsize, npels, pels, ncols, npals; int badread; gushort tmpval; if (stat (filename,&st) == -1) return -1; fp = fopen (filename, "rb"); if (!fp) return -1; bs = (bs_header_t *) g_malloc (st.st_size); fread (bs,st.st_size,1,fp); fclose (fp); if (bs->magic != BS_MAGIC) { printf("not a .bs file\n"); return -1; } gimp_get_data ("bs_width",&width); gimp_get_data ("bs_height",&height); printf("%d x %d\n",width,height); itype = RGB; dtype = RGB_IMAGE; image_ID = gimp_image_new (width, height, itype); gimp_image_set_filename (image_ID, filename); layer_ID = gimp_layer_new (image_ID, "Background", width, height, dtype, 100, NORMAL_MODE); gimp_image_add_layer (image_ID, layer_ID, 0); drawable = gimp_drawable_get (layer_ID); gimp_pixel_rgn_init (&pixel_rgn, drawable, 0, 0, width, height, TRUE, FALSE); data = (guchar *) g_malloc (width * height * 3); bs_init(); bs_decode_rgb24 (data,bs,width,height,0); printf ("image decoded!\n"); gimp_pixel_rgn_set_rect (&pixel_rgn, data, 0, 0, width, height); g_free (data); gimp_drawable_flush (drawable); gimp_drawable_detach (drawable); return image_ID; }
/* * '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; }
gint32 load_djvu (const gchar * filename, GimpRunMode runmode, gboolean preview) { GimpPixelRgn rgn_in; GimpDrawable *drawable; gint32 volatile image_ID; gint32 layer_ID; int x1, y1, x2, y2, width, height; unsigned char *src = NULL; int file_length; ctx = ddjvu_context_create("gimp"); // doc = ddjvu_document_create_by_filename(ctx,filename, TRUE); while (! ddjvu_document_decoding_done(doc)) handle(TRUE); i = ddjvu_document_get_pagenum(doc); dialog( &pageno ,i); //processing the page page = ddjvu_page_create_by_pageno(doc, pageno-1); while (! ddjvu_page_decoding_done(page)) handle(TRUE); if (ddjvu_page_decoding_error(page)) { fprintf(stderr,"unexpected error "); exit(10); } // ddjvu variables ddjvu_rect_t prect; ddjvu_rect_t rrect; ddjvu_format_style_t style; ddjvu_render_mode_t mode; ddjvu_format_t *fmt; int iw = ddjvu_page_get_width(page); int ih = ddjvu_page_get_height(page); int dpi = ddjvu_page_get_resolution(page); ddjvu_page_type_t type = ddjvu_page_get_type(page); char *image = 0; int rowsize; //end of ddjvu variables style= DDJVU_FORMAT_RGB24; mode=DDJVU_RENDER_COLOR; fmt = ddjvu_format_create(style, 0, 0); ddjvu_format_set_row_order(fmt, 1); prect.w = iw; prect.h = ih; prect.x = 0; prect.y = 0; flag_scale=150; prect.w = (unsigned int) (iw * flag_scale) / dpi; prect.h = (unsigned int) (ih * flag_scale) / dpi; rrect = prect; rowsize = (rrect.w *3); image = (char*)malloc(rowsize * rrect.h); //generating page ddjvu_page_render(page, mode, &prect, &rrect, fmt, rowsize, image); ddjvu_page_release(page); char *s =image; /* create output image */ width = prect.w; height = prect.h; x1 = 0; y1 = 0; x2 = prect.w; y2 = prect.h; image_ID = gimp_image_new (width, height, GIMP_RGB); layer_ID = gimp_layer_new (image_ID, _("Background"), width, height, GIMP_RGB, 100, GIMP_NORMAL_MODE); gimp_image_add_layer (image_ID, layer_ID, 0); drawable = gimp_drawable_get (layer_ID); // initializes the drawable gimp_drawable_mask_bounds (drawable->drawable_id, &x1, &y1, &x2, &y2); gimp_pixel_rgn_init (&rgn_in, drawable, x1, y1, x2 - x1, y2 - y1, TRUE, TRUE); gimp_pixel_rgn_set_rect (&rgn_in, image, 0, 0, width, height); //g_free (buf); gimp_drawable_flush (drawable); gimp_drawable_merge_shadow (drawable->drawable_id, TRUE); gimp_drawable_update (drawable->drawable_id, x1, y1, x2 - x1, y2 - y1); gimp_image_set_filename (image_ID, filename); return image_ID; image =NULL; //not handling any error if (doc) ddjvu_document_release(doc); if (ctx) ddjvu_context_release(ctx); }
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); }
gboolean load_image(const gchar *filename, gint32 *image_ID, GError **error) { gboolean status = FALSE; gchar *indata = NULL; gsize indatalen; gint width; gint height; WebPMux *mux = NULL; WebPData wp_data; uint32_t flags; uint8_t *outdata = NULL; #ifdef GIMP_2_9 /* Initialize GEGL */ gegl_init(NULL, NULL); #endif do { /* Attempt to read the file contents from disk */ if (g_file_get_contents(filename, &indata, &indatalen, error) == FALSE) { break; } /* Validate WebP data, grabbing the width and height */ if (!WebPGetInfo(indata, indatalen, &width, &height)) { break; } /* Create a WebPMux from the contents of the file */ wp_data.bytes = (uint8_t*)indata; wp_data.size = indatalen; mux = WebPMuxCreate(&wp_data, 1); if (mux == NULL) { break; } /* Retrieve the features present */ if (WebPMuxGetFeatures(mux, &flags) != WEBP_MUX_OK) { break; } /* TODO: decode the image in "chunks" or "tiles" */ /* TODO: check if an alpha channel is present */ /* Create the new image and associated layer */ *image_ID = gimp_image_new(width, height, GIMP_RGB); #ifdef WEBP_0_5 if (flags & ANIMATION_FLAG) { int frames, i; /* Retrieve the number of frames */ WebPMuxNumChunks(mux, WEBP_CHUNK_ANMF, &frames); /* Loop over each of the frames */ for (i = 0; i < frames; ++i) { WebPMuxFrameInfo frame = {0}; /* Retrieve the data for the frame */ if (WebPMuxGetFrame(mux, i, &frame) != WEBP_MUX_OK) { goto error; } /* Decode the frame */ outdata = WebPDecodeRGBA(frame.bitstream.bytes, frame.bitstream.size, &width, &height); /* Free the compressed data */ WebPDataClear(&frame.bitstream); if (!outdata) { goto error; } /* Create a layer for the frame */ char name[255]; snprintf(name, 255, "Frame %d", (i + 1)); if (create_layer(*image_ID, outdata, 0, (gchar*)name, width, height, frame.x_offset, frame.y_offset) == FALSE) { goto error; } } /* If all is well, jump *over* the error label - otherwise leave the loop and begin cleaning things up */ goto success; error: break; success: ; } else { #endif /* Attempt to decode the data as a WebP image */ outdata = WebPDecodeRGBA(indata, indatalen, &width, &height); if (!outdata) { break; } /* Create a single layer */ status = create_layer(*image_ID, outdata, 0, "Background", width, height, 0, 0); #ifdef WEBP_0_5 } #ifdef GIMP_2_9 /* Load a color profile if one was provided */ if (flags & ICCP_FLAG) { WebPData icc_profile; GimpColorProfile *profile; /* Load the ICC profile from the file */ WebPMuxGetChunk(mux, "ICCP", &icc_profile); /* Have Gimp load the color profile */ profile = gimp_color_profile_new_from_icc_profile( icc_profile.bytes, icc_profile.size, NULL); if (profile) { gimp_image_set_color_profile(image_ID, profile); g_object_unref(profile); } } #endif #endif /* Set the filename for the image */ gimp_image_set_filename(*image_ID, filename); } while(0); /* Delete the mux object */ if (mux) { WebPMuxDelete(mux); } /* Free the data read from disk */ if (indata) { g_free(indata); } return status; }
static gint32 do_optimizations (GimpRunMode run_mode, gboolean diff_only) { GimpPixelRgn pixel_rgn; static guchar *rawframe = NULL; guchar *srcptr; guchar *destptr; gint row, this_frame_num; guint32 frame_sizebytes; gint32 new_layer_id; DisposeType dispose; guchar *this_frame = NULL; guchar *last_frame = NULL; guchar *opti_frame = NULL; guchar *back_frame = NULL; gint this_delay; gint cumulated_delay = 0; gint last_true_frame = -1; gint buflen; gchar *oldlayer_name; gchar *newlayer_name; gboolean can_combine; gint32 bbox_top, bbox_bottom, bbox_left, bbox_right; gint32 rbox_top, rbox_bottom, rbox_left, rbox_right; switch (opmode) { case OPUNOPTIMIZE: gimp_progress_init (_("Unoptimizing animation")); break; case OPFOREGROUND: gimp_progress_init (_("Removing animation background")); break; case OPBACKGROUND: gimp_progress_init (_("Finding animation background")); break; case OPOPTIMIZE: default: gimp_progress_init (_("Optimizing animation")); break; } width = gimp_image_width (image_id); height = gimp_image_height (image_id); layers = gimp_image_get_layers (image_id, &total_frames); imagetype = gimp_image_base_type (image_id); pixelstep = (imagetype == GIMP_RGB) ? 4 : 2; /* gimp_tile_cache_ntiles(total_frames * (width / gimp_tile_width() + 1) );*/ drawabletype_alpha = (imagetype == GIMP_RGB) ? GIMP_RGBA_IMAGE : ((imagetype == GIMP_INDEXED) ? GIMP_INDEXEDA_IMAGE : GIMP_GRAYA_IMAGE); frame_sizebytes = width * height * pixelstep; this_frame = g_malloc (frame_sizebytes); last_frame = g_malloc (frame_sizebytes); opti_frame = g_malloc (frame_sizebytes); if (opmode == OPBACKGROUND || opmode == OPFOREGROUND) back_frame = g_malloc (frame_sizebytes); total_alpha (this_frame, width*height, pixelstep); total_alpha (last_frame, width*height, pixelstep); new_image_id = gimp_image_new(width, height, imagetype); gimp_image_undo_disable (new_image_id); if (imagetype == GIMP_INDEXED) { palette = gimp_image_get_colormap (image_id, &ncolours); gimp_image_set_colormap (new_image_id, palette, ncolours); } #if 1 if (opmode == OPBACKGROUND || opmode == OPFOREGROUND) { /* iterate through all rows of all frames, find statistical mode for each pixel position. */ gint i,j; guchar **these_rows; guchar **red; guchar **green; guchar **blue; guint **count; guint *num_colours; these_rows = g_new (guchar *, total_frames); red = g_new (guchar *, total_frames); green = g_new (guchar *, total_frames); blue = g_new (guchar *, total_frames); count = g_new (guint *, total_frames); num_colours = g_new (guint, width); for (this_frame_num=0; this_frame_num<total_frames; this_frame_num++) { these_rows[this_frame_num] = g_malloc(width * pixelstep); red[this_frame_num] = g_new (guchar, width); green[this_frame_num] = g_new (guchar, width); blue[this_frame_num] = g_new (guchar, width); count[this_frame_num] = g_new0(guint, width); } for (row = 0; row < height; row++) { memset(num_colours, 0, width * sizeof(guint)); for (this_frame_num=0; this_frame_num<total_frames; this_frame_num++) { drawable = gimp_drawable_get (layers[total_frames-(this_frame_num+1)]); dispose = get_frame_disposal (this_frame_num); compose_row(this_frame_num, dispose, row, these_rows[this_frame_num], width, drawable, FALSE ); gimp_drawable_detach(drawable); } for (this_frame_num=0; this_frame_num<total_frames; this_frame_num++) { for (i=0; i<width; i++) { if (these_rows[this_frame_num][i * pixelstep + pixelstep -1] >= 128) { for (j=0; j<num_colours[i]; j++) { switch (pixelstep) { case 4: if (these_rows[this_frame_num][i * 4 +0] == red[j][i] && these_rows[this_frame_num][i * 4 +1] == green[j][i] && these_rows[this_frame_num][i * 4 +2] == blue[j][i]) { (count[j][i])++; goto same; } break; case 2: if (these_rows[this_frame_num][i * 2 +0] == red[j][i]) { (count[j][i])++; goto same; } break; default: g_error ("Eeep!"); break; } } count[num_colours[i]][i] = 1; red[num_colours[i]][i] = these_rows[this_frame_num][i * pixelstep]; if (pixelstep == 4) { green[num_colours[i]][i] = these_rows[this_frame_num][i * 4 +1]; blue[num_colours[i]][i] = these_rows[this_frame_num][i * 4 +2]; } num_colours[i]++; } same: /* nop */; } } for (i=0; i<width; i++) { guint best_count = 0; guchar best_r = 255, best_g = 0, best_b = 255; for (j=0; j<num_colours[i]; j++) { if (count[j][i] > best_count) { best_count = count[j][i]; best_r = red[j][i]; best_g = green[j][i]; best_b = blue[j][i]; } } back_frame[width * pixelstep * row +i*pixelstep + 0] = best_r; if (pixelstep == 4) { back_frame[width * pixelstep * row +i*pixelstep + 1] = best_g; back_frame[width * pixelstep * row +i*pixelstep + 2] = best_b; } back_frame[width * pixelstep * row +i*pixelstep +pixelstep-1] = (best_count == 0) ? 0 : 255; if (best_count == 0) g_warning("yayyyy!"); } /* memcpy(&back_frame[width * pixelstep * row], these_rows[0], width * pixelstep);*/ } for (this_frame_num=0; this_frame_num<total_frames; this_frame_num++) { g_free (these_rows[this_frame_num]); g_free (red[this_frame_num]); g_free (green[this_frame_num]); g_free (blue[this_frame_num]); g_free (count[this_frame_num]); } g_free (these_rows); g_free (red); g_free (green); g_free (blue); g_free (count); g_free (num_colours); }
static void run ( const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[3]; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; SeparateContext mysc; //enum separate_function func = SEP_NONE; run_mode = param[0].data.d_int32; /* setup for localization */ INIT_I18N (); cmsErrorAction( LCMS_ERROR_IGNORE ); mysc.filename = NULL; if( nparams != ( run_mode == GIMP_RUN_NONINTERACTIVE ? 2 : 1 ) ) status = GIMP_PDB_CALLING_ERROR; else if( run_mode == GIMP_RUN_NONINTERACTIVE ) { if( param[1].type != GIMP_PDB_STRING || strlen( param[1].data.d_string ) == 0 ) status = GIMP_PDB_CALLING_ERROR; else mysc.filename = g_strdup( param[1].data.d_string ); } else { gint size = gimp_get_data_size( "plug-in-separate-import/lastpath" ); if( size ) { mysc.filename = g_malloc( size ); gimp_get_data( "plug-in-separate-import/lastpath", mysc.filename ); } } if( status == GIMP_PDB_SUCCESS && ( run_mode == GIMP_RUN_NONINTERACTIVE || separate_import_dialog( &mysc ) ) ) { gint i, j, x, y; TIFF *in; guint32 width, height, stripSize, stripCount, stripHeight; gint16 bps, spp, step, planerConfig, photometric, inkset, resolutionUnit; float xres, yres; const gchar *layerNames[] = { "C", "M", "Y", "K" }; guchar *buf, *maskbuf[4], *srcbuf, *destbuf[4], *iccProfile; gint32 layers[5], masks[4]; GimpDrawable *drw[4]; GimpPixelRgn rgn[4]; GimpRGB primaries[4] = { { .180, .541, .870, 1.0 }, { .925, .149, .388, 1.0 }, { .929, .862, .129, 1.0 }, { 0, 0, 0, 1.0 } }; gchar *str = NULL; gchar *baseName = g_path_get_basename( gimp_filename_to_utf8( mysc.filename ) ); #ifdef G_OS_WIN32 { gchar *_filename = NULL; // win32 filename encoding(not UTF-8) _filename = g_win32_locale_filename_from_utf8( mysc.filename ); in = TIFFOpen( _filename ? _filename : mysc.filename, "r" ); g_free( _filename ); } #else in = TIFFOpen( mysc.filename, "r" ); #endif if( !in ) { str = g_strdup_printf( _( "Cannot open : \"%s\"" ), baseName ); gimp_message( str ); g_free( str ); status = GIMP_PDB_EXECUTION_ERROR; } else { if( ( TIFFGetField( in, TIFFTAG_BITSPERSAMPLE, &bps ) == FALSE || ( bps != 8 && bps != 16 ) ) || ( TIFFGetField( in, TIFFTAG_SAMPLESPERPIXEL, &spp ) == FALSE || spp != 4 ) || ( TIFFGetField( in, TIFFTAG_PHOTOMETRIC, &photometric ) == FALSE || photometric != PHOTOMETRIC_SEPARATED ) || ( TIFFGetField( in, TIFFTAG_PLANARCONFIG, &planerConfig ) == FALSE || planerConfig != PLANARCONFIG_CONTIG ) || ( TIFFGetField( in, TIFFTAG_INKSET, &inkset ) == TRUE && inkset != INKSET_CMYK ) ) { str = g_strdup_printf( _( "\"%s\" is unsupported." ), baseName ); gimp_message( str ); g_free( str ); status = GIMP_PDB_EXECUTION_ERROR; } else { stripCount = TIFFNumberOfStrips( in ); stripSize = TIFFStripSize( in ); TIFFGetField( in, TIFFTAG_IMAGEWIDTH, &width ); TIFFGetField( in, TIFFTAG_IMAGELENGTH, &height ); TIFFGetField( in, TIFFTAG_ROWSPERSTRIP, &stripHeight ); TIFFGetField( in, TIFFTAG_RESOLUTIONUNIT, &resolutionUnit ); TIFFGetField( in, TIFFTAG_XRESOLUTION, &xres ); TIFFGetField( in, TIFFTAG_YRESOLUTION, &yres ); #if 0 str = g_strdup_printf( "Photometric : %d BPS : %d SPP : %d\nInkset : %d StripCount : %d", photometric, bps, spp, inkset, stripCount ); gimp_message( str ); g_free( str ); #endif step = ( bps == 16 ) ? 2 : 1; buf = g_malloc( stripSize ); values[1].data.d_image = gimp_image_new( width, height, GIMP_RGB ); gimp_image_set_resolution( values[1].data.d_image, xres, yres ); gimp_context_push(); for( i = 0; i < 4; i++ ) { layers[i] = gimp_layer_new( values[1].data.d_image, layerNames[i], width, height, GIMP_RGBA_IMAGE, 100.0, GIMP_DARKEN_ONLY_MODE ); gimp_context_set_foreground( &primaries[i] ); gimp_drawable_fill( layers[i], GIMP_FOREGROUND_FILL ); gimp_image_add_layer( values[1].data.d_image, layers[i], i ); masks[i] = gimp_layer_create_mask( layers[i], GIMP_ADD_BLACK_MASK ); gimp_layer_add_mask( layers[i], masks[i] ); drw[i] = gimp_drawable_get( masks[i] ); maskbuf[i] = g_malloc( width * stripHeight ); } gimp_context_pop(); layers[4] = gimp_layer_new( values[1].data.d_image, _( "Background" ), width, height, GIMP_RGB_IMAGE, 100.0, GIMP_NORMAL_MODE ); gimp_drawable_fill( layers[4], GIMP_WHITE_FILL ); gimp_image_add_layer( values[1].data.d_image, layers[4], 4 ); str = g_strdup_printf( _( "Reading \"%s\"..." ), baseName ); gimp_progress_init( str ); g_free( str ); for( i = 0; i < stripCount; i++ ) { guint32 size = TIFFReadEncodedStrip( in, i, buf, stripSize ); guint32 rowCount = ( size < stripSize ? height % stripHeight : stripHeight ); srcbuf = buf; if( bps == 16 ) srcbuf++; for( j = 0; j < 4; j++ ) { gimp_pixel_rgn_init( &( rgn[j] ), drw[j], 0, stripHeight * i, width, rowCount, FALSE, FALSE ); destbuf[j] = maskbuf[j]; } for( y = 0; y < rowCount; y++ ) { for( x = 0; x < width; x++ ) { *destbuf[0]++ = *srcbuf; srcbuf += step; *destbuf[1]++ = *srcbuf; srcbuf += step; *destbuf[2]++ = *srcbuf; srcbuf += step; *destbuf[3]++ = *srcbuf; srcbuf += step; //srcbuf += spp > 4 ? spp - 4 : 0; } } gimp_pixel_rgn_set_rect( &( rgn[0] ), maskbuf[0], 0, stripHeight * i, width, rowCount ); gimp_pixel_rgn_set_rect( &( rgn[1] ), maskbuf[1], 0, stripHeight * i, width, rowCount ); gimp_pixel_rgn_set_rect( &( rgn[2] ), maskbuf[2], 0, stripHeight * i, width, rowCount ); gimp_pixel_rgn_set_rect( &( rgn[3] ), maskbuf[3], 0, stripHeight * i, width, rowCount ); gimp_progress_update( (gdouble)i / stripCount ); } g_free( buf ); for( i = 0; i < 4; i++ ) { g_free( maskbuf[i] ); gimp_drawable_detach( drw[i] ); } #ifdef ENABLE_COLOR_MANAGEMENT if ( TIFFGetField( in, TIFFTAG_ICCPROFILE, &width, &iccProfile ) ) { GimpParasite *parasite; parasite = gimp_parasite_new( CMYKPROFILE, 0, width, iccProfile ); gimp_image_parasite_attach( values[1].data.d_image, parasite ); gimp_parasite_free( parasite ); //g_free( iccProfile ); // This causes clash on TIFFClose( in ). } #endif } TIFFClose( in ); } g_free( baseName ); } else status = GIMP_PDB_CANCEL; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; if( status == GIMP_PDB_SUCCESS ) { *nreturn_vals = 2; values[1].type = GIMP_PDB_IMAGE; if( run_mode != GIMP_RUN_NONINTERACTIVE ) { gimp_image_undo_enable( values[1].data.d_image ); gimp_display_new( values[1].data.d_image ); gimp_displays_flush(); } gimp_set_data( "plug-in-separate-import/lastpath", mysc.filename, strlen( mysc.filename ) + 1 ); } else *nreturn_vals = 1; g_free( mysc.filename ); }
static void border (gint32 image_ID) { GdkPixbuf *pixbuf = NULL; int texture_width; int texture_height; gdouble margin_x; gdouble margin_y; pixbuf = gdk_pixbuf_new_from_inline (-1, bvals.border->texture, FALSE, NULL); if (pixbuf) { texture_width = gdk_pixbuf_get_width (pixbuf); texture_height = gdk_pixbuf_get_height (pixbuf); gint32 texture_image = gimp_image_new (texture_width, texture_height, GIMP_RGB); gint32 texture_layer = gimp_layer_new_from_pixbuf (texture_image, "texture", pixbuf, 100, GIMP_NORMAL_MODE, 0, 0); gimp_image_add_layer (texture_image, texture_layer, -1); gint width = gimp_image_width (image_ID); gint height = gimp_image_height (image_ID); if (bvals.border->top || bvals.border->bottom || bvals.border->left || bvals.border->right) { width += bvals.border->left + bvals.border->right; height += bvals.border->top + bvals.border->bottom; gimp_image_resize (image_ID, width, height, bvals.border->left, bvals.border->top); } gint32 layer = gimp_layer_new (image_ID, "border", width, height, GIMP_RGBA_IMAGE, 100, GIMP_NORMAL_MODE); gimp_image_add_layer (image_ID, layer, -1); if (width > texture_width - bvals.border->length) margin_x = (texture_width - bvals.border->length) / 2; else margin_x = (gdouble) width / 2; if (height > texture_height - bvals.border->length) margin_y = (texture_height - bvals.border->length) / 2; else margin_y = (gdouble) height / 2; /* fix gimp_context_set_pattern ("Clipboard") only works on English versions of Gimp */ //gimp_context_set_pattern ("Clipboard"); INIT_I18N (); gimp_context_set_pattern (_("Clipboard")); if (width > margin_x * 2) { /* top */ gimp_rect_select (texture_image, margin_x, 0, texture_width - margin_x * 2, margin_y, GIMP_CHANNEL_OP_REPLACE, FALSE, 0); gimp_edit_copy (texture_layer); gimp_rect_select (image_ID, margin_x, 0, width - margin_x * 2, margin_y, GIMP_CHANNEL_OP_REPLACE, FALSE, 0); gimp_edit_fill (layer, GIMP_PATTERN_FILL); /* bottom */ gimp_rect_select (texture_image, margin_x, texture_height - margin_y, texture_width - margin_x * 2, texture_height, GIMP_CHANNEL_OP_REPLACE, FALSE, 0); gimp_edit_copy (texture_layer); gimp_rect_select (image_ID, margin_x, height - margin_y, width - margin_x * 2, height, GIMP_CHANNEL_OP_REPLACE, FALSE, 0); gimp_edit_fill (layer, GIMP_PATTERN_FILL); } if (height > margin_y * 2) { /* left */ gimp_rect_select (texture_image, 0, margin_y, margin_x, texture_height - margin_y * 2, GIMP_CHANNEL_OP_REPLACE, FALSE, 0); gimp_edit_copy (texture_layer); gimp_rect_select (image_ID, 0, margin_y, margin_x, height - margin_y * 2, GIMP_CHANNEL_OP_REPLACE, FALSE, 0); gimp_edit_fill (layer, GIMP_PATTERN_FILL); /* right */ gimp_rect_select (texture_image, texture_width - margin_x, margin_y, margin_x, texture_height - margin_y * 2, GIMP_CHANNEL_OP_REPLACE, FALSE, 0); gimp_edit_copy (texture_layer); gimp_rect_select (image_ID, width - margin_x, margin_y, margin_x, height - margin_y * 2, GIMP_CHANNEL_OP_REPLACE, FALSE, 0); gimp_edit_fill (layer, GIMP_PATTERN_FILL); } /* top left */ gimp_rect_select (texture_image, 0, 0, margin_x, margin_y, GIMP_CHANNEL_OP_REPLACE, FALSE, 0); gimp_edit_copy (texture_layer); gimp_rect_select (image_ID, 0, 0, margin_x, margin_y, GIMP_CHANNEL_OP_REPLACE, FALSE, 0); gimp_edit_fill (layer, GIMP_PATTERN_FILL); /* top right */ gimp_rect_select (texture_image, texture_width - margin_x, 0, margin_x, margin_y, GIMP_CHANNEL_OP_REPLACE, FALSE, 0); gimp_edit_copy (texture_layer); gimp_rect_select (image_ID, width - margin_x, 0, margin_x, margin_y, GIMP_CHANNEL_OP_REPLACE, FALSE, 0); gimp_edit_fill (layer, GIMP_PATTERN_FILL); /* bottom left */ gimp_rect_select (texture_image, 0, texture_height - margin_y, margin_x, margin_y, GIMP_CHANNEL_OP_REPLACE, FALSE, 0); gimp_edit_copy (texture_layer); gimp_rect_select (image_ID, 0, height - margin_y, margin_x, margin_y, GIMP_CHANNEL_OP_REPLACE, FALSE, 0); gimp_edit_fill (layer, GIMP_PATTERN_FILL); /* bottom right */ gimp_rect_select (texture_image, texture_width - margin_x, texture_height - margin_y, margin_x, margin_y, GIMP_CHANNEL_OP_REPLACE, FALSE, 0); gimp_edit_copy (texture_layer); gimp_rect_select (image_ID, width - margin_x, height - margin_y, margin_x, margin_y, GIMP_CHANNEL_OP_REPLACE, FALSE, 0); gimp_edit_fill (layer, GIMP_PATTERN_FILL); gimp_image_merge_down(image_ID, layer, GIMP_CLIP_TO_IMAGE); gimp_selection_none (image_ID); } }
static gint32 load_image (PopplerDocument *doc, const gchar *filename, GimpRunMode run_mode, GimpPageSelectorTarget target, guint32 resolution, PdfSelectedPages *pages) { gint32 image_ID = 0; gint32 *images = NULL; gint i; gdouble scale; gdouble doc_progress = 0; if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES) images = g_new0 (gint32, pages->n_pages); gimp_progress_init_printf (_("Opening '%s'"), gimp_filename_to_utf8 (filename)); scale = resolution / gimp_unit_get_factor (GIMP_UNIT_POINT); /* read the file */ for (i = 0; i < pages->n_pages; i++) { PopplerPage *page; gchar *page_label; gdouble page_width; gdouble page_height; GdkPixbuf *buf; gint width; gint height; page = poppler_document_get_page (doc, pages->pages[i]); poppler_page_get_size (page, &page_width, &page_height); width = page_width * scale; height = page_height * scale; g_object_get (G_OBJECT (page), "label", &page_label, NULL); if (! image_ID) { gchar *name; image_ID = gimp_image_new (width, height, GIMP_RGB); gimp_image_undo_disable (image_ID); if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES) name = g_strdup_printf (_("%s-%s"), filename, page_label); else name = g_strdup_printf (_("%s-pages"), filename); gimp_image_set_filename (image_ID, name); g_free (name); gimp_image_set_resolution (image_ID, resolution, resolution); } buf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, width, height); poppler_page_render_to_pixbuf (page, 0, 0, width, height, scale, 0, buf); layer_from_pixbuf (image_ID, page_label, i, buf, doc_progress, 1.0 / pages->n_pages); g_free (page_label); g_object_unref (buf); doc_progress = (double) (i + 1) / pages->n_pages; gimp_progress_update (doc_progress); if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES) { images[i] = image_ID; gimp_image_undo_enable (image_ID); gimp_image_clean_all (image_ID); image_ID = 0; } } if (image_ID) { gimp_image_undo_enable (image_ID); gimp_image_clean_all (image_ID); } if (target == GIMP_PAGE_SELECTOR_TARGET_IMAGES) { if (run_mode != GIMP_RUN_NONINTERACTIVE) { /* Display images in reverse order. The last will be * displayed by GIMP itself */ for (i = pages->n_pages - 1; i > 0; i--) gimp_display_new (images[i]); } image_ID = images[0]; g_free (images); } return image_ID; }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[6]; GimpRunMode run_mode; GimpPDBStatusType status = GIMP_PDB_SUCCESS; gint32 image_ID = -1; PopplerDocument *doc = NULL; GError *error = NULL; run_mode = param[0].data.d_int32; INIT_I18N (); *nreturn_vals = 1; *return_vals = values; values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR; if (! g_thread_supported ()) g_thread_init (NULL); if (strcmp (name, LOAD_PROC) == 0) { PdfSelectedPages pages = { 0, NULL }; switch (run_mode) { case GIMP_RUN_INTERACTIVE: /* Possibly retrieve last settings */ gimp_get_data (LOAD_PROC, &loadvals); doc = open_document (param[1].data.d_string, &error); if (!doc) { status = GIMP_PDB_EXECUTION_ERROR; break; } if (load_dialog (doc, &pages)) gimp_set_data (LOAD_PROC, &loadvals, sizeof(loadvals)); else status = GIMP_PDB_CANCEL; break; case GIMP_RUN_WITH_LAST_VALS: /* FIXME: implement last vals mode */ status = GIMP_PDB_EXECUTION_ERROR; break; case GIMP_RUN_NONINTERACTIVE: doc = open_document (param[1].data.d_string, &error); if (doc) { PopplerPage *test_page = poppler_document_get_page (doc, 0); if (test_page) { pages.n_pages = 1; pages.pages = g_new (gint, 1); pages.pages[0] = 0; g_object_unref (test_page); } else { status = GIMP_PDB_EXECUTION_ERROR; g_object_unref (doc); } } else { status = GIMP_PDB_EXECUTION_ERROR; } break; } if (status == GIMP_PDB_SUCCESS) { image_ID = load_image (doc, param[1].data.d_string, run_mode, loadvals.target, loadvals.resolution, &pages); if (image_ID != -1) { *nreturn_vals = 2; values[1].type = GIMP_PDB_IMAGE; values[1].data.d_image = image_ID; } else { status = GIMP_PDB_EXECUTION_ERROR; } } if (doc) g_object_unref (doc); g_free (pages.pages); } else if (strcmp (name, LOAD_THUMB_PROC) == 0) { if (nparams < 2) { status = GIMP_PDB_CALLING_ERROR; } else { gdouble width = 0; gdouble height = 0; gdouble scale; gint32 image = -1; gint num_pages = 0; GdkPixbuf *pixbuf = NULL; /* Possibly retrieve last settings */ gimp_get_data (LOAD_PROC, &loadvals); doc = open_document (param[0].data.d_string, &error); if (doc) { PopplerPage *page = poppler_document_get_page (doc, 0); if (page) { poppler_page_get_size (page, &width, &height); g_object_unref (page); } num_pages = poppler_document_get_n_pages (doc); pixbuf = get_thumbnail (doc, 0, param[1].data.d_int32); g_object_unref (doc); } if (pixbuf) { image = gimp_image_new (gdk_pixbuf_get_width (pixbuf), gdk_pixbuf_get_height (pixbuf), GIMP_RGB); gimp_image_undo_disable (image); layer_from_pixbuf (image, "thumbnail", 0, pixbuf, 0.0, 1.0); g_object_unref (pixbuf); gimp_image_undo_enable (image); gimp_image_clean_all (image); } scale = loadvals.resolution / gimp_unit_get_factor (GIMP_UNIT_POINT); width *= scale; height *= scale; if (image != -1) { *nreturn_vals = 6; values[1].type = GIMP_PDB_IMAGE; values[1].data.d_image = image; values[2].type = GIMP_PDB_INT32; values[2].data.d_int32 = width; values[3].type = GIMP_PDB_INT32; values[3].data.d_int32 = height; values[4].type = GIMP_PDB_INT32; values[4].data.d_int32 = GIMP_RGB_IMAGE; values[5].type = GIMP_PDB_INT32; values[5].data.d_int32 = num_pages; } else { status = GIMP_PDB_EXECUTION_ERROR; } } } else { status = GIMP_PDB_CALLING_ERROR; } if (status != GIMP_PDB_SUCCESS && error) { *nreturn_vals = 2; values[1].type = GIMP_PDB_STRING; values[1].data.d_string = error->message; } values[0].data.d_status = status; }
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; }
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; }
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); }