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; }
static void export_add_alpha (gint32 image_ID, gint32 *drawable_ID) { gint32 nlayers; gint32 i; gint32 *layers; layers = gimp_image_get_layers (image_ID, &nlayers); for (i = 0; i < nlayers; i++) { if (!gimp_drawable_has_alpha (layers[i])) gimp_layer_add_alpha (layers[i]); } g_free (layers); }
void bimp_apply_drawable_manipulations(image_output imageout, gchar* orig_filename, gchar* orig_basename) { imageout->image_id = gimp_file_load(GIMP_RUN_NONINTERACTIVE, orig_filename, orig_basename); /* load file and get image id */ /* LOAD ERROR CHECK HERE */ g_print("Image ID is %d\n", imageout->image_id); imageout->drawable_id = gimp_image_merge_visible_layers(imageout->image_id, GIMP_CLIP_TO_IMAGE); /* merge levels and get drawable id */ gimp_layer_add_alpha (imageout->drawable_id); g_print("Drawable ID is %d\n", imageout->drawable_id); /* apply all the intermediate manipulations */ g_slist_foreach(bimp_selected_manipulations, (GFunc)apply_manipulation, imageout); /* watermark at last */ if(list_contains_watermark) { g_print("Applying WATERMARK...\n"); apply_watermark((watermark_settings)(bimp_list_get_manip(MANIP_WATERMARK))->settings, imageout); } }
void file_import_image (GimpImage *image, GimpContext *context, GFile *file, gboolean interactive, GimpProgress *progress) { GimpCoreConfig *config; g_return_if_fail (GIMP_IS_IMAGE (image)); g_return_if_fail (GIMP_IS_CONTEXT (context)); g_return_if_fail (G_IS_FILE (file)); g_return_if_fail (progress == NULL || GIMP_IS_PROGRESS (progress)); config = image->gimp->config; if (interactive && gimp_image_get_base_type (image) != GIMP_INDEXED) { if (config->import_promote_float) { GimpPrecision old_precision = gimp_image_get_precision (image); if (old_precision != GIMP_PRECISION_FLOAT_LINEAR) { gimp_image_convert_precision (image, GIMP_PRECISION_FLOAT_LINEAR, GEGL_DITHER_NONE, GEGL_DITHER_NONE, GEGL_DITHER_NONE, progress); if (config->import_promote_dither && old_precision == GIMP_PRECISION_U8_NON_LINEAR) { gimp_image_convert_dither_u8 (image, progress); } } } if (config->import_add_alpha) { GList *layers = gimp_image_get_layer_list (image); GList *list; for (list = layers; list; list = g_list_next (list)) { if (! gimp_viewable_get_children (list->data) && ! gimp_item_is_text_layer (list->data) && ! gimp_drawable_has_alpha (list->data)) { gimp_layer_add_alpha (list->data); } } g_list_free (layers); } } gimp_image_import_color_profile (image, context, progress, interactive); /* Remember the import source */ gimp_image_set_imported_file (image, file); /* We shall treat this file as an Untitled file */ gimp_image_set_file (image, NULL); }
/* Decompose an image. It returns the number of new (gray) images. The image IDs for the new images are returned in image_ID_dst. On failure, -1 is returned. */ static gint32 decompose (gint32 image_ID, gint32 drawable_ID, const gchar *extract_type, gint32 *image_ID_dst, gint32 *nlayers, gint32 *layer_ID_dst) { const gchar *layername; gint i, j, extract_idx, scan_lines; gint height, width, tile_height, num_layers; gchar *filename; guchar *src; guchar *dst[MAX_EXTRACT_IMAGES]; GimpDrawable *drawable_src; GimpDrawable *drawable_dst[MAX_EXTRACT_IMAGES]; GimpPixelRgn pixel_rgn_src; GimpPixelRgn pixel_rgn_dst[MAX_EXTRACT_IMAGES]; extract_idx = -1; /* Search extract type */ for (j = 0; j < G_N_ELEMENTS (extract); j++) { if (g_ascii_strcasecmp (extract_type, extract[j].type) == 0) { extract_idx = j; break; } } if (extract_idx < 0) return -1; /* Check structure of source image */ drawable_src = gimp_drawable_get (drawable_ID); if (drawable_src->bpp < 3) { g_message ("Not an RGB image."); return -1; } if ((extract[extract_idx].extract_fun == extract_alpha || extract[extract_idx].extract_fun == extract_rgba) && (!gimp_drawable_has_alpha (drawable_ID))) { g_message ("No alpha channel available."); return -1; } width = drawable_src->width; height = drawable_src->height; tile_height = gimp_tile_height (); gimp_pixel_rgn_init (&pixel_rgn_src, drawable_src, 0, 0, width, height, FALSE, FALSE); /* allocate a buffer for retrieving information from the src pixel region */ src = g_new (guchar, tile_height * width * drawable_src->bpp); /* Create all new gray images */ num_layers = extract[extract_idx].num_images; if (num_layers > MAX_EXTRACT_IMAGES) num_layers = MAX_EXTRACT_IMAGES; for (j = 0; j < num_layers; j++) { /* Build a filename like <imagename>-<channel>.<extension> */ gchar *fname; gchar *extension; gdouble xres, yres; fname = gimp_image_get_filename (image_ID); if (fname) { extension = fname + strlen (fname) - 1; while (extension >= fname) { if (*extension == '.') break; extension--; } if (extension >= fname) { *(extension++) = '\0'; if (decovals.as_layers) filename = g_strdup_printf ("%s-%s.%s", fname, gettext (extract[extract_idx].type), extension); else filename = g_strdup_printf ("%s-%s.%s", fname, gettext (extract[extract_idx].channel_name[j]), extension); } else { if (decovals.as_layers) filename = g_strdup_printf ("%s-%s", fname, gettext (extract[extract_idx].type)); else filename = g_strdup_printf ("%s-%s", fname, gettext (extract[extract_idx].channel_name[j])); } } else { filename = g_strdup (gettext (extract[extract_idx].channel_name[j])); } gimp_image_get_resolution (image_ID, &xres, &yres); if (decovals.as_layers) { layername = gettext (extract[extract_idx].channel_name[j]); if (j == 0) image_ID_dst[j] = create_new_image (filename, layername, width, height, GIMP_GRAY, xres, yres, layer_ID_dst + j, drawable_dst + j, pixel_rgn_dst + j); else layer_ID_dst[j] = create_new_layer (image_ID_dst[0], j, layername, width, height, GIMP_GRAY, drawable_dst + j, pixel_rgn_dst + j); } else { image_ID_dst[j] = create_new_image (filename, NULL, width, height, GIMP_GRAY, xres, yres, layer_ID_dst + j, drawable_dst + j, pixel_rgn_dst + j); } g_free (filename); g_free (fname); dst[j] = g_new (guchar, tile_height * width); } i = 0; while (i < height) { /* Get source pixel region */ scan_lines = (i+tile_height-1 < height) ? tile_height : (height-i); gimp_pixel_rgn_get_rect (&pixel_rgn_src, src, 0, i, width, scan_lines); /* Extract the channel information */ extract[extract_idx].extract_fun (src, drawable_src->bpp, scan_lines*width, dst); /* Transfer the registration color */ if (decovals.use_registration) transfer_registration_color (src, drawable_src->bpp, scan_lines*width, dst, extract[extract_idx].num_images); /* Set destination pixel regions */ for (j = 0; j < num_layers; j++) gimp_pixel_rgn_set_rect (&(pixel_rgn_dst[j]), dst[j], 0, i, width, scan_lines); i += scan_lines; gimp_progress_update ((gdouble) i / (gdouble) height); } g_free (src); for (j = 0; j < num_layers; j++) { gimp_drawable_detach (drawable_dst[j]); gimp_drawable_update (layer_ID_dst[j], 0, 0, gimp_drawable_width (layer_ID_dst[j]), gimp_drawable_height (layer_ID_dst[j])); gimp_layer_add_alpha (layer_ID_dst[j]); g_free (dst[j]); } gimp_drawable_detach (drawable_src); *nlayers = num_layers; return (decovals.as_layers ? 1 : num_layers); }
gint xjpg_load_layer_alpha (const char *filename, gint32 image_id, gint32 layer_id) { GimpPixelRgn l_pixel_rgn; GimpDrawable *l_drawable; struct jpeg_decompress_struct cinfo; struct my_error_mgr jerr; FILE *infile; guchar *l_buf; guchar *l_dstbuf; guchar **l_rowbuf; int l_tile_height; int l_scanlines; int l_idx, l_start, l_end; int l_alpha_offset; guchar *l_buf_ptr; guchar *l_dstbuf_ptr; /* We set up the normal JPEG error routines. */ cinfo.err = jpeg_std_error (&jerr.pub); jerr.pub.error_exit = my_error_exit; /* add alpha channel */ gimp_layer_add_alpha (layer_id); if ((infile = g_fopen (filename, "rb")) == NULL) { /* No alpha found, thats OK, use full opaque alpha channel * (there is no need not store alpha channels on full opaque channels) * (fixme: if filename exists but is not readable * we should return -1 to indicate an error */ return 0; /* OK */ } /* 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); g_printerr ("XJT: JPEG alpha load error\n"); 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); /* Step 3: read file parameters with jpeg_read_header() */ (void) 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. * In this example, we need to make an output work buffer of the right size. */ /* temporary buffer (for read in jpeg lines) */ l_tile_height = gimp_tile_height (); l_buf = g_new (guchar, l_tile_height * cinfo.output_width * cinfo.output_components); l_rowbuf = g_new (guchar*, l_tile_height); for (l_idx = 0; l_idx < l_tile_height; l_idx++) { l_rowbuf[l_idx] = l_buf + cinfo.output_width * cinfo.output_components * l_idx; } l_drawable = gimp_drawable_get (layer_id); if(l_drawable == NULL) { g_printerr ("XJT: gimp_drawable_get failed on layer id %d\n", (int)layer_id); fclose(infile); return -1; } /* Check if jpeg file can be used as alpha channel */ if((cinfo.output_components != 1) || (cinfo.output_width != l_drawable->width) || (cinfo.output_height != l_drawable->height)) { g_printerr ("XJT: cant load %s as alpha channel\n", filename); fclose (infile); return -1; } /* buffer to read in the layer and merge with the alpha from jpeg file */ l_dstbuf = g_new (guchar, l_tile_height * l_drawable->width * l_drawable->bpp); gimp_pixel_rgn_init (&l_pixel_rgn, l_drawable, 0, 0, l_drawable->width, l_drawable->height, TRUE, FALSE); l_alpha_offset = l_drawable->bpp -1; /* 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. */ while (cinfo.output_scanline < cinfo.output_height) { l_start = cinfo.output_scanline; l_end = cinfo.output_scanline + l_tile_height; l_end = MIN (l_end, cinfo.output_height); l_scanlines = l_end - l_start; for (l_idx = 0; l_idx < l_scanlines; l_idx++) { jpeg_read_scanlines (&cinfo, (JSAMPARRAY) &l_rowbuf[l_idx], 1); } gimp_pixel_rgn_get_rect (&l_pixel_rgn, l_dstbuf, 0, l_start, l_drawable->width, l_scanlines); /* copy the loaded jpeg data (from buf) to the layers alpha channel data */ l_idx = l_tile_height * l_drawable->width; l_buf_ptr = l_buf; l_dstbuf_ptr = l_dstbuf; while(l_idx--) { l_dstbuf_ptr += l_alpha_offset; *l_dstbuf_ptr++ = *l_buf_ptr++; } gimp_pixel_rgn_set_rect (&l_pixel_rgn, l_dstbuf, 0, l_start, l_drawable->width, l_scanlines); gimp_progress_update ((double) cinfo.output_scanline / (double) cinfo.output_height); } gimp_progress_update (1.0); /* Step 7: Finish decompression */ jpeg_finish_decompress (&cinfo); /* We can ignore the return value since suspension is not possible * with the stdio data source. */ /* Step 8: Release JPEG decompression object */ /* This is an important step since it will release a good deal of memory. */ jpeg_destroy_decompress (&cinfo); /* free up the temporary buffers */ g_free (l_rowbuf); g_free (l_buf); g_free (l_dstbuf); /* 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). */ return (0); /* OK */ } /* xjpg_load_layer_alpha */
static GimpLayer * gimp_image_merge_layers (GimpImage *image, GSList *merge_list, GimpContext *context, GimpMergeType merge_type, const gchar *undo_desc) { GList *list; GSList *reverse_list = NULL; PixelRegion src1PR, src2PR, maskPR; PixelRegion *mask; GimpLayer *merge_layer; GimpLayer *layer; GimpLayer *bottom_layer; GimpImageType type; gint count; gint x1, y1, x2, y2; gint x3, y3, x4, y4; CombinationMode operation; gint position; gboolean active[MAX_CHANNELS] = { TRUE, TRUE, TRUE, TRUE }; gint off_x, off_y; gchar *name; g_return_val_if_fail (GIMP_IS_IMAGE (image), NULL); g_return_val_if_fail (GIMP_IS_CONTEXT (context), NULL); layer = NULL; type = GIMP_RGBA_IMAGE; x1 = y1 = 0; x2 = y2 = 0; bottom_layer = NULL; /* Get the layer extents */ count = 0; while (merge_list) { layer = merge_list->data; gimp_item_offsets (GIMP_ITEM (layer), &off_x, &off_y); switch (merge_type) { case GIMP_EXPAND_AS_NECESSARY: case GIMP_CLIP_TO_IMAGE: if (! count) { x1 = off_x; y1 = off_y; x2 = off_x + gimp_item_width (GIMP_ITEM (layer)); y2 = off_y + gimp_item_height (GIMP_ITEM (layer)); } else { if (off_x < x1) x1 = off_x; if (off_y < y1) y1 = off_y; if ((off_x + gimp_item_width (GIMP_ITEM (layer))) > x2) x2 = (off_x + gimp_item_width (GIMP_ITEM (layer))); if ((off_y + gimp_item_height (GIMP_ITEM (layer))) > y2) y2 = (off_y + gimp_item_height (GIMP_ITEM (layer))); } if (merge_type == GIMP_CLIP_TO_IMAGE) { x1 = CLAMP (x1, 0, gimp_image_get_width (image)); y1 = CLAMP (y1, 0, gimp_image_get_height (image)); x2 = CLAMP (x2, 0, gimp_image_get_width (image)); y2 = CLAMP (y2, 0, gimp_image_get_height (image)); } break; case GIMP_CLIP_TO_BOTTOM_LAYER: if (merge_list->next == NULL) { x1 = off_x; y1 = off_y; x2 = off_x + gimp_item_width (GIMP_ITEM (layer)); y2 = off_y + gimp_item_height (GIMP_ITEM (layer)); } break; case GIMP_FLATTEN_IMAGE: if (merge_list->next == NULL) { x1 = 0; y1 = 0; x2 = gimp_image_get_width (image); y2 = gimp_image_get_height (image); } break; } count ++; reverse_list = g_slist_prepend (reverse_list, layer); merge_list = g_slist_next (merge_list); } if ((x2 - x1) == 0 || (y2 - y1) == 0) return NULL; /* Start a merge undo group. */ gimp_image_undo_group_start (image, GIMP_UNDO_GROUP_IMAGE_LAYERS_MERGE, undo_desc); name = g_strdup (gimp_object_get_name (GIMP_OBJECT (layer))); if (merge_type == GIMP_FLATTEN_IMAGE || gimp_drawable_type (GIMP_DRAWABLE (layer)) == GIMP_INDEXED_IMAGE) { guchar bg[4] = { 0, 0, 0, 0 }; type = GIMP_IMAGE_TYPE_FROM_BASE_TYPE (gimp_image_base_type (image)); merge_layer = gimp_layer_new (image, (x2 - x1), (y2 - y1), type, gimp_object_get_name (GIMP_OBJECT (layer)), GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE); if (! merge_layer) { g_warning ("%s: could not allocate merge layer.", G_STRFUNC); return NULL; } GIMP_ITEM (merge_layer)->offset_x = x1; GIMP_ITEM (merge_layer)->offset_y = y1; /* get the background for compositing */ gimp_image_get_background (image, context, gimp_drawable_type (GIMP_DRAWABLE (merge_layer)), bg); /* init the pixel region */ pixel_region_init (&src1PR, gimp_drawable_get_tiles (GIMP_DRAWABLE (merge_layer)), 0, 0, (x2 - x1), (y2 - y1), TRUE); /* set the region to the background color */ color_region (&src1PR, bg); position = 0; } else { /* The final merged layer inherits the name of the bottom most layer * and the resulting layer has an alpha channel whether or not the * original did. Opacity is set to 100% and the MODE is set to normal. */ merge_layer = gimp_layer_new (image, (x2 - x1), (y2 - y1), gimp_drawable_type_with_alpha (GIMP_DRAWABLE (layer)), "merged layer", GIMP_OPACITY_OPAQUE, GIMP_NORMAL_MODE); if (!merge_layer) { g_warning ("%s: could not allocate merge layer", G_STRFUNC); return NULL; } GIMP_ITEM (merge_layer)->offset_x = x1; GIMP_ITEM (merge_layer)->offset_y = y1; /* clear the layer */ pixel_region_init (&src1PR, gimp_drawable_get_tiles (GIMP_DRAWABLE (merge_layer)), 0, 0, (x2 - x1), (y2 - y1), TRUE); clear_region (&src1PR); /* Find the index in the layer list of the bottom layer--we need this * in order to add the final, merged layer to the layer list correctly */ layer = reverse_list->data; position = gimp_container_num_children (image->layers) - gimp_container_get_child_index (image->layers, GIMP_OBJECT (layer)); } bottom_layer = layer; /* Copy the tattoo and parasites of the bottom layer to the new layer */ gimp_item_set_tattoo (GIMP_ITEM (merge_layer), gimp_item_get_tattoo (GIMP_ITEM (bottom_layer))); g_object_unref (GIMP_ITEM (merge_layer)->parasites); GIMP_ITEM (merge_layer)->parasites = gimp_parasite_list_copy (GIMP_ITEM (bottom_layer)->parasites); while (reverse_list) { GimpLayerModeEffects mode; layer = reverse_list->data; /* determine what sort of operation is being attempted and * if it's actually legal... */ operation = gimp_image_merge_layers_get_operation (merge_layer, layer); if (operation == -1) { gimp_layer_add_alpha (layer); /* try again ... */ operation = gimp_image_merge_layers_get_operation (merge_layer, layer); } if (operation == -1) { g_warning ("%s: attempting to merge incompatible layers.", G_STRFUNC); return NULL; } gimp_item_offsets (GIMP_ITEM (layer), &off_x, &off_y); x3 = CLAMP (off_x, x1, x2); y3 = CLAMP (off_y, y1, y2); x4 = CLAMP (off_x + gimp_item_width (GIMP_ITEM (layer)), x1, x2); y4 = CLAMP (off_y + gimp_item_height (GIMP_ITEM (layer)), y1, y2); /* configure the pixel regions */ pixel_region_init (&src1PR, gimp_drawable_get_tiles (GIMP_DRAWABLE (merge_layer)), (x3 - x1), (y3 - y1), (x4 - x3), (y4 - y3), TRUE); pixel_region_init (&src2PR, gimp_drawable_get_tiles (GIMP_DRAWABLE (layer)), (x3 - off_x), (y3 - off_y), (x4 - x3), (y4 - y3), FALSE); if (gimp_layer_get_mask (layer) && gimp_layer_mask_get_apply (layer->mask)) { TileManager *tiles; tiles = gimp_drawable_get_tiles (GIMP_DRAWABLE (layer->mask)); pixel_region_init (&maskPR, tiles, (x3 - off_x), (y3 - off_y), (x4 - x3), (y4 - y3), FALSE); mask = &maskPR; } else { mask = NULL; } /* DISSOLVE_MODE is special since it is the only mode that does not * work on the projection with the lower layer, but only locally on * the layers alpha channel. */ mode = gimp_layer_get_mode (layer); if (layer == bottom_layer && mode != GIMP_DISSOLVE_MODE) mode = GIMP_NORMAL_MODE; combine_regions (&src1PR, &src2PR, &src1PR, mask, NULL, gimp_layer_get_opacity (layer) * 255.999, mode, active, operation); gimp_image_remove_layer (image, layer); reverse_list = g_slist_next (reverse_list); } g_slist_free (reverse_list); /* if the type is flatten, remove all the remaining layers */ if (merge_type == GIMP_FLATTEN_IMAGE) { list = GIMP_LIST (image->layers)->list; while (list) { layer = list->data; list = g_list_next (list); gimp_image_remove_layer (image, layer); } gimp_image_add_layer (image, merge_layer, position); } else { /* Add the layer to the image */ gimp_image_add_layer (image, merge_layer, gimp_container_num_children (image->layers) - position + 1); } /* set the name after the original layers have been removed so we * don't end up with #2 appended to the name */ gimp_object_take_name (GIMP_OBJECT (merge_layer), name); gimp_item_set_visible (GIMP_ITEM (merge_layer), TRUE, TRUE); /* End the merge undo group */ gimp_image_undo_group_end (image); gimp_drawable_update (GIMP_DRAWABLE (merge_layer), 0, 0, gimp_item_width (GIMP_ITEM (merge_layer)), gimp_item_height (GIMP_ITEM (merge_layer))); return merge_layer; }
static void init_calculation (gint32 drawable_id) { gdouble k; gdouble alpha, beta; gdouble angle; GimpVector2 v1, v2; gint32 *image_layers; gint32 nlayers; GimpRGB color; gimp_layer_add_alpha (drawable_id); /* Image parameters */ /* Determine Position of original Layer in the Layer stack. */ image_layers = gimp_image_get_layers (image_id, &nlayers); drawable_position = 0; while (drawable_position < nlayers && image_layers[drawable_position] != drawable_id) drawable_position++; switch (curl.orientation) { case CURL_ORIENTATION_VERTICAL: sel_width = true_sel_width; sel_height = true_sel_height; break; case CURL_ORIENTATION_HORIZONTAL: sel_width = true_sel_height; sel_height = true_sel_width; break; } /* Circle parameters */ alpha = atan ((double) sel_height / sel_width); beta = alpha / 2.0; k = sel_width / ((G_PI + alpha) * sin (beta) + cos (beta)); gimp_vector2_set (¢er, k * cos (beta), k * sin (beta)); radius = center.y; /* left_tangent */ gimp_vector2_set (&left_tangent, radius * -sin (alpha), radius * cos (alpha)); gimp_vector2_add (&left_tangent, &left_tangent, ¢er); /* right_tangent */ gimp_vector2_sub (&v1, &left_tangent, ¢er); gimp_vector2_set (&v2, sel_width - center.x, sel_height - center.y); angle = -2.0 * acos (gimp_vector2_inner_product (&v1, &v2) / (gimp_vector2_length (&v1) * gimp_vector2_length (&v2))); gimp_vector2_set (&right_tangent, v1.x * cos (angle) + v1.y * -sin (angle), v1.x * sin (angle) + v1.y * cos (angle)); gimp_vector2_add (&right_tangent, &right_tangent, ¢er); /* Slopes */ diagl_slope = (double) sel_width / sel_height; diagr_slope = (sel_width - right_tangent.x) / (sel_height - right_tangent.y); diagb_slope = ((right_tangent.y - left_tangent.y) / (right_tangent.x - left_tangent.x)); diagm_slope = (sel_width - center.x) / sel_height; /* Colors */ gimp_context_get_foreground (&color); gimp_rgb_get_uchar (&color, &fore_color[0], &fore_color[1], &fore_color[2]); gimp_context_get_background (&color); gimp_rgb_get_uchar (&color, &back_color[0], &back_color[1], &back_color[2]); }
static void run (const gchar *name, gint nparams, const GimpParam *param, gint *nreturn_vals, GimpParam **return_vals) { static GimpParam values[1]; GimpDrawable *drawable; GimpPDBStatusType status = GIMP_PDB_SUCCESS; GimpRunMode run_mode; gint32 image_ID; run_mode = param[0].data.d_int32; *nreturn_vals = 1; *return_vals = values; INIT_I18N (); values[0].type = GIMP_PDB_STATUS; values[0].data.d_status = status; image_ID = param[1].data.d_image; drawable = gimp_drawable_get (param[2].data.d_drawable); switch (run_mode) { case GIMP_RUN_INTERACTIVE: gimp_get_data (PLUG_IN_PROC, &pvals); if (! color_to_alpha_dialog (drawable)) { gimp_drawable_detach (drawable); return; } break; case GIMP_RUN_NONINTERACTIVE: if (nparams != 4) status = GIMP_PDB_CALLING_ERROR; if (status == GIMP_PDB_SUCCESS) pvals.color = param[3].data.d_color; break; case GIMP_RUN_WITH_LAST_VALS: gimp_get_data (PLUG_IN_PROC, &pvals); break; default: break; } if (status == GIMP_PDB_SUCCESS && gimp_drawable_is_rgb (drawable->drawable_id) && gimp_item_is_layer (drawable->drawable_id)) { gboolean lock_alpha; gimp_image_undo_group_start (image_ID); /* Add alpha if not present */ gimp_layer_add_alpha (drawable->drawable_id); /* Reget the drawable, bpp might have changed */ drawable = gimp_drawable_get (drawable->drawable_id); /* Unset 'Lock alpha' */ lock_alpha = gimp_layer_get_lock_alpha (drawable->drawable_id); gimp_layer_set_lock_alpha (drawable->drawable_id, FALSE); gimp_progress_init (_("Removing color")); gimp_rgn_iterate2 (drawable, 0 /* unused */, to_alpha_func, NULL); gimp_layer_set_lock_alpha (drawable->drawable_id, lock_alpha); gimp_image_undo_group_end (image_ID); if (run_mode != GIMP_RUN_NONINTERACTIVE) gimp_displays_flush (); } gimp_drawable_detach (drawable); if (run_mode == GIMP_RUN_INTERACTIVE) gimp_set_data (PLUG_IN_PROC, &pvals, sizeof (pvals)); values[0].data.d_status = status; }
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; }